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 < 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)
THEN
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 ")
599 cpabort(
"No initialization for image charges available?")
612 SUBROUTINE calculate_image_matrix(image_matrix, ipiv, qs_env, qmmm_env)
614 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
615 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: ipiv
619 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_matrix'
621 INTEGER :: handle, natom, output_unit, stat
625 CALL timeset(routinen, handle)
626 NULLIFY (input, logger)
630 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
632 IF (.NOT.
ASSOCIATED(image_matrix))
THEN
633 ALLOCATE (image_matrix(natom, natom))
635 IF (
PRESENT(ipiv))
THEN
636 IF (.NOT.
ASSOCIATED(ipiv))
THEN
637 ALLOCATE (ipiv(natom))
645 "QMMM%PRINT%PROGRAM_RUN_INFO", &
646 extension=
".qmmmLog")
647 IF (qmmm_env%image_charge_pot%coeff_iterative)
THEN
648 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A)") &
649 "Calculating image matrix"
651 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T2,A)") &
652 "Calculating image matrix"
655 "QMMM%PRINT%PROGRAM_RUN_INFO")
658 SELECT CASE (qmmm_env%image_charge_pot%image_matrix_method)
660 CALL calculate_image_matrix_gpw(image_matrix, qs_env, qmmm_env)
662 CALL calculate_image_matrix_mme(image_matrix, qs_env, qmmm_env)
664 cpabort(
"Unknown method for calculating image matrix")
667 IF (qmmm_env%image_charge_pot%coeff_iterative)
THEN
670 CALL write_image_matrix(qs_env%image_matrix, qs_env)
673 IF (
PRESENT(ipiv))
THEN
674 CALL dgetrf(natom, natom, image_matrix, natom, ipiv, stat)
679 CALL timestop(handle)
681 END SUBROUTINE calculate_image_matrix
689 SUBROUTINE calculate_image_matrix_gpw(image_matrix, qs_env, qmmm_env)
690 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
694 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_matrix_gpw'
696 INTEGER :: handle, iatom, iatom_ref, natom
697 REAL(kind=
dp),
DIMENSION(:),
POINTER :: int_res
705 CALL timeset(routinen, handle)
706 NULLIFY (pw_env, auxbas_pw_pool, poisson_env, para_env, int_res)
708 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
709 ALLOCATE (int_res(natom))
711 image_matrix = 0.0_dp
713 CALL get_qs_env(qs_env, pw_env=pw_env, para_env=para_env)
715 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
716 poisson_env=poisson_env)
717 CALL auxbas_pw_pool%create_pw(rho_gb)
718 CALL auxbas_pw_pool%create_pw(vb_gspace)
719 CALL auxbas_pw_pool%create_pw(vb_rspace)
731 CALL pw_scale(vb_rspace, vb_rspace%pw_grid%dvol)
736 CALL integrate_potential_ga_rspace(vb_rspace, qs_env%qmmm_env_qm, &
737 qs_env, int_res, atom_num=iatom, &
738 atom_num_ref=iatom_ref)
739 image_matrix(iatom, iatom:natom) = int_res(iatom:natom)
740 image_matrix(iatom + 1:natom, iatom) = int_res(iatom + 1:natom)
743 CALL vb_gspace%release()
744 CALL vb_rspace%release()
745 CALL rho_gb%release()
749 CALL timestop(handle)
750 END SUBROUTINE calculate_image_matrix_gpw
758 SUBROUTINE calculate_image_matrix_mme(image_matrix, qs_env, qmmm_env)
759 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
763 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_image_matrix_mme'
765 INTEGER :: atom_a, handle, iatom, natom
766 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: zeta
767 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: ra
770 CALL timeset(routinen, handle)
773 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
774 ALLOCATE (zeta(natom), ra(3, natom))
776 zeta(:) = qmmm_env%image_charge_pot%eta
779 atom_a = qmmm_env%image_charge_pot%image_mm_list(iatom)
780 ra(:, iatom) = qmmm_env%image_charge_pot%particles_all(atom_a)%r(:)
785 CALL integrate_s_mme(qmmm_env%image_charge_pot%eri_mme_param, &
786 zeta, zeta, ra, ra, image_matrix, para_env)
788 CALL timestop(handle)
789 END SUBROUTINE calculate_image_matrix_mme
802 SUBROUTINE integrate_s_mme(param, zeta, zetb, ra, rb, hab, para_env)
804 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: zeta, zetb
805 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: ra, rb
806 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: hab
809 CHARACTER(len=*),
PARAMETER :: routinen =
'integrate_s_mme'
811 INTEGER :: g_count, handle, ipgf, ipgf_prod, jpgf, &
812 npgf_prod, npgfa, npgfb, r_count
813 INTEGER,
DIMENSION(2) :: limits
814 REAL(kind=
dp),
DIMENSION(3) :: rab
816 CALL timeset(routinen, handle)
817 g_count = 0; r_count = 0
823 npgf_prod = npgfa*npgfb
825 limits =
get_limit(npgf_prod, para_env%num_pe, para_env%mepos)
827 DO ipgf_prod = limits(1), limits(2)
828 ipgf = (ipgf_prod - 1)/npgfb + 1
829 jpgf = mod(ipgf_prod - 1, npgfb) + 1
830 rab(:) = ra(:, ipgf) - rb(:, jpgf)
832 zetb(jpgf), rab, hab, ipgf - 1, jpgf - 1, g_count=g_count, r_count=r_count)
836 CALL para_env%sum(hab)
837 CALL timestop(handle)
839 END SUBROUTINE integrate_s_mme
851 SUBROUTINE calculate_potential_metal(v_metal_rspace, coeff, rho_hartree_gspace, energy, &
855 REAL(kind=
dp),
DIMENSION(:),
POINTER :: coeff
860 CHARACTER(len=*),
PARAMETER :: routinen =
'calculate_potential_metal'
863 REAL(kind=
dp) :: en_external, en_vmetal_rhohartree, &
870 CALL timeset(routinen, handle)
872 NULLIFY (pw_env, auxbas_pw_pool, poisson_env)
873 en_vmetal_rhohartree = 0.0_dp
877 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
878 poisson_env=poisson_env)
880 CALL auxbas_pw_pool%create_pw(rho_metal)
882 CALL auxbas_pw_pool%create_pw(v_metal_gspace)
884 CALL auxbas_pw_pool%create_pw(v_metal_rspace)
892 vhartree=v_metal_gspace)
894 IF (
PRESENT(rho_hartree_gspace))
THEN
897 en_external = qs_env%qmmm_env_qm%image_charge_pot%V0*total_rho_metal
898 energy%image_charge = en_vmetal_rhohartree - 0.5_dp*en_external
899 CALL print_image_energy_terms(en_vmetal_rhohartree, en_external, &
900 total_rho_metal, qs_env)
905 CALL pw_scale(v_metal_rspace, v_metal_rspace%pw_grid%dvol)
906 CALL v_metal_gspace%release()
907 CALL rho_metal%release()
909 CALL timestop(handle)
911 END SUBROUTINE calculate_potential_metal
925 CHARACTER(len=*),
PARAMETER :: routinen =
'add_image_pot_to_hartree_pot'
927 INTEGER :: handle, output_unit
931 CALL timeset(routinen, handle)
933 NULLIFY (input, logger)
937 CALL pw_axpy(v_metal, v_hartree)
943 "QMMM%PRINT%PROGRAM_RUN_INFO", &
944 extension=
".qmmmLog")
945 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A)") &
946 "Adding image charge potential to the Hartree potential."
948 "QMMM%PRINT%PROGRAM_RUN_INFO")
950 CALL timestop(handle)
960 SUBROUTINE write_image_matrix(image_matrix, qs_env)
962 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
965 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_image_matrix'
967 CHARACTER(LEN=default_path_length) :: filename
968 INTEGER :: handle, rst_unit
973 CALL timeset(routinen, handle)
975 NULLIFY (qmmm_section, print_key, logger, para_env)
979 CALL get_qs_env(qs_env=qs_env, para_env=para_env, &
983 "QMMM%PRINT%IMAGE_CHARGE_RESTART")
986 qmmm_section,
"QMMM%PRINT%IMAGE_CHARGE_RESTART"), &
990 "QMMM%PRINT%IMAGE_CHARGE_RESTART", &
991 extension=
".Image", &
992 file_status=
"REPLACE", &
993 file_action=
"WRITE", &
994 file_form=
"UNFORMATTED")
997 print_key, extension=
".IMAGE", &
1000 IF (rst_unit > 0)
THEN
1001 WRITE (rst_unit) image_matrix
1005 "QMMM%PRINT%IMAGE_CHARGE_RESTART")
1008 CALL timestop(handle)
1010 END SUBROUTINE write_image_matrix
1019 SUBROUTINE restart_image_matrix(image_matrix, qs_env, qmmm_env)
1021 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: image_matrix
1025 CHARACTER(LEN=*),
PARAMETER :: routinen =
'restart_image_matrix'
1027 CHARACTER(LEN=default_path_length) :: image_filename
1028 INTEGER :: handle, natom, output_unit, rst_unit
1034 CALL timeset(routinen, handle)
1036 NULLIFY (qmmm_section, logger, para_env)
1041 natom =
SIZE(qmmm_env%image_charge_pot%image_mm_list)
1043 IF (.NOT.
ASSOCIATED(image_matrix))
THEN
1044 ALLOCATE (image_matrix(natom, natom))
1047 image_matrix = 0.0_dp
1049 CALL get_qs_env(qs_env=qs_env, para_env=para_env, &
1053 c_val=image_filename)
1055 INQUIRE (file=image_filename, exist=exist)
1058 IF (para_env%is_source())
THEN
1059 CALL open_file(file_name=image_filename, &
1060 file_status=
"OLD", &
1061 file_form=
"UNFORMATTED", &
1062 file_action=
"READ", &
1063 unit_number=rst_unit)
1065 READ (rst_unit) qs_env%image_matrix
1068 CALL para_env%bcast(qs_env%image_matrix)
1070 IF (para_env%is_source())
CALL close_file(unit_number=rst_unit)
1073 "QMMM%PRINT%PROGRAM_RUN_INFO", &
1074 extension=
".qmmmLog")
1075 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T3,A)") &
1076 "Restarted image matrix"
1078 cpabort(
"Restart file for image matrix not found")
1081 qmmm_env%image_charge_pot%image_restart = .false.
1083 CALL timestop(handle)
1085 END SUBROUTINE restart_image_matrix
1093 SUBROUTINE print_gradients_image_atoms(forces, qs_env)
1095 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: forces
1098 INTEGER :: atom_a, iatom, natom, output_unit
1099 REAL(kind=
dp),
DIMENSION(3) :: sum_gradients
1103 NULLIFY (input, logger)
1106 sum_gradients = 0.0_dp
1107 natom =
SIZE(qs_env%qmmm_env_qm%image_charge_pot%image_mm_list)
1110 sum_gradients(:) = sum_gradients(:) + forces(:, iatom)
1116 "QMMM%PRINT%DERIVATIVES", extension=
".Log")
1117 IF (output_unit > 0)
THEN
1118 WRITE (unit=output_unit, fmt=
"(/1X,A)") &
1119 "Image gradients [a.u.] on MM image charge atoms after QMMM calculation: "
1120 WRITE (unit=output_unit, fmt=
"(T4,A4,T27,A1,T50,A1,T74,A1)") &
1121 "Atom",
"X",
"Y",
"Z"
1123 atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
1124 WRITE (unit=output_unit, fmt=
"(T2,I6,T22,ES12.5,T45,ES12.5,T69,ES12.5)") &
1125 atom_a, forces(:, iatom)
1128 WRITE (unit=output_unit, fmt=
"(T2,A)") repeat(
"-", 79)
1129 WRITE (unit=output_unit, fmt=
"(T2,A,T22,ES12.5,T45,ES12.5,T69,ES12.5)") &
1130 "sum gradients:", sum_gradients
1131 WRITE (unit=output_unit, fmt=
"(/)")
1135 "QMMM%PRINT%DERIVATIVES")
1137 END SUBROUTINE print_gradients_image_atoms
1146 REAL(kind=
dp),
DIMENSION(:),
POINTER :: image_coeff
1149 INTEGER :: atom_a, iatom, natom, output_unit
1150 REAL(kind=
dp) :: normalize_factor, sum_coeff
1154 NULLIFY (input, logger)
1158 natom =
SIZE(qs_env%qmmm_env_qm%image_charge_pot%image_mm_list)
1159 normalize_factor = sqrt((qs_env%qmmm_env_qm%image_charge_pot%eta/
pi)**3)
1162 sum_coeff = sum_coeff + image_coeff(iatom)
1168 "QMMM%PRINT%IMAGE_CHARGE_INFO", extension=
".Log")
1169 IF (output_unit > 0)
THEN
1170 WRITE (unit=output_unit, fmt=
"(/)")
1171 WRITE (unit=output_unit, fmt=
"(T2,A)") &
1172 "Image charges [a.u.] after QMMM calculation: "
1173 WRITE (unit=output_unit, fmt=
"(T4,A4,T67,A)")
"Atom",
"Image charge"
1174 WRITE (unit=output_unit, fmt=
"(T4,A,T67,A)") repeat(
"-", 4), repeat(
"-", 12)
1177 atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
1181 WRITE (unit=output_unit, fmt=
"(T2,I6,T65,ES16.9)") &
1182 atom_a, -image_coeff(iatom)/normalize_factor
1185 WRITE (unit=output_unit, fmt=
"(T2,A)") repeat(
"-", 79)
1186 WRITE (unit=output_unit, fmt=
"(T2,A,T65,ES16.9)") &
1187 "sum image charges:", -sum_coeff/normalize_factor
1191 "QMMM%PRINT%IMAGE_CHARGE_INFO")
1204 SUBROUTINE print_image_energy_terms(en_vmetal_rhohartree, en_external, &
1205 total_rho_metal, qs_env)
1207 REAL(kind=
dp),
INTENT(IN) :: en_vmetal_rhohartree, en_external, &
1211 INTEGER :: output_unit
1215 NULLIFY (input, logger)
1221 "QMMM%PRINT%IMAGE_CHARGE_INFO", extension=
".Log")
1223 IF (output_unit > 0)
THEN
1224 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1225 "Total induced charge density [a.u.]:", total_rho_metal
1226 WRITE (unit=output_unit, fmt=
"(T3,A)")
"Image energy terms: "
1227 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1228 "Coulomb energy of QM and image charge density [a.u.]:", en_vmetal_rhohartree
1229 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1230 "External potential energy term [a.u.]:", -0.5_dp*en_external
1231 WRITE (unit=output_unit, fmt=
"(T3,A,T56,F25.14)") &
1232 "Total image charge energy [a.u.]:", en_vmetal_rhohartree - 0.5_dp*en_external
1236 "QMMM%PRINT%IMAGE_CHARGE_INFO")
1238 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, 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 ...