92 fg_coulomb, vg_coulomb, pv_g, shell_particle_set, core_particle_set, &
93 fgshell_coulomb, fgcore_coulomb, use_virial, charges, atprop)
99 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: fg_coulomb
100 REAL(kind=
dp),
INTENT(OUT) :: vg_coulomb
101 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: pv_g
103 POINTER :: shell_particle_set, core_particle_set
104 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT), &
105 OPTIONAL :: fgshell_coulomb, fgcore_coulomb
106 LOGICAL,
INTENT(IN) :: use_virial
107 REAL(kind=
dp),
DIMENSION(:),
OPTIONAL,
POINTER :: charges
110 CHARACTER(len=*),
PARAMETER :: routinen =
'spme_evaluate'
112 INTEGER :: handle, i, ipart, j, n, ncore, npart, &
113 nshell, o_spline, p1, p1_shell
114 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: center, core_center, shell_center
115 INTEGER,
DIMENSION(3) :: npts
117 REAL(kind=
dp) :: alpha, dvols, fat1, ffa
118 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: core_delta, delta, shell_delta
119 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: rhos
120 REAL(kind=
dp),
DIMENSION(3) :: fat
121 REAL(kind=
dp),
DIMENSION(3, 3) :: f_stress, h_stress
134 NULLIFY (grid_spme, green, poisson_env, phi_g, rhob_g, rhob_r, pw_pool, rden, rpot)
135 CALL timeset(routinen, handle)
139 CALL ewald_env_get(ewald_env, alpha=alpha, o_spline=o_spline, &
141 CALL ewald_pw_get(ewald_pw, pw_big_pool=pw_pool, rs_desc=rs_desc, &
142 poisson_env=poisson_env)
144 green => poisson_env%green_fft
145 grid_spme => pw_pool%pw_grid
147 npart =
SIZE(particle_set)
152 ALLOCATE (rhos(n, n, n))
158 ALLOCATE (center(3, npart), delta(3, npart))
159 CALL get_center(particle_set, box, center, delta, npts, n)
161 IF (
PRESENT(shell_particle_set) .AND. (
PRESENT(core_particle_set)))
THEN
162 cpassert(
ASSOCIATED(shell_particle_set))
163 cpassert(
ASSOCIATED(core_particle_set))
164 nshell =
SIZE(shell_particle_set)
165 ncore =
SIZE(core_particle_set)
166 cpassert(nshell == ncore)
167 ALLOCATE (shell_center(3, nshell), shell_delta(3, nshell))
168 CALL get_center(shell_particle_set, box, shell_center, shell_delta, npts, n)
169 ALLOCATE (core_center(3, nshell), core_delta(3, nshell))
170 CALL get_center(core_particle_set, box, core_center, core_delta, npts, n)
177 CALL set_list(particle_set, npart, center, p1, rden, ipart)
180 do_shell = (particle_set(p1)%shell_index /= 0)
183 CALL get_patch(particle_set, delta, green, p1, rhos, is_core=.false., &
184 is_shell=.false., unit_charge=.false., charges=charges)
190 IF (
PRESENT(shell_particle_set) .AND.
PRESENT(core_particle_set))
THEN
194 CALL set_list(shell_particle_set, nshell, shell_center, p1_shell, &
196 IF (p1_shell == 0)
EXIT
197 CALL get_patch(shell_particle_set, shell_delta, green, p1_shell, rhos, &
198 is_core=.false., is_shell=.true., unit_charge=.false.)
201 CALL dg_sum_patch(rden, rhos, shell_center(:, p1_shell))
206 CALL set_list(core_particle_set, nshell, core_center, p1_shell, &
208 IF (p1_shell == 0)
EXIT
209 CALL get_patch(core_particle_set, core_delta, green, p1_shell, rhos, &
210 is_core=.true., is_shell=.false., unit_charge=.false.)
220 CALL pw_pool%create_pw(rhob_r)
225 CALL pw_pool%create_pw(rhob_g)
233 CALL pw_pool%create_pw(dphi_g(i))
237 CALL pw_pool%create_pw(phi_g)
243 IF (atprop%energy)
THEN
252 CALL set_list(particle_set, npart, center, p1, rden, ipart)
254 do_shell = (particle_set(p1)%shell_index /= 0)
257 CALL get_patch(particle_set, delta, green, p1, rhos, is_core=.false., &
258 is_shell=.false., unit_charge=.false., charges=charges)
261 IF (atprop%energy)
THEN
262 atprop%atener(p1) = atprop%atener(p1) + 0.5_dp*fat1*dvols
266 IF (
PRESENT(shell_particle_set) .AND.
PRESENT(core_particle_set))
THEN
269 CALL set_list(shell_particle_set, nshell, shell_center, p1_shell, rden, ipart)
270 IF (p1_shell == 0)
EXIT
271 CALL get_patch(shell_particle_set, shell_delta, green, p1_shell, rhos, &
272 is_core=.false., is_shell=.true., unit_charge=.false.)
274 p1 = shell_particle_set(p1_shell)%atom_index
275 IF (atprop%energy)
THEN
276 atprop%atener(p1) = atprop%atener(p1) + 0.5_dp*fat1*dvols
281 CALL set_list(core_particle_set, nshell, core_center, p1_shell, rden, ipart)
282 IF (p1_shell == 0)
EXIT
283 CALL get_patch(core_particle_set, core_delta, green, p1_shell, rhos, &
284 is_core=.true., is_shell=.false., unit_charge=.false.)
286 p1 = core_particle_set(p1_shell)%atom_index
287 IF (atprop%energy)
THEN
288 atprop%atener(p1) = atprop%atener(p1) + 0.5_dp*fat1*dvols
296 CALL pw_pool%give_back_pw(phi_g)
297 CALL pw_pool%give_back_pw(rhob_g)
298 DEALLOCATE (phi_g, rhob_g)
305 f_stress(j, i) = f_stress(i, j)
308 ffa = (1.0_dp/
fourpi)*(0.5_dp/alpha)**2
309 f_stress = -ffa*f_stress
310 pv_g = h_stress + f_stress
320 CALL pw_pool%give_back_pw(dphi_g(i))
324 CALL pw_pool%give_back_pw(rhob_r)
332 CALL set_list(particle_set, npart, center, p1, rden, ipart)
335 do_shell = (particle_set(p1)%shell_index /= 0)
338 CALL get_patch(particle_set, delta, green, p1, rhos, is_core=.false., &
339 is_shell=.false., unit_charge=.false., charges=charges)
343 fg_coulomb(1, p1) = fg_coulomb(1, p1) - fat(1)*dvols
344 fg_coulomb(2, p1) = fg_coulomb(2, p1) - fat(2)*dvols
345 fg_coulomb(3, p1) = fg_coulomb(3, p1) - fat(3)*dvols
348 IF (
PRESENT(shell_particle_set) .AND. (
PRESENT(core_particle_set)))
THEN
349 IF (
PRESENT(fgshell_coulomb))
THEN
351 fgshell_coulomb = 0.0_dp
354 CALL set_list(shell_particle_set, nshell, shell_center, p1_shell, &
356 IF (p1_shell == 0)
EXIT
358 CALL get_patch(shell_particle_set, shell_delta, green, &
359 p1_shell, rhos, is_core=.false., is_shell=.true., unit_charge=.false.)
363 fgshell_coulomb(1, p1_shell) = fgshell_coulomb(1, p1_shell) - fat(1)*dvols
364 fgshell_coulomb(2, p1_shell) = fgshell_coulomb(2, p1_shell) - fat(2)*dvols
365 fgshell_coulomb(3, p1_shell) = fgshell_coulomb(3, p1_shell) - fat(3)*dvols
369 IF (
PRESENT(fgcore_coulomb))
THEN
371 fgcore_coulomb = 0.0_dp
374 CALL set_list(core_particle_set, nshell, core_center, p1_shell, &
376 IF (p1_shell == 0)
EXIT
378 CALL get_patch(core_particle_set, core_delta, green, &
379 p1_shell, rhos, is_core=.true., is_shell=.false., unit_charge=.false.)
383 fgcore_coulomb(1, p1_shell) = fgcore_coulomb(1, p1_shell) - fat(1)*dvols
384 fgcore_coulomb(2, p1_shell) = fgcore_coulomb(2, p1_shell) - fat(2)*dvols
385 fgcore_coulomb(3, p1_shell) = fgcore_coulomb(3, p1_shell) - fat(3)*dvols
400 DEALLOCATE (center, delta)
401 IF (
ALLOCATED(shell_center))
THEN
402 DEALLOCATE (shell_center, shell_delta)
404 IF (
ALLOCATED(core_center))
THEN
405 DEALLOCATE (core_center, core_delta)
407 CALL timestop(handle)
426 particle_set_b, potential)
431 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set_a
432 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
POINTER :: charges_a
433 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set_b
434 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: potential
436 CHARACTER(len=*),
PARAMETER :: routinen =
'spme_potential'
438 INTEGER :: handle, ipart, n, npart_a, npart_b, &
440 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: center
441 INTEGER,
DIMENSION(3) :: npts
442 REAL(kind=
dp) :: alpha, dvols, fat1
443 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: delta
444 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: rhos
455 NULLIFY (grid_spme, green, poisson_env, phi_g, rhob_g, rhob_r, pw_pool, &
457 CALL timeset(routinen, handle)
461 CALL ewald_env_get(ewald_env, alpha=alpha, o_spline=o_spline, group=group)
462 CALL ewald_pw_get(ewald_pw, pw_big_pool=pw_pool, rs_desc=rs_desc, poisson_env=poisson_env)
464 green => poisson_env%green_fft
465 grid_spme => pw_pool%pw_grid
467 npart_a =
SIZE(particle_set_a)
468 npart_b =
SIZE(particle_set_b)
473 ALLOCATE (rhos(n, n, n))
479 ALLOCATE (center(3, npart_a), delta(3, npart_a))
480 CALL get_center(particle_set_a, box, center, delta, npts, n)
486 CALL set_list(particle_set_a, npart_a, center, p1, rden, ipart)
490 CALL get_patch(particle_set_a, delta, green, p1, rhos, charges_a)
495 DEALLOCATE (center, delta)
500 CALL pw_pool%create_pw(rhob_r)
505 CALL pw_pool%create_pw(rhob_g)
514 CALL pw_pool%create_pw(phi_g)
519 ALLOCATE (center(3, npart_b), delta(3, npart_b))
520 CALL get_center(particle_set_b, box, center, delta, npts, n)
527 CALL set_list(particle_set_b, npart_b, center, p1, rden, ipart)
530 CALL get_patch(particle_set_b, delta, green, p1, rhos, &
531 is_core=.false., is_shell=.false., unit_charge=.true.)
534 potential(p1) = potential(p1) + fat1*dvols
538 CALL pw_pool%give_back_pw(phi_g)
539 CALL pw_pool%give_back_pw(rhob_g)
540 CALL pw_pool%give_back_pw(rhob_r)
541 DEALLOCATE (phi_g, rhob_g, rhob_r)
546 DEALLOCATE (center, delta)
547 CALL timestop(handle)
566 SUBROUTINE spme_forces(ewald_env, ewald_pw, box, particle_set_a, charges_a, &
567 particle_set_b, charges_b, forces_b)
572 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set_a
573 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
POINTER :: charges_a
574 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set_b
575 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
POINTER :: charges_b
576 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: forces_b
578 CHARACTER(len=*),
PARAMETER :: routinen =
'spme_forces'
580 INTEGER :: handle, i, ipart, n, npart_a, npart_b, &
582 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: center
583 INTEGER,
DIMENSION(3) :: npts
584 REAL(kind=
dp) :: alpha, dvols
585 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: delta
586 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: rhos
587 REAL(kind=
dp),
DIMENSION(3) :: fat
600 NULLIFY (grid_spme, green, poisson_env, phi_g, rhob_g, rhob_r, &
602 CALL timeset(routinen, handle)
606 CALL ewald_env_get(ewald_env, alpha=alpha, o_spline=o_spline, group=group)
607 CALL ewald_pw_get(ewald_pw, pw_big_pool=pw_pool, rs_desc=rs_desc, poisson_env=poisson_env)
609 green => poisson_env%green_fft
610 grid_spme => pw_pool%pw_grid
612 npart_a =
SIZE(particle_set_a)
613 npart_b =
SIZE(particle_set_b)
618 ALLOCATE (rhos(n, n, n))
624 ALLOCATE (center(3, npart_a), delta(3, npart_a))
625 CALL get_center(particle_set_a, box, center, delta, npts, n)
631 CALL set_list(particle_set_a, npart_a, center, p1, rden, ipart)
635 CALL get_patch(particle_set_a, delta, green, p1, rhos, charges_a)
640 DEALLOCATE (center, delta)
645 CALL pw_pool%create_pw(rhob_r)
650 CALL pw_pool%create_pw(rhob_g)
658 CALL pw_pool%create_pw(dphi_g(i))
662 CALL pw_pool%create_pw(phi_g)
673 CALL pw_pool%give_back_pw(dphi_g(i))
677 ALLOCATE (center(3, npart_b), delta(3, npart_b))
678 CALL get_center(particle_set_b, box, center, delta, npts, n)
681 CALL set_list(particle_set_b, npart_b, center, p1, rden, ipart)
684 CALL get_patch(particle_set_b, delta, green, p1, rhos, &
685 is_core=.false., is_shell=.false., unit_charge=.false., charges=charges_b)
688 forces_b(1, p1) = forces_b(1, p1) - fat(1)*dvols
689 forces_b(2, p1) = forces_b(2, p1) - fat(2)*dvols
690 forces_b(3, p1) = forces_b(3, p1) - fat(3)*dvols
696 CALL pw_pool%give_back_pw(phi_g)
697 CALL pw_pool%give_back_pw(rhob_g)
698 CALL pw_pool%give_back_pw(rhob_r)
699 DEALLOCATE (phi_g, rhob_g, rhob_r)
704 DEALLOCATE (center, delta)
705 CALL timestop(handle)
718 SUBROUTINE spme_virial(ewald_env, ewald_pw, particle_set, box, mcharge, virial)
722 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
724 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: mcharge
725 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(OUT) :: virial
727 CHARACTER(len=*),
PARAMETER :: routinen =
'spme_virial'
729 INTEGER :: handle, i, ipart, j, n, npart, o_spline, &
731 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: center
732 INTEGER,
DIMENSION(3) :: npts
733 REAL(kind=
dp) :: alpha, dvols, ffa, vgc
734 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: delta
735 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: rhos
736 REAL(kind=
dp),
DIMENSION(3, 3) :: f_stress, h_stress
749 CALL timeset(routinen, handle)
752 CALL ewald_env_get(ewald_env, alpha=alpha, o_spline=o_spline, group=group, &
754 NULLIFY (green, poisson_env, pw_pool)
755 CALL ewald_pw_get(ewald_pw, pw_big_pool=pw_pool, rs_desc=rs_desc, &
756 poisson_env=poisson_env)
758 green => poisson_env%green_fft
759 grid_spme => pw_pool%pw_grid
763 npart =
SIZE(particle_set)
766 ALLOCATE (rhos(n, n, n))
772 ALLOCATE (center(3, npart), delta(3, npart))
773 CALL get_center(particle_set, box, center, delta, npts, n)
778 CALL set_list(particle_set, npart, center, p1, rden, ipart)
782 CALL get_patch(particle_set, delta, green, p1, rhos, is_core=.false., &
783 is_shell=.false., unit_charge=.true.)
784 rhos(:, :, :) = rhos(:, :, :)*mcharge(p1)
792 CALL pw_pool%create_pw(rhob_r)
799 CALL pw_pool%create_pw(rhob_g)
808 CALL pw_pool%create_pw(dphi_g(i))
812 CALL pw_pool%create_pw(phi_g)
813 CALL pw_poisson_solve(poisson_env, rhob_g, vgc, phi_g, dphi_g, h_stress=h_stress)
818 CALL pw_pool%give_back_pw(rhob_g)
824 CALL pw_pool%give_back_pw(phi_g)
835 f_stress(j, i) = f_stress(i, j)
838 ffa = (1.0_dp/
fourpi)*(0.5_dp/alpha)**2
839 virial = virial - (ffa*f_stress - h_stress)/real(para_env%num_pe,
dp)
844 CALL pw_pool%give_back_pw(dphi_g(i))
846 CALL pw_pool%give_back_pw(rhob_r)
852 DEALLOCATE (center, delta)
854 CALL timestop(handle)