86#include "./base/base_uses.f90"
94 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_resp'
99 LOGICAL :: equal_charges = .false., itc = .false., &
100 molecular_sys = .false., rheavies = .false., &
101 use_repeat_method = .false.
102 INTEGER :: nres = -1, ncons = -1, &
103 nrest_sec = -1, ncons_sec = -1, &
104 npoints = -1, stride(3) = -1, my_fit = -1, &
106 auto_vdw_radii_table = -1
107 INTEGER,
DIMENSION(:),
POINTER :: atom_surf_list => null()
108 INTEGER,
DIMENSION(:, :),
POINTER :: fitpoints => null()
109 REAL(KIND=
dp) :: rheavies_strength = -1.0_dp, &
110 length = -1.0_dp, eta = -1.0_dp, &
111 sum_vhartree = -1.0_dp, offset = -1.0_dp
112 REAL(KIND=
dp),
DIMENSION(3) :: box_hi = -1.0_dp, box_low = -1.0_dp
113 REAL(KIND=
dp),
DIMENSION(:),
POINTER :: rmin_kind => null(), &
115 REAL(KIND=
dp),
DIMENSION(:),
POINTER :: range_surf => null()
116 REAL(KIND=
dp),
DIMENSION(:),
POINTER :: rhs => null()
117 REAL(KIND=
dp),
DIMENSION(:),
POINTER :: sum_vpot => null()
118 REAL(KIND=
dp),
DIMENSION(:, :),
POINTER :: matrix => null()
122 TYPE(resp_type),
POINTER :: p_resp => null()
134 CHARACTER(len=*),
PARAMETER :: routinen =
'resp_fit'
136 INTEGER :: handle, info, my_per, natom, nvar, &
138 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ipiv
140 REAL(kind=
dp),
DIMENSION(:),
POINTER :: rhs_to_save
148 TYPE(resp_p_type),
DIMENSION(:),
POINTER :: rep_sys
149 TYPE(resp_type),
POINTER :: resp_env
151 resp_section, rest_section
153 CALL timeset(routinen, handle)
155 NULLIFY (logger, atomic_kind_set, cell, subsys, particles, particle_set, input, &
156 resp_section, cons_section, rest_section, poisson_section, resp_env, rep_sys)
158 cpassert(
ASSOCIATED(qs_env))
160 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, input=input, &
161 subsys=subsys, particle_set=particle_set, cell=cell)
169 CALL create_resp_type(resp_env, rep_sys)
171 CALL init_resp(resp_env, rep_sys, subsys, atomic_kind_set, &
172 cell, resp_section, cons_section, rest_section)
175 CALL print_resp_parameter_info(qs_env, resp_env, rep_sys, my_per)
178 natom = particles%n_els
179 nvar = natom + resp_env%ncons
181 CALL resp_allocate(resp_env, natom, nvar)
182 ALLOCATE (ipiv(nvar))
188 CALL calc_resp_matrix_nonper(qs_env, resp_env, atomic_kind_set, particles, cell, &
189 resp_env%matrix, resp_env%rhs, natom)
192 IF (resp_env%use_repeat_method)
CALL cite_reference(
campana2009)
193 CALL calc_resp_matrix_periodic(qs_env, resp_env, rep_sys, particles, cell, natom)
195 CALL cp_abort(__location__, &
196 "RESP charges only implemented for nonperiodic systems"// &
197 " or XYZ periodicity!")
202 IF (output_unit > 0)
THEN
203 WRITE (output_unit,
'(T3,A,T69,I12)')
"Number of fitting points "// &
204 "found: ", resp_env%npoints
205 WRITE (output_unit,
'()')
209 CALL add_restraints_and_constraints(qs_env, resp_env, rest_section, &
210 subsys, natom, cons_section, particle_set)
213 CALL dgetrf(nvar, nvar, resp_env%matrix, nvar, ipiv, info)
216 CALL dgetrs(
'N', nvar, 1, resp_env%matrix, nvar, ipiv, resp_env%rhs, nvar, info)
219 IF (resp_env%use_repeat_method) resp_env%offset = resp_env%rhs(natom + 1)
220 CALL print_resp_charges(qs_env, resp_env, output_unit, natom)
221 CALL print_fitting_points(qs_env, resp_env)
222 CALL print_pot_from_resp_charges(qs_env, resp_env, particles, natom, output_unit)
225 NULLIFY (dft_control)
226 CALL get_qs_env(qs_env, dft_control=dft_control)
227 IF (dft_control%qs_control%ref_embed_subsys)
THEN
228 ALLOCATE (rhs_to_save(
SIZE(resp_env%rhs)))
229 rhs_to_save = resp_env%rhs
234 CALL resp_dealloc(resp_env, rep_sys)
236 "PRINT%PROGRAM_RUN_INFO")
240 CALL timestop(handle)
249 SUBROUTINE create_resp_type(resp_env, rep_sys)
250 TYPE(resp_type),
POINTER :: resp_env
251 TYPE(resp_p_type),
DIMENSION(:),
POINTER :: rep_sys
253 IF (
ASSOCIATED(resp_env))
CALL resp_dealloc(resp_env, rep_sys)
256 NULLIFY (resp_env%matrix, &
257 resp_env%fitpoints, &
258 resp_env%rmin_kind, &
259 resp_env%rmax_kind, &
263 resp_env%equal_charges = .false.
264 resp_env%itc = .false.
265 resp_env%molecular_sys = .false.
266 resp_env%rheavies = .false.
267 resp_env%use_repeat_method = .false.
269 resp_env%box_hi = 0.0_dp
270 resp_env%box_low = 0.0_dp
273 resp_env%ncons_sec = 0
275 resp_env%nrest_sec = 0
277 resp_env%npoints_proc = 0
280 END SUBROUTINE create_resp_type
288 SUBROUTINE resp_allocate(resp_env, natom, nvar)
289 TYPE(resp_type),
POINTER :: resp_env
290 INTEGER,
INTENT(IN) :: natom, nvar
292 IF (.NOT.
ASSOCIATED(resp_env%matrix))
THEN
293 ALLOCATE (resp_env%matrix(nvar, nvar))
295 IF (.NOT.
ASSOCIATED(resp_env%rhs))
THEN
296 ALLOCATE (resp_env%rhs(nvar))
298 IF (.NOT.
ASSOCIATED(resp_env%sum_vpot))
THEN
299 ALLOCATE (resp_env%sum_vpot(natom))
301 resp_env%matrix = 0.0_dp
302 resp_env%rhs = 0.0_dp
303 resp_env%sum_vpot = 0.0_dp
305 END SUBROUTINE resp_allocate
312 SUBROUTINE resp_dealloc(resp_env, rep_sys)
313 TYPE(resp_type),
POINTER :: resp_env
314 TYPE(resp_p_type),
DIMENSION(:),
POINTER :: rep_sys
318 IF (
ASSOCIATED(resp_env))
THEN
319 IF (
ASSOCIATED(resp_env%matrix))
THEN
320 DEALLOCATE (resp_env%matrix)
322 IF (
ASSOCIATED(resp_env%rhs))
THEN
323 DEALLOCATE (resp_env%rhs)
325 IF (
ASSOCIATED(resp_env%sum_vpot))
THEN
326 DEALLOCATE (resp_env%sum_vpot)
328 IF (
ASSOCIATED(resp_env%fitpoints))
THEN
329 DEALLOCATE (resp_env%fitpoints)
331 IF (
ASSOCIATED(resp_env%rmin_kind))
THEN
332 DEALLOCATE (resp_env%rmin_kind)
334 IF (
ASSOCIATED(resp_env%rmax_kind))
THEN
335 DEALLOCATE (resp_env%rmax_kind)
337 DEALLOCATE (resp_env)
339 IF (
ASSOCIATED(rep_sys))
THEN
340 DO i = 1,
SIZE(rep_sys)
341 DEALLOCATE (rep_sys(i)%p_resp%atom_surf_list)
342 DEALLOCATE (rep_sys(i)%p_resp)
347 END SUBROUTINE resp_dealloc
360 SUBROUTINE init_resp(resp_env, rep_sys, subsys, atomic_kind_set, &
361 cell, resp_section, cons_section, rest_section)
363 TYPE(resp_type),
POINTER :: resp_env
364 TYPE(resp_p_type),
DIMENSION(:),
POINTER :: rep_sys
370 CHARACTER(len=*),
PARAMETER :: routinen =
'init_resp'
372 INTEGER :: handle, i, nrep
373 INTEGER,
DIMENSION(:),
POINTER :: atom_list_cons, my_stride
377 CALL timeset(routinen, handle)
379 NULLIFY (atom_list_cons, my_stride, sphere_section, slab_section)
390 IF (resp_env%itc) resp_env%ncons = resp_env%ncons + 1
393 l_val=resp_env%rheavies)
394 IF (resp_env%rheavies)
THEN
396 r_val=resp_env%rheavies_strength)
399 IF (
SIZE(my_stride) /= 1 .AND.
SIZE(my_stride) /= 3)
THEN
400 CALL cp_abort(__location__,
"STRIDE keyword can accept only 1 (the same for X,Y,Z) "// &
401 "or 3 values. Correct your input file.")
403 IF (
SIZE(my_stride) == 1)
THEN
405 resp_env%stride(i) = my_stride(1)
408 resp_env%stride = my_stride(1:3)
414 l_val=resp_env%use_repeat_method)
415 IF (resp_env%use_repeat_method)
THEN
416 resp_env%ncons = resp_env%ncons + 1
418 resp_env%rheavies = .false.
423 CALL get_parameter_molecular_sys(resp_env, sphere_section, cell, &
429 IF (resp_env%molecular_sys)
THEN
430 CALL cp_abort(__location__, &
431 "You can only use either SPHERE_SAMPLING or SLAB_SAMPLING, but "// &
434 ALLOCATE (rep_sys(nrep))
436 ALLOCATE (rep_sys(i)%p_resp)
437 NULLIFY (rep_sys(i)%p_resp%range_surf, rep_sys(i)%p_resp%atom_surf_list)
443 i_rep_section=i, i_val=rep_sys(i)%p_resp%my_fit)
444 IF (any(rep_sys(i)%p_resp%range_surf < 0.0_dp))
THEN
445 cpabort(
"Numbers in RANGE in SLAB_SAMPLING cannot be negative.")
447 IF (rep_sys(i)%p_resp%length <= epsilon(0.0_dp))
THEN
448 cpabort(
"Parameter LENGTH in SLAB_SAMPLING has to be larger than zero.")
451 CALL build_atom_list(slab_section, subsys, rep_sys(i)%p_resp%atom_surf_list, rep=i)
459 DO i = 1, resp_env%ncons_sec
461 l_val=resp_env%equal_charges, explicit=explicit)
462 IF (.NOT. explicit) cycle
463 CALL build_atom_list(cons_section, subsys, atom_list_cons, i)
465 resp_env%ncons = resp_env%ncons +
SIZE(atom_list_cons) - 2
466 DEALLOCATE (atom_list_cons)
473 resp_env%ncons = resp_env%ncons + resp_env%ncons_sec
474 resp_env%nres = resp_env%nres + resp_env%nrest_sec
476 CALL timestop(handle)
478 END SUBROUTINE init_resp
488 SUBROUTINE get_parameter_molecular_sys(resp_env, sphere_section, cell, &
491 TYPE(resp_type),
POINTER :: resp_env
496 CHARACTER(LEN=2) :: symbol
497 CHARACTER(LEN=default_string_length) :: missing_rmax, missing_rmin
498 CHARACTER(LEN=default_string_length), &
499 DIMENSION(:),
POINTER :: tmpstringlist
500 INTEGER :: ikind, j, kind_number, n_rmax_missing, &
501 n_rmin_missing, nkind, nrep_rmax, &
503 LOGICAL :: explicit, has_rmax, has_rmin
504 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: rmax_is_set, rmin_is_set
505 REAL(kind=
dp) :: auto_rmax_scale, auto_rmin_scale, rmax, &
507 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
512 nkind =
SIZE(atomic_kind_set)
519 resp_env%molecular_sys = .true.
521 i_val=resp_env%auto_vdw_radii_table)
528 ALLOCATE (resp_env%rmin_kind(nkind))
529 ALLOCATE (resp_env%rmax_kind(nkind))
530 resp_env%rmin_kind = 0.0_dp
531 resp_env%rmax_kind = 0.0_dp
532 ALLOCATE (rmin_is_set(nkind))
533 ALLOCATE (rmax_is_set(nkind))
534 rmin_is_set = .false.
535 rmax_is_set = .false.
538 atomic_kind => atomic_kind_set(ikind)
540 element_symbol=symbol, &
541 kind_number=kind_number, &
543 SELECT CASE (resp_env%auto_vdw_radii_table)
545 CALL get_ptable_info(symbol, vdw_radius=resp_env%rmin_kind(kind_number))
546 rmin_is_set(kind_number) = .true.
550 found=rmin_is_set(kind_number))
552 CALL get_ptable_info(symbol, vdw_radius=resp_env%rmin_kind(kind_number))
553 rmin_is_set(kind_number) = .true.
555 IF (rmin_is_set(kind_number))
THEN
556 resp_env%rmin_kind(kind_number) =
cp_unit_to_cp2k(resp_env%rmin_kind(kind_number), &
558 resp_env%rmin_kind(kind_number) = resp_env%rmin_kind(kind_number)*auto_rmin_scale
560 resp_env%rmax_kind(kind_number) = &
561 max(resp_env%rmin_kind(kind_number), &
562 resp_env%rmin_kind(kind_number)*auto_rmax_scale)
563 rmax_is_set(kind_number) = .true.
569 resp_env%rmin_kind = rmin
573 resp_env%rmax_kind = rmax
580 c_vals=tmpstringlist)
582 atomic_kind => atomic_kind_set(ikind)
583 CALL get_atomic_kind(atomic_kind, element_symbol=symbol, kind_number=kind_number)
584 IF (trim(tmpstringlist(2)) == trim(symbol))
THEN
585 READ (tmpstringlist(1), *) resp_env%rmin_kind(kind_number)
586 resp_env%rmin_kind(kind_number) = &
589 rmin_is_set(kind_number) = .true.
595 c_vals=tmpstringlist)
597 atomic_kind => atomic_kind_set(ikind)
598 CALL get_atomic_kind(atomic_kind, element_symbol=symbol, kind_number=kind_number)
599 IF (trim(tmpstringlist(2)) == trim(symbol))
THEN
600 READ (tmpstringlist(1), *) resp_env%rmax_kind(kind_number)
601 resp_env%rmax_kind(kind_number) =
cp_unit_to_cp2k(resp_env%rmax_kind(kind_number), &
603 rmax_is_set(kind_number) = .true.
613 atomic_kind => atomic_kind_set(ikind)
615 element_symbol=symbol, &
616 kind_number=kind_number)
617 IF (.NOT. rmin_is_set(kind_number))
THEN
618 n_rmin_missing = n_rmin_missing + 1
619 missing_rmin = trim(missing_rmin)//
" "//trim(symbol)//
","
621 IF (.NOT. rmax_is_set(kind_number))
THEN
622 n_rmax_missing = n_rmax_missing + 1
623 missing_rmax = trim(missing_rmax)//
" "//trim(symbol)//
","
626 IF (n_rmin_missing > 0)
THEN
627 CALL cp_warn(__location__, &
628 "RMIN for the following elements are missing: "// &
629 trim(missing_rmin)// &
630 " please set these values manually using "// &
631 "RMIN_KIND in SPHERE_SAMPLING section")
633 IF (n_rmax_missing > 0)
THEN
634 CALL cp_warn(__location__, &
635 "RMAX for the following elements are missing: "// &
636 trim(missing_rmax)// &
637 " please set these values manually using "// &
638 "RMAX_KIND in SPHERE_SAMPLING section")
640 IF (n_rmin_missing > 0 .OR. &
641 n_rmax_missing > 0)
THEN
642 cpabort(
"Insufficient data for RMIN or RMAX")
646 resp_env%box_hi = [hmat(1, 1), hmat(2, 2), hmat(3, 3)]
647 resp_env%box_low = 0.0_dp
650 r_val=resp_env%box_hi(1))
653 r_val=resp_env%box_low(1))
656 r_val=resp_env%box_hi(2))
659 r_val=resp_env%box_low(2))
662 r_val=resp_env%box_hi(3))
665 r_val=resp_env%box_low(3))
667 DEALLOCATE (rmin_is_set)
668 DEALLOCATE (rmax_is_set)
671 END SUBROUTINE get_parameter_molecular_sys
682 SUBROUTINE build_atom_list(section, subsys, atom_list, rep)
686 INTEGER,
DIMENSION(:),
POINTER :: atom_list
687 INTEGER,
INTENT(IN),
OPTIONAL :: rep
689 CHARACTER(len=*),
PARAMETER :: routinen =
'build_atom_list'
691 INTEGER :: atom_a, atom_b, handle, i, irep, j, &
692 max_index, n_var, num_atom
693 INTEGER,
DIMENSION(:),
POINTER :: indexes
694 LOGICAL :: index_in_range
696 CALL timeset(routinen, handle)
700 IF (
PRESENT(rep)) irep = rep
707 i_rep_val=i, i_vals=indexes)
708 num_atom = num_atom +
SIZE(indexes)
710 ALLOCATE (atom_list(num_atom))
715 i_rep_val=i, i_vals=indexes)
716 atom_list(num_atom:num_atom +
SIZE(indexes) - 1) = indexes(:)
717 num_atom = num_atom +
SIZE(indexes)
720 num_atom = num_atom - 1
722 cpassert(
SIZE(atom_list) /= 0)
723 index_in_range = (maxval(atom_list) <= max_index) &
724 .AND. (minval(atom_list) > 0)
725 cpassert(index_in_range)
727 DO j = i + 1, num_atom
728 atom_a = atom_list(i)
729 atom_b = atom_list(j)
730 IF (atom_a == atom_b)
THEN
731 cpabort(
"There are atoms doubled in atom list for RESP.")
736 CALL timestop(handle)
738 END SUBROUTINE build_atom_list
751 SUBROUTINE calc_resp_matrix_nonper(qs_env, resp_env, atomic_kind_set, particles, &
752 cell, matrix, rhs, natom)
755 TYPE(resp_type),
POINTER :: resp_env
759 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: matrix
760 REAL(kind=
dp),
DIMENSION(:),
POINTER :: rhs
761 INTEGER,
INTENT(IN) :: natom
763 CHARACTER(len=*),
PARAMETER :: routinen =
'calc_resp_matrix_nonper'
765 INTEGER :: bo(2, 3), gbo(2, 3), handle, i, ikind, &
766 jx, jy, jz, k, kind_number, l, m, &
768 LOGICAL,
ALLOCATABLE,
DIMENSION(:, :) :: not_in_range
769 REAL(kind=
dp) :: delta, dh(3, 3), dvol, r(3), rmax, rmin, &
770 vec(3), vec_pbc(3), vj
771 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dist
772 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat, hmat_inv
776 CALL timeset(routinen, handle)
778 NULLIFY (particle_set, v_hartree_pw)
781 CALL get_cell(cell=cell, h=hmat, h_inv=hmat_inv)
783 IF (.NOT. cell%orthorhombic)
THEN
784 CALL cp_abort(__location__, &
785 "Nonperiodic solution for RESP charges only"// &
786 " implemented for orthorhombic cells!")
788 IF (.NOT. resp_env%molecular_sys)
THEN
789 CALL cp_abort(__location__, &
790 "Nonperiodic solution for RESP charges (i.e. nonperiodic"// &
791 " Poisson solver) can only be used with section SPHERE_SAMPLING")
793 IF (resp_env%use_repeat_method)
THEN
794 CALL cp_abort(__location__, &
795 "REPEAT method only reasonable for periodic RESP fitting")
797 CALL get_qs_env(qs_env, particle_set=particle_set, v_hartree_rspace=v_hartree_pw)
799 bo = v_hartree_pw%pw_grid%bounds_local
800 gbo = v_hartree_pw%pw_grid%bounds
801 np = v_hartree_pw%pw_grid%npts
802 dh = v_hartree_pw%pw_grid%dh
803 dvol = v_hartree_pw%pw_grid%dvol
804 nkind =
SIZE(atomic_kind_set)
806 ALLOCATE (dist(natom))
807 ALLOCATE (not_in_range(natom, 2))
810 IF (.NOT.
ASSOCIATED(resp_env%fitpoints))
THEN
812 ALLOCATE (resp_env%fitpoints(3, now))
814 now =
SIZE(resp_env%fitpoints, 2)
817 DO jz = bo(1, 3), bo(2, 3)
818 DO jy = bo(1, 2), bo(2, 2)
819 DO jx = bo(1, 1), bo(2, 1)
820 IF (.NOT. (
modulo(jz, resp_env%stride(3)) == 0)) cycle
821 IF (.NOT. (
modulo(jy, resp_env%stride(2)) == 0)) cycle
822 IF (.NOT. (
modulo(jx, resp_env%stride(1)) == 0)) cycle
827 r(3) = p*dh(3, 3) + k*dh(3, 2) + l*dh(3, 1)
828 r(2) = p*dh(2, 3) + k*dh(2, 2) + l*dh(2, 1)
829 r(1) = p*dh(1, 3) + k*dh(1, 2) + l*dh(1, 1)
830 IF (r(3) < resp_env%box_low(3) .OR. r(3) > resp_env%box_hi(3)) cycle
831 IF (r(2) < resp_env%box_low(2) .OR. r(2) > resp_env%box_hi(2)) cycle
832 IF (r(1) < resp_env%box_low(1) .OR. r(1) > resp_env%box_hi(1)) cycle
834 not_in_range = .false.
836 vec = r - particles%els(i)%r
837 vec_pbc(1) = vec(1) - hmat(1, 1)*anint(hmat_inv(1, 1)*vec(1))
838 vec_pbc(2) = vec(2) - hmat(2, 2)*anint(hmat_inv(2, 2)*vec(2))
839 vec_pbc(3) = vec(3) - hmat(3, 3)*anint(hmat_inv(3, 3)*vec(3))
840 dist(i) = sqrt(sum(vec_pbc**2))
842 kind_number=kind_number)
844 IF (ikind == kind_number)
THEN
845 rmin = resp_env%rmin_kind(ikind)
846 rmax = resp_env%rmax_kind(ikind)
850 IF (dist(i) < rmin + delta) not_in_range(i, 1) = .true.
851 IF (dist(i) > rmax - delta) not_in_range(i, 2) = .true.
855 IF (any(not_in_range(:, 1)) .OR. all(not_in_range(:, 2))) cycle
856 resp_env%npoints_proc = resp_env%npoints_proc + 1
857 IF (resp_env%npoints_proc > now)
THEN
859 CALL reallocate(resp_env%fitpoints, 1, 3, 1, now)
861 resp_env%fitpoints(1, resp_env%npoints_proc) = jx
862 resp_env%fitpoints(2, resp_env%npoints_proc) = jy
863 resp_env%fitpoints(3, resp_env%npoints_proc) = jz
865 IF (qs_env%qmmm)
THEN
867 vj = -v_hartree_pw%array(jx, jy, jz)/dvol + qs_env%ks_qmmm_env%v_qmmm_rspace%array(jx, jy, jz)
869 vj = -v_hartree_pw%array(jx, jy, jz)/dvol
871 dist(:) = 1.0_dp/dist(:)
875 matrix(m, i) = matrix(m, i) + 2.0_dp*dist(i)*dist(m)
877 rhs(i) = rhs(i) + 2.0_dp*vj*dist(i)
883 resp_env%npoints = resp_env%npoints_proc
884 CALL v_hartree_pw%pw_grid%para%group%sum(resp_env%npoints)
885 CALL v_hartree_pw%pw_grid%para%group%sum(matrix)
886 CALL v_hartree_pw%pw_grid%para%group%sum(rhs)
888 matrix = matrix/resp_env%npoints
889 rhs = rhs/resp_env%npoints
892 DEALLOCATE (not_in_range)
894 CALL timestop(handle)
896 END SUBROUTINE calc_resp_matrix_nonper
907 SUBROUTINE calc_resp_matrix_periodic(qs_env, resp_env, rep_sys, particles, cell, &
911 TYPE(resp_type),
POINTER :: resp_env
912 TYPE(resp_p_type),
DIMENSION(:),
POINTER :: rep_sys
915 INTEGER,
INTENT(IN) :: natom
917 CHARACTER(len=*),
PARAMETER :: routinen =
'calc_resp_matrix_periodic'
919 INTEGER :: handle, i, ip, j, jx, jy, jz
920 INTEGER,
DIMENSION(3) :: periodic
921 REAL(kind=
dp) :: normalize_factor
922 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: vpot
930 CALL timeset(routinen, handle)
932 NULLIFY (pw_env, para_env, auxbas_pw_pool, poisson_env)
934 CALL get_cell(cell=cell, periodic=periodic)
936 IF (.NOT. all(periodic /= 0))
THEN
937 CALL cp_abort(__location__, &
938 "Periodic solution for RESP (with periodic Poisson solver)"// &
939 " can only be obtained with a cell that has XYZ periodicity")
942 CALL get_qs_env(qs_env, pw_env=pw_env, para_env=para_env)
944 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
945 poisson_env=poisson_env)
946 CALL auxbas_pw_pool%create_pw(rho_ga)
947 CALL auxbas_pw_pool%create_pw(va_gspace)
948 CALL auxbas_pw_pool%create_pw(va_rspace)
951 CALL get_fitting_points(qs_env, resp_env, rep_sys, particles=particles, &
953 ALLOCATE (vpot(resp_env%npoints_proc, natom))
954 normalize_factor = sqrt((resp_env%eta/
pi)**3)
965 CALL pw_scale(va_rspace, normalize_factor)
966 DO ip = 1, resp_env%npoints_proc
967 jx = resp_env%fitpoints(1, ip)
968 jy = resp_env%fitpoints(2, ip)
969 jz = resp_env%fitpoints(3, ip)
970 vpot(ip, i) = va_rspace%array(jx, jy, jz)
974 CALL va_gspace%release()
975 CALL va_rspace%release()
976 CALL rho_ga%release()
981 resp_env%matrix(i, j) = resp_env%matrix(i, j) + 2.0_dp*sum(vpot(:, i)*vpot(:, j))
984 CALL calculate_rhs(qs_env, resp_env, resp_env%rhs(i), vpot(:, i))
987 CALL para_env%sum(resp_env%matrix)
988 CALL para_env%sum(resp_env%rhs)
990 resp_env%matrix = resp_env%matrix/resp_env%npoints
991 resp_env%rhs = resp_env%rhs/resp_env%npoints
994 IF (resp_env%use_repeat_method)
THEN
997 resp_env%sum_vpot(i) = 2.0_dp*
accurate_sum(vpot(:, i))/resp_env%npoints
999 CALL para_env%sum(resp_env%sum_vpot)
1000 CALL para_env%sum(resp_env%sum_vhartree)
1001 resp_env%sum_vhartree = 2.0_dp*resp_env%sum_vhartree/resp_env%npoints
1005 CALL timestop(handle)
1007 END SUBROUTINE calc_resp_matrix_periodic
1017 SUBROUTINE get_fitting_points(qs_env, resp_env, rep_sys, particles, cell)
1020 TYPE(resp_type),
POINTER :: resp_env
1021 TYPE(resp_p_type),
DIMENSION(:),
POINTER :: rep_sys
1025 CHARACTER(len=*),
PARAMETER :: routinen =
'get_fitting_points'
1027 INTEGER :: bo(2, 3), gbo(2, 3), handle, i, iatom, &
1028 ikind, in_x, in_y, in_z, jx, jy, jz, &
1029 k, kind_number, l, m, natom, nkind, &
1031 LOGICAL,
ALLOCATABLE,
DIMENSION(:, :) :: not_in_range
1032 REAL(kind=
dp) :: delta, dh(3, 3), r(3), rmax, rmin, &
1034 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dist
1040 CALL timeset(routinen, handle)
1042 NULLIFY (atomic_kind_set, v_hartree_pw, para_env, particle_set)
1046 particle_set=particle_set, &
1047 atomic_kind_set=atomic_kind_set, &
1048 para_env=para_env, &
1049 v_hartree_rspace=v_hartree_pw)
1051 bo = v_hartree_pw%pw_grid%bounds_local
1052 gbo = v_hartree_pw%pw_grid%bounds
1053 dh = v_hartree_pw%pw_grid%dh
1054 natom =
SIZE(particles%els)
1055 nkind =
SIZE(atomic_kind_set)
1057 IF (.NOT.
ASSOCIATED(resp_env%fitpoints))
THEN
1059 ALLOCATE (resp_env%fitpoints(3, now))
1061 now =
SIZE(resp_env%fitpoints, 2)
1064 ALLOCATE (dist(natom))
1065 ALLOCATE (not_in_range(natom, 2))
1068 DO jz = bo(1, 3), bo(2, 3)
1069 IF (.NOT. (
modulo(jz, resp_env%stride(3)) == 0)) cycle
1070 DO jy = bo(1, 2), bo(2, 2)
1071 IF (.NOT. (
modulo(jy, resp_env%stride(2)) == 0)) cycle
1072 DO jx = bo(1, 1), bo(2, 1)
1073 IF (.NOT. (
modulo(jx, resp_env%stride(1)) == 0)) cycle
1078 r(3) = p*dh(3, 3) + k*dh(3, 2) + l*dh(3, 1)
1079 r(2) = p*dh(2, 3) + k*dh(2, 2) + l*dh(2, 1)
1080 r(1) = p*dh(1, 3) + k*dh(1, 2) + l*dh(1, 1)
1081 IF (resp_env%molecular_sys)
THEN
1082 not_in_range = .false.
1084 vec_pbc =
pbc(r, particles%els(m)%r, cell)
1085 dist(m) = sqrt(sum(vec_pbc**2))
1087 kind_number=kind_number)
1089 IF (ikind == kind_number)
THEN
1090 rmin = resp_env%rmin_kind(ikind)
1091 rmax = resp_env%rmax_kind(ikind)
1095 IF (dist(m) < rmin + delta) not_in_range(m, 1) = .true.
1096 IF (dist(m) > rmax - delta) not_in_range(m, 2) = .true.
1098 IF (any(not_in_range(:, 1)) .OR. all(not_in_range(:, 2))) cycle
1100 DO i = 1,
SIZE(rep_sys)
1101 DO m = 1,
SIZE(rep_sys(i)%p_resp%atom_surf_list)
1105 iatom = rep_sys(i)%p_resp%atom_surf_list(m)
1106 SELECT CASE (rep_sys(i)%p_resp%my_fit)
1108 vec_pbc =
pbc(particles%els(iatom)%r, r, cell)
1110 vec_pbc =
pbc(r, particles%els(iatom)%r, cell)
1112 SELECT CASE (rep_sys(i)%p_resp%my_fit)
1115 IF (abs(vec_pbc(3)) < rep_sys(i)%p_resp%length - delta) in_z = 1
1116 IF (abs(vec_pbc(2)) < rep_sys(i)%p_resp%length - delta) in_y = 1
1117 IF (vec_pbc(1) > rep_sys(i)%p_resp%range_surf(1) + delta .AND. &
1118 vec_pbc(1) < rep_sys(i)%p_resp%range_surf(2) - delta) in_x = 1
1120 IF (abs(vec_pbc(3)) < rep_sys(i)%p_resp%length - delta) in_z = 1
1121 IF (vec_pbc(2) > rep_sys(i)%p_resp%range_surf(1) + delta .AND. &
1122 vec_pbc(2) < rep_sys(i)%p_resp%range_surf(2) - delta) in_y = 1
1123 IF (abs(vec_pbc(1)) < rep_sys(i)%p_resp%length - delta) in_x = 1
1125 IF (vec_pbc(3) > rep_sys(i)%p_resp%range_surf(1) + delta .AND. &
1126 vec_pbc(3) < rep_sys(i)%p_resp%range_surf(2) - delta) in_z = 1
1127 IF (abs(vec_pbc(2)) < rep_sys(i)%p_resp%length - delta) in_y = 1
1128 IF (abs(vec_pbc(1)) < rep_sys(i)%p_resp%length - delta) in_x = 1
1130 IF (in_z*in_y*in_x == 1)
EXIT
1132 IF (in_z*in_y*in_x == 1)
EXIT
1134 IF (in_z*in_y*in_x == 0) cycle
1136 resp_env%npoints_proc = resp_env%npoints_proc + 1
1137 IF (resp_env%npoints_proc > now)
THEN
1139 CALL reallocate(resp_env%fitpoints, 1, 3, 1, now)
1141 resp_env%fitpoints(1, resp_env%npoints_proc) = jx
1142 resp_env%fitpoints(2, resp_env%npoints_proc) = jy
1143 resp_env%fitpoints(3, resp_env%npoints_proc) = jz
1148 resp_env%npoints = resp_env%npoints_proc
1149 CALL para_env%sum(resp_env%npoints)
1152 DEALLOCATE (not_in_range)
1154 CALL timestop(handle)
1156 END SUBROUTINE get_fitting_points
1165 SUBROUTINE calculate_rhs(qs_env, resp_env, rhs, vpot)
1168 TYPE(resp_type),
POINTER :: resp_env
1169 REAL(kind=
dp),
INTENT(INOUT) :: rhs
1170 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: vpot
1172 CHARACTER(len=*),
PARAMETER :: routinen =
'calculate_rhs'
1174 INTEGER :: handle, ip, jx, jy, jz
1175 REAL(kind=
dp) :: dvol
1176 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: vhartree
1179 CALL timeset(routinen, handle)
1181 NULLIFY (v_hartree_pw)
1182 CALL get_qs_env(qs_env, v_hartree_rspace=v_hartree_pw)
1183 dvol = v_hartree_pw%pw_grid%dvol
1184 ALLOCATE (vhartree(resp_env%npoints_proc))
1189 DO ip = 1, resp_env%npoints_proc
1190 jx = resp_env%fitpoints(1, ip)
1191 jy = resp_env%fitpoints(2, ip)
1192 jz = resp_env%fitpoints(3, ip)
1193 vhartree(ip) = -v_hartree_pw%array(jx, jy, jz)/dvol
1194 IF (qs_env%qmmm)
THEN
1196 vhartree(ip) = vhartree(ip) + qs_env%ks_qmmm_env%v_qmmm_rspace%array(jx, jy, jz)
1198 rhs = rhs + 2.0_dp*vhartree(ip)*vpot(ip)
1201 IF (resp_env%use_repeat_method)
THEN
1205 DEALLOCATE (vhartree)
1207 CALL timestop(handle)
1209 END SUBROUTINE calculate_rhs
1217 SUBROUTINE print_fitting_points(qs_env, resp_env)
1220 TYPE(resp_type),
POINTER :: resp_env
1222 CHARACTER(len=*),
PARAMETER :: routinen =
'print_fitting_points'
1224 CHARACTER(LEN=2) :: element_symbol
1225 CHARACTER(LEN=default_path_length) :: filename
1226 INTEGER :: gbo(2, 3), handle, i, iatom, ip, jx, jy, &
1227 jz, k, l, my_pos, nobjects, &
1229 INTEGER,
DIMENSION(:),
POINTER :: tmp_npoints, tmp_size
1230 INTEGER,
DIMENSION(:, :),
POINTER :: tmp_points
1231 REAL(kind=
dp) :: conv, dh(3, 3), r(3)
1239 CALL timeset(routinen, handle)
1241 NULLIFY (para_env, input, logger, resp_section, print_key, particle_set, tmp_size, &
1242 tmp_points, tmp_npoints, v_hartree_pw)
1244 CALL get_qs_env(qs_env, input=input, para_env=para_env, &
1245 particle_set=particle_set, v_hartree_rspace=v_hartree_pw)
1247 gbo = v_hartree_pw%pw_grid%bounds
1248 dh = v_hartree_pw%pw_grid%dh
1249 nobjects =
SIZE(particle_set) + resp_env%npoints
1255 "PRINT%COORD_FIT_POINTS", &
1257 file_status=
"REPLACE", &
1258 file_action=
"WRITE", &
1259 file_form=
"FORMATTED")
1262 resp_section,
"PRINT%COORD_FIT_POINTS"), &
1264 IF (output_unit > 0)
THEN
1266 print_key, extension=
".xyz", &
1268 WRITE (unit=output_unit, fmt=
"(I12,/)") nobjects
1269 DO iatom = 1,
SIZE(particle_set)
1271 element_symbol=element_symbol)
1272 WRITE (unit=output_unit, fmt=
"(A,1X,3F10.5)") element_symbol, &
1273 particle_set(iatom)%r(1:3)*conv
1276 DO ip = 1, resp_env%npoints_proc
1277 jx = resp_env%fitpoints(1, ip)
1278 jy = resp_env%fitpoints(2, ip)
1279 jz = resp_env%fitpoints(3, ip)
1283 r(3) = p*dh(3, 3) + k*dh(3, 2) + l*dh(3, 1)
1284 r(2) = p*dh(2, 3) + k*dh(2, 2) + l*dh(2, 1)
1285 r(1) = p*dh(1, 3) + k*dh(1, 2) + l*dh(1, 1)
1287 WRITE (unit=output_unit, fmt=
"(A,2X,3F10.5)")
"X", r(1), r(2), r(3)
1291 ALLOCATE (tmp_size(1))
1292 ALLOCATE (tmp_npoints(1))
1295 IF (output_unit > 0)
THEN
1296 my_pos = para_env%mepos
1297 DO i = 1, para_env%num_pe
1298 IF (my_pos == i - 1) cycle
1299 CALL para_env%irecv(msgout=tmp_size, source=i - 1, &
1302 ALLOCATE (tmp_points(3, tmp_size(1)))
1303 CALL para_env%irecv(msgout=tmp_points, source=i - 1, &
1306 CALL para_env%irecv(msgout=tmp_npoints, source=i - 1, &
1309 DO ip = 1, tmp_npoints(1)
1310 jx = tmp_points(1, ip)
1311 jy = tmp_points(2, ip)
1312 jz = tmp_points(3, ip)
1316 r(3) = p*dh(3, 3) + k*dh(3, 2) + l*dh(3, 1)
1317 r(2) = p*dh(2, 3) + k*dh(2, 2) + l*dh(2, 1)
1318 r(1) = p*dh(1, 3) + k*dh(1, 2) + l*dh(1, 1)
1320 WRITE (unit=output_unit, fmt=
"(A,2X,3F10.5)")
"X", r(1), r(2), r(3)
1322 DEALLOCATE (tmp_points)
1325 tmp_size(1) =
SIZE(resp_env%fitpoints, 2)
1327 CALL para_env%isend(msgin=tmp_size, dest=para_env%source, &
1330 CALL para_env%isend(msgin=resp_env%fitpoints, dest=para_env%source, &
1333 tmp_npoints(1) = resp_env%npoints_proc
1334 CALL para_env%isend(msgin=tmp_npoints, dest=para_env%source, &
1339 DEALLOCATE (tmp_size)
1340 DEALLOCATE (tmp_npoints)
1344 "PRINT%COORD_FIT_POINTS")
1346 CALL timestop(handle)
1348 END SUBROUTINE print_fitting_points
1360 SUBROUTINE add_restraints_and_constraints(qs_env, resp_env, rest_section, &
1361 subsys, natom, cons_section, particle_set)
1364 TYPE(resp_type),
POINTER :: resp_env
1367 INTEGER,
INTENT(IN) :: natom
1371 CHARACTER(len=*),
PARAMETER :: routinen =
'add_restraints_and_constraints'
1373 INTEGER :: handle, i, k, m, ncons_v, z
1374 INTEGER,
DIMENSION(:),
POINTER :: atom_list_cons, atom_list_res
1375 LOGICAL :: explicit_coeff
1376 REAL(kind=
dp) :: my_atom_coef(2), strength,
TARGET
1377 REAL(kind=
dp),
DIMENSION(:),
POINTER :: atom_coef
1380 CALL timeset(routinen, handle)
1382 NULLIFY (atom_coef, atom_list_res, atom_list_cons, dft_control)
1384 CALL get_qs_env(qs_env, dft_control=dft_control)
1387 DO i = 1, resp_env%nrest_sec
1390 CALL build_atom_list(rest_section, subsys, atom_list_res, i)
1392 IF (explicit_coeff)
THEN
1394 cpassert(
SIZE(atom_list_res) ==
SIZE(atom_coef))
1396 DO m = 1,
SIZE(atom_list_res)
1397 IF (explicit_coeff)
THEN
1398 DO k = 1,
SIZE(atom_list_res)
1399 resp_env%matrix(atom_list_res(m), atom_list_res(k)) = &
1400 resp_env%matrix(atom_list_res(m), atom_list_res(k)) + &
1401 atom_coef(m)*atom_coef(k)*2.0_dp*strength
1403 resp_env%rhs(atom_list_res(m)) = resp_env%rhs(atom_list_res(m)) + &
1404 2.0_dp*
TARGET*strength*atom_coef(m)
1406 resp_env%matrix(atom_list_res(m), atom_list_res(m)) = &
1407 resp_env%matrix(atom_list_res(m), atom_list_res(m)) + &
1409 resp_env%rhs(atom_list_res(m)) = resp_env%rhs(atom_list_res(m)) + &
1410 2.0_dp*
TARGET*strength
1413 DEALLOCATE (atom_list_res)
1417 IF (resp_env%rheavies)
THEN
1421 resp_env%matrix(i, i) = resp_env%matrix(i, i) + 2.0_dp*resp_env%rheavies_strength
1428 ncons_v = ncons_v + natom
1431 IF (resp_env%use_repeat_method)
THEN
1432 ncons_v = ncons_v + 1
1433 resp_env%matrix(1:natom, ncons_v) = resp_env%sum_vpot(1:natom)
1434 resp_env%matrix(ncons_v, 1:natom) = resp_env%sum_vpot(1:natom)
1435 resp_env%matrix(ncons_v, ncons_v) = 2.0_dp
1436 resp_env%rhs(ncons_v) = resp_env%sum_vhartree
1440 IF (resp_env%itc)
THEN
1441 ncons_v = ncons_v + 1
1442 resp_env%matrix(1:natom, ncons_v) = 1.0_dp
1443 resp_env%matrix(ncons_v, 1:natom) = 1.0_dp
1444 resp_env%rhs(ncons_v) = dft_control%charge
1448 DO i = 1, resp_env%ncons_sec
1449 CALL build_atom_list(cons_section, subsys, atom_list_cons, i)
1450 IF (.NOT. resp_env%equal_charges)
THEN
1451 ncons_v = ncons_v + 1
1454 cpassert(
SIZE(atom_list_cons) ==
SIZE(atom_coef))
1455 DO m = 1,
SIZE(atom_list_cons)
1456 resp_env%matrix(atom_list_cons(m), ncons_v) = atom_coef(m)
1457 resp_env%matrix(ncons_v, atom_list_cons(m)) = atom_coef(m)
1459 resp_env%rhs(ncons_v) =
TARGET
1461 my_atom_coef(1) = 1.0_dp
1462 my_atom_coef(2) = -1.0_dp
1463 DO k = 2,
SIZE(atom_list_cons)
1464 ncons_v = ncons_v + 1
1465 resp_env%matrix(atom_list_cons(1), ncons_v) = my_atom_coef(1)
1466 resp_env%matrix(ncons_v, atom_list_cons(1)) = my_atom_coef(1)
1467 resp_env%matrix(atom_list_cons(k), ncons_v) = my_atom_coef(2)
1468 resp_env%matrix(ncons_v, atom_list_cons(k)) = my_atom_coef(2)
1469 resp_env%rhs(ncons_v) = 0.0_dp
1472 DEALLOCATE (atom_list_cons)
1474 CALL timestop(handle)
1476 END SUBROUTINE add_restraints_and_constraints
1485 SUBROUTINE print_resp_parameter_info(qs_env, resp_env, rep_sys, my_per)
1488 TYPE(resp_type),
POINTER :: resp_env
1489 TYPE(resp_p_type),
DIMENSION(:),
POINTER :: rep_sys
1490 INTEGER,
INTENT(IN) :: my_per
1492 CHARACTER(len=*),
PARAMETER :: routinen =
'print_resp_parameter_info'
1494 CHARACTER(len=2) :: symbol
1495 INTEGER :: handle, i, ikind, kind_number, nkinds, &
1497 REAL(kind=
dp) :: conv, eta_conv
1502 CALL timeset(routinen, handle)
1503 NULLIFY (logger, input, resp_section)
1507 atomic_kind_set=atomic_kind_set)
1512 nkinds =
SIZE(atomic_kind_set)
1519 IF (output_unit > 0)
THEN
1520 WRITE (output_unit,
'(/,1X,A,/)')
"STARTING RESP FIT"
1521 IF (resp_env%use_repeat_method)
THEN
1522 WRITE (output_unit,
'(T3,A)') &
1523 "Fit the variance of the potential (REPEAT method)."
1525 IF (.NOT. resp_env%equal_charges)
THEN
1526 WRITE (output_unit,
'(T3,A,T75,I6)')
"Number of explicit constraints: ", resp_env%ncons_sec
1528 IF (resp_env%itc)
THEN
1529 WRITE (output_unit,
'(T3,A,T75,I6)')
"Number of explicit constraints: ", resp_env%ncons - 1
1531 WRITE (output_unit,
'(T3,A,T75,I6)')
"Number of explicit constraints: ", resp_env%ncons
1534 WRITE (output_unit,
'(T3,A,T75,I6)')
"Number of explicit restraints: ", resp_env%nrest_sec
1535 WRITE (output_unit,
'(T3,A,T80,A)')
"Constrain total charge ", merge(
"T",
"F", resp_env%itc)
1536 WRITE (output_unit,
'(T3,A,T80,A)')
"Restrain heavy atoms ", merge(
"T",
"F", resp_env%rheavies)
1537 IF (resp_env%rheavies)
THEN
1538 WRITE (output_unit,
'(T3,A,T71,F10.6)')
"Heavy atom restraint strength: ", &
1539 resp_env%rheavies_strength
1541 WRITE (output_unit,
'(T3,A,T66,3I5)')
"Stride: ", resp_env%stride
1542 IF (resp_env%molecular_sys)
THEN
1543 WRITE (output_unit,
'(T3,A)') &
1544 "------------------------------------------------------------------------------"
1545 WRITE (output_unit,
'(T3,A)')
"Using sphere sampling"
1546 WRITE (output_unit,
'(T3,A,T46,A,T66,A)') &
1547 "Element",
"RMIN [angstrom]",
"RMAX [angstrom]"
1548 DO ikind = 1, nkinds
1550 kind_number=kind_number, &
1551 element_symbol=symbol)
1552 WRITE (output_unit,
'(T3,A,T51,F10.5,T71,F10.5)') &
1554 resp_env%rmin_kind(kind_number)*conv, &
1555 resp_env%rmax_kind(kind_number)*conv
1558 WRITE (output_unit,
'(T3,A,T51,3F10.5)')
"Box min [angstrom]: ", resp_env%box_low(1:3)*conv
1559 WRITE (output_unit,
'(T3,A,T51,3F10.5)')
"Box max [angstrom]: ", resp_env%box_hi(1:3)*conv
1561 WRITE (output_unit,
'(T3,A)') &
1562 "------------------------------------------------------------------------------"
1564 WRITE (output_unit,
'(T3,A)') &
1565 "------------------------------------------------------------------------------"
1566 WRITE (output_unit,
'(T3,A)')
"Using slab sampling"
1567 WRITE (output_unit,
'(2X,A,F10.5)')
"Index of atoms defining the surface: "
1568 DO i = 1,
SIZE(rep_sys)
1569 IF (i > 1 .AND. all(rep_sys(i)%p_resp%atom_surf_list == rep_sys(1)%p_resp%atom_surf_list))
EXIT
1570 WRITE (output_unit,
'(7X,10I6)') rep_sys(i)%p_resp%atom_surf_list
1572 DO i = 1,
SIZE(rep_sys)
1573 IF (i > 1 .AND. all(rep_sys(i)%p_resp%range_surf == rep_sys(1)%p_resp%range_surf))
EXIT
1574 WRITE (output_unit,
'(T3,A,T61,2F10.5)') &
1575 "Range for sampling above the surface [angstrom]:", &
1576 rep_sys(i)%p_resp%range_surf(1:2)*conv
1578 DO i = 1,
SIZE(rep_sys)
1579 IF (i > 1 .AND. rep_sys(i)%p_resp%length == rep_sys(1)%p_resp%length)
EXIT
1580 WRITE (output_unit,
'(T3,A,T71,F10.5)')
"Length of sampling box above each"// &
1581 " surface atom [angstrom]: ", rep_sys(i)%p_resp%length*conv
1583 WRITE (output_unit,
'(T3,A)') &
1584 "------------------------------------------------------------------------------"
1587 WRITE (output_unit,
'(T3,A,T71,F10.5)')
"Width of Gaussian charge"// &
1588 " distribution [angstrom^-2]: ", eta_conv
1593 "PRINT%PROGRAM_RUN_INFO")
1595 CALL timestop(handle)
1597 END SUBROUTINE print_resp_parameter_info
1606 SUBROUTINE print_resp_charges(qs_env, resp_env, output_runinfo, natom)
1609 TYPE(resp_type),
POINTER :: resp_env
1610 INTEGER,
INTENT(IN) :: output_runinfo, natom
1612 CHARACTER(len=*),
PARAMETER :: routinen =
'print_resp_charges'
1614 CHARACTER(LEN=default_path_length) :: filename
1615 INTEGER :: handle, output_file
1618 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1621 CALL timeset(routinen, handle)
1623 NULLIFY (particle_set, qs_kind_set, input, logger, resp_section, print_key)
1625 CALL get_qs_env(qs_env, input=input, particle_set=particle_set, &
1626 qs_kind_set=qs_kind_set)
1630 "PRINT%RESP_CHARGES_TO_FILE")
1634 resp_section,
"PRINT%RESP_CHARGES_TO_FILE"), &
1637 "PRINT%RESP_CHARGES_TO_FILE", &
1638 extension=
".resp", &
1639 file_status=
"REPLACE", &
1640 file_action=
"WRITE", &
1641 file_form=
"FORMATTED")
1642 IF (output_file > 0)
THEN
1644 print_key, extension=
".resp", &
1648 IF (output_runinfo > 0)
WRITE (output_runinfo,
'(2X,A,/)')
"PRINTED RESP CHARGES TO FILE"
1652 "PRINT%RESP_CHARGES_TO_FILE")
1658 CALL timestop(handle)
1660 END SUBROUTINE print_resp_charges
1670 SUBROUTINE print_pot_from_resp_charges(qs_env, resp_env, particles, natom, output_runinfo)
1673 TYPE(resp_type),
POINTER :: resp_env
1675 INTEGER,
INTENT(IN) :: natom, output_runinfo
1677 CHARACTER(len=*),
PARAMETER :: routinen =
'print_pot_from_resp_charges'
1679 CHARACTER(LEN=default_path_length) :: my_pos_cube
1680 INTEGER :: handle, ip, jx, jy, jz, unit_nr
1681 LOGICAL :: append_cube, mpi_io
1682 REAL(kind=
dp) :: dvol, normalize_factor, rms, rrms, &
1683 sum_diff, sum_hartree, udvol
1694 CALL timeset(routinen, handle)
1696 NULLIFY (auxbas_pw_pool, logger, pw_env, poisson_env, input, print_key, &
1697 para_env, resp_section, v_hartree_rspace)
1700 para_env=para_env, &
1702 v_hartree_rspace=v_hartree_rspace)
1703 normalize_factor = sqrt((resp_env%eta/
pi)**3)
1706 "PRINT%V_RESP_CUBE")
1710 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1711 poisson_env=poisson_env)
1713 CALL auxbas_pw_pool%create_pw(rho_resp)
1714 CALL auxbas_pw_pool%create_pw(v_resp_gspace)
1715 CALL auxbas_pw_pool%create_pw(v_resp_rspace)
1719 resp_env%eta, qs_env)
1722 vhartree=v_resp_gspace)
1725 dvol = v_resp_rspace%pw_grid%dvol
1727 CALL pw_scale(v_resp_rspace, -normalize_factor)
1730 IF (resp_env%use_repeat_method)
THEN
1731 v_resp_rspace%array(:, :, :) = v_resp_rspace%array(:, :, :) - resp_env%offset*dvol
1733 CALL v_resp_gspace%release()
1734 CALL rho_resp%release()
1739 CALL auxbas_pw_pool%create_pw(aux_r)
1741 my_pos_cube =
"REWIND"
1742 IF (append_cube)
THEN
1743 my_pos_cube =
"APPEND"
1747 "PRINT%V_RESP_CUBE", &
1748 extension=
".cube", &
1749 file_position=my_pos_cube, &
1752 CALL pw_copy(v_resp_rspace, aux_r)
1754 CALL cp_pw_to_cube(aux_r, unit_nr,
"RESP POTENTIAL", particles=particles, &
1756 "PRINT%V_RESP_CUBE%STRIDE"), &
1759 "PRINT%V_RESP_CUBE", mpi_io=mpi_io)
1760 CALL auxbas_pw_pool%give_back_pw(aux_r)
1765 sum_hartree = 0.0_dp
1768 DO ip = 1, resp_env%npoints_proc
1769 jx = resp_env%fitpoints(1, ip)
1770 jy = resp_env%fitpoints(2, ip)
1771 jz = resp_env%fitpoints(3, ip)
1772 sum_diff = sum_diff + (v_hartree_rspace%array(jx, jy, jz) - &
1773 v_resp_rspace%array(jx, jy, jz))**2
1774 sum_hartree = sum_hartree + v_hartree_rspace%array(jx, jy, jz)**2
1776 CALL para_env%sum(sum_diff)
1777 CALL para_env%sum(sum_hartree)
1778 rms = sqrt(sum_diff/resp_env%npoints)
1779 rrms = sqrt(sum_diff/sum_hartree)
1780 IF (output_runinfo > 0)
THEN
1781 WRITE (output_runinfo,
'(2X,A,T69,ES12.5)')
"Root-mean-square (RMS) "// &
1782 "error of RESP fit:", rms
1783 WRITE (output_runinfo,
'(2X,A,T69,ES12.5,/)')
"Relative root-mean-square "// &
1784 "(RRMS) error of RESP fit:", rrms
1787 CALL v_resp_rspace%release()
1789 CALL timestop(handle)
1791 END SUBROUTINE print_pot_from_resp_charges
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
simple routine to print charges for all atomic charge methods (currently mulliken,...
subroutine, public print_atomic_charges(particle_set, qs_kind_set, scr, title, electronic_charges, atomic_charges)
generates a unified output format for atomic charges
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public golze2015
integer, save, public rappe1992
integer, save, public campana2009
Handles all functions related to the CELL.
integer, parameter, public use_perd_xyz
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
integer, parameter, public use_perd_none
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)
...
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...
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_pw_to_cube(pw, unit_nr, title, particles, zeff, stride, max_file_size_mb, zero_tails, silent, mpi_io)
...
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
real(kind=dp) function, public cp_unit_to_cp2k(value, unit_str, defaults, power)
converts to the internal cp2k units to the given unit
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Utility routines for the memory handling.
Interface to the message passing library MPI.
represent a simple array based list of the given type
Define the data structure for the particle information.
Periodic Table related data definitions.
subroutine, public get_ptable_info(symbol, number, amass, ielement, covalent_radius, metallic_radius, vdw_radius, found)
Pass information about the kind given the element symbol.
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 ...
Calculate the plane wave density by collocating the primitive Gaussian functions (pgf).
subroutine, public calculate_rho_resp_single(rho_gb, qs_env, eta, iatom_in)
collocate a single Gaussian on the grid for periodic RESP fitting
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.
subroutine, public set_qs_env(qs_env, super_cell, mos, qmmm, qmmm_periodic, mimic, ewald_env, ewald_pw, mpools, rho_external, external_vxc, mask, scf_control, rel_control, qs_charges, ks_env, ks_qmmm_env, wf_history, scf_env, active_space, input, oce, rho_atom_set, rho0_atom_set, rho0_mpole, run_rtp, rtp, rhoz_set, rhoz_tot, ecoul_1c, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, efield, rhoz_cneo_set, linres_control, xas_env, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, ls_scf_env, do_transport, transport_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, harris_env, gcp_env, mp2_env, bs_env, kg_env, force, kpoints, wanniercentres, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Set the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
provides a resp fit for gas phase systems
subroutine, public resp_fit(qs_env)
performs resp fit and generates RESP charges
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
provides a table for UFF vdW radii: Rappe et al. J. Am. Chem. Soc. 114, 10024 (1992)
pure subroutine, public get_uff_vdw_radius(z, radius, found)
get UFF vdW radius for a given element
Provides all information about an atomic kind.
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
represent a list of objects
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 ...
Provides all information about a quickstep kind.