76 SUBROUTINE ewald_evaluate(ewald_env, ewald_pw, cell, atomic_kind_set, particle_set, &
77 local_particles, fg_coulomb, vg_coulomb, pv_g, use_virial, charges, e_coulomb)
84 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: fg_coulomb
85 REAL(kind=
dp),
INTENT(OUT) :: vg_coulomb
86 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: pv_g
87 LOGICAL,
INTENT(IN) :: use_virial
88 REAL(kind=
dp),
DIMENSION(:),
OPTIONAL,
POINTER :: charges, e_coulomb
90 CHARACTER(LEN=*),
PARAMETER :: routinen =
'ewald_evaluate'
92 COMPLEX(KIND=dp) :: snode
93 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:) :: summe
94 INTEGER :: gpt, handle, iparticle, iparticle_kind, &
95 iparticle_local, lp, mp, nnodes, node, &
96 np, nparticle_kind, nparticle_local
97 INTEGER,
DIMENSION(:, :),
POINTER :: bds
98 LOGICAL :: atenergy, use_charge_array
99 REAL(kind=
dp) :: alpha, denom, e_igdotr, factor, &
100 four_alpha_sq, gauss, pref, q
101 REAL(kind=
dp),
DIMENSION(3) :: vec
102 REAL(kind=
dp),
DIMENSION(:),
POINTER :: charge
103 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: rho0
112 CALL timeset(routinen, handle)
114 use_charge_array = .false.
115 IF (
PRESENT(charges)) use_charge_array =
ASSOCIATED(charges)
116 atenergy =
PRESENT(e_coulomb)
117 IF (atenergy) atenergy =
ASSOCIATED(e_coulomb)
118 IF (atenergy) e_coulomb = 0._dp
123 CALL dg_get(dg, dg_rho0=dg_rho0)
124 rho0 => dg_rho0%density%array
125 pw_grid => pw_pool%pw_grid
126 bds => pw_grid%bounds
129 nparticle_kind =
SIZE(atomic_kind_set)
131 DO iparticle_kind = 1, nparticle_kind
132 nnodes = nnodes + local_particles%n_el(iparticle_kind)
137 ALLOCATE (summe(1:pw_grid%ngpts_cut))
138 ALLOCATE (charge(1:nnodes))
143 IF (use_virial) pv_g = 0.0_dp
145 four_alpha_sq = 4.0_dp*alpha**2
148 DO iparticle_kind = 1, nparticle_kind
149 nparticle_local = local_particles%n_el(iparticle_kind)
150 IF (use_charge_array)
THEN
151 DO iparticle_local = 1, nparticle_local
153 iparticle = local_particles%list(iparticle_kind)%array(iparticle_local)
154 charge(node) = charges(iparticle)
155 vec = matmul(cell%h_inv, particle_set(iparticle)%r)
157 exp_igr%ex(:, node), exp_igr%ey(:, node), exp_igr%ez(:, node))
160 atomic_kind => atomic_kind_set(iparticle_kind)
162 DO iparticle_local = 1, nparticle_local
164 iparticle = local_particles%list(iparticle_kind)%array(iparticle_local)
166 vec = matmul(cell%h_inv, particle_set(iparticle)%r)
168 exp_igr%ex(:, node), exp_igr%ey(:, node), exp_igr%ez(:, node))
175 DO gpt = 1, pw_grid%ngpts_cut_local
177 lp = pw_grid%mapl%pos(pw_grid%g_hat(1, gpt))
178 mp = pw_grid%mapm%pos(pw_grid%g_hat(2, gpt))
179 np = pw_grid%mapn%pos(pw_grid%g_hat(3, gpt))
187 summe(gpt) = summe(gpt) + charge(node)* &
188 (exp_igr%ex(lp, node) &
189 *exp_igr%ey(mp, node) &
190 *exp_igr%ez(np, node))
193 CALL group%sum(summe)
198 DO gpt = 1, pw_grid%ngpts_cut_local
200 lp = pw_grid%mapl%pos(pw_grid%g_hat(1, gpt))
201 mp = pw_grid%mapm%pos(pw_grid%g_hat(2, gpt))
202 np = pw_grid%mapn%pos(pw_grid%g_hat(3, gpt))
208 IF (pw_grid%gsq(gpt) <= 1.0e-10_dp) cycle
210 gauss = (rho0(lp, mp, np)*pw_grid%vol)**2/pw_grid%gsq(gpt)
211 factor = gauss*real(summe(gpt)*conjg(summe(gpt)), kind=
dp)
212 vg_coulomb = vg_coulomb + factor
217 snode = conjg(exp_igr%ex(lp, node) &
218 *exp_igr%ey(mp, node) &
219 *exp_igr%ez(np, node))
220 e_coulomb(node) = e_coulomb(node) + gauss*charge(node)*real(summe(gpt)*snode, kind=
dp)
227 e_igdotr = aimag(summe(gpt)*conjg &
228 (exp_igr%ex(lp, node) &
229 *exp_igr%ey(mp, node) &
230 *exp_igr%ez(np, node)))
231 fg_coulomb(:, node) = fg_coulomb(:, node) &
232 + charge(node)*gauss*e_igdotr*pw_grid%g(:, gpt)
236 denom = 1.0_dp/four_alpha_sq + 1.0_dp/pw_grid%gsq(gpt)
238 pv_g(1, 1) = pv_g(1, 1) + factor*(1.0_dp - 2.0_dp*pw_grid%g(1, gpt)*pw_grid%g(1, gpt)*denom)
239 pv_g(1, 2) = pv_g(1, 2) - factor*(2.0_dp*pw_grid%g(1, gpt)*pw_grid%g(2, gpt)*denom)
240 pv_g(1, 3) = pv_g(1, 3) - factor*(2.0_dp*pw_grid%g(1, gpt)*pw_grid%g(3, gpt)*denom)
241 pv_g(2, 1) = pv_g(2, 1) - factor*(2.0_dp*pw_grid%g(2, gpt)*pw_grid%g(1, gpt)*denom)
242 pv_g(2, 2) = pv_g(2, 2) + factor*(1.0_dp - 2.0_dp*pw_grid%g(2, gpt)*pw_grid%g(2, gpt)*denom)
243 pv_g(2, 3) = pv_g(2, 3) - factor*(2.0_dp*pw_grid%g(2, gpt)*pw_grid%g(3, gpt)*denom)
244 pv_g(3, 1) = pv_g(3, 1) - factor*(2.0_dp*pw_grid%g(3, gpt)*pw_grid%g(1, gpt)*denom)
245 pv_g(3, 2) = pv_g(3, 2) - factor*(2.0_dp*pw_grid%g(3, gpt)*pw_grid%g(2, gpt)*denom)
246 pv_g(3, 3) = pv_g(3, 3) + factor*(1.0_dp - 2.0_dp*pw_grid%g(3, gpt)*pw_grid%g(3, gpt)*denom)
250 vg_coulomb = vg_coulomb*pref
251 IF (use_virial) pv_g = pv_g*pref
252 IF (atenergy) e_coulomb = e_coulomb*pref
254 fg_coulomb = fg_coulomb*(2.0_dp*pref)
258 DEALLOCATE (charge, summe)
260 CALL timestop(handle)
278 SUBROUTINE ewald_self(ewald_env, cell, atomic_kind_set, local_particles, e_self, &
285 REAL(kind=
dp),
INTENT(OUT) :: e_self, e_neut
286 REAL(kind=
dp),
DIMENSION(:),
POINTER :: charges
288 INTEGER :: ewald_type, iparticle_kind, &
289 nparticle_kind, nparticle_local
291 REAL(kind=
dp) :: alpha, mm_radius, q, q_neutg, q_self, &
298 alpha=alpha, group=group)
302 nparticle_kind =
SIZE(atomic_kind_set)
303 IF (
ASSOCIATED(charges))
THEN
304 q_self = dot_product(charges, charges)
307 DO iparticle_kind = 1, nparticle_kind
308 atomic_kind => atomic_kind_set(iparticle_kind)
310 IF (mm_radius > 0.0_dp)
THEN
311 cpabort(
"Array of charges not implemented for mm_radius > 0.0")
315 DO iparticle_kind = 1, nparticle_kind
316 atomic_kind => atomic_kind_set(iparticle_kind)
318 qeff=q, shell_active=is_shell, shell=shell)
319 nparticle_local = local_particles%n_el(iparticle_kind)
321 CALL get_shell(shell=shell, charge_core=qcore, charge_shell=qshell)
324 q_self = q_self + qcore*qcore*nparticle_local + qshell*qshell*nparticle_local
325 q_sum = q_sum + qcore*nparticle_local + qshell*nparticle_local
326 IF (mm_radius > 0)
THEN
328 q_neutg = q_neutg + 2.0_dp*qshell*mm_radius**2
331 q_self = q_self + q*q*nparticle_local
332 q_sum = q_sum + q*nparticle_local
333 IF (mm_radius > 0)
THEN
334 q_neutg = q_neutg + 2.0_dp*q*mm_radius**2
339 CALL group%sum(q_self)
340 CALL group%sum(q_sum)
347 e_neut = -q_sum*
pi/(2.0_dp*cell%deth)*(q_sum/alpha**2 - q_neutg)
369 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: e_self(:)
370 REAL(kind=
dp),
DIMENSION(:),
POINTER :: charges
372 INTEGER :: ewald_type, ii, iparticle_kind, &
373 iparticle_local, nparticle_kind, &
376 REAL(kind=
dp) :: alpha, fself, q, qcore, qshell
380 CALL ewald_env_get(ewald_env, ewald_type=ewald_type, alpha=alpha)
385 nparticle_kind =
SIZE(atomic_kind_set)
386 IF (
ASSOCIATED(charges))
THEN
387 cpabort(
"Atomic energy not implemented for charges")
389 DO iparticle_kind = 1, nparticle_kind
390 atomic_kind => atomic_kind_set(iparticle_kind)
391 nparticle_local = local_particles%n_el(iparticle_kind)
393 shell_active=is_shell, shell=shell)
395 CALL get_shell(shell=shell, charge_core=qcore, charge_shell=qshell)
396 DO iparticle_local = 1, nparticle_local
397 ii = local_particles%list(iparticle_kind)%array(iparticle_local)
398 e_self(ii) = e_self(ii) - (qcore*qcore + qshell*qshell)*fself
401 DO iparticle_local = 1, nparticle_local
402 ii = local_particles%list(iparticle_kind)%array(iparticle_local)
403 e_self(ii) = e_self(ii) - q*q*fself