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'
217 INTEGER :: handle, iter_steps, natom, output_unit
218 REAL(kind=
dp) :: alpha, eta, rsnew, rsold, v0
219 REAL(kind=
dp),
DIMENSION(:),
POINTER :: ad, d, pot_const, r, vmetal_const, z
224 CALL timeset(routinen, handle)
226 NULLIFY (pot_const, vmetal_const, logger, input)
230 v0 = -qmmm_env%image_charge_pot%V0
231 eta = qmmm_env%image_charge_pot%eta
232 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
234 ALLOCATE (pot_const(natom))
235 ALLOCATE (vmetal_const(natom))
240 IF (.NOT.
ASSOCIATED(coeff))
THEN
241 ALLOCATE (coeff(natom))
244 CALL integrate_potential_ga_rspace(v_hartree_rspace, qmmm_env, qs_env, &
248 pot_const(:) = -pot_const(:) + v0*sqrt((
pi/eta)**3)
260 CALL calculate_potential_metal(v_metal_rspace=v_metal_rspace_guess, &
261 coeff=coeff, qs_env=qs_env)
262 CALL integrate_potential_ga_rspace(potential=v_metal_rspace_guess, &
263 qmmm_env=qmmm_env, qs_env=qs_env, int_res=vmetal_const)
266 r = pot_const - vmetal_const
267 z = matmul(qs_env%image_matrix, r)
269 rsold = dot_product(r, z)
274 CALL calculate_potential_metal(v_metal_rspace= &
275 auxpot_ad_rspace, coeff=d, qs_env=qs_env)
276 CALL integrate_potential_ga_rspace(potential= &
277 auxpot_ad_rspace, qmmm_env=qmmm_env, &
278 qs_env=qs_env, int_res=ad)
280 alpha = rsold/dot_product(d, ad)
281 coeff = coeff + alpha*d
284 z = matmul(qs_env%image_matrix, r)
285 rsnew = dot_product(r, z)
286 iter_steps = iter_steps + 1
288 IF (rsnew < 1.0e-16)
THEN
289 CALL auxpot_ad_rspace%release()
292 d = z + rsnew/rsold*d
294 CALL auxpot_ad_rspace%release()
301 "QMMM%PRINT%PROGRAM_RUN_INFO", &
302 extension=
".qmmmLog")
303 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A,T74,I7)") &
304 "Number of iteration steps for determination of image coefficients:", iter_steps
306 "QMMM%PRINT%PROGRAM_RUN_INFO")
308 IF (iter_steps .LT. 25)
THEN
309 qs_env%calc_image_preconditioner = .false.
311 qs_env%calc_image_preconditioner = .true.
314 CALL v_metal_rspace_guess%release()
315 DEALLOCATE (pot_const)
316 DEALLOCATE (vmetal_const)
321 CALL timestop(handle)
323 END SUBROUTINE calc_image_coeff_iterative
335 SUBROUTINE integrate_potential_ga_rspace(potential, qmmm_env, qs_env, int_res, &
336 atom_num, atom_num_ref)
341 REAL(kind=
dp),
DIMENSION(:),
POINTER :: int_res
342 INTEGER,
INTENT(IN),
OPTIONAL :: atom_num, atom_num_ref
344 CHARACTER(LEN=*),
PARAMETER :: routinen =
'integrate_potential_ga_rspace'
346 INTEGER :: atom_a, atom_b, atom_ref, handle, iatom, &
348 INTEGER,
DIMENSION(:),
POINTER :: cores
349 REAL(kind=
dp) :: eps_rho_rspace, radius
350 REAL(kind=
dp),
DIMENSION(3) :: ra
351 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: hab
359 CALL timeset(routinen, handle)
361 NULLIFY (cores, hab, cell, auxbas_rs_desc, pw_env, para_env, &
366 CALL pw_env_get(pw_env=pw_env, auxbas_rs_desc=auxbas_rs_desc, &
372 dft_control=dft_control, &
373 para_env=para_env, pw_env=pw_env)
375 eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
377 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
379 IF (
PRESENT(atom_num)) k = atom_num
387 IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed)
THEN
389 IF (
modulo(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos)
THEN
402 atom_a = qmmm_env%image_charge_pot%image_mm_list(iatom)
404 IF (
PRESENT(atom_num) .AND.
PRESENT(atom_num_ref))
THEN
406 atom_b = qmmm_env%image_charge_pot%image_mm_list(k)
407 atom_ref = qmmm_env%image_charge_pot%image_mm_list(atom_num_ref)
408 ra(:) =
pbc(qmmm_env%image_charge_pot%particles_all(atom_a)%r, cell) &
409 -
pbc(qmmm_env%image_charge_pot%particles_all(atom_b)%r, cell) &
410 +
pbc(qmmm_env%image_charge_pot%particles_all(atom_ref)%r, cell)
413 ra(:) =
pbc(qmmm_env%image_charge_pot%particles_all(atom_a)%r, cell)
419 ra=ra, rb=ra, rp=ra, &
420 zetp=qmmm_env%image_charge_pot%eta, eps=eps_rho_rspace, &
421 prefactor=1.0_dp, cutoff=1.0_dp)
423 CALL integrate_pgf_product(0, qmmm_env%image_charge_pot%eta, 0, &
424 0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), &
425 rs_v, hab, o1=0, o2=0, &
426 radius=radius, calculate_forces=.false., &
427 use_subpatch=.true., subpatch_pattern=0)
429 int_res(iatom) = hab(1, 1)
433 CALL para_env%sum(int_res)
435 DEALLOCATE (hab, cores)
437 CALL timestop(handle)
439 END SUBROUTINE integrate_potential_ga_rspace
455 REAL(kind=
dp),
DIMENSION(:),
POINTER :: coeff
456 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces
460 CHARACTER(LEN=*),
PARAMETER :: routinen =
'integrate_potential_devga_rspace'
462 INTEGER :: atom_a, handle, iatom, j, natom, npme
463 INTEGER,
DIMENSION(:),
POINTER :: cores
464 LOGICAL :: use_virial
465 REAL(kind=
dp) :: eps_rho_rspace, radius
466 REAL(kind=
dp),
DIMENSION(3) :: force_a, force_b, ra
467 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: hab, pab
476 CALL timeset(routinen, handle)
478 NULLIFY (cores, hab, pab, cell, auxbas_rs_desc, pw_env, para_env, &
479 dft_control, rs_v, virial)
486 CALL pw_env_get(pw_env=pw_env, auxbas_rs_desc=auxbas_rs_desc, &
492 dft_control=dft_control, &
493 para_env=para_env, pw_env=pw_env, &
496 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
499 cpabort(
"Virial not implemented for image charge method")
502 eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
504 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
506 IF (.NOT.
ASSOCIATED(forces))
THEN
507 ALLOCATE (forces(3, natom))
510 forces(:, :) = 0.0_dp
517 IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed)
THEN
519 IF (
modulo(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos)
THEN
532 atom_a = qmmm_env%image_charge_pot%image_mm_list(iatom)
533 ra(:) =
pbc(qmmm_env%image_charge_pot%particles_all(atom_a)%r, cell)
540 ra=ra, rb=ra, rp=ra, &
541 zetp=qmmm_env%image_charge_pot%eta, eps=eps_rho_rspace, &
542 pab=pab, o1=0, o2=0, &
543 prefactor=1.0_dp, cutoff=1.0_dp)
545 CALL integrate_pgf_product(0, qmmm_env%image_charge_pot%eta, 0, &
546 0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), &
547 rs_v, hab, pab, o1=0, o2=0, &
548 radius=radius, calculate_forces=.true., &
549 force_a=force_a, force_b=force_b, use_subpatch=.true., &
552 force_a(:) = coeff(iatom)*force_a(:)
553 forces(:, iatom) = force_a(:)
557 CALL para_env%sum(forces)
559 DEALLOCATE (hab, pab, cores)
562 CALL print_gradients_image_atoms(forces, qs_env)
564 CALL timestop(handle)
579 IF (.NOT. qmmm_env%image_charge_pot%coeff_iterative)
THEN
580 SELECT CASE (qmmm_env%image_charge_pot%state_image_matrix)
582 CALL calculate_image_matrix(image_matrix=qs_env%image_matrix, &
583 ipiv=qs_env%ipiv, qs_env=qs_env, qmmm_env=qmmm_env)
587 CALL calculate_image_matrix(image_matrix=qs_env%image_matrix, &
588 ipiv=qs_env%ipiv, qs_env=qs_env, qmmm_env=qmmm_env)
590 IF (qmmm_env%center_qm_subsys0) &
591 CALL cp_warn(__location__, &
592 "The image atoms are fully "// &
593 "constrained and the image matrix is only calculated once. "// &
594 "To be safe, set CENTER to NEVER ")
598 cpabort(
"No initialization for image charges available?")
611 SUBROUTINE calculate_image_matrix(image_matrix, ipiv, qs_env, qmmm_env)
613 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
614 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: ipiv
618 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_matrix'
620 INTEGER :: handle, natom, output_unit, stat
624 CALL timeset(routinen, handle)
625 NULLIFY (input, logger)
629 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
631 IF (.NOT.
ASSOCIATED(image_matrix))
THEN
632 ALLOCATE (image_matrix(natom, natom))
634 IF (
PRESENT(ipiv))
THEN
635 IF (.NOT.
ASSOCIATED(ipiv))
THEN
636 ALLOCATE (ipiv(natom))
644 "QMMM%PRINT%PROGRAM_RUN_INFO", &
645 extension=
".qmmmLog")
646 IF (qmmm_env%image_charge_pot%coeff_iterative)
THEN
647 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A)") &
648 "Calculating image matrix"
650 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T2,A)") &
651 "Calculating image matrix"
654 "QMMM%PRINT%PROGRAM_RUN_INFO")
657 SELECT CASE (qmmm_env%image_charge_pot%image_matrix_method)
659 CALL calculate_image_matrix_gpw(image_matrix, qs_env, qmmm_env)
661 CALL calculate_image_matrix_mme(image_matrix, qs_env, qmmm_env)
663 cpabort(
"Unknown method for calculating image matrix")
666 IF (qmmm_env%image_charge_pot%coeff_iterative)
THEN
669 CALL write_image_matrix(qs_env%image_matrix, qs_env)
672 IF (
PRESENT(ipiv))
THEN
673 CALL dgetrf(natom, natom, image_matrix, natom, ipiv, stat)
678 CALL timestop(handle)
680 END SUBROUTINE calculate_image_matrix
688 SUBROUTINE calculate_image_matrix_gpw(image_matrix, qs_env, qmmm_env)
689 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
693 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_matrix_gpw'
695 INTEGER :: handle, iatom, iatom_ref, natom
696 REAL(kind=
dp),
DIMENSION(:),
POINTER :: int_res
704 CALL timeset(routinen, handle)
705 NULLIFY (pw_env, auxbas_pw_pool, poisson_env, para_env, int_res)
707 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
708 ALLOCATE (int_res(natom))
710 image_matrix = 0.0_dp
712 CALL get_qs_env(qs_env, pw_env=pw_env, para_env=para_env)
714 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
715 poisson_env=poisson_env)
716 CALL auxbas_pw_pool%create_pw(rho_gb)
717 CALL auxbas_pw_pool%create_pw(vb_gspace)
718 CALL auxbas_pw_pool%create_pw(vb_rspace)
730 CALL pw_scale(vb_rspace, vb_rspace%pw_grid%dvol)
735 CALL integrate_potential_ga_rspace(vb_rspace, qs_env%qmmm_env_qm, &
736 qs_env, int_res, atom_num=iatom, &
737 atom_num_ref=iatom_ref)
738 image_matrix(iatom, iatom:natom) = int_res(iatom:natom)
739 image_matrix(iatom + 1:natom, iatom) = int_res(iatom + 1:natom)
742 CALL vb_gspace%release()
743 CALL vb_rspace%release()
744 CALL rho_gb%release()
748 CALL timestop(handle)
749 END SUBROUTINE calculate_image_matrix_gpw
757 SUBROUTINE calculate_image_matrix_mme(image_matrix, qs_env, qmmm_env)
758 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
762 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_matrix_mme'
764 INTEGER :: atom_a, handle, iatom, natom
765 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: zeta
766 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: ra
769 CALL timeset(routinen, handle)
772 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
773 ALLOCATE (zeta(natom), ra(3, natom))
775 zeta(:) = qmmm_env%image_charge_pot%eta
778 atom_a = qmmm_env%image_charge_pot%image_mm_list(iatom)
779 ra(:, iatom) = qmmm_env%image_charge_pot%particles_all(atom_a)%r(:)
784 CALL integrate_s_mme(qmmm_env%image_charge_pot%eri_mme_param, &
785 zeta, zeta, ra, ra, image_matrix, para_env)
787 CALL timestop(handle)
788 END SUBROUTINE calculate_image_matrix_mme
801 SUBROUTINE integrate_s_mme(param, zeta, zetb, ra, rb, hab, para_env)
803 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: zeta, zetb
804 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: ra, rb
805 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: hab
808 CHARACTER(len=*),
PARAMETER :: routinen =
'integrate_s_mme'
810 INTEGER :: g_count, handle, ipgf, ipgf_prod, jpgf, &
811 npgf_prod, npgfa, npgfb, r_count
812 INTEGER,
DIMENSION(2) :: limits
813 REAL(kind=
dp),
DIMENSION(3) :: rab
815 CALL timeset(routinen, handle)
816 g_count = 0; r_count = 0
822 npgf_prod = npgfa*npgfb
824 limits =
get_limit(npgf_prod, para_env%num_pe, para_env%mepos)
826 DO ipgf_prod = limits(1), limits(2)
827 ipgf = (ipgf_prod - 1)/npgfb + 1
828 jpgf = mod(ipgf_prod - 1, npgfb) + 1
829 rab(:) = ra(:, ipgf) - rb(:, jpgf)
831 zetb(jpgf), rab, hab, ipgf - 1, jpgf - 1, g_count=g_count, r_count=r_count)
835 CALL para_env%sum(hab)
836 CALL timestop(handle)
838 END SUBROUTINE integrate_s_mme
850 SUBROUTINE calculate_potential_metal(v_metal_rspace, coeff, rho_hartree_gspace, energy, &
854 REAL(kind=
dp),
DIMENSION(:),
POINTER :: coeff
859 CHARACTER(len=*),
PARAMETER :: routinen =
'calculate_potential_metal'
862 REAL(kind=
dp) :: en_external, en_vmetal_rhohartree, &
869 CALL timeset(routinen, handle)
871 NULLIFY (pw_env, auxbas_pw_pool, poisson_env)
872 en_vmetal_rhohartree = 0.0_dp
876 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
877 poisson_env=poisson_env)
879 CALL auxbas_pw_pool%create_pw(rho_metal)
881 CALL auxbas_pw_pool%create_pw(v_metal_gspace)
883 CALL auxbas_pw_pool%create_pw(v_metal_rspace)
891 vhartree=v_metal_gspace)
893 IF (
PRESENT(rho_hartree_gspace))
THEN
896 en_external = qs_env%qmmm_env_qm%image_charge_pot%V0*total_rho_metal
897 energy%image_charge = en_vmetal_rhohartree - 0.5_dp*en_external
898 CALL print_image_energy_terms(en_vmetal_rhohartree, en_external, &
899 total_rho_metal, qs_env)
904 CALL pw_scale(v_metal_rspace, v_metal_rspace%pw_grid%dvol)
905 CALL v_metal_gspace%release()
906 CALL rho_metal%release()
908 CALL timestop(handle)
910 END SUBROUTINE calculate_potential_metal
924 CHARACTER(len=*),
PARAMETER :: routinen =
'add_image_pot_to_hartree_pot'
926 INTEGER :: handle, output_unit
930 CALL timeset(routinen, handle)
932 NULLIFY (input, logger)
936 CALL pw_axpy(v_metal, v_hartree)
942 "QMMM%PRINT%PROGRAM_RUN_INFO", &
943 extension=
".qmmmLog")
944 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A)") &
945 "Adding image charge potential to the Hartree potential."
947 "QMMM%PRINT%PROGRAM_RUN_INFO")
949 CALL timestop(handle)
959 SUBROUTINE write_image_matrix(image_matrix, qs_env)
961 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
964 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_image_matrix'
966 CHARACTER(LEN=default_path_length) :: filename
967 INTEGER :: handle, rst_unit
972 CALL timeset(routinen, handle)
974 NULLIFY (qmmm_section, print_key, logger, para_env)
978 CALL get_qs_env(qs_env=qs_env, para_env=para_env, &
982 "QMMM%PRINT%IMAGE_CHARGE_RESTART")
985 qmmm_section,
"QMMM%PRINT%IMAGE_CHARGE_RESTART"), &
989 "QMMM%PRINT%IMAGE_CHARGE_RESTART", &
990 extension=
".Image", &
991 file_status=
"REPLACE", &
992 file_action=
"WRITE", &
993 file_form=
"UNFORMATTED")
996 print_key, extension=
".IMAGE", &
999 IF (rst_unit > 0)
THEN
1000 WRITE (rst_unit) image_matrix
1004 "QMMM%PRINT%IMAGE_CHARGE_RESTART")
1007 CALL timestop(handle)
1009 END SUBROUTINE write_image_matrix
1018 SUBROUTINE restart_image_matrix(image_matrix, qs_env, qmmm_env)
1020 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
1024 CHARACTER(LEN=*),
PARAMETER :: routinen =
'restart_image_matrix'
1026 CHARACTER(LEN=default_path_length) :: image_filename
1027 INTEGER :: handle, natom, output_unit, rst_unit
1033 CALL timeset(routinen, handle)
1035 NULLIFY (qmmm_section, logger, para_env)
1040 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
1042 IF (.NOT.
ASSOCIATED(image_matrix))
THEN
1043 ALLOCATE (image_matrix(natom, natom))
1046 image_matrix = 0.0_dp
1048 CALL get_qs_env(qs_env=qs_env, para_env=para_env, &
1052 c_val=image_filename)
1054 INQUIRE (file=image_filename, exist=exist)
1057 IF (para_env%is_source())
THEN
1058 CALL open_file(file_name=image_filename, &
1059 file_status=
"OLD", &
1060 file_form=
"UNFORMATTED", &
1061 file_action=
"READ", &
1062 unit_number=rst_unit)
1064 READ (rst_unit) qs_env%image_matrix
1067 CALL para_env%bcast(qs_env%image_matrix)
1069 IF (para_env%is_source())
CALL close_file(unit_number=rst_unit)
1072 "QMMM%PRINT%PROGRAM_RUN_INFO", &
1073 extension=
".qmmmLog")
1074 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A)") &
1075 "Restarted image matrix"
1077 cpabort(
"Restart file for image matrix not found")
1080 qmmm_env%image_charge_pot%image_restart = .false.
1082 CALL timestop(handle)
1084 END SUBROUTINE restart_image_matrix
1092 SUBROUTINE print_gradients_image_atoms(forces, qs_env)
1094 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces
1097 INTEGER :: atom_a, iatom, natom, output_unit
1098 REAL(kind=
dp),
DIMENSION(3) :: sum_gradients
1102 NULLIFY (input, logger)
1105 sum_gradients = 0.0_dp
1106 natom =
SIZE(qs_env%qmmm_env_qm%image_charge_pot%image_mm_list)
1109 sum_gradients(:) = sum_gradients(:) + forces(:, iatom)
1115 "QMMM%PRINT%DERIVATIVES", extension=
".Log")
1116 IF (output_unit > 0)
THEN
1117 WRITE (unit=output_unit, fmt=
"(/1X,A)") &
1118 "Image gradients [a.u.] on MM image charge atoms after QMMM calculation: "
1119 WRITE (unit=output_unit, fmt=
"(T4,A4,T27,A1,T50,A1,T74,A1)") &
1120 "Atom",
"X",
"Y",
"Z"
1122 atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
1123 WRITE (unit=output_unit, fmt=
"(T2,I6,T22,ES12.5,T45,ES12.5,T69,ES12.5)") &
1124 atom_a, forces(:, iatom)
1127 WRITE (unit=output_unit, fmt=
"(T2,A)") repeat(
"-", 79)
1128 WRITE (unit=output_unit, fmt=
"(T2,A,T22,ES12.5,T45,ES12.5,T69,ES12.5)") &
1129 "sum gradients:", sum_gradients
1130 WRITE (unit=output_unit, fmt=
"(/)")
1134 "QMMM%PRINT%DERIVATIVES")
1136 END SUBROUTINE print_gradients_image_atoms
1145 REAL(kind=
dp),
DIMENSION(:),
POINTER :: image_coeff
1148 INTEGER :: atom_a, iatom, natom, output_unit
1149 REAL(kind=
dp) :: normalize_factor, sum_coeff
1153 NULLIFY (input, logger)
1157 natom =
SIZE(qs_env%qmmm_env_qm%image_charge_pot%image_mm_list)
1158 normalize_factor = sqrt((qs_env%qmmm_env_qm%image_charge_pot%eta/
pi)**3)
1161 sum_coeff = sum_coeff + image_coeff(iatom)
1167 "QMMM%PRINT%IMAGE_CHARGE_INFO", extension=
".Log")
1168 IF (output_unit > 0)
THEN
1169 WRITE (unit=output_unit, fmt=
"(/)")
1170 WRITE (unit=output_unit, fmt=
"(T2,A)") &
1171 "Image charges [a.u.] after QMMM calculation: "
1172 WRITE (unit=output_unit, fmt=
"(T4,A4,T67,A)")
"Atom",
"Image charge"
1173 WRITE (unit=output_unit, fmt=
"(T4,A,T67,A)") repeat(
"-", 4), repeat(
"-", 12)
1176 atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
1180 WRITE (unit=output_unit, fmt=
"(T2,I6,T65,ES16.9)") &
1181 atom_a, -image_coeff(iatom)/normalize_factor
1184 WRITE (unit=output_unit, fmt=
"(T2,A)") repeat(
"-", 79)
1185 WRITE (unit=output_unit, fmt=
"(T2,A,T65,ES16.9)") &
1186 "sum image charges:", -sum_coeff/normalize_factor
1190 "QMMM%PRINT%IMAGE_CHARGE_INFO")
1203 SUBROUTINE print_image_energy_terms(en_vmetal_rhohartree, en_external, &
1204 total_rho_metal, qs_env)
1206 REAL(kind=
dp),
INTENT(IN) :: en_vmetal_rhohartree, en_external, &
1210 INTEGER :: output_unit
1214 NULLIFY (input, logger)
1220 "QMMM%PRINT%IMAGE_CHARGE_INFO", extension=
".Log")
1222 IF (output_unit > 0)
THEN
1223 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1224 "Total induced charge density [a.u.]:", total_rho_metal
1225 WRITE (unit=output_unit, fmt=
"(T3,A)")
"Image energy terms: "
1226 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1227 "Coulomb energy of QM and image charge density [a.u.]:", en_vmetal_rhohartree
1228 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1229 "External potential energy term [a.u.]:", -0.5_dp*en_external
1230 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1231 "Total image charge energy [a.u.]:", en_vmetal_rhohartree - 0.5_dp*en_external
1235 "QMMM%PRINT%IMAGE_CHARGE_INFO")
1237 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. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
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, 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.
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 ...