89 gmcharge, mcharge, calculate_forces, virial, use_virial, atprop)
95 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(inout) :: gmcharge
96 REAL(kind=
dp),
DIMENSION(:),
INTENT(in) :: mcharge
97 LOGICAL,
INTENT(in) :: calculate_forces
99 LOGICAL,
INTENT(in) :: use_virial
102 CHARACTER(len=*),
PARAMETER :: routinen =
'tb_spme_evaluate'
104 INTEGER :: handle, i, ig, ipart, j, n, npart, &
106 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: center
107 INTEGER,
DIMENSION(3) :: nd, npts
108 REAL(kind=
dp) :: alpha, dvols, fat(3), ffa, ffb, fint, vgc
109 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: delta
110 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: rhos
111 REAL(kind=
dp),
DIMENSION(3, 3) :: f_stress, h_stress
124 DIMENSION(:) :: drpot
126 CALL timeset(routinen, handle)
128 CALL ewald_env_get(ewald_env, alpha=alpha, o_spline=o_spline, group=group, &
130 NULLIFY (green, poisson_env, pw_pool)
131 CALL ewald_pw_get(ewald_pw, pw_big_pool=pw_pool, rs_desc=rs_desc, &
132 poisson_env=poisson_env)
134 green => poisson_env%green_fft
135 grid_spme => pw_pool%pw_grid
139 npart =
SIZE(particle_set)
142 ALLOCATE (rhos(n, n, n))
148 ALLOCATE (center(3, npart), delta(3, npart))
149 CALL get_center(particle_set, box, center, delta, npts, n)
154 CALL set_list(particle_set, npart, center, p1, rden, ipart)
158 CALL get_patch(particle_set, delta, green, p1, rhos, is_core=.false., &
159 is_shell=.false., unit_charge=.true.)
160 rhos(:, :, :) = rhos(:, :, :)*mcharge(p1)
168 CALL pw_pool%create_pw(rhob_r)
175 CALL pw_pool%create_pw(rhob_g)
184 CALL pw_pool%create_pw(dphi_g(i))
188 CALL pw_pool%create_pw(phi_g)
190 CALL pw_poisson_solve(poisson_env, rhob_g, vgc, phi_g, dphi_g, h_stress=h_stress)
199 IF (
PRESENT(atprop))
THEN
200 IF (
ASSOCIATED(atprop))
THEN
201 IF (atprop%stress .AND. use_virial)
THEN
210 CALL set_list(particle_set, npart, center, p1, rden, ipart)
213 CALL get_patch(particle_set, delta, green, p1, rhos, is_core=.false., &
214 is_shell=.false., unit_charge=.true.)
216 atprop%atstress(1, 1, p1) = atprop%atstress(1, 1, p1) + 0.5_dp*mcharge(p1)*fint*dvols
217 atprop%atstress(2, 2, p1) = atprop%atstress(2, 2, p1) + 0.5_dp*mcharge(p1)*fint*dvols
218 atprop%atstress(3, 3, p1) = atprop%atstress(3, 3, p1) + 0.5_dp*mcharge(p1)*fint*dvols
223 CALL pw_pool%create_pw(phib_g)
224 ffa = (0.5_dp/alpha)**2
227 DO ig = grid_spme%first_gne0, grid_spme%ngpts_cut_local
228 phib_g%array(ig) = ffb*dphi_g(i)%array(ig)*(1.0_dp + ffa*grid_spme%gsq(ig))
229 phib_g%array(ig) = phib_g%array(ig)*green%influence_fn%array(ig)
231 IF (grid_spme%have_g0) phib_g%array(1) = 0.0_dp
243 CALL set_list(particle_set, npart, center, p1, rden, ipart)
246 CALL get_patch(particle_set, delta, green, p1, rhos, &
247 is_core=.false., is_shell=.false., unit_charge=.true.)
250 atprop%atstress(i, j, p1) = atprop%atstress(i, j, p1) + fint*dvols*mcharge(p1)
251 IF (i /= j) atprop%atstress(j, i, p1) = atprop%atstress(j, i, p1) + fint*dvols*mcharge(p1)
256 CALL pw_pool%give_back_pw(phib_g)
263 CALL pw_pool%give_back_pw(rhob_g)
269 CALL pw_pool%give_back_pw(phi_g)
281 f_stress(j, i) = f_stress(i, j)
284 ffa = (1.0_dp/
fourpi)*(0.5_dp/alpha)**2
285 virial%pv_virial = virial%pv_virial - (ffa*f_stress - h_stress)/real(para_env%num_pe,
dp)
290 IF (calculate_forces)
THEN
299 CALL pw_pool%give_back_pw(dphi_g(i))
304 CALL pw_pool%give_back_pw(dphi_g(i))
307 CALL pw_pool%give_back_pw(rhob_r)
315 CALL set_list(particle_set, npart, center, p1, rden, ipart)
319 CALL get_patch(particle_set, delta, green, p1, rhos, is_core=.false., &
320 is_shell=.false., unit_charge=.true.)
323 gmcharge(p1, 1) = gmcharge(p1, 1) + fint*dvols
325 IF (calculate_forces)
THEN
327 gmcharge(p1, 2) = gmcharge(p1, 2) - fat(1)*dvols
328 gmcharge(p1, 3) = gmcharge(p1, 3) - fat(2)*dvols
329 gmcharge(p1, 4) = gmcharge(p1, 4) - fat(3)*dvols
340 IF (calculate_forces)
THEN
347 DEALLOCATE (center, delta)
349 CALL timestop(handle)
365 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(inout) :: gmcharge
366 REAL(kind=
dp),
DIMENSION(:),
INTENT(in) :: mcharge
367 REAL(kind=
dp),
INTENT(in) :: alpha
371 LOGICAL,
INTENT(IN) :: use_virial
374 CHARACTER(LEN=*),
PARAMETER :: routinen =
'tb_ewald_overlap'
376 INTEGER :: handle, i, iatom, jatom, nmat
377 REAL(kind=
dp) :: dfr, dr, fr, pfr, rij(3)
379 DIMENSION(:),
POINTER :: nl_iterator
381 CALL timeset(routinen, handle)
383 nmat =
SIZE(gmcharge, 2)
389 dr = sqrt(sum(rij(:)**2))
390 IF (dr > 1.e-10)
THEN
391 fr = erfc(alpha*dr)/dr
392 gmcharge(iatom, 1) = gmcharge(iatom, 1) + mcharge(jatom)*fr
393 gmcharge(jatom, 1) = gmcharge(jatom, 1) + mcharge(iatom)*fr
395 dfr = -2._dp*alpha*exp(-alpha*alpha*dr*dr)*
oorootpi/dr - fr/dr
398 gmcharge(iatom, i) = gmcharge(iatom, i) - rij(i - 1)*mcharge(jatom)*dfr
399 gmcharge(jatom, i) = gmcharge(jatom, i) + rij(i - 1)*mcharge(iatom)*dfr
403 IF (iatom == jatom)
THEN
404 pfr = -0.5_dp*dfr*mcharge(iatom)*mcharge(jatom)
406 pfr = -dfr*mcharge(iatom)*mcharge(jatom)
409 IF (
PRESENT(atprop))
THEN
410 IF (
ASSOCIATED(atprop))
THEN
411 IF (atprop%stress)
THEN
423 CALL timestop(handle)
436 SUBROUTINE tb_spme_zforce(ewald_env, ewald_pw, particle_set, box, gmcharge, mcharge)
440 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
442 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(inout) :: gmcharge
443 REAL(kind=
dp),
DIMENSION(:),
INTENT(in) :: mcharge
445 CHARACTER(len=*),
PARAMETER :: routinen =
'tb_spme_zforce'
447 INTEGER :: handle, i, ipart, n, npart, o_spline, p1
448 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: center
449 INTEGER,
DIMENSION(3) :: npts
450 REAL(kind=
dp) :: alpha, dvols, fat(3), fint, vgc
451 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: delta
452 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: rhos
466 CALL timeset(routinen, handle)
468 CALL ewald_env_get(ewald_env, alpha=alpha, o_spline=o_spline, group=group, &
470 NULLIFY (green, poisson_env, pw_pool)
471 CALL ewald_pw_get(ewald_pw, pw_big_pool=pw_pool, rs_desc=rs_desc, &
472 poisson_env=poisson_env)
474 green => poisson_env%green_fft
475 grid_spme => pw_pool%pw_grid
479 npart =
SIZE(particle_set)
482 ALLOCATE (rhos(n, n, n))
488 ALLOCATE (center(3, npart), delta(3, npart))
489 CALL get_center(particle_set, box, center, delta, npts, n)
494 CALL set_list(particle_set, npart, center, p1, rden, ipart)
498 CALL get_patch(particle_set, delta, green, p1, rhos, is_core=.false., &
499 is_shell=.false., unit_charge=.true.)
500 rhos(:, :, :) = rhos(:, :, :)*mcharge(p1)
508 CALL pw_pool%create_pw(rhob_r)
515 CALL pw_pool%create_pw(rhob_g)
524 CALL pw_pool%create_pw(dphi_g(i))
528 CALL pw_pool%create_pw(phi_g)
534 CALL pw_pool%give_back_pw(rhob_g)
540 CALL pw_pool%give_back_pw(phi_g)
553 CALL pw_pool%give_back_pw(dphi_g(i))
556 CALL pw_pool%give_back_pw(rhob_r)
564 CALL set_list(particle_set, npart, center, p1, rden, ipart)
568 CALL get_patch(particle_set, delta, green, p1, rhos, is_core=.false., &
569 is_shell=.false., unit_charge=.true.)
572 gmcharge(p1, 1) = gmcharge(p1, 1) + fint*dvols
575 gmcharge(p1, 2) = gmcharge(p1, 2) - fat(1)*dvols
576 gmcharge(p1, 3) = gmcharge(p1, 3) - fat(2)*dvols
577 gmcharge(p1, 4) = gmcharge(p1, 4) - fat(3)*dvols
591 DEALLOCATE (center, delta)
593 CALL timestop(handle)