Vous êtes sur la page 1sur 2

from numpy import sqrt

from scipy.special import erfc


from scipy import exp, pi

# constant value: Vacuum Permittivity


vacuum_permittivity = 8.854187817 * 10 ** (-12)

def ewald_sum(i, r, p, box, volume, image_box, sigma, n_max=3, m_max=9):

"""
i : potential location
r : distance between particles
p : list of charged particles
sigma : Ewald convergence parameter, determines the relative rate of
convergence b/w real and reciprocal sum
n_max : an integer defines the range of real-space sum and control its max no
of vectors
m_max : an integer define the summation range in the reciprocal space and its
no of vectors
"""

pot_realsum = potential_r_ewald(i, r, p, box, sigma, n_max)


pot_recipsum = potential_k_ewald(i, r, p, image_box, sigma, m_max, volume)
pot_selfsum = potential_self_ewald(i, r, p, sigma)
return pot_realsum + pot_recipsum + pot_selfsum

# Compute general operations ...#

def compute_dot_product(vec_1, vec_2):

if len(vec_1) != len(vec_2):
return 0

dot_product = 0
for i in range(len(vec_1)):
dot_product += vec_1[i] * vec_2[i]

return dot_product

def compute_norm(vector):

summation = 0
for i in range(len(vector)):
summation += vector[i]**2
distance = sqrt(summation)

return distance

# Evaluate potentials ...#

def potential_r_ewald(i, r, p, box, sigma, n_max):


pot_r = 0
for j in range(0, len(p)):
rij = r[i, :] - r[j, :]
potr_loc = 0
for nx in range(-n_max, n_max+1):
for ny in range(-n_max, n_max+1):
for nz in range(-n_max, n_max+1):
if max([abs(nx), abs(ny), abs(nz)]):
nl = nx*box[0, :]+ny*box[1, :]+nz*box[2, :]
particle_distance = rij - nl
mag = compute_norm(particle_distance)
potr_loc += erfc(mag/(sqrt(2) * sigma * mag))
pot_r += (1/8 * pi * vacuum_permittivity) * p[j] * potr_loc
return pot_r

def potential_k_ewald(i, r, p, box, sigma, m_max, volume):


pot_k = 0
for j in range(0, len(p)):
rij = r[i, :] - r[j, :]
potk_loc = 0
for nz in range(-m_max, m_max+1):
for ny in range(-m_max, m_max+1):
for nx in range(-m_max, m_max+1):
if max([abs(nx), abs(ny), abs(nz)]):
m = 2*pi*(nx*box[0, :]+ny*box[1, :]+nz*box[2, :])
potk_loc += exp(1.j * compute_dot_product(m, rij) -
(compute_dot_product(m, m) * sigma**2/2))/(compute_dot_product(m, m)/(4*pi**2))

pot_k += (1/2 * pi * vacuum_permittivity * volume) * p[j] * potk_loc


return pot_k

def potential_self_ewald(i, r, p, sigma):


pot_self = 0
for j in range(0, len(p)):
if i == j:
pot_self -= p[j] * (1/(2 * pi)**3/2 * sigma * vacuum_permittivity)
else:
particle_distance = r[i, :] - r[j, :]
mag = compute_norm(particle_distance)
pot_self += (1/4 * pi * vacuum_permittivity) * p[j] * erfc(mag/(sqrt(2)
* sigma * mag))
return pot_self

Vous aimerez peut-être aussi