69#include "./base/base_uses.f90"
74 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
75 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qmmm_image_charge'
104 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_pot'
108 CALL timeset(routinen, handle)
110 IF (qmmm_env%image_charge_pot%coeff_iterative)
THEN
112 IF (qs_env%calc_image_preconditioner)
THEN
113 IF (qmmm_env%image_charge_pot%image_restart)
THEN
114 CALL restart_image_matrix(image_matrix=qs_env%image_matrix, &
115 qs_env=qs_env, qmmm_env=qmmm_env)
117 CALL calculate_image_matrix(image_matrix=qs_env%image_matrix, &
118 qs_env=qs_env, qmmm_env=qmmm_env)
121 CALL calc_image_coeff_iterative(v_hartree_rspace=v_hartree_rspace, &
122 coeff=qs_env%image_coeff, qmmm_env=qmmm_env, &
126 CALL calc_image_coeff_gaussalgorithm(v_hartree_rspace=v_hartree_rspace, &
127 coeff=qs_env%image_coeff, qmmm_env=qmmm_env, &
132 ALLOCATE (qs_env%ks_qmmm_env%v_metal_rspace)
133 CALL calculate_potential_metal(v_metal_rspace= &
134 qs_env%ks_qmmm_env%v_metal_rspace, coeff=qs_env%image_coeff, &
135 rho_hartree_gspace=rho_hartree_gspace, &
136 energy=energy, qs_env=qs_env)
138 CALL timestop(handle)
151 SUBROUTINE calc_image_coeff_gaussalgorithm(v_hartree_rspace, coeff, qmmm_env, &
155 REAL(kind=
dp),
DIMENSION(:),
POINTER :: coeff
159 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calc_image_coeff_gaussalgorithm'
161 INTEGER :: handle, info, natom
162 REAL(kind=
dp) :: eta, v0
163 REAL(kind=
dp),
DIMENSION(:),
POINTER :: pot_const
165 CALL timeset(routinen, handle)
170 v0 = -qmmm_env%image_charge_pot%V0
171 eta = qmmm_env%image_charge_pot%eta
172 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
174 ALLOCATE (pot_const(natom))
175 IF (.NOT.
ASSOCIATED(coeff))
THEN
176 ALLOCATE (coeff(natom))
180 CALL integrate_potential_ga_rspace(v_hartree_rspace, qmmm_env, qs_env, &
183 pot_const(:) = -pot_const(:) + v0*sqrt((
pi/eta)**3)
187 CALL dgetrs(
'N', natom, 1, qs_env%image_matrix, natom, qs_env%ipiv, &
188 pot_const, natom, info)
193 DEALLOCATE (pot_const)
195 CALL timestop(handle)
197 END SUBROUTINE calc_image_coeff_gaussalgorithm
207 SUBROUTINE calc_image_coeff_iterative(v_hartree_rspace, coeff, qmmm_env, &
211 REAL(kind=
dp),
DIMENSION(:),
POINTER :: coeff
215 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calc_image_coeff_iterative'
216 REAL(kind=
dp),
PARAMETER :: eps_rsnew = 1.0e-16_dp
218 INTEGER :: handle, iter_steps, natom, output_unit
219 REAL(kind=
dp) :: alpha, eta, rsnew, rsold, v0
220 REAL(kind=
dp),
DIMENSION(:),
POINTER :: ad, d, pot_const, r, vmetal_const, z
225 CALL timeset(routinen, handle)
227 NULLIFY (pot_const, vmetal_const, logger, input)
231 v0 = -qmmm_env%image_charge_pot%V0
232 eta = qmmm_env%image_charge_pot%eta
233 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
235 ALLOCATE (pot_const(natom))
236 ALLOCATE (vmetal_const(natom))
241 IF (.NOT.
ASSOCIATED(coeff))
THEN
242 ALLOCATE (coeff(natom))
245 CALL integrate_potential_ga_rspace(v_hartree_rspace, qmmm_env, qs_env, &
249 pot_const(:) = -pot_const(:) + v0*sqrt((
pi/eta)**3)
261 CALL calculate_potential_metal(v_metal_rspace=v_metal_rspace_guess, &
262 coeff=coeff, qs_env=qs_env)
263 CALL integrate_potential_ga_rspace(potential=v_metal_rspace_guess, &
264 qmmm_env=qmmm_env, qs_env=qs_env, int_res=vmetal_const)
267 r = pot_const - vmetal_const
268 z = matmul(qs_env%image_matrix, r)
270 rsold = dot_product(r, z)
275 CALL calculate_potential_metal(v_metal_rspace= &
276 auxpot_ad_rspace, coeff=d, qs_env=qs_env)
277 CALL integrate_potential_ga_rspace(potential= &
278 auxpot_ad_rspace, qmmm_env=qmmm_env, &
279 qs_env=qs_env, int_res=ad)
281 alpha = rsold/dot_product(d, ad)
282 coeff = coeff + alpha*d
285 z = matmul(qs_env%image_matrix, r)
286 rsnew = dot_product(r, z)
287 iter_steps = iter_steps + 1
289 IF (rsnew < eps_rsnew)
THEN
290 CALL auxpot_ad_rspace%release()
293 d = z + rsnew/rsold*d
295 CALL auxpot_ad_rspace%release()
302 "QMMM%PRINT%PROGRAM_RUN_INFO", &
303 extension=
".qmmmLog")
304 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A,T74,I7)") &
305 "Number of iteration steps for determination of image coefficients:", iter_steps
307 "QMMM%PRINT%PROGRAM_RUN_INFO")
309 IF (iter_steps < 25)
THEN
310 qs_env%calc_image_preconditioner = .false.
312 qs_env%calc_image_preconditioner = .true.
315 CALL v_metal_rspace_guess%release()
316 DEALLOCATE (pot_const)
317 DEALLOCATE (vmetal_const)
322 CALL timestop(handle)
324 END SUBROUTINE calc_image_coeff_iterative
336 SUBROUTINE integrate_potential_ga_rspace(potential, qmmm_env, qs_env, int_res, &
337 atom_num, atom_num_ref)
342 REAL(kind=
dp),
DIMENSION(:),
POINTER :: int_res
343 INTEGER,
INTENT(IN),
OPTIONAL :: atom_num, atom_num_ref
345 CHARACTER(LEN=*),
PARAMETER :: routinen =
'integrate_potential_ga_rspace'
347 INTEGER :: atom_a, atom_b, atom_ref, handle, iatom, &
349 INTEGER,
DIMENSION(:),
POINTER :: cores
350 REAL(kind=
dp) :: eps_rho_rspace, radius
351 REAL(kind=
dp),
DIMENSION(3) :: ra
352 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: hab
360 CALL timeset(routinen, handle)
362 NULLIFY (cores, hab, cell, auxbas_rs_desc, pw_env, para_env, &
367 CALL pw_env_get(pw_env=pw_env, auxbas_rs_desc=auxbas_rs_desc, &
373 dft_control=dft_control, &
374 para_env=para_env, pw_env=pw_env)
376 eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
378 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
380 IF (
PRESENT(atom_num)) k = atom_num
388 IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed)
THEN
390 IF (
modulo(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos)
THEN
403 atom_a = qmmm_env%image_charge_pot%image_mm_list(iatom)
405 IF (
PRESENT(atom_num) .AND.
PRESENT(atom_num_ref))
THEN
407 atom_b = qmmm_env%image_charge_pot%image_mm_list(k)
408 atom_ref = qmmm_env%image_charge_pot%image_mm_list(atom_num_ref)
409 ra(:) =
pbc(qmmm_env%image_charge_pot%particles_all(atom_a)%r, cell) &
410 -
pbc(qmmm_env%image_charge_pot%particles_all(atom_b)%r, cell) &
411 +
pbc(qmmm_env%image_charge_pot%particles_all(atom_ref)%r, cell)
414 ra(:) =
pbc(qmmm_env%image_charge_pot%particles_all(atom_a)%r, cell)
420 ra=ra, rb=ra, rp=ra, &
421 zetp=qmmm_env%image_charge_pot%eta, eps=eps_rho_rspace, &
422 prefactor=1.0_dp, cutoff=1.0_dp)
424 CALL integrate_pgf_product(0, qmmm_env%image_charge_pot%eta, 0, &
425 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], &
426 rs_v, hab, o1=0, o2=0, &
427 radius=radius, calculate_forces=.false., &
428 use_subpatch=.true., subpatch_pattern=0)
430 int_res(iatom) = hab(1, 1)
434 CALL para_env%sum(int_res)
436 DEALLOCATE (hab, cores)
438 CALL timestop(handle)
440 END SUBROUTINE integrate_potential_ga_rspace
456 REAL(kind=
dp),
DIMENSION(:),
POINTER :: coeff
457 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces
461 CHARACTER(LEN=*),
PARAMETER :: routinen =
'integrate_potential_devga_rspace'
463 INTEGER :: atom_a, handle, iatom, j, natom, npme
464 INTEGER,
DIMENSION(:),
POINTER :: cores
465 LOGICAL :: use_virial
466 REAL(kind=
dp) :: eps_rho_rspace, radius
467 REAL(kind=
dp),
DIMENSION(3) :: force_a, force_b, ra
468 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: hab, pab
477 CALL timeset(routinen, handle)
479 NULLIFY (cores, hab, pab, cell, auxbas_rs_desc, pw_env, para_env, &
480 dft_control, rs_v, virial)
487 CALL pw_env_get(pw_env=pw_env, auxbas_rs_desc=auxbas_rs_desc, &
493 dft_control=dft_control, &
494 para_env=para_env, pw_env=pw_env, &
497 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
500 cpabort(
"Virial not implemented for image charge method")
503 eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
505 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
507 IF (.NOT.
ASSOCIATED(forces))
THEN
508 ALLOCATE (forces(3, natom))
511 forces(:, :) = 0.0_dp
518 IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed)
THEN
520 IF (
modulo(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos)
THEN
533 atom_a = qmmm_env%image_charge_pot%image_mm_list(iatom)
534 ra(:) =
pbc(qmmm_env%image_charge_pot%particles_all(atom_a)%r, cell)
541 ra=ra, rb=ra, rp=ra, &
542 zetp=qmmm_env%image_charge_pot%eta, eps=eps_rho_rspace, &
543 pab=pab, o1=0, o2=0, &
544 prefactor=1.0_dp, cutoff=1.0_dp)
546 CALL integrate_pgf_product(0, qmmm_env%image_charge_pot%eta, 0, &
547 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], &
548 rs_v, hab, pab, o1=0, o2=0, &
549 radius=radius, calculate_forces=.true., &
550 force_a=force_a, force_b=force_b, use_subpatch=.true., &
553 force_a(:) = coeff(iatom)*force_a(:)
554 forces(:, iatom) = force_a(:)
558 CALL para_env%sum(forces)
560 DEALLOCATE (hab, pab, cores)
563 CALL print_gradients_image_atoms(forces, qs_env)
565 CALL timestop(handle)
580 IF (.NOT. qmmm_env%image_charge_pot%coeff_iterative)
THEN
581 SELECT CASE (qmmm_env%image_charge_pot%state_image_matrix)
583 CALL calculate_image_matrix(image_matrix=qs_env%image_matrix, &
584 ipiv=qs_env%ipiv, qs_env=qs_env, qmmm_env=qmmm_env)
588 CALL calculate_image_matrix(image_matrix=qs_env%image_matrix, &
589 ipiv=qs_env%ipiv, qs_env=qs_env, qmmm_env=qmmm_env)
591 IF (qmmm_env%center_qm_subsys0)
THEN
592 CALL cp_warn(__location__, &
593 "The image atoms are fully "// &
594 "constrained and the image matrix is only calculated once. "// &
595 "To be safe, set CENTER to NEVER ")
600 cpabort(
"No initialization for image charges available?")
613 SUBROUTINE calculate_image_matrix(image_matrix, ipiv, qs_env, qmmm_env)
615 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
616 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: ipiv
620 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_matrix'
622 INTEGER :: handle, natom, output_unit, stat
626 CALL timeset(routinen, handle)
627 NULLIFY (input, logger)
631 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
633 IF (.NOT.
ASSOCIATED(image_matrix))
THEN
634 ALLOCATE (image_matrix(natom, natom))
636 IF (
PRESENT(ipiv))
THEN
637 IF (.NOT.
ASSOCIATED(ipiv))
THEN
638 ALLOCATE (ipiv(natom))
646 "QMMM%PRINT%PROGRAM_RUN_INFO", &
647 extension=
".qmmmLog")
648 IF (qmmm_env%image_charge_pot%coeff_iterative)
THEN
649 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A)") &
650 "Calculating image matrix"
652 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T2,A)") &
653 "Calculating image matrix"
656 "QMMM%PRINT%PROGRAM_RUN_INFO")
659 SELECT CASE (qmmm_env%image_charge_pot%image_matrix_method)
661 CALL calculate_image_matrix_gpw(image_matrix, qs_env, qmmm_env)
663 CALL calculate_image_matrix_mme(image_matrix, qs_env, qmmm_env)
665 cpabort(
"Unknown method for calculating image matrix")
668 IF (qmmm_env%image_charge_pot%coeff_iterative)
THEN
671 CALL write_image_matrix(qs_env%image_matrix, qs_env)
674 IF (
PRESENT(ipiv))
THEN
675 CALL dgetrf(natom, natom, image_matrix, natom, ipiv, stat)
680 CALL timestop(handle)
682 END SUBROUTINE calculate_image_matrix
690 SUBROUTINE calculate_image_matrix_gpw(image_matrix, qs_env, qmmm_env)
691 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
695 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_matrix_gpw'
697 INTEGER :: handle, iatom, iatom_ref, natom
698 REAL(kind=
dp),
DIMENSION(:),
POINTER :: int_res
706 CALL timeset(routinen, handle)
707 NULLIFY (pw_env, auxbas_pw_pool, poisson_env, para_env, int_res)
709 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
710 ALLOCATE (int_res(natom))
712 image_matrix = 0.0_dp
714 CALL get_qs_env(qs_env, pw_env=pw_env, para_env=para_env)
716 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
717 poisson_env=poisson_env)
718 CALL auxbas_pw_pool%create_pw(rho_gb)
719 CALL auxbas_pw_pool%create_pw(vb_gspace)
720 CALL auxbas_pw_pool%create_pw(vb_rspace)
732 CALL pw_scale(vb_rspace, vb_rspace%pw_grid%dvol)
737 CALL integrate_potential_ga_rspace(vb_rspace, qs_env%qmmm_env_qm, &
738 qs_env, int_res, atom_num=iatom, &
739 atom_num_ref=iatom_ref)
740 image_matrix(iatom, iatom:natom) = int_res(iatom:natom)
741 image_matrix(iatom + 1:natom, iatom) = int_res(iatom + 1:natom)
744 CALL vb_gspace%release()
745 CALL vb_rspace%release()
746 CALL rho_gb%release()
750 CALL timestop(handle)
751 END SUBROUTINE calculate_image_matrix_gpw
759 SUBROUTINE calculate_image_matrix_mme(image_matrix, qs_env, qmmm_env)
760 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
764 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_matrix_mme'
766 INTEGER :: atom_a, handle, iatom, natom
767 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: zeta
768 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: ra
771 CALL timeset(routinen, handle)
774 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
775 ALLOCATE (zeta(natom), ra(3, natom))
777 zeta(:) = qmmm_env%image_charge_pot%eta
780 atom_a = qmmm_env%image_charge_pot%image_mm_list(iatom)
781 ra(:, iatom) = qmmm_env%image_charge_pot%particles_all(atom_a)%r(:)
786 CALL integrate_s_mme(qmmm_env%image_charge_pot%eri_mme_param, &
787 zeta, zeta, ra, ra, image_matrix, para_env)
789 CALL timestop(handle)
790 END SUBROUTINE calculate_image_matrix_mme
803 SUBROUTINE integrate_s_mme(param, zeta, zetb, ra, rb, hab, para_env)
805 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: zeta, zetb
806 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: ra, rb
807 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: hab
810 CHARACTER(len=*),
PARAMETER :: routinen =
'integrate_s_mme'
812 INTEGER :: g_count, handle, ipgf, ipgf_prod, jpgf, &
813 npgf_prod, npgfa, npgfb, r_count
814 INTEGER,
DIMENSION(2) :: limits
815 REAL(kind=
dp),
DIMENSION(3) :: rab
817 CALL timeset(routinen, handle)
818 g_count = 0; r_count = 0
824 npgf_prod = npgfa*npgfb
826 limits =
get_limit(npgf_prod, para_env%num_pe, para_env%mepos)
828 DO ipgf_prod = limits(1), limits(2)
829 ipgf = (ipgf_prod - 1)/npgfb + 1
830 jpgf = mod(ipgf_prod - 1, npgfb) + 1
831 rab(:) = ra(:, ipgf) - rb(:, jpgf)
833 zetb(jpgf), rab, hab, ipgf - 1, jpgf - 1, g_count=g_count, r_count=r_count)
837 CALL para_env%sum(hab)
838 CALL timestop(handle)
840 END SUBROUTINE integrate_s_mme
852 SUBROUTINE calculate_potential_metal(v_metal_rspace, coeff, rho_hartree_gspace, energy, &
856 REAL(kind=
dp),
DIMENSION(:),
POINTER :: coeff
861 CHARACTER(len=*),
PARAMETER :: routinen =
'calculate_potential_metal'
864 REAL(kind=
dp) :: en_external, en_vmetal_rhohartree, &
871 CALL timeset(routinen, handle)
873 NULLIFY (pw_env, auxbas_pw_pool, poisson_env)
874 en_vmetal_rhohartree = 0.0_dp
878 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
879 poisson_env=poisson_env)
881 CALL auxbas_pw_pool%create_pw(rho_metal)
883 CALL auxbas_pw_pool%create_pw(v_metal_gspace)
885 CALL auxbas_pw_pool%create_pw(v_metal_rspace)
893 vhartree=v_metal_gspace)
895 IF (
PRESENT(rho_hartree_gspace))
THEN
898 en_external = qs_env%qmmm_env_qm%image_charge_pot%V0*total_rho_metal
899 energy%image_charge = en_vmetal_rhohartree - 0.5_dp*en_external
900 CALL print_image_energy_terms(en_vmetal_rhohartree, en_external, &
901 total_rho_metal, qs_env)
906 CALL pw_scale(v_metal_rspace, v_metal_rspace%pw_grid%dvol)
907 CALL v_metal_gspace%release()
908 CALL rho_metal%release()
910 CALL timestop(handle)
912 END SUBROUTINE calculate_potential_metal
926 CHARACTER(len=*),
PARAMETER :: routinen =
'add_image_pot_to_hartree_pot'
928 INTEGER :: handle, output_unit
932 CALL timeset(routinen, handle)
934 NULLIFY (input, logger)
938 CALL pw_axpy(v_metal, v_hartree)
944 "QMMM%PRINT%PROGRAM_RUN_INFO", &
945 extension=
".qmmmLog")
946 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A)") &
947 "Adding image charge potential to the Hartree potential."
949 "QMMM%PRINT%PROGRAM_RUN_INFO")
951 CALL timestop(handle)
961 SUBROUTINE write_image_matrix(image_matrix, qs_env)
963 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
966 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_image_matrix'
968 CHARACTER(LEN=default_path_length) :: filename
969 INTEGER :: handle, rst_unit
974 CALL timeset(routinen, handle)
976 NULLIFY (qmmm_section, print_key, logger, para_env)
980 CALL get_qs_env(qs_env=qs_env, para_env=para_env, &
984 "QMMM%PRINT%IMAGE_CHARGE_RESTART")
987 qmmm_section,
"QMMM%PRINT%IMAGE_CHARGE_RESTART"), &
991 "QMMM%PRINT%IMAGE_CHARGE_RESTART", &
992 extension=
".Image", &
993 file_status=
"REPLACE", &
994 file_action=
"WRITE", &
995 file_form=
"UNFORMATTED")
998 print_key, extension=
".IMAGE", &
1001 IF (rst_unit > 0)
THEN
1002 WRITE (rst_unit) image_matrix
1006 "QMMM%PRINT%IMAGE_CHARGE_RESTART")
1009 CALL timestop(handle)
1011 END SUBROUTINE write_image_matrix
1020 SUBROUTINE restart_image_matrix(image_matrix, qs_env, qmmm_env)
1022 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
1026 CHARACTER(LEN=*),
PARAMETER :: routinen =
'restart_image_matrix'
1028 CHARACTER(LEN=default_path_length) :: image_filename
1029 INTEGER :: handle, natom, output_unit, rst_unit
1035 CALL timeset(routinen, handle)
1037 NULLIFY (qmmm_section, logger, para_env)
1042 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
1044 IF (.NOT.
ASSOCIATED(image_matrix))
THEN
1045 ALLOCATE (image_matrix(natom, natom))
1048 image_matrix = 0.0_dp
1050 CALL get_qs_env(qs_env=qs_env, para_env=para_env, &
1054 c_val=image_filename)
1056 INQUIRE (file=image_filename, exist=exist)
1059 IF (para_env%is_source())
THEN
1060 CALL open_file(file_name=image_filename, &
1061 file_status=
"OLD", &
1062 file_form=
"UNFORMATTED", &
1063 file_action=
"READ", &
1064 unit_number=rst_unit)
1066 READ (rst_unit) qs_env%image_matrix
1069 CALL para_env%bcast(qs_env%image_matrix)
1071 IF (para_env%is_source())
CALL close_file(unit_number=rst_unit)
1074 "QMMM%PRINT%PROGRAM_RUN_INFO", &
1075 extension=
".qmmmLog")
1076 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A)") &
1077 "Restarted image matrix"
1079 cpabort(
"Restart file for image matrix not found")
1082 qmmm_env%image_charge_pot%image_restart = .false.
1084 CALL timestop(handle)
1086 END SUBROUTINE restart_image_matrix
1094 SUBROUTINE print_gradients_image_atoms(forces, qs_env)
1096 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces
1099 INTEGER :: atom_a, iatom, natom, output_unit
1100 REAL(kind=
dp),
DIMENSION(3) :: sum_gradients
1104 NULLIFY (input, logger)
1107 sum_gradients = 0.0_dp
1108 natom =
SIZE(qs_env%qmmm_env_qm%image_charge_pot%image_mm_list)
1111 sum_gradients(:) = sum_gradients(:) + forces(:, iatom)
1117 "QMMM%PRINT%DERIVATIVES", extension=
".Log")
1118 IF (output_unit > 0)
THEN
1119 WRITE (unit=output_unit, fmt=
"(/1X,A)") &
1120 "Image gradients [a.u.] on MM image charge atoms after QMMM calculation: "
1121 WRITE (unit=output_unit, fmt=
"(T4,A4,T27,A1,T50,A1,T74,A1)") &
1122 "Atom",
"X",
"Y",
"Z"
1124 atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
1125 WRITE (unit=output_unit, fmt=
"(T2,I6,T22,ES12.5,T45,ES12.5,T69,ES12.5)") &
1126 atom_a, forces(:, iatom)
1129 WRITE (unit=output_unit, fmt=
"(T2,A)") repeat(
"-", 79)
1130 WRITE (unit=output_unit, fmt=
"(T2,A,T22,ES12.5,T45,ES12.5,T69,ES12.5)") &
1131 "sum gradients:", sum_gradients
1132 WRITE (unit=output_unit, fmt=
"(/)")
1136 "QMMM%PRINT%DERIVATIVES")
1138 END SUBROUTINE print_gradients_image_atoms
1147 REAL(kind=
dp),
DIMENSION(:),
POINTER :: image_coeff
1150 INTEGER :: atom_a, iatom, natom, output_unit
1151 REAL(kind=
dp) :: normalize_factor, sum_coeff
1155 NULLIFY (input, logger)
1159 natom =
SIZE(qs_env%qmmm_env_qm%image_charge_pot%image_mm_list)
1160 normalize_factor = sqrt((qs_env%qmmm_env_qm%image_charge_pot%eta/
pi)**3)
1163 sum_coeff = sum_coeff + image_coeff(iatom)
1169 "QMMM%PRINT%IMAGE_CHARGE_INFO", extension=
".Log")
1170 IF (output_unit > 0)
THEN
1171 WRITE (unit=output_unit, fmt=
"(/)")
1172 WRITE (unit=output_unit, fmt=
"(T2,A)") &
1173 "Image charges [a.u.] after QMMM calculation: "
1174 WRITE (unit=output_unit, fmt=
"(T4,A4,T67,A)")
"Atom",
"Image charge"
1175 WRITE (unit=output_unit, fmt=
"(T4,A,T67,A)") repeat(
"-", 4), repeat(
"-", 12)
1178 atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
1182 WRITE (unit=output_unit, fmt=
"(T2,I6,T65,ES16.9)") &
1183 atom_a, -image_coeff(iatom)/normalize_factor
1186 WRITE (unit=output_unit, fmt=
"(T2,A)") repeat(
"-", 79)
1187 WRITE (unit=output_unit, fmt=
"(T2,A,T65,ES16.9)") &
1188 "sum image charges:", -sum_coeff/normalize_factor
1192 "QMMM%PRINT%IMAGE_CHARGE_INFO")
1205 SUBROUTINE print_image_energy_terms(en_vmetal_rhohartree, en_external, &
1206 total_rho_metal, qs_env)
1208 REAL(kind=
dp),
INTENT(IN) :: en_vmetal_rhohartree, en_external, &
1212 INTEGER :: output_unit
1216 NULLIFY (input, logger)
1222 "QMMM%PRINT%IMAGE_CHARGE_INFO", extension=
".Log")
1224 IF (output_unit > 0)
THEN
1225 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1226 "Total induced charge density [a.u.]:", total_rho_metal
1227 WRITE (unit=output_unit, fmt=
"(T3,A)")
"Image energy terms: "
1228 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1229 "Coulomb energy of QM and image charge density [a.u.]:", en_vmetal_rhohartree
1230 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1231 "External potential energy term [a.u.]:", -0.5_dp*en_external
1232 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1233 "Total image charge energy [a.u.]:", en_vmetal_rhohartree - 0.5_dp*en_external
1237 "QMMM%PRINT%IMAGE_CHARGE_INFO")
1239 END SUBROUTINE print_image_energy_terms
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
All kind of helpful little routines.
real(kind=dp) function, public exp_radius_very_extended(la_min, la_max, lb_min, lb_max, pab, o1, o2, ra, rb, rp, zetp, eps, prefactor, cutoff, epsabs)
computes the radius of the Gaussian outside of which it is smaller than eps
Handles all functions related to the CELL.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Interface to Minimax-Ewald method for periodic ERI's to be used in CP2K.
subroutine, public cp_eri_mme_update_local_counts(param, para_env, g_count_2c, r_count_2c, gg_count_3c, gr_count_3c, rr_count_3c)
Update local counters to gather statistics on different paths taken in MME algorithm (each Ewald sum ...
Utility routines to open and close files.
subroutine, public open_file(file_name, unit_number, file_status, file_form, file_action, file_position, file_pad, file_access, debug)
Opens a file and returns its logical unit number.
subroutine, public close_file(unit_number, file_status)
Closes an open file given by its logical unit number.
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)
...
character(len=default_path_length) function, public cp_print_key_generate_filename(logger, print_key, middle_name, extension, my_local)
Utility function that returns a unit number to write the print key. Might open a file with a unique f...
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,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
Minimax-Ewald (MME) method for calculating 2-center and 3-center electron repulsion integrals (ERI) o...
subroutine, public eri_mme_2c_integrate(param, la_min, la_max, lb_min, lb_max, zeta, zetb, rab, hab, o1, o2, g_count, r_count, normalize, potential, pot_par)
Low-level integration routine for 2-center ERIs.
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_path_length
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Collection of simple mathematical functions and subroutines.
subroutine, public invmat_symm(a, potrf, uplo)
returns inverse of real symmetric, positive definite matrix
Utility routines for the memory handling.
Interface to the message passing library MPI.
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
functions related to the poisson solver on regular grids
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Routines for image charge calculation within QM/MM.
subroutine, public calculate_image_pot(v_hartree_rspace, rho_hartree_gspace, energy, qmmm_env, qs_env)
determines coefficients by solving image_matrix*coeff=-pot_const by Gaussian elimination or in an ite...
subroutine, public print_image_coefficients(image_coeff, qs_env)
Print image coefficients.
subroutine, public integrate_potential_devga_rspace(potential, coeff, forces, qmmm_env, qs_env)
calculates the image forces on the MM atoms
subroutine, public conditional_calc_image_matrix(qs_env, qmmm_env)
calculate image matrix T depending on constraints on image atoms in case coefficients are estimated n...
subroutine, public add_image_pot_to_hartree_pot(v_hartree, v_metal, qs_env)
Add potential of metal (image charge pot) to Hartree Potential.
Calculate the plane wave density by collocating the primitive Gaussian functions (pgf).
subroutine, public calculate_rho_metal(rho_metal, coeff, total_rho_metal, qs_env)
computes the image charge density on the grid (including coeffcients)
subroutine, public calculate_rho_single_gaussian(rho_gb, qs_env, iatom_in)
collocate a single Gaussian on the grid
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, mimic, 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, sab_cneo, 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, matrix_vhxc, 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, xcint_weights, 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, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_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, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Integrate single or product functions over a potential on a RS grid.
subroutine, public transfer_pw2rs(rs, pw)
...
All kind of helpful little routines.
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
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
environment for the poisson solver
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...