93 SUBROUTINE pme_evaluate(ewald_env, ewald_pw, box, particle_set, vg_coulomb, &
94 fg_coulomb, pv_g, shell_particle_set, core_particle_set, &
95 fgshell_coulomb, fgcore_coulomb, use_virial, charges, atprop)
100 REAL(kind=
dp),
INTENT(OUT) :: vg_coulomb
101 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT), &
102 OPTIONAL :: fg_coulomb, pv_g
104 POINTER :: shell_particle_set, core_particle_set
105 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT), &
106 OPTIONAL :: fgshell_coulomb, fgcore_coulomb
107 LOGICAL,
INTENT(IN) :: use_virial
108 REAL(kind=
dp),
DIMENSION(:),
OPTIONAL,
POINTER :: charges
111 CHARACTER(LEN=*),
PARAMETER :: routinen =
'pme_evaluate'
113 INTEGER :: handle, i, ipart, j, npart, nshell, p1, &
115 LOGICAL :: is1_core, is2_core
116 REAL(kind=
dp) :: alpha, dvols, fat1, ffa
117 REAL(kind=
dp),
DIMENSION(3) :: fat
118 REAL(kind=
dp),
DIMENSION(3, 3) :: f_stress, h_stress
125 TYPE(
pw_pool_type),
POINTER :: pw_big_pool, pw_small_pool
132 CALL timeset(routinen, handle)
133 NULLIFY (poisson_env, rden)
137 pw_small_pool=pw_small_pool, rs_desc=rs_desc, &
138 poisson_env=poisson_env, dg=dg)
140 grid_b => pw_big_pool%pw_grid
141 grid_s => pw_small_pool%pw_grid
143 CALL dg_get(dg, dg_rho0=dg_rho0)
145 npart =
SIZE(particle_set)
149 IF (
PRESENT(shell_particle_set))
THEN
150 cpassert(
ASSOCIATED(shell_particle_set))
151 cpassert(
ASSOCIATED(core_particle_set))
152 nshell =
SIZE(shell_particle_set)
154 allocate_centre=.true., allocate_shell_e=.true., &
155 allocate_shell_centre=.true., nshell=nshell)
159 allocate_centre=.true.)
162 CALL pw_small_pool%create_pw(rhos1)
163 CALL pw_small_pool%create_pw(rhos2)
170 cpassert(
ASSOCIATED(box))
172 IF (rden%desc%parallel .AND. rden%desc%distributed)
THEN
173 CALL get_center(particle_set, box, exp_igr%centre, exp_igr%delta, grid_b%npts, 1)
175 IF (
PRESENT(shell_particle_set) .AND. rden%desc%parallel .AND. rden%desc%distributed)
THEN
176 CALL get_center(shell_particle_set, box, exp_igr%shell_centre, exp_igr%shell_delta, grid_b%npts, 1)
177 CALL get_center(core_particle_set, box, exp_igr%core_centre, exp_igr%core_delta, grid_b%npts, 1)
185 CALL set_list(particle_set, npart, exp_igr%centre, p1, rden, ipart, exp_igr%core_centre)
186 CALL set_list(particle_set, npart, exp_igr%centre, p2, rden, ipart, exp_igr%core_centre)
187 IF (p1 == 0 .AND. p2 == 0)
EXIT
189 is1_core = (particle_set(p1)%shell_index /= 0)
191 is2_core = (particle_set(p2)%shell_index /= 0)
197 IF (is1_core .OR. is2_core)
THEN
198 CALL get_patch(dg, particle_set, exp_igr, box, p1, p2, grid_b, grid_s, &
199 rhos1, rhos2, is1_core=is1_core, is2_core=is2_core, &
200 core_particle_set=core_particle_set, charges=charges)
204 CALL dg_sum_patch(rden, rhos1, exp_igr%core_centre(:, particle_set(p1)%shell_index))
208 IF (p2 /= 0 .AND. is2_core)
THEN
209 CALL dg_sum_patch(rden, rhos2, exp_igr%core_centre(:, particle_set(p2)%shell_index))
210 ELSE IF (p2 /= 0)
THEN
214 CALL get_patch(dg, particle_set, exp_igr, box, p1, p2, grid_b, grid_s, &
215 rhos1, rhos2, charges=charges)
218 IF (p2 /= 0)
CALL dg_sum_patch(rden, rhos2, exp_igr%centre(:, p2))
222 IF (
PRESENT(shell_particle_set))
THEN
225 CALL set_list(shell_particle_set, nshell, exp_igr%shell_centre, p1, rpot, ipart)
226 CALL set_list(shell_particle_set, nshell, exp_igr%shell_centre, p2, rpot, ipart)
227 IF (p1 == 0 .AND. p2 == 0)
EXIT
229 CALL get_patch(dg, shell_particle_set, exp_igr, box, p1, p2, grid_b, grid_s, &
230 rhos1, rhos2, is1_shell=.true., is2_shell=.true., charges=charges)
232 CALL dg_sum_patch(rpot, rhos1, exp_igr%shell_centre(:, p1))
233 IF (p2 /= 0)
CALL dg_sum_patch(rpot, rhos2, exp_igr%shell_centre(:, p2))
237 CALL pw_big_pool%create_pw(rhob_r)
244 CALL pw_big_pool%create_pw(dphi_g(i))
246 CALL pw_big_pool%create_pw(phi_r)
248 CALL pw_poisson_solve(poisson_env, rhob_r, vg_coulomb, phi_r, dphi_g, h_stress)
251 IF (atprop%energy)
THEN
252 dvols = rhos1%pw_grid%dvol
258 CALL set_list(particle_set, npart, exp_igr%centre, p1, rden, ipart, exp_igr%core_centre)
259 CALL set_list(particle_set, npart, exp_igr%centre, p2, rden, ipart, exp_igr%core_centre)
260 IF (p1 == 0 .AND. p2 == 0)
EXIT
262 CALL get_patch(dg, particle_set, exp_igr, box, p1, p2, grid_b, grid_s, &
263 rhos1, rhos2, charges=charges)
266 IF (atprop%energy)
THEN
267 atprop%atener(p1) = atprop%atener(p1) + 0.5_dp*fat1*dvols
271 IF (atprop%energy)
THEN
272 atprop%atener(p2) = atprop%atener(p2) + 0.5_dp*fat1*dvols
280 CALL pw_big_pool%give_back_pw(phi_r)
286 IF ((use_virial) .AND. (
PRESENT(pv_g)))
THEN
290 f_stress(j, i) = f_stress(i, j)
293 ffa = (1.0_dp/
fourpi)*(0.5_dp/dg_rho0%zet(1))**2
294 f_stress = -ffa*f_stress
295 pv_g = h_stress + f_stress
304 CALL pw_big_pool%give_back_pw(dphi_g(i))
308 CALL pw_big_pool%give_back_pw(rhob_r)
313 IF (
PRESENT(fg_coulomb))
THEN
315 dvols = rhos1%pw_grid%dvol
320 CALL set_list(particle_set, npart, exp_igr%centre, p1, rden, ipart, exp_igr%core_centre)
321 CALL set_list(particle_set, npart, exp_igr%centre, p2, rden, ipart, exp_igr%core_centre)
322 IF (p1 == 0 .AND. p2 == 0)
EXIT
324 is1_core = (particle_set(p1)%shell_index /= 0)
326 is2_core = (particle_set(p2)%shell_index /= 0)
333 CALL get_patch_again(dg, particle_set, exp_igr, p1, p2, rhos1, rhos2, &
334 is1_core=is1_core, is2_core=is2_core, charges=charges)
339 exp_igr%core_centre(:, particle_set(p1)%shell_index), fat)
340 fgcore_coulomb(1, particle_set(p1)%shell_index) = &
341 fgcore_coulomb(1, particle_set(p1)%shell_index) - fat(1)*dvols
342 fgcore_coulomb(2, particle_set(p1)%shell_index) = &
343 fgcore_coulomb(2, particle_set(p1)%shell_index) - fat(2)*dvols
344 fgcore_coulomb(3, particle_set(p1)%shell_index) = &
345 fgcore_coulomb(3, particle_set(p1)%shell_index) - fat(3)*dvols
348 fg_coulomb(1, p1) = fg_coulomb(1, p1) - fat(1)*dvols
349 fg_coulomb(2, p1) = fg_coulomb(2, p1) - fat(2)*dvols
350 fg_coulomb(3, p1) = fg_coulomb(3, p1) - fat(3)*dvols
352 IF (p2 /= 0 .AND. is2_core)
THEN
354 exp_igr%core_centre(:, particle_set(p2)%shell_index), fat)
355 fgcore_coulomb(1, particle_set(p2)%shell_index) = &
356 fgcore_coulomb(1, particle_set(p2)%shell_index) - fat(1)*dvols
357 fgcore_coulomb(2, particle_set(p2)%shell_index) = &
358 fgcore_coulomb(2, particle_set(p2)%shell_index) - fat(2)*dvols
359 fgcore_coulomb(3, particle_set(p2)%shell_index) = &
360 fgcore_coulomb(3, particle_set(p2)%shell_index) - fat(3)*dvols
361 ELSEIF (p2 /= 0)
THEN
363 fg_coulomb(1, p2) = fg_coulomb(1, p2) - fat(1)*dvols
364 fg_coulomb(2, p2) = fg_coulomb(2, p2) - fat(2)*dvols
365 fg_coulomb(3, p2) = fg_coulomb(3, p2) - fat(3)*dvols
370 IF (
PRESENT(fgshell_coulomb))
THEN
371 fgshell_coulomb = 0.0_dp
372 dvols = rhos1%pw_grid%dvol
376 CALL set_list(shell_particle_set, nshell, exp_igr%shell_centre, p1, rden, ipart)
377 CALL set_list(shell_particle_set, nshell, exp_igr%shell_centre, p2, rden, ipart)
378 IF (p1 == 0 .AND. p2 == 0)
EXIT
381 CALL get_patch_again(dg, shell_particle_set, exp_igr, p1, p2, rhos1, rhos2, &
382 is1_shell=.true., is2_shell=.true., charges=charges)
386 fgshell_coulomb(1, p1) = fgshell_coulomb(1, p1) - fat(1)*dvols
387 fgshell_coulomb(2, p1) = fgshell_coulomb(2, p1) - fat(2)*dvols
388 fgshell_coulomb(3, p1) = fgshell_coulomb(3, p1) - fat(3)*dvols
391 fgshell_coulomb(1, p2) = fgshell_coulomb(1, p2) - fat(1)*dvols
392 fgshell_coulomb(2, p2) = fgshell_coulomb(2, p2) - fat(2)*dvols
393 fgshell_coulomb(3, p2) = fgshell_coulomb(3, p2) - fat(3)*dvols
408 CALL pw_small_pool%give_back_pw(rhos1)
409 CALL pw_small_pool%give_back_pw(rhos2)
412 CALL timestop(handle)