# coding: utf-8
# Copyright (c) Pymatgen Development Team.
# Distributed under the terms of the MIT License.

"""
This module provides classes for calculating the ewald sum of a structure.
"""

from math import pi, sqrt, log
from datetime import datetime
from copy import deepcopy, copy
from warnings import warn
import bisect

import numpy as np
from scipy.special import erfc, comb
import scipy.constants as constants

__author__ = "Shyue Ping Ong, William Davidson Richard"
__copyright__ = "Copyright 2011, The Materials Project"
__credits__ = "Christopher Fischer"
__version__ = "1.0"
__maintainer__ = "Shyue Ping Ong"
__email__ = "shyuep@gmail.com"
__status__ = "Production"
__date__ = "Aug 1 2012"


class EwaldSummation:
    """
    Calculates the electrostatic energy of a periodic array of charges using
    the Ewald technique.


    Ref:
    Ewald summation techniques in perspective: a survey
    Abdulnour Y. Toukmaji and John A. Board Jr.
    DOI: 10.1016/0010-4655(96)00016-1
    URL: http://www.ee.duke.edu/~ayt/ewaldpaper/ewaldpaper.html

    This matrix can be used to do fast calculations of ewald sums after species
    removal.

    E = E_recip + E_real + E_point

    Atomic units used in the code, then converted to eV.
    """

    # Converts unit of q*q/r into eV
    CONV_FACT = 1e10 * constants.e / (4 * pi * constants.epsilon_0)

    def __init__(self, structure, real_space_cut=None, recip_space_cut=None,
                 eta=None, acc_factor=12.0, w=1 / sqrt(2), compute_forces=False):
        """