74#include "./base/base_uses.f90"
79 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .false.
80 REAL(KIND=
dp),
PARAMETER,
PRIVATE :: dx = 0.01_dp
81 REAL(KIND=
dp),
PARAMETER,
PRIVATE :: maxerr = 10.0_dp
82 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qmmm_gpw_forces'
99 SUBROUTINE qmmm_forces(qs_env, qmmm_env, mm_particles, calc_force, mm_cell)
103 LOGICAL,
INTENT(in),
OPTIONAL :: calc_force
106 CHARACTER(len=*),
PARAMETER :: routinen =
'qmmm_forces'
108 INTEGER :: handle, iatom, image_indmm, imm, indmm, &
110 LOGICAL :: gapw, need_f, periodic
111 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces, forces_added_charges, &
128 CALL timeset(routinen, handle)
130 periodic = qmmm_env%periodic
131 IF (
PRESENT(calc_force)) need_f = calc_force
132 NULLIFY (dft_control, ks_qmmm_env_loc, rho, pw_env, rho_tot_r, energy, forces, &
133 forces_added_charges, input_section, rho0_s_gs, rho_r)
140 input=input_section, &
141 rho0_s_gs=rho0_s_gs, &
142 dft_control=dft_control)
147 ks_qmmm_env_loc => qs_env%ks_qmmm_env
151 extension=
".qmmmLog")
152 gapw = dft_control%qs_control%gapw
155 ALLOCATE (forces(3, qmmm_env%num_mm_atoms))
156 ALLOCATE (forces_added_charges(3, qmmm_env%added_charges%num_mm_atoms))
157 ALLOCATE (forces_added_shells(3, qmmm_env%added_shells%num_mm_atoms))
158 forces(:, :) = 0.0_dp
159 forces_added_charges(:, :) = 0.0_dp
160 forces_added_shells(:, :) = 0.0_dp
162 IF (dft_control%qs_control%semi_empirical)
THEN
164 SELECT CASE (qmmm_env%qmmm_coupl_type)
167 need_f, forces, forces_added_charges)
169 cpabort(
"Point Charge QM/MM electrostatic coupling not yet implemented for SE.")
171 cpabort(
"GAUSS or SWAVE QM/MM electrostatic coupling not yet implemented for SE.")
173 IF (iw > 0)
WRITE (iw,
'(T2,"QMMM|",1X,A)') &
174 "- No QM/MM Electrostatic coupling. Just Mechanical Coupling!"
176 IF (iw > 0)
WRITE (iw,
'(T2,"QMMM|",1X,A)')
"Unknown Coupling..."
179 ELSEIF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb)
THEN
181 SELECT CASE (qmmm_env%qmmm_coupl_type)
183 IF (iw > 0)
WRITE (iw,
'(T2,"QMMM|",1X,A)') &
184 "- No QM/MM Electrostatic coupling. Just Mechanical Coupling!"
187 need_f, forces, forces_added_charges)
190 need_f, forces, forces_added_charges)
192 cpabort(
"GAUSS or SWAVE QM/MM electrostatic coupling not yet implemented for DFTB.")
194 IF (iw > 0)
WRITE (iw,
'(T2,"QMMM|",1X,A)')
"Unknown Coupling..."
198 forces(:, :) = forces(:, :)/real(para_env%num_pe, kind=
dp)
199 forces_added_charges(:, :) = forces_added_charges(:, :)/real(para_env%num_pe, kind=
dp)
205 auxbas_pw_pool=auxbas_pool)
208 CALL auxbas_pool%create_pw(rho_tot_r)
211 IF (dft_control%qs_control%gapw_control%nopaw_as_gpw)
THEN
213 energy%qmmm_nu =
pw_integral_ab(rho_tot_r, ks_qmmm_env_loc%v_qmmm_rspace)
215 ALLOCATE (rho_tot_r2)
216 CALL auxbas_pool%create_pw(rho_tot_r2)
218 CALL pw_axpy(rho_tot_r2, rho_tot_r)
219 CALL auxbas_pool%give_back_pw(rho_tot_r2)
220 DEALLOCATE (rho_tot_r2)
226 energy%qmmm_nu = 0.0_dp
233 energy%qmmm_nu =
pw_integral_ab(rho_tot_r, ks_qmmm_env_loc%v_qmmm_rspace)
237 DO ispin = 1,
SIZE(rho_r)
238 CALL pw_axpy(rho_r(ispin), rho_tot_r)
240 IF (iw > 0)
WRITE (iw,
'(T2,"QMMM|",1X,A)')
"Evaluating forces on MM atoms due to the:"
242 SELECT CASE (qmmm_env%qmmm_coupl_type)
244 cpabort(
"Coulomb QM/MM electrostatic coupling not implemented for GPW/GAPW.")
246 cpabort(
"Point Charge QM/MM electrostatic coupling not yet implemented for GPW/GAPW.")
248 IF (iw > 0)
WRITE (iw,
'(T2,"QMMM|",1X,A)') &
249 "- QM/MM Coupling computed collocating the Gaussian Potential Functions."
250 CALL qmmm_forces_with_gaussian(rho=rho_tot_r, &
252 mm_particles=mm_particles, &
253 aug_pools=qmmm_env%aug_pools, &
254 auxbas_grid=qmmm_env%gridlevel_info%auxbas_grid, &
255 coarser_grid=qmmm_env%gridlevel_info%coarser_grid, &
258 eps_mm_rspace=qmmm_env%eps_mm_rspace, &
259 cube_info=ks_qmmm_env_loc%cube_info, &
261 forces_added_charges=forces_added_charges, &
262 forces_added_shells=forces_added_shells, &
263 interp_section=interp_section, &
267 IF (iw > 0)
WRITE (iw,
'(T2,"QMMM|",1X,A)') &
268 "- No QM/MM Electrostatic coupling. Just Mechanical Coupling!"
270 IF (iw > 0)
WRITE (iw,
'(T2,"QMMM|",1X,A)')
"- Unknown Coupling..."
276 energy%total = energy%total + energy%qmmm_nu
281 IF (qmmm_env%num_mm_atoms /= 0)
CALL para_env%sum(forces)
282 IF (qmmm_env%added_charges%num_mm_atoms /= 0)
CALL para_env%sum(forces_added_charges)
283 IF (qmmm_env%added_shells%num_mm_atoms /= 0)
CALL para_env%sum(forces_added_shells)
285 IF (debug_this_module)
THEN
286 IF (dft_control%qs_control%semi_empirical .OR. &
287 dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb)
THEN
288 WRITE (iw, *)
"NO DEBUG AVAILABLE in module"//trim(routinen)
292 DO imm = 1,
SIZE(qmmm_env%mm_atom_index)
293 WRITE (iw, *)
"ANALYTICAL FORCES:"
294 indmm = qmmm_env%mm_atom_index(imm)
295 WRITE (iw,
'(I6,3F15.9)') indmm, forces(:, imm)
298 CALL qmmm_debug_forces(rho=rho_tot_r, &
301 analytical_forces=forces, &
302 mm_particles=mm_particles, &
303 mm_atom_index=qmmm_env%mm_atom_index, &
304 num_mm_atoms=qmmm_env%num_mm_atoms, &
305 interp_section=interp_section, &
311 IF ((.NOT. dft_control%qs_control%semi_empirical) .AND. &
312 (.NOT. dft_control%qs_control%dftb) .AND. (.NOT. dft_control%qs_control%xtb))
THEN
313 CALL auxbas_pool%give_back_pw(rho_tot_r)
314 DEALLOCATE (rho_tot_r)
317 IF (.NOT. gapw)
WRITE (iw,
'(T2,"QMMM|",1X,A,T66,F15.9)') &
318 "QM/MM Nuclear Electrostatic Potential :", energy%qmmm_nu
319 WRITE (iw,
'(T2,"QMMM|",1X,A,T66,F15.9)') &
320 "QMMM Total Energy (QM + QMMM electronic + QMMM nuclear):", energy%total
321 WRITE (iw,
'(T2,"QMMM|",1X,A)')
"MM energy NOT included in the above term!"// &
322 " Check for: FORCE_EVAL ( QMMM )"
323 WRITE (iw,
'(T2,"QMMM|",1X,A)')
"that includes both QM, QMMM and MM energy terms!"
327 DO imm = 1, qmmm_env%num_mm_atoms
328 indmm = qmmm_env%mm_atom_index(imm)
331 IF (qmmm_env%image_charge)
THEN
332 DO iatom = 1, qmmm_env%num_image_mm_atoms
333 image_indmm = qmmm_env%image_charge_pot%image_mm_list(iatom)
334 IF (image_indmm .EQ. indmm)
THEN
335 forces(:, imm) = forces(:, imm) &
336 + qmmm_env%image_charge_pot%image_forcesMM(:, iatom)
343 mm_particles(indmm)%f(:) = -forces(:, imm) + mm_particles(indmm)%f(:)
346 IF (qmmm_env%move_mm_charges .OR. qmmm_env%add_mm_charges)
THEN
347 DO imm = 1, qmmm_env%added_charges%num_mm_atoms
348 indmm = qmmm_env%added_charges%mm_atom_index(imm)
351 qmmm_env%added_charges%added_particles(indmm)%f(:) = -forces_added_charges(:, imm)
354 DEALLOCATE (forces_added_charges)
355 IF (qmmm_env%added_shells%num_mm_atoms .GT. 0)
THEN
356 DO imm = 1, qmmm_env%added_shells%num_mm_atoms
357 indmm = qmmm_env%added_shells%mm_core_index(imm)
360 qmmm_env%added_shells%added_particles(imm)%f(:) = qmmm_env%added_shells%added_particles(imm)%f(:) - &
361 forces_added_shells(:, imm)
365 DEALLOCATE (forces_added_shells)
368 CALL timestop(handle)
396 SUBROUTINE qmmm_forces_with_gaussian(rho, qmmm_env, mm_particles, &
397 aug_pools, auxbas_grid, coarser_grid, cube_info, para_env, &
398 eps_mm_rspace, pw_pools, Forces, Forces_added_charges, Forces_added_shells, &
399 interp_section, iw, mm_cell)
404 INTEGER,
INTENT(IN) :: auxbas_grid, coarser_grid
407 REAL(kind=
dp),
INTENT(IN) :: eps_mm_rspace
409 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces, forces_added_charges, &
412 INTEGER,
INTENT(IN) :: iw
415 CHARACTER(len=*),
PARAMETER :: routinen =
'qmmm_forces_with_gaussian'
417 INTEGER :: handle, i, igrid, j, k, kind_interp, me, &
419 INTEGER,
DIMENSION(3) :: glb, gub, lb, ub
420 INTEGER,
DIMENSION(:),
POINTER :: pos_of_x
422 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: tmp
429 CALL timeset(routinen, handle)
431 cpassert(
ASSOCIATED(mm_particles))
432 cpassert(
ASSOCIATED(qmmm_env%mm_atom_chrg))
433 cpassert(
ASSOCIATED(qmmm_env%mm_atom_index))
434 cpassert(
ASSOCIATED(forces))
436 ngrids =
SIZE(pw_pools)
442 lb = rho%pw_grid%bounds_local(1, :)
443 ub = rho%pw_grid%bounds_local(2, :)
444 grids(auxbas_grid)%array(lb(1):ub(1), &
446 lb(3):ub(3)) = rho%array
449 grids(auxbas_grid)%array(i, ub(2) + 1, ub(3) + 1) = rho%array(i, lb(2), lb(3))
453 grids(auxbas_grid)%array(i, ub(2) + 1, k) = rho%array(i, lb(2), k)
458 grids(auxbas_grid)%array(i, j, ub(3) + 1) = rho%array(i, j, lb(3))
461 pos_of_x => grids(auxbas_grid)%pw_grid%para%pos_of_x
462 group = grids(auxbas_grid)%pw_grid%para%group
463 me = grids(auxbas_grid)%pw_grid%para%group%mepos
464 glb = rho%pw_grid%bounds(1, :)
465 gub = rho%pw_grid%bounds(2, :)
466 IF ((pos_of_x(glb(1)) .EQ. me) .AND. (pos_of_x(gub(1)) .EQ. me))
THEN
469 grids(auxbas_grid)%array(ub(1) + 1, j, k) = rho%array(lb(1), j, k)
471 grids(auxbas_grid)%array(ub(1) + 1, ub(2) + 1, k) = rho%array(lb(1), lb(2), k)
474 grids(auxbas_grid)%array(ub(1) + 1, j, ub(3) + 1) = rho%array(lb(1), j, lb(3))
476 grids(auxbas_grid)%array(ub(1) + 1, ub(2) + 1, ub(3) + 1) = rho%array(lb(1), lb(2), lb(3))
477 ELSE IF (pos_of_x(glb(1)) .EQ. me)
THEN
478 ALLOCATE (tmp(rho%pw_grid%bounds_local(1, 2):rho%pw_grid%bounds_local(2, 2), &
479 rho%pw_grid%bounds_local(1, 3):rho%pw_grid%bounds_local(2, 3)), &
482 tmp = rho%array(lb(1), :, :)
483 CALL group%isend(msgin=tmp, dest=pos_of_x(rho%pw_grid%bounds(2, 1)), &
484 request=request, tag=112)
486 ELSE IF (pos_of_x(gub(1)) .EQ. me)
THEN
487 ALLOCATE (tmp(rho%pw_grid%bounds_local(1, 2):rho%pw_grid%bounds_local(2, 2), &
488 rho%pw_grid%bounds_local(1, 3):rho%pw_grid%bounds_local(2, 3)), &
491 CALL group%irecv(msgout=tmp, source=pos_of_x(rho%pw_grid%bounds(1, 1)), &
492 request=request, tag=112)
497 grids(auxbas_grid)%array(ub(1) + 1, j, k) = tmp(j, k)
499 grids(auxbas_grid)%array(ub(1) + 1, ub(2) + 1, k) = tmp(lb(2), k)
502 grids(auxbas_grid)%array(ub(1) + 1, j, ub(3) + 1) = tmp(j, lb(3))
504 grids(auxbas_grid)%array(ub(1) + 1, ub(2) + 1, ub(3) + 1) = tmp(lb(2), lb(3))
506 IF (
ASSOCIATED(tmp))
THEN
511 CALL para_env%sum(grids(auxbas_grid)%array)
515 SELECT CASE (kind_interp)
518 DO igrid = auxbas_grid,
SIZE(grids) - 1
521 aug_pools(igrid + 1)%pool, &
522 param_section=interp_section)
529 CALL qmmm_force_with_gaussian_low(grids, mm_particles, &
530 qmmm_env%mm_atom_chrg, qmmm_env%mm_atom_index, &
531 qmmm_env%num_mm_atoms, cube_info, para_env, eps_mm_rspace, auxbas_grid, &
532 coarser_grid, qmmm_env%pgfs, qmmm_env%potentials, forces, aug_pools, &
533 mm_cell, qmmm_env%dOmmOqm, qmmm_env%periodic, qmmm_env%per_potentials, &
534 iw, qmmm_env%par_scheme, qmmm_env%spherical_cutoff, shells)
536 IF (qmmm_env%move_mm_charges .OR. qmmm_env%add_mm_charges)
THEN
537 CALL qmmm_force_with_gaussian_low(grids, qmmm_env%added_charges%added_particles, &
538 qmmm_env%added_charges%mm_atom_chrg, &
539 qmmm_env%added_charges%mm_atom_index, qmmm_env%added_charges%num_mm_atoms, &
540 cube_info, para_env, eps_mm_rspace, auxbas_grid, coarser_grid, qmmm_env%added_charges%pgfs, &
541 qmmm_env%added_charges%potentials, forces_added_charges, aug_pools, mm_cell, &
542 qmmm_env%dOmmOqm, qmmm_env%periodic, qmmm_env%added_charges%per_potentials, iw, qmmm_env%par_scheme, &
543 qmmm_env%spherical_cutoff, shells)
546 IF (qmmm_env%added_shells%num_mm_atoms .GT. 0)
THEN
548 CALL qmmm_force_with_gaussian_low(grids, qmmm_env%added_shells%added_particles, &
549 qmmm_env%added_shells%mm_core_chrg, &
550 qmmm_env%added_shells%mm_core_index, qmmm_env%added_shells%num_mm_atoms, &
551 cube_info, para_env, eps_mm_rspace, auxbas_grid, coarser_grid, qmmm_env%added_shells%pgfs, &
552 qmmm_env%added_shells%potentials, forces_added_shells, aug_pools, mm_cell, &
553 qmmm_env%dOmmOqm, qmmm_env%periodic, qmmm_env%added_shells%per_potentials, iw, qmmm_env%par_scheme, &
554 qmmm_env%spherical_cutoff, shells)
558 CALL timestop(handle)
560 END SUBROUTINE qmmm_forces_with_gaussian
592 SUBROUTINE qmmm_force_with_gaussian_low(grids, mm_particles, mm_charges, &
593 mm_atom_index, num_mm_atoms, cube_info, para_env, &
594 eps_mm_rspace, auxbas_grid, coarser_grid, pgfs, potentials, Forces, &
595 aug_pools, mm_cell, dOmmOqm, periodic, per_potentials, iw, par_scheme, &
596 qmmm_spherical_cutoff, shells)
599 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mm_charges
600 INTEGER,
DIMENSION(:),
POINTER :: mm_atom_index
601 INTEGER,
INTENT(IN) :: num_mm_atoms
604 REAL(kind=
dp),
INTENT(IN) :: eps_mm_rspace
605 INTEGER,
INTENT(IN) :: auxbas_grid, coarser_grid
608 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces
611 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: dommoqm
612 LOGICAL,
INTENT(in) :: periodic
614 INTEGER,
INTENT(IN) :: iw, par_scheme
615 REAL(kind=
dp),
INTENT(IN) :: qmmm_spherical_cutoff(2)
616 LOGICAL,
INTENT(in) :: shells
618 CHARACTER(len=*),
PARAMETER :: routinen =
'qmmm_force_with_gaussian_low', &
619 routinenb =
'qmmm_forces_gaussian_low'
621 INTEGER :: handle, handle2, igauss, ilevel, imm, &
622 indmm, iradtyp, lindmm, myind, &
624 INTEGER,
DIMENSION(2, 3) :: bo
625 REAL(kind=
dp) :: alpha, dvol, height, sph_chrg_factor, w
626 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: xdat, ydat, zdat
627 REAL(kind=
dp),
DIMENSION(3) :: force, ra
632 CALL timeset(routinen, handle)
633 CALL timeset(routinenb//
"_G", handle2)
634 NULLIFY (pgf, pot, per_pot)
636 radius:
DO iradtyp = 1,
SIZE(pgfs)
637 pgf => pgfs(iradtyp)%pgf
638 pot => potentials(iradtyp)%pot
641 per_pot => per_potentials(iradtyp)%pot
642 n_rep_real = per_pot%n_rep_real
644 gaussian:
DO igauss = 1, pgf%Number_of_Gaussians
645 alpha = 1.0_dp/pgf%Gk(igauss)
647 height = pgf%Ak(igauss)
648 ilevel = pgf%grid_level(igauss)
649 dvol = grids(ilevel)%pw_grid%dvol
650 bo = grids(ilevel)%pw_grid%bounds_local
651 ALLOCATE (xdat(2, bo(1, 1):bo(2, 1)))
652 ALLOCATE (ydat(2, bo(1, 2):bo(2, 2)))
653 ALLOCATE (zdat(2, bo(1, 3):bo(2, 3)))
661 atoms:
DO imm = 1,
SIZE(pot%mm_atom_index)
663 myind = imm + (igauss - 1)*
SIZE(pot%mm_atom_index) + (iradtyp - 1)*pgf%Number_of_Gaussians
664 IF (mod(myind, para_env%num_pe) /= para_env%mepos) cycle atoms
666 lindmm = pot%mm_atom_index(imm)
667 indmm = mm_atom_index(lindmm)
669 ra(:) =
pbc(mm_particles(imm)%r - dommoqm, mm_cell) + dommoqm
671 ra(:) =
pbc(mm_particles(indmm)%r - dommoqm, mm_cell) + dommoqm
673 w = mm_charges(lindmm)*height
676 IF (qmmm_spherical_cutoff(1) > 0.0_dp)
THEN
678 w = w*sph_chrg_factor
680 IF (abs(w) <= epsilon(0.0_dp)) cycle atoms
685 pwgrid=grids(ilevel), &
686 cube_info=cube_info(ilevel), &
687 eps_mm_rspace=eps_mm_rspace, &
693 n_rep_real=n_rep_real, &
696 forces(:, lindmm) = forces(:, lindmm) + force(:)
700 IF (debug_this_module)
THEN
701 CALL debug_integrate_gf_rspace_nopbc(ilevel=ilevel, &
705 pwgrid=grids(ilevel), &
706 cube_info=cube_info(ilevel), &
707 eps_mm_rspace=eps_mm_rspace, &
708 aug_pools=aug_pools, &
711 auxbas_grid=auxbas_grid, &
712 n_rep_real=n_rep_real, &
722 CALL timestop(handle2)
723 CALL timeset(routinenb//
"_R", handle2)
725 CALL qmmm_forces_with_gaussian_lg(pgfs=pgfs, &
726 cgrid=grids(coarser_grid), &
727 num_mm_atoms=num_mm_atoms, &
728 mm_charges=mm_charges, &
729 mm_atom_index=mm_atom_index, &
730 mm_particles=mm_particles, &
732 coarser_grid_level=coarser_grid, &
734 per_potentials=per_potentials, &
735 aug_pools=aug_pools, &
739 par_scheme=par_scheme, &
740 qmmm_spherical_cutoff=qmmm_spherical_cutoff, &
743 CALL qmmm_forces_with_gaussian_lr(pgfs=pgfs, &
744 cgrid=grids(coarser_grid), &
745 num_mm_atoms=num_mm_atoms, &
746 mm_charges=mm_charges, &
747 mm_atom_index=mm_atom_index, &
748 mm_particles=mm_particles, &
750 coarser_grid_level=coarser_grid, &
752 potentials=potentials, &
753 aug_pools=aug_pools, &
757 par_scheme=par_scheme, &
758 qmmm_spherical_cutoff=qmmm_spherical_cutoff, &
761 CALL timestop(handle2)
762 CALL timestop(handle)
763 END SUBROUTINE qmmm_force_with_gaussian_low
790 SUBROUTINE qmmm_forces_with_gaussian_lg(pgfs, cgrid, num_mm_atoms, mm_charges, mm_atom_index, &
791 mm_particles, para_env, coarser_grid_level, Forces, per_potentials, &
792 aug_pools, mm_cell, dOmmOqm, iw, par_scheme, qmmm_spherical_cutoff, shells)
795 INTEGER,
INTENT(IN) :: num_mm_atoms
796 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mm_charges
797 INTEGER,
DIMENSION(:),
POINTER :: mm_atom_index
800 INTEGER,
INTENT(IN) :: coarser_grid_level
801 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces
805 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: dommoqm
806 INTEGER,
INTENT(IN) :: iw, par_scheme
807 REAL(kind=
dp),
DIMENSION(2),
INTENT(IN) :: qmmm_spherical_cutoff
810 CHARACTER(len=*),
PARAMETER :: routinen =
'qmmm_forces_with_gaussian_LG'
812 INTEGER :: handle, i, ii1, ii2, ii3, ii4, ij1, ij2, ij3, ij4, ik1, ik2, ik3, ik4, imm, &
813 indmm, iradtyp, ivec(3), j, k, lindmm, my_i, my_j, my_k, myind, npts(3)
814 INTEGER,
DIMENSION(2, 3) :: bo, gbo
815 REAL(kind=
dp) :: a1, a2, a3, abc_x(4, 4), abc_x_y(4), b1, b2, b3, c1, c2, c3, d1, d2, d3, &
816 dr1, dr1c, dr1i, dr2, dr2c, dr2i, dr3, dr3c, dr3i, dvol, e1, e2, e3, f1, f2, f3,
fac, &
817 ft1, ft2, ft3, g1, g2, g3, h1, h2, h3, p1, p2, p3, q1, q2, q3, qt, r1, r2, r3, rt1, rt2, &
818 rt3, rv1, rv2, rv3, s1, s1d, s1o, s2, s2d, s2o, s3, s3d, s3o, s4, s4d, s4o, &
819 sph_chrg_factor, t1, t1d, t1o, t2, t2d, t2o, t3, t3d, t3o, t4, t4d, t4o, u1, u2, u3, v1, &
820 v1d, v1o, v2, v2d, v2o, v3, v3d, v3o, v4, v4d, v4o, xd1, xd2, xd3, xs1, xs2, xs3
821 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: lforces
822 REAL(kind=
dp),
DIMENSION(3) :: ra, val, vec
823 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: grid, grid2
827 CALL timeset(routinen, handle)
829 ALLOCATE (lforces(3, num_mm_atoms))
831 dr1c = cgrid%pw_grid%dr(1)
832 dr2c = cgrid%pw_grid%dr(2)
833 dr3c = cgrid%pw_grid%dr(3)
834 dvol = cgrid%pw_grid%dvol
835 gbo = cgrid%pw_grid%bounds
836 bo = cgrid%pw_grid%bounds_local
839 radius:
DO iradtyp = 1,
SIZE(pgfs)
840 per_pot => per_potentials(iradtyp)%pot
842 grid2 => pw%array(:, :, :)
843 npts = pw%pw_grid%npts
844 dr1 = pw%pw_grid%dr(1)
845 dr2 = pw%pw_grid%dr(2)
846 dr3 = pw%pw_grid%dr(3)
865 atoms:
DO imm = 1,
SIZE(per_pot%mm_atom_index)
867 myind = imm + (iradtyp - 1)*
SIZE(per_pot%mm_atom_index)
868 IF (mod(myind, para_env%num_pe) /= para_env%mepos) cycle
870 lindmm = per_pot%mm_atom_index(imm)
871 indmm = mm_atom_index(lindmm)
873 ra(:) =
pbc(mm_particles(lindmm)%r - dommoqm, mm_cell) + dommoqm
875 ra(:) =
pbc(mm_particles(indmm)%r - dommoqm, mm_cell) + dommoqm
877 qt = mm_charges(lindmm)
879 IF (qmmm_spherical_cutoff(1) > 0.0_dp)
THEN
881 qt = qt*sph_chrg_factor
883 IF (abs(qt) <= epsilon(0.0_dp)) cycle atoms
890 loopongrid:
DO k = bo(1, 3), bo(2, 3)
892 xs3 = real(my_k,
dp)*dr3c
893 my_j = bo(1, 2) - gbo(1, 2)
894 xs2 = real(my_j,
dp)*dr2c
897 ivec(3) = floor(vec(3)/pw%pw_grid%dr(3))
898 ik1 =
modulo(ivec(3) - 1, npts(3)) + 1
899 ik2 =
modulo(ivec(3), npts(3)) + 1
900 ik3 =
modulo(ivec(3) + 1, npts(3)) + 1
901 ik4 =
modulo(ivec(3) + 2, npts(3)) + 1
902 xd3 = (vec(3)/dr3) - real(ivec(3), kind=
dp)
915 v1o = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*p1 + 12.0_dp*p2 - p3)
916 v2o = -22.0_dp/3.0_dp + 10.0_dp*q1 - 4.0_dp*q2 + 0.5_dp*q3
917 v3o = 2.0_dp/3.0_dp - 2.0_dp*r1 + 2.0_dp*r2 - 0.5_dp*r3
918 v4o = 1.0_dp/6.0_dp*u3
919 v1d = -8.0_dp + 4.0_dp*p1 - 0.5_dp*p2
920 v2d = 10.0_dp - 8.0_dp*q1 + 1.5_dp*q2
921 v3d = -2.0_dp + 4.0_dp*r1 - 1.5_dp*r2
923 DO j = bo(1, 2), bo(2, 2)
924 my_i = bo(1, 1) - gbo(1, 1)
925 xs1 = real(my_i,
dp)*dr1c
928 ivec(2) = floor(vec(2)/pw%pw_grid%dr(2))
929 ij1 =
modulo(ivec(2) - 1, npts(2)) + 1
930 ij2 =
modulo(ivec(2), npts(2)) + 1
931 ij3 =
modulo(ivec(2) + 1, npts(2)) + 1
932 ij4 =
modulo(ivec(2) + 2, npts(2)) + 1
933 xd2 = (vec(2)/dr2) - real(ivec(2), kind=
dp)
946 s1o = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*e1 + 12.0_dp*e2 - e3)
947 s2o = -22.0_dp/3.0_dp + 10.0_dp*f1 - 4.0_dp*f2 + 0.5_dp*f3
948 s3o = 2.0_dp/3.0_dp - 2.0_dp*g1 + 2.0_dp*g2 - 0.5_dp*g3
949 s4o = 1.0_dp/6.0_dp*h3
950 s1d = -8.0_dp + 4.0_dp*e1 - 0.5_dp*e2
951 s2d = 10.0_dp - 8.0_dp*f1 + 1.5_dp*f2
952 s3d = -2.0_dp + 4.0_dp*g1 - 1.5_dp*g2
954 DO i = bo(1, 1), bo(2, 1)
957 ivec(1) = floor(vec(1)/pw%pw_grid%dr(1))
958 ii1 =
modulo(ivec(1) - 1, npts(1)) + 1
959 ii2 =
modulo(ivec(1), npts(1)) + 1
960 ii3 =
modulo(ivec(1) + 1, npts(1)) + 1
961 ii4 =
modulo(ivec(1) + 2, npts(1)) + 1
962 xd1 = (vec(1)/dr1) - real(ivec(1), kind=
dp)
975 t1o = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*a1 + 12.0_dp*a2 - a3)
976 t2o = -22.0_dp/3.0_dp + 10.0_dp*b1 - 4.0_dp*b2 + 0.5_dp*b3
977 t3o = 2.0_dp/3.0_dp - 2.0_dp*c1 + 2.0_dp*c2 - 0.5_dp*c3
978 t4o = 1.0_dp/6.0_dp*d3
979 t1d = -8.0_dp + 4.0_dp*a1 - 0.5_dp*a2
980 t2d = 10.0_dp - 8.0_dp*b1 + 1.5_dp*b2
981 t3d = -2.0_dp + 4.0_dp*c1 - 1.5_dp*c2
997 abc_x(1, 1) = grid2(ii1, ij1, ik1)*v1 + grid2(ii1, ij1, ik2)*v2 + grid2(ii1, ij1, ik3)*v3 + grid2(ii1, ij1, ik4)*v4
998 abc_x(2, 1) = grid2(ii2, ij1, ik1)*v1 + grid2(ii2, ij1, ik2)*v2 + grid2(ii2, ij1, ik3)*v3 + grid2(ii2, ij1, ik4)*v4
999 abc_x(3, 1) = grid2(ii3, ij1, ik1)*v1 + grid2(ii3, ij1, ik2)*v2 + grid2(ii3, ij1, ik3)*v3 + grid2(ii3, ij1, ik4)*v4
1000 abc_x(4, 1) = grid2(ii4, ij1, ik1)*v1 + grid2(ii4, ij1, ik2)*v2 + grid2(ii4, ij1, ik3)*v3 + grid2(ii4, ij1, ik4)*v4
1001 abc_x_y(1) = abc_x(1, 1)*t1 + abc_x(2, 1)*t2 + abc_x(3, 1)*t3 + abc_x(4, 1)*t4
1003 abc_x(1, 2) = grid2(ii1, ij2, ik1)*v1 + grid2(ii1, ij2, ik2)*v2 + grid2(ii1, ij2, ik3)*v3 + grid2(ii1, ij2, ik4)*v4
1004 abc_x(2, 2) = grid2(ii2, ij2, ik1)*v1 + grid2(ii2, ij2, ik2)*v2 + grid2(ii2, ij2, ik3)*v3 + grid2(ii2, ij2, ik4)*v4
1005 abc_x(3, 2) = grid2(ii3, ij2, ik1)*v1 + grid2(ii3, ij2, ik2)*v2 + grid2(ii3, ij2, ik3)*v3 + grid2(ii3, ij2, ik4)*v4
1006 abc_x(4, 2) = grid2(ii4, ij2, ik1)*v1 + grid2(ii4, ij2, ik2)*v2 + grid2(ii4, ij2, ik3)*v3 + grid2(ii4, ij2, ik4)*v4
1007 abc_x_y(2) = abc_x(1, 2)*t1 + abc_x(2, 2)*t2 + abc_x(3, 2)*t3 + abc_x(4, 2)*t4
1009 abc_x(1, 3) = grid2(ii1, ij3, ik1)*v1 + grid2(ii1, ij3, ik2)*v2 + grid2(ii1, ij3, ik3)*v3 + grid2(ii1, ij3, ik4)*v4
1010 abc_x(2, 3) = grid2(ii2, ij3, ik1)*v1 + grid2(ii2, ij3, ik2)*v2 + grid2(ii2, ij3, ik3)*v3 + grid2(ii2, ij3, ik4)*v4
1011 abc_x(3, 3) = grid2(ii3, ij3, ik1)*v1 + grid2(ii3, ij3, ik2)*v2 + grid2(ii3, ij3, ik3)*v3 + grid2(ii3, ij3, ik4)*v4
1012 abc_x(4, 3) = grid2(ii4, ij3, ik1)*v1 + grid2(ii4, ij3, ik2)*v2 + grid2(ii4, ij3, ik3)*v3 + grid2(ii4, ij3, ik4)*v4
1013 abc_x_y(3) = abc_x(1, 3)*t1 + abc_x(2, 3)*t2 + abc_x(3, 3)*t3 + abc_x(4, 3)*t4
1015 abc_x(1, 4) = grid2(ii1, ij4, ik1)*v1 + grid2(ii1, ij4, ik2)*v2 + grid2(ii1, ij4, ik3)*v3 + grid2(ii1, ij4, ik4)*v4
1016 abc_x(2, 4) = grid2(ii2, ij4, ik1)*v1 + grid2(ii2, ij4, ik2)*v2 + grid2(ii2, ij4, ik3)*v3 + grid2(ii2, ij4, ik4)*v4
1017 abc_x(3, 4) = grid2(ii3, ij4, ik1)*v1 + grid2(ii3, ij4, ik2)*v2 + grid2(ii3, ij4, ik3)*v3 + grid2(ii3, ij4, ik4)*v4
1018 abc_x(4, 4) = grid2(ii4, ij4, ik1)*v1 + grid2(ii4, ij4, ik2)*v2 + grid2(ii4, ij4, ik3)*v3 + grid2(ii4, ij4, ik4)*v4
1019 abc_x_y(4) = abc_x(1, 4)*t1 + abc_x(2, 4)*t2 + abc_x(3, 4)*t3 + abc_x(4, 4)*t4
1021 val(1) = abc_x_y(1)*s1 + abc_x_y(2)*s2 + abc_x_y(3)*s3 + abc_x_y(4)*s4
1032 abc_x_y(1) = abc_x(1, 1)*t1 + abc_x(2, 1)*t2 + abc_x(3, 1)*t3 + abc_x(4, 1)*t4
1033 abc_x_y(2) = abc_x(1, 2)*t1 + abc_x(2, 2)*t2 + abc_x(3, 2)*t3 + abc_x(4, 2)*t4
1034 abc_x_y(3) = abc_x(1, 3)*t1 + abc_x(2, 3)*t2 + abc_x(3, 3)*t3 + abc_x(4, 3)*t4
1035 abc_x_y(4) = abc_x(1, 4)*t1 + abc_x(2, 4)*t2 + abc_x(3, 4)*t3 + abc_x(4, 4)*t4
1037 val(2) = abc_x_y(1)*s1 + abc_x_y(2)*s2 + abc_x_y(3)*s3 + abc_x_y(4)*s4
1052 abc_x(1, 1) = grid2(ii1, ij1, ik1)*v1 + grid2(ii1, ij1, ik2)*v2 + grid2(ii1, ij1, ik3)*v3 + grid2(ii1, ij1, ik4)*v4
1053 abc_x(2, 1) = grid2(ii2, ij1, ik1)*v1 + grid2(ii2, ij1, ik2)*v2 + grid2(ii2, ij1, ik3)*v3 + grid2(ii2, ij1, ik4)*v4
1054 abc_x(3, 1) = grid2(ii3, ij1, ik1)*v1 + grid2(ii3, ij1, ik2)*v2 + grid2(ii3, ij1, ik3)*v3 + grid2(ii3, ij1, ik4)*v4
1055 abc_x(4, 1) = grid2(ii4, ij1, ik1)*v1 + grid2(ii4, ij1, ik2)*v2 + grid2(ii4, ij1, ik3)*v3 + grid2(ii4, ij1, ik4)*v4
1056 abc_x_y(1) = abc_x(1, 1)*t1 + abc_x(2, 1)*t2 + abc_x(3, 1)*t3 + abc_x(4, 1)*t4
1057 abc_x(1, 2) = grid2(ii1, ij2, ik1)*v1 + grid2(ii1, ij2, ik2)*v2 + grid2(ii1, ij2, ik3)*v3 + grid2(ii1, ij2, ik4)*v4
1058 abc_x(2, 2) = grid2(ii2, ij2, ik1)*v1 + grid2(ii2, ij2, ik2)*v2 + grid2(ii2, ij2, ik3)*v3 + grid2(ii2, ij2, ik4)*v4
1059 abc_x(3, 2) = grid2(ii3, ij2, ik1)*v1 + grid2(ii3, ij2, ik2)*v2 + grid2(ii3, ij2, ik3)*v3 + grid2(ii3, ij2, ik4)*v4
1060 abc_x(4, 2) = grid2(ii4, ij2, ik1)*v1 + grid2(ii4, ij2, ik2)*v2 + grid2(ii4, ij2, ik3)*v3 + grid2(ii4, ij2, ik4)*v4
1061 abc_x_y(2) = abc_x(1, 2)*t1 + abc_x(2, 2)*t2 + abc_x(3, 2)*t3 + abc_x(4, 2)*t4
1062 abc_x(1, 3) = grid2(ii1, ij3, ik1)*v1 + grid2(ii1, ij3, ik2)*v2 + grid2(ii1, ij3, ik3)*v3 + grid2(ii1, ij3, ik4)*v4
1063 abc_x(2, 3) = grid2(ii2, ij3, ik1)*v1 + grid2(ii2, ij3, ik2)*v2 + grid2(ii2, ij3, ik3)*v3 + grid2(ii2, ij3, ik4)*v4
1064 abc_x(3, 3) = grid2(ii3, ij3, ik1)*v1 + grid2(ii3, ij3, ik2)*v2 + grid2(ii3, ij3, ik3)*v3 + grid2(ii3, ij3, ik4)*v4
1065 abc_x(4, 3) = grid2(ii4, ij3, ik1)*v1 + grid2(ii4, ij3, ik2)*v2 + grid2(ii4, ij3, ik3)*v3 + grid2(ii4, ij3, ik4)*v4
1066 abc_x_y(3) = abc_x(1, 3)*t1 + abc_x(2, 3)*t2 + abc_x(3, 3)*t3 + abc_x(4, 3)*t4
1067 abc_x(1, 4) = grid2(ii1, ij4, ik1)*v1 + grid2(ii1, ij4, ik2)*v2 + grid2(ii1, ij4, ik3)*v3 + grid2(ii1, ij4, ik4)*v4
1068 abc_x(2, 4) = grid2(ii2, ij4, ik1)*v1 + grid2(ii2, ij4, ik2)*v2 + grid2(ii2, ij4, ik3)*v3 + grid2(ii2, ij4, ik4)*v4
1069 abc_x(3, 4) = grid2(ii3, ij4, ik1)*v1 + grid2(ii3, ij4, ik2)*v2 + grid2(ii3, ij4, ik3)*v3 + grid2(ii3, ij4, ik4)*v4
1070 abc_x(4, 4) = grid2(ii4, ij4, ik1)*v1 + grid2(ii4, ij4, ik2)*v2 + grid2(ii4, ij4, ik3)*v3 + grid2(ii4, ij4, ik4)*v4
1071 abc_x_y(4) = abc_x(1, 4)*t1 + abc_x(2, 4)*t2 + abc_x(3, 4)*t3 + abc_x(4, 4)*t4
1073 val(3) = abc_x_y(1)*s1 + abc_x_y(2)*s2 + abc_x_y(3)*s3 + abc_x_y(4)*s4
1076 ft1 = ft1 + val(1)*
fac
1077 ft2 = ft2 + val(2)*
fac
1078 ft3 = ft3 + val(3)*
fac
1085 lforces(1, lindmm) = ft1*qt
1086 lforces(2, lindmm) = ft2*qt
1087 lforces(3, lindmm) = ft3*qt
1089 forces(1, lindmm) = forces(1, lindmm) + lforces(1, lindmm)
1090 forces(2, lindmm) = forces(2, lindmm) + lforces(2, lindmm)
1091 forces(3, lindmm) = forces(3, lindmm) + lforces(3, lindmm)
1098 IF (debug_this_module)
THEN
1099 CALL debug_qmmm_forces_with_gauss_lg(pgfs=pgfs, &
1100 aug_pools=aug_pools, &
1102 num_mm_atoms=num_mm_atoms, &
1103 mm_charges=mm_charges, &
1104 mm_atom_index=mm_atom_index, &
1105 mm_particles=mm_particles, &
1106 coarser_grid_level=coarser_grid_level, &
1107 debug_force=lforces, &
1108 per_potentials=per_potentials, &
1109 para_env=para_env, &
1113 par_scheme=par_scheme, &
1114 qmmm_spherical_cutoff=qmmm_spherical_cutoff, &
1117 DEALLOCATE (lforces)
1118 CALL timestop(handle)
1119 END SUBROUTINE qmmm_forces_with_gaussian_lg
1146 SUBROUTINE qmmm_forces_with_gaussian_lr(pgfs, cgrid, num_mm_atoms, mm_charges, mm_atom_index, &
1147 mm_particles, para_env, coarser_grid_level, Forces, potentials, &
1148 aug_pools, mm_cell, dOmmOqm, iw, par_scheme, qmmm_spherical_cutoff, shells)
1151 INTEGER,
INTENT(IN) :: num_mm_atoms
1152 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mm_charges
1153 INTEGER,
DIMENSION(:),
POINTER :: mm_atom_index
1156 INTEGER,
INTENT(IN) :: coarser_grid_level
1157 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces
1161 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: dommoqm
1162 INTEGER,
INTENT(IN) :: iw, par_scheme
1163 REAL(kind=
dp),
DIMENSION(2),
INTENT(IN) :: qmmm_spherical_cutoff
1166 CHARACTER(len=*),
PARAMETER :: routinen =
'qmmm_forces_with_gaussian_LR'
1168 INTEGER :: handle, i, imm, indmm, iradtyp, ix, j, &
1169 k, lindmm, my_i, my_j, my_k, myind, &
1171 INTEGER,
DIMENSION(2, 3) :: bo, gbo
1172 REAL(kind=
dp) :: dr1, dr2, dr3, dvol, dx,
fac, ft1, ft2, &
1173 ft3, qt, r, r2, rd1, rd2, rd3, rt1, &
1174 rt2, rt3, rv1, rv2, rv3, rx, rx2, &
1175 sph_chrg_factor, term, xs1, xs2, xs3
1176 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: lforces
1177 REAL(kind=
dp),
DIMENSION(3) :: ra
1178 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: pot0_2
1179 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: grid
1182 CALL timeset(routinen, handle)
1183 ALLOCATE (lforces(3, num_mm_atoms))
1185 n1 = cgrid%pw_grid%npts(1)
1186 n2 = cgrid%pw_grid%npts(2)
1187 n3 = cgrid%pw_grid%npts(3)
1188 dr1 = cgrid%pw_grid%dr(1)
1189 dr2 = cgrid%pw_grid%dr(2)
1190 dr3 = cgrid%pw_grid%dr(3)
1191 dvol = cgrid%pw_grid%dvol
1192 gbo = cgrid%pw_grid%bounds
1193 bo = cgrid%pw_grid%bounds_local
1196 radius:
DO iradtyp = 1,
SIZE(pgfs)
1197 pot => potentials(iradtyp)%pot
1199 pot0_2 => pot%pot0_2
1207 atoms:
DO imm = 1,
SIZE(pot%mm_atom_index)
1209 myind = imm + (iradtyp - 1)*
SIZE(pot%mm_atom_index)
1210 IF (mod(myind, para_env%num_pe) /= para_env%mepos) cycle
1212 lindmm = pot%mm_atom_index(imm)
1213 indmm = mm_atom_index(lindmm)
1214 ra(:) =
pbc(mm_particles(indmm)%r - dommoqm, mm_cell) + dommoqm
1216 ra(:) =
pbc(mm_particles(lindmm)%r - dommoqm, mm_cell) + dommoqm
1217 qt = mm_charges(lindmm)
1219 IF (qmmm_spherical_cutoff(1) > 0.0_dp)
THEN
1221 qt = qt*sph_chrg_factor
1223 IF (abs(qt) <= epsilon(0.0_dp)) cycle atoms
1230 loopongrid:
DO k = bo(1, 3), bo(2, 3)
1231 my_k = k - gbo(1, 3)
1232 xs3 = real(my_k,
dp)*dr3
1233 my_j = bo(1, 2) - gbo(1, 2)
1234 xs2 = real(my_j,
dp)*dr2
1236 DO j = bo(1, 2), bo(2, 2)
1237 my_i = bo(1, 1) - gbo(1, 1)
1238 xs1 = real(my_i,
dp)*dr1
1240 DO i = bo(1, 1), bo(2, 1)
1242 r2 = rv1*rv1 + rv2*rv2 + rv3*rv3
1244 ix = floor(r/dx) + 1
1245 rx = (r - real(ix - 1,
dp)*dx)/dx
1247 term = pot0_2(1, ix)*(-6.0_dp*(rx - rx2)) &
1248 + pot0_2(2, ix)*(1.0_dp - 4.0_dp*rx + 3.0_dp*rx2) &
1249 + pot0_2(1, ix + 1)*(6.0_dp*(rx - rx2)) &
1250 + pot0_2(2, ix + 1)*(-2.0_dp*rx + 3.0_dp*rx2)
1251 fac = grid(i, j, k)*term
1252 IF (r == 0.0_dp)
THEN
1270 lforces(1, lindmm) = ft1*qt
1271 lforces(2, lindmm) = ft2*qt
1272 lforces(3, lindmm) = ft3*qt
1274 forces(1, lindmm) = forces(1, lindmm) + lforces(1, lindmm)
1275 forces(2, lindmm) = forces(2, lindmm) + lforces(2, lindmm)
1276 forces(3, lindmm) = forces(3, lindmm) + lforces(3, lindmm)
1283 IF (debug_this_module)
THEN
1284 CALL debug_qmmm_forces_with_gauss_lr(pgfs=pgfs, &
1285 aug_pools=aug_pools, &
1287 num_mm_atoms=num_mm_atoms, &
1288 mm_charges=mm_charges, &
1289 mm_atom_index=mm_atom_index, &
1290 mm_particles=mm_particles, &
1291 coarser_grid_level=coarser_grid_level, &
1292 debug_force=lforces, &
1293 potentials=potentials, &
1294 para_env=para_env, &
1298 par_scheme=par_scheme, &
1299 qmmm_spherical_cutoff=qmmm_spherical_cutoff, &
1303 DEALLOCATE (lforces)
1304 CALL timestop(handle)
1305 END SUBROUTINE qmmm_forces_with_gaussian_lr
1324 SUBROUTINE qmmm_debug_forces(rho, qs_env, qmmm_env, Analytical_Forces, &
1325 mm_particles, mm_atom_index, num_mm_atoms, &
1326 interp_section, mm_cell)
1330 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: analytical_forces
1332 INTEGER,
DIMENSION(:),
POINTER :: mm_atom_index
1333 INTEGER,
INTENT(IN) :: num_mm_atoms
1337 CHARACTER(len=*),
PARAMETER :: routinen =
'qmmm_debug_forces'
1339 INTEGER :: handle, i, indmm, iw, j, k
1340 REAL(kind=
dp) :: coord_save
1341 REAL(kind=
dp),
DIMENSION(2) :: energy
1342 REAL(kind=
dp),
DIMENSION(3) :: err
1343 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: num_forces
1352 CALL timeset(routinen, handle)
1353 NULLIFY (num_forces)
1356 input=input_section, &
1362 CALL pw_env_get(pw_env=pw_env, pw_pools=pw_pools)
1363 CALL pw_pools(1)%pool%create_pw(v_qmmm_rspace)
1364 ALLOCATE (num_forces(3, num_mm_atoms))
1365 ks_qmmm_env_loc => qs_env%ks_qmmm_env
1366 IF (iw > 0)
WRITE (iw,
'(/A)')
"DEBUG SECTION:"
1367 atoms:
DO i = 1, num_mm_atoms
1368 indmm = mm_atom_index(i)
1370 coord_save = mm_particles(indmm)%r(j)
1373 mm_particles(indmm)%r(j) = coord_save + (-1)**k*dx
1375 SELECT CASE (qmmm_env%qmmm_coupl_type)
1377 cpabort(
"Coulomb QM/MM electrostatic coupling not implemented for GPW/GAPW.")
1379 cpabort(
"Point Charge QM/MM electrostatic coupling not implemented for GPW/GAPW.")
1382 v_qmmm=v_qmmm_rspace, &
1383 mm_particles=mm_particles, &
1384 aug_pools=qmmm_env%aug_pools, &
1385 para_env=para_env, &
1386 eps_mm_rspace=qmmm_env%eps_mm_rspace, &
1387 cube_info=ks_qmmm_env_loc%cube_info, &
1388 pw_pools=pw_pools, &
1389 auxbas_grid=qmmm_env%gridlevel_info%auxbas_grid, &
1390 coarser_grid=qmmm_env%gridlevel_info%coarser_grid, &
1391 interp_section=interp_section, &
1396 IF (iw > 0)
WRITE (iw,
'(T3,A)')
"Unknown Coupling..."
1402 WRITE (iw,
'(A,I6,A,I3,A,2F15.9)') &
1403 "DEBUG :: MM Atom = ", indmm,
" Coord = ", j,
" Energies (+/-) :: ", energy(2), energy(1)
1405 num_forces(j, i) = (energy(2) - energy(1))/(2.0_dp*dx)
1406 mm_particles(indmm)%r(j) = coord_save
1410 SELECT CASE (qmmm_env%qmmm_coupl_type)
1412 cpabort(
"Coulomb QM/MM electrostatic coupling not implemented for GPW/GAPW.")
1414 cpabort(
"Point Charge QM/MM electrostatic coupling not implemented for GPW/GAPW.")
1416 IF (iw > 0)
WRITE (iw,
'(/A/)')
"CHECKING NUMERICAL Vs ANALYTICAL FORCES (Err%):"
1417 DO i = 1, num_mm_atoms
1418 indmm = mm_atom_index(i)
1421 IF (abs(num_forces(k, i)) >= 5.0e-5_dp)
THEN
1422 err(k) = (analytical_forces(k, i) - num_forces(k, i))/num_forces(k, i)*100.0_dp
1426 WRITE (iw, 100) indmm, analytical_forces(1, i), num_forces(1, i), err(1), &
1427 analytical_forces(2, i), num_forces(2, i), err(2), &
1428 analytical_forces(3, i), num_forces(3, i), err(3)
1429 cpassert(abs(err(1)) <= maxerr)
1430 cpassert(abs(err(2)) <= maxerr)
1431 cpassert(abs(err(3)) <= maxerr)
1434 IF (iw > 0)
WRITE (iw,
'(T3,A)')
"No QM/MM Derivatives to debug. Just Mechanical Coupling!"
1436 IF (iw > 0)
WRITE (iw,
'(T3,A)')
"Unknown Coupling..."
1441 CALL pw_pools(1)%pool%give_back_pw(v_qmmm_rspace)
1442 DEALLOCATE (num_forces)
1443 CALL timestop(handle)
1444100
FORMAT(i5, 2f15.9,
" ( ", f7.2,
" ) ", 2f15.9,
" ( ", f7.2,
" ) ", 2f15.9,
" ( ", f7.2,
" ) ")
1445 END SUBROUTINE qmmm_debug_forces
1466 SUBROUTINE debug_integrate_gf_rspace_nopbc(ilevel, zetp, rp, W, pwgrid, cube_info, &
1467 eps_mm_rspace, aug_pools, debug_force, &
1468 mm_cell, auxbas_grid, n_rep_real, iw)
1469 INTEGER,
INTENT(IN) :: ilevel
1470 REAL(kind=
dp),
INTENT(IN) :: zetp
1471 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: rp
1472 REAL(kind=
dp),
INTENT(IN) :: w
1475 REAL(kind=
dp),
INTENT(IN) :: eps_mm_rspace
1477 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: debug_force
1479 INTEGER,
INTENT(IN) :: auxbas_grid
1480 INTEGER,
DIMENSION(3),
INTENT(IN) :: n_rep_real
1481 INTEGER,
INTENT(IN) :: iw
1483 CHARACTER(len=*),
PARAMETER :: routinen =
'debug_integrate_gf_rspace_NoPBC'
1485 INTEGER :: handle, i, igrid, k, ngrids
1486 INTEGER,
DIMENSION(2, 3) :: bo2
1487 INTEGER,
SAVE :: icount
1488 REAL(kind=
dp),
DIMENSION(2) :: energy
1489 REAL(kind=
dp),
DIMENSION(3) :: err, force, myrp
1490 REAL(kind=
dp),
DIMENSION(:),
POINTER :: xdat, ydat, zdat
1495 CALL timeset(routinen, handle)
1497 ngrids =
SIZE(aug_pools)
1499 DO igrid = 1, ngrids
1502 bo2 = grids(auxbas_grid)%pw_grid%bounds
1503 ALLOCATE (xdat(bo2(1, 1):bo2(2, 1)))
1504 ALLOCATE (ydat(bo2(1, 2):bo2(2, 2)))
1505 ALLOCATE (zdat(bo2(1, 3):bo2(2, 3)))
1511 myrp(i) = myrp(i) + (-1.0_dp)**k*dx
1517 pwgrid=grids(ilevel), &
1518 cube_info=cube_info, &
1519 eps_mm_rspace=eps_mm_rspace, &
1524 n_rep_real=n_rep_real, &
1529 force(i) = (energy(2) - energy(1))/(2.0_dp*dx)
1532 IF (all(force /= 0.0_dp))
THEN
1533 err(1) = (debug_force(1) - force(1))/force(1)*100.0_dp
1534 err(2) = (debug_force(2) - force(2))/force(2)*100.0_dp
1535 err(3) = (debug_force(3) - force(3))/force(3)*100.0_dp
1538 WRITE (iw, 100) icount, debug_force(1), force(1), err(1), &
1539 debug_force(2), force(2), err(2), &
1540 debug_force(3), force(3), err(3)
1541 cpassert(abs(err(1)) <= maxerr)
1542 cpassert(abs(err(2)) <= maxerr)
1543 cpassert(abs(err(3)) <= maxerr)
1545 IF (
ASSOCIATED(xdat))
THEN
1548 IF (
ASSOCIATED(ydat))
THEN
1551 IF (
ASSOCIATED(zdat))
THEN
1556 CALL timestop(handle)
1557100
FORMAT(
"Collocation : ", i5, 2f15.9,
" ( ", f7.2,
" ) ", 2f15.9,
" ( ", f7.2,
" ) ", 2f15.9,
" ( ", f7.2,
" ) ")
1558 END SUBROUTINE debug_integrate_gf_rspace_nopbc
1583 SUBROUTINE debug_qmmm_forces_with_gauss_lg(pgfs, aug_pools, rho, mm_charges, mm_atom_index, &
1584 mm_particles, num_mm_atoms, coarser_grid_level, per_potentials, &
1585 debug_force, para_env, mm_cell, dOmmOqm, iw, par_scheme, qmmm_spherical_cutoff, shells)
1590 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mm_charges
1591 INTEGER,
DIMENSION(:),
POINTER :: mm_atom_index
1593 INTEGER,
INTENT(IN) :: num_mm_atoms, coarser_grid_level
1595 REAL(kind=
dp),
DIMENSION(:, :) :: debug_force
1598 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: dommoqm
1599 INTEGER,
INTENT(IN) :: iw, par_scheme
1600 REAL(kind=
dp),
DIMENSION(2),
INTENT(IN) :: qmmm_spherical_cutoff
1603 CHARACTER(len=*),
PARAMETER :: routinen =
'debug_qmmm_forces_with_gauss_LG'
1605 INTEGER :: handle, i, igrid, indmm, j, k, ngrids
1606 REAL(kind=
dp) :: coord_save
1607 REAL(kind=
dp),
DIMENSION(2) :: energy
1608 REAL(kind=
dp),
DIMENSION(3) :: err
1609 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: num_forces
1612 ALLOCATE (num_forces(3, num_mm_atoms))
1613 CALL timeset(routinen, handle)
1614 ngrids =
SIZE(aug_pools)
1616 DO igrid = 1, ngrids
1619 atoms:
DO i = 1, num_mm_atoms
1620 indmm = mm_atom_index(i)
1622 coord_save = mm_particles(indmm)%r(j)
1625 mm_particles(indmm)%r(j) = coord_save + (-1)**k*dx
1626 CALL pw_zero(grids(coarser_grid_level))
1629 cgrid=grids(coarser_grid_level), &
1630 mm_charges=mm_charges, &
1631 mm_atom_index=mm_atom_index, &
1632 mm_particles=mm_particles, &
1633 para_env=para_env, &
1634 per_potentials=per_potentials, &
1637 par_scheme=par_scheme, &
1638 qmmm_spherical_cutoff=qmmm_spherical_cutoff, &
1644 WRITE (iw,
'(A,I6,A,I3,A,2F15.9)') &
1645 "DEBUG LR:: MM Atom = ", indmm,
" Coord = ", j,
" Energies (+/-) :: ", energy(2), energy(1)
1646 num_forces(j, i) = (energy(2) - energy(1))/(2.0_dp*dx)
1647 mm_particles(indmm)%r(j) = coord_save
1651 DO i = 1, num_mm_atoms
1652 indmm = mm_atom_index(i)
1654 IF (all(num_forces /= 0.0_dp))
THEN
1655 err(1) = (debug_force(1, i) - num_forces(1, i))/num_forces(1, i)*100.0_dp
1656 err(2) = (debug_force(2, i) - num_forces(2, i))/num_forces(2, i)*100.0_dp
1657 err(3) = (debug_force(3, i) - num_forces(3, i))/num_forces(3, i)*100.0_dp
1660 WRITE (iw, 100) indmm, debug_force(1, i), num_forces(1, i), err(1), &
1661 debug_force(2, i), num_forces(2, i), err(2), &
1662 debug_force(3, i), num_forces(3, i), err(3)
1663 cpassert(abs(err(1)) <= maxerr)
1664 cpassert(abs(err(2)) <= maxerr)
1665 cpassert(abs(err(3)) <= maxerr)
1668 DEALLOCATE (num_forces)
1670 CALL timestop(handle)
1671100
FORMAT(
"MM Atom LR : ", i5, 2f15.9,
" ( ", f7.2,
" ) ", 2f15.9,
" ( ", f7.2,
" ) ", 2f15.9,
" ( ", f7.2,
" ) ")
1672 END SUBROUTINE debug_qmmm_forces_with_gauss_lg
1697 SUBROUTINE debug_qmmm_forces_with_gauss_lr(pgfs, aug_pools, rho, mm_charges, mm_atom_index, &
1698 mm_particles, num_mm_atoms, coarser_grid_level, potentials, &
1699 debug_force, para_env, mm_cell, dOmmOqm, iw, par_scheme, qmmm_spherical_cutoff, shells)
1704 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mm_charges
1705 INTEGER,
DIMENSION(:),
POINTER :: mm_atom_index
1707 INTEGER,
INTENT(IN) :: num_mm_atoms, coarser_grid_level
1709 REAL(kind=
dp),
DIMENSION(:, :) :: debug_force
1712 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: dommoqm
1713 INTEGER,
INTENT(IN) :: iw, par_scheme
1714 REAL(kind=
dp),
DIMENSION(2),
INTENT(IN) :: qmmm_spherical_cutoff
1717 CHARACTER(len=*),
PARAMETER :: routinen =
'debug_qmmm_forces_with_gauss_LR'
1719 INTEGER :: handle, i, igrid, indmm, j, k, ngrids
1720 REAL(kind=
dp) :: coord_save
1721 REAL(kind=
dp),
DIMENSION(2) :: energy
1722 REAL(kind=
dp),
DIMENSION(3) :: err
1723 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: num_forces
1726 ALLOCATE (num_forces(3, num_mm_atoms))
1727 CALL timeset(routinen, handle)
1728 ngrids =
SIZE(aug_pools)
1730 DO igrid = 1, ngrids
1733 atoms:
DO i = 1, num_mm_atoms
1734 indmm = mm_atom_index(i)
1736 coord_save = mm_particles(indmm)%r(j)
1739 mm_particles(indmm)%r(j) = coord_save + (-1)**k*dx
1740 CALL pw_zero(grids(coarser_grid_level))
1743 grid=grids(coarser_grid_level), &
1744 mm_charges=mm_charges, &
1745 mm_atom_index=mm_atom_index, &
1746 mm_particles=mm_particles, &
1747 para_env=para_env, &
1748 potentials=potentials, &
1751 par_scheme=par_scheme, &
1752 qmmm_spherical_cutoff=qmmm_spherical_cutoff, &
1758 WRITE (iw,
'(A,I6,A,I3,A,2F15.9)') &
1759 "DEBUG LR:: MM Atom = ", indmm,
" Coord = ", j,
" Energies (+/-) :: ", energy(2), energy(1)
1760 num_forces(j, i) = (energy(2) - energy(1))/(2.0_dp*dx)
1761 mm_particles(indmm)%r(j) = coord_save
1765 DO i = 1, num_mm_atoms
1766 indmm = mm_atom_index(i)
1768 IF (all(num_forces(:, i) /= 0.0_dp))
THEN
1769 err(1) = (debug_force(1, i) - num_forces(1, i))/num_forces(1, i)*100.0_dp
1770 err(2) = (debug_force(2, i) - num_forces(2, i))/num_forces(2, i)*100.0_dp
1771 err(3) = (debug_force(3, i) - num_forces(3, i))/num_forces(3, i)*100.0_dp
1774 WRITE (iw, 100) indmm, debug_force(1, i), num_forces(1, i), err(1), &
1775 debug_force(2, i), num_forces(2, i), err(2), &
1776 debug_force(3, i), num_forces(3, i), err(3)
1777 cpassert(abs(err(1)) <= maxerr)
1778 cpassert(abs(err(2)) <= maxerr)
1779 cpassert(abs(err(3)) <= maxerr)
1782 DEALLOCATE (num_forces)
1784 CALL timestop(handle)
1785100
FORMAT(
"MM Atom LR : ", i5, 2f15.9,
" ( ", f7.2,
" ) ", 2f15.9,
" ( ", f7.2,
" ) ", 2f15.9,
" ( ", f7.2,
" ) ")
1786 END SUBROUTINE debug_qmmm_forces_with_gauss_lr
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
static GRID_HOST_DEVICE double fac(const int i)
Factorial function, e.g. fac(5) = 5! = 120.
Handles all functions related to the CELL.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
utils to manipulate splines on the regular grid of a pw
integer, parameter, public spline3_nopbc_interp
integer, parameter, public spline3_pbc_interp
subroutine, public pw_restrict_s3(pw_fine_in, pw_coarse_out, coarse_pool, param_section)
restricts the function from a fine grid to a coarse one
for a given dr()/dh(r) this will provide the bounds to be used if one wants to go over a sphere-subre...
Defines the basic variable types.
integer, parameter, public dp
Interface to the message passing library MPI.
Calculate the MM potential by collocating the primitive Gaussian functions (pgf)
subroutine, public integrate_gf_rspace_nopbc(zetp, rp, scale, w, pwgrid, cube_info, eps_mm_rspace, xdat, ydat, zdat, bo, force, n_rep_real, mm_cell)
Main driver to integrate gaussian functions on a grid function without using periodic boundary condit...
subroutine, public collocate_gf_rspace_nopbc(zetp, rp, scale, w, pwgrid, cube_info, eps_mm_rspace, xdat, ydat, zdat, bo2, n_rep_real, mm_cell)
Main driver to collocate gaussian functions on grid without using periodic boundary conditions (NoPBC...
Define the data structure for the particle information.
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Sets the typo for the gaussian treatment of the qm/mm interaction.
A collection of methods to treat the QM/MM electrostatic coupling.
subroutine, public qmmm_elec_with_gaussian(qmmm_env, v_qmmm, mm_particles, aug_pools, cube_info, para_env, eps_mm_rspace, pw_pools, auxbas_grid, coarser_grid, interp_section, mm_cell)
Compute the QM/MM electrostatic Interaction collocating the gaussian Electrostatic Potential.
subroutine, public qmmm_elec_with_gaussian_lr(pgfs, grid, mm_charges, mm_atom_index, mm_particles, para_env, potentials, mm_cell, dommoqm, par_scheme, qmmm_spherical_cutoff, shells)
Compute the QM/MM electrostatic Interaction collocating (1/R - Sum_NG Gaussians) on the coarser grid ...
subroutine, public qmmm_elec_with_gaussian_lg(pgfs, cgrid, mm_charges, mm_atom_index, mm_particles, para_env, per_potentials, mm_cell, dommoqm, par_scheme, qmmm_spherical_cutoff, shells)
Compute the QM/MM electrostatic Interaction collocating (1/R - Sum_NG Gaussians) on the coarser grid ...
Routines to compute energy and forces in a QM/MM calculation.
subroutine, public qmmm_forces(qs_env, qmmm_env, mm_particles, calc_force, mm_cell)
General driver to Compute the contribution to the forces due to the QM/MM potential.
Calculation of the derivative of the QMMM Hamiltonian integral matrix <a|\sum_i q_i|b> for semi-empir...
subroutine, public deriv_se_qmmm_matrix(qs_env, qmmm_env, particles_mm, mm_cell, para_env, calc_force, forces, forces_added_charges)
Constructs the derivative w.r.t. 1-el semi-empirical hamiltonian QMMM terms.
TB methods used with QMMM.
subroutine, public deriv_tb_qmmm_matrix(qs_env, qmmm_env, particles_mm, mm_cell, para_env, calc_force, forces, forces_added_charges)
Constructs the derivative w.r.t. 1-el DFTB hamiltonian QMMM terms.
subroutine, public deriv_tb_qmmm_matrix_pc(qs_env, qmmm_env, particles_mm, mm_cell, para_env, calc_force, forces, forces_added_charges)
Constructs the derivative w.r.t. 1-el DFTB hamiltonian QMMM terms.
subroutine, public spherical_cutoff_factor(spherical_cutoff, rij, factor)
Computes a spherical cutoff factor for the QMMM interactions.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Get the QUICKSTEP environment.
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
Type defining parameters related to the simulation cell.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
contained for different pw related things
to create arrays of pools
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
represent a pointer to a qmmm_gaussian_type, to be able to create arrays of pointers
calculation environment to calculate the ks_qmmm matrix, holds the QM/MM potential and all the needed...
keeps the density in various representations, keeping track of which ones are valid.