90#include "./base/base_uses.f90"
96 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'eeq_method'
98 INTEGER,
PARAMETER :: maxElem = 86
101 REAL(KIND=
dp),
PARAMETER :: rcov(1:maxelem) = [&
102 & 0.32_dp, 0.46_dp, 1.20_dp, 0.94_dp, 0.77_dp, 0.75_dp, 0.71_dp, 0.63_dp, &
103 & 0.64_dp, 0.67_dp, 1.40_dp, 1.25_dp, 1.13_dp, 1.04_dp, 1.10_dp, 1.02_dp, &
104 & 0.99_dp, 0.96_dp, 1.76_dp, 1.54_dp, 1.33_dp, 1.22_dp, 1.21_dp, 1.10_dp, &
105 & 1.07_dp, 1.04_dp, 1.00_dp, 0.99_dp, 1.01_dp, 1.09_dp, 1.12_dp, 1.09_dp, &
106 & 1.15_dp, 1.10_dp, 1.14_dp, 1.17_dp, 1.89_dp, 1.67_dp, 1.47_dp, 1.39_dp, &
107 & 1.32_dp, 1.24_dp, 1.15_dp, 1.13_dp, 1.13_dp, 1.08_dp, 1.15_dp, 1.23_dp, &
108 & 1.28_dp, 1.26_dp, 1.26_dp, 1.23_dp, 1.32_dp, 1.31_dp, 2.09_dp, 1.76_dp, &
109 & 1.62_dp, 1.47_dp, 1.58_dp, 1.57_dp, 1.56_dp, 1.55_dp, 1.51_dp, 1.52_dp, &
110 & 1.51_dp, 1.50_dp, 1.49_dp, 1.49_dp, 1.48_dp, 1.53_dp, 1.46_dp, 1.37_dp, &
111 & 1.31_dp, 1.23_dp, 1.18_dp, 1.16_dp, 1.11_dp, 1.12_dp, 1.13_dp, 1.32_dp, &
112 & 1.30_dp, 1.30_dp, 1.36_dp, 1.31_dp, 1.38_dp, 1.42_dp]
129 INTEGER,
INTENT(IN) :: iounit, print_level
130 LOGICAL,
INTENT(IN) :: ext
132 CHARACTER(LEN=2) :: element_symbol
133 INTEGER :: enshift_type, iatom, ikind, natom
134 REAL(kind=
dp),
DIMENSION(:),
POINTER :: charges
139 mark_used(print_level)
141 CALL get_qs_env(qs_env, natom=natom, particle_set=particle_set, cell=cell)
145 cpassert(
ASSOCIATED(charges))
148 ALLOCATE (charges(natom))
153 CALL eeq_charges(qs_env, charges, eeq_sparam, 2, enshift_type)
158 IF (enshift_type == 0)
THEN
159 WRITE (unit=iounit, fmt=
"(/,T2,A)")
"EEQ Charges (External)"
160 ELSE IF (enshift_type == 1)
THEN
161 WRITE (unit=iounit, fmt=
"(/,T2,A)")
"EEQ Charges (Parametrization 2019 (Molecules))"
162 ELSE IF (enshift_type == 2)
THEN
163 WRITE (unit=iounit, fmt=
"(/,T2,A)")
"EEQ Charges (Parametrization 2019 (Crystals))"
165 cpabort(
"Unknown enshift_type")
167 WRITE (unit=iounit, fmt=
"(/,T2,A)") &
168 "# Atom Element Kind Atomic Charge"
172 element_symbol=element_symbol, &
174 WRITE (unit=iounit, fmt=
"(T4,I8,T18,A2,I10,T43,F12.4)") &
175 iatom, element_symbol, ikind, charges(iatom)
180 IF (.NOT. ext)
DEALLOCATE (charges)
192 SUBROUTINE eeq_charges(qs_env, charges, eeq_sparam, eeq_model, enshift_type)
195 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
197 INTEGER,
INTENT(IN) :: eeq_model, enshift_type
199 CHARACTER(len=*),
PARAMETER :: routinen =
'eeq_charges'
201 INTEGER :: handle, iatom, ikind, iunit, jkind, &
203 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of
204 INTEGER,
DIMENSION(3) :: periodic
206 REAL(kind=
dp) :: ala, alb, eeq_energy, esg, kappa, &
207 lambda, scn, sgamma, totalcharge, xi
208 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: chia, cnumbers, efr, gam
209 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: gab
211 TYPE(
cell_type),
POINTER :: cell, cell_ref
214 TYPE(
dcnum_type),
ALLOCATABLE,
DIMENSION(:) :: dcnum
220 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
224 CALL timeset(routinen, handle)
227 qs_kind_set=qs_kind_set, &
228 atomic_kind_set=atomic_kind_set, &
229 particle_set=particle_set, &
231 blacs_env=blacs_env, &
233 dft_control=dft_control)
234 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
237 IF (para_env%is_source() .AND. logger%iter_info%print_level >=
medium_print_level)
THEN
243 totalcharge = dft_control%charge
245 CALL get_cnumbers(qs_env, cnumbers, dcnum, .false.)
248 ALLOCATE (gab(nkind, nkind), gam(nkind))
253 CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
258 gab(ikind, jkind) = sqrt(1._dp/(ala*ala + alb*alb))
265 esg = 1.0_dp + exp(sgamma)
266 ALLOCATE (chia(natom))
269 ikind = kind_of(iatom)
273 IF (enshift_type == 1)
THEN
274 scn = cnumbers(iatom)/sqrt(cnumbers(iatom) + 1.0e-14_dp)
275 ELSE IF (enshift_type == 2)
THEN
276 scn = log(esg/(esg - cnumbers(iatom)))
278 cpabort(
"Unknown enshift_type")
280 chia(iatom) = xi - kappa*scn
285 IF (dft_control%apply_period_efield .OR. dft_control%apply_efield .OR. &
286 dft_control%apply_efield_field)
THEN
287 ALLOCATE (efr(natom))
288 efr(1:natom) = 0.0_dp
290 chia(1:natom) = chia(1:natom) + efr(1:natom)
296 CALL get_cell(cell, periodic=periodic)
297 do_ewald = .NOT. all(periodic == 0)
302 CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
307 silent=.true., pset=
"EEQ")
309 CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
311 CALL eeq_solver(charges, lambda, eeq_energy, &
312 particle_set, kind_of, cell, chia, gam, gab, &
313 para_env, blacs_env, dft_control, eeq_sparam, &
314 totalcharge=totalcharge, ewald=do_ewald, &
315 ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
319 DEALLOCATE (ewald_env, ewald_pw)
321 CALL eeq_solver(charges, lambda, eeq_energy, &
322 particle_set, kind_of, cell, chia, gam, gab, &
323 para_env, blacs_env, dft_control, eeq_sparam, &
324 totalcharge=totalcharge, iounit=iunit)
327 DEALLOCATE (gab, gam, chia)
329 CALL timestop(handle)
345 SUBROUTINE eeq_forces(qs_env, charges, dcharges, gradient, stress, &
346 eeq_sparam, eeq_model, enshift_type, response_only)
349 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges, dcharges
350 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: gradient
351 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(INOUT) :: stress
353 INTEGER,
INTENT(IN) :: eeq_model, enshift_type
354 LOGICAL,
INTENT(IN) :: response_only
356 CHARACTER(len=*),
PARAMETER :: routinen =
'eeq_forces'
358 INTEGER :: handle, i, ia, iatom, ikind, iunit, &
359 jatom, jkind, katom, natom, nkind, za, &
361 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of
362 INTEGER,
DIMENSION(3) :: periodic
363 LOGICAL :: do_ewald, use_virial
364 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: default_present
365 REAL(kind=
dp) :: ala, alb, alpha, cn, ctot, dr, dr2, drk, &
366 elag, esg, fe, gam2, gama, grc, kappa, &
367 qlam, qq, qq1, qq2, rcut, scn, sgamma, &
368 subcells, totalcharge, xi
369 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: c_radius, cnumbers, gam, qlag
370 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: epforce, gab, pair_radius
371 REAL(kind=
dp),
DIMENSION(3) :: fdik, ri, rij, rik, rj
372 REAL(kind=
dp),
DIMENSION(3, 3) :: pvir
373 REAL(kind=
dp),
DIMENSION(:),
POINTER :: chrgx, dchia
376 TYPE(
cell_type),
POINTER :: cell, cell_ref
379 TYPE(
dcnum_type),
ALLOCATABLE,
DIMENSION(:) :: dcnum
389 DIMENSION(:),
POINTER :: nl_iterator
394 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
399 CALL timeset(routinen, handle)
402 qs_kind_set=qs_kind_set, &
403 atomic_kind_set=atomic_kind_set, &
404 particle_set=particle_set, &
406 blacs_env=blacs_env, &
411 dft_control=dft_control)
414 IF (para_env%is_source() .AND. logger%iter_info%print_level >=
medium_print_level)
THEN
420 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
421 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
425 totalcharge = dft_control%charge
427 CALL get_cnumbers(qs_env, cnumbers, dcnum, .true.)
430 ALLOCATE (gab(nkind, nkind), gam(nkind))
435 CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
440 gab(ikind, jkind) = sqrt(1._dp/(ala*ala + alb*alb))
445 ALLOCATE (qlag(natom))
447 CALL get_cell(cell, periodic=periodic)
448 do_ewald = .NOT. all(periodic == 0)
453 CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
458 silent=.true., pset=
"EEQ")
460 CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
463 particle_set, kind_of, cell, -dcharges, gam, gab, &
464 para_env, blacs_env, dft_control, eeq_sparam, &
465 ewald=do_ewald, ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
468 particle_set, kind_of, cell, -dcharges, gam, gab, &
469 para_env, blacs_env, dft_control, eeq_sparam, iounit=iunit)
473 esg = 1.0_dp + exp(sgamma)
474 ALLOCATE (chrgx(natom), dchia(natom))
476 ikind = kind_of(iatom)
480 IF (response_only)
THEN
481 ctot = -0.5_dp*qlag(iatom)
483 ctot = 0.5_dp*(charges(iatom) - qlag(iatom))
485 IF (enshift_type == 1)
THEN
486 scn = sqrt(cnumbers(iatom)) + 1.0e-14_dp
487 dchia(iatom) = -ctot*kappa/scn
488 ELSE IF (enshift_type == 2)
THEN
490 scn = 1.0_dp/(esg - cn)
491 dchia(iatom) = -ctot*kappa*scn
493 cpabort(
"Unknown enshift_type")
498 IF (dft_control%apply_period_efield)
THEN
500 ELSE IF (dft_control%apply_efield)
THEN
502 ELSE IF (dft_control%apply_efield_field)
THEN
503 cpabort(
"apply field")
507 CALL get_qs_env(qs_env=qs_env, local_particles=local_particles)
509 DO ia = 1, local_particles%n_el(ikind)
510 iatom = local_particles%list(ikind)%array(ia)
511 DO i = 1, dcnum(iatom)%neighbors
512 katom = dcnum(iatom)%nlist(i)
513 rik = dcnum(iatom)%rik(:, i)
514 drk = sqrt(sum(rik(:)**2))
515 IF (drk > 1.e-3_dp)
THEN
516 fdik(:) = dchia(iatom)*dcnum(iatom)%dvals(i)*rik(:)/drk
517 gradient(:, iatom) = gradient(:, iatom) - fdik(:)
518 gradient(:, katom) = gradient(:, katom) + fdik(:)
532 distribution_2d=distribution_2d, &
533 local_particles=distribution_1d, &
534 molecule_set=molecule_set)
539 ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
541 default_present = .true.
542 ALLOCATE (atom2d(nkind))
543 CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
544 molecule_set, .false., particle_set=particle_set)
545 CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
547 subcells=subcells, operator_type=
"PP", nlname=
"sab_ew")
548 DEALLOCATE (c_radius, pair_radius, default_present)
554 iatom=iatom, jatom=jatom, r=rij)
558 IF (dr > rcut .OR. dr < 1.e-6_dp) cycle
560 IF (iatom == jatom) fe = 0.5_dp
561 IF (response_only)
THEN
562 qq = -qlag(iatom)*charges(jatom)
564 qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
566 gama = gab(ikind, jkind)
568 grc = 2._dp*gama*exp(-gam2*dr2)*
oorootpi/dr - erf(gama*dr)/dr2 &
569 - 2._dp*alpha*exp(-alpha**2*dr2)*
oorootpi/dr + erf(alpha*dr)/dr2
570 IF (response_only)
THEN
571 qq1 = -qlag(iatom)*charges(jatom)
572 qq2 = -qlag(jatom)*charges(iatom)
574 qq1 = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
575 qq2 = (0.5_dp*charges(jatom) - qlag(jatom))*charges(iatom)
577 fdik(:) = -qq1*grc*rij(:)/dr
578 gradient(:, iatom) = gradient(:, iatom) + fdik(:)
579 gradient(:, jatom) = gradient(:, jatom) - fdik(:)
583 fdik(:) = qq2*grc*rij(:)/dr
584 gradient(:, iatom) = gradient(:, iatom) - fdik(:)
585 gradient(:, jatom) = gradient(:, jatom) + fdik(:)
595 DO ia = 1, local_particles%n_el(ikind)
596 iatom = local_particles%list(ikind)%array(ia)
597 ri(1:3) = particle_set(iatom)%r(1:3)
599 IF (iatom == jatom) cycle
600 jkind = kind_of(jatom)
601 IF (response_only)
THEN
602 qq = -qlag(iatom)*charges(jatom)
604 qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
606 rj(1:3) = particle_set(jatom)%r(1:3)
607 rij(1:3) = ri(1:3) - rj(1:3)
611 gama = gab(ikind, jkind)
613 grc = 2._dp*gama*exp(-gam2*dr2)*
oorootpi/dr - erf(gama*dr)/dr2
614 fdik(:) = qq*grc*rij(:)/dr
615 gradient(:, iatom) = gradient(:, iatom) + fdik(:)
616 gradient(:, jatom) = gradient(:, jatom) - fdik(:)
624 ALLOCATE (epforce(3, natom))
626 IF (response_only)
THEN
627 dchia(1:natom) = qlag(1:natom)
629 dchia(1:natom) = -charges(1:natom) + qlag(1:natom)
631 chrgx(1:natom) = charges(1:natom)
632 CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
633 particle_set, dchia, epforce)
634 dchia(1:natom) = charges(1:natom)
635 chrgx(1:natom) = qlag(1:natom)
636 CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
637 particle_set, dchia, epforce)
638 gradient(1:3, 1:natom) = gradient(1:3, 1:natom) + epforce(1:3, 1:natom)
643 chrgx(1:natom) = charges(1:natom) - qlag(1:natom)
644 CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
645 stress = stress - pvir
646 chrgx(1:natom) = qlag(1:natom)
647 CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
648 stress = stress + pvir
649 IF (response_only)
THEN
650 chrgx(1:natom) = charges(1:natom)
651 CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
652 stress = stress + pvir
658 DEALLOCATE (ewald_env, ewald_pw)
663 DEALLOCATE (gab, gam, qlag, chrgx, dchia)
665 CALL timestop(handle)
676 SUBROUTINE get_cnumbers(qs_env, cnumbers, dcnum, calculate_forces)
679 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cnumbers
680 TYPE(
dcnum_type),
ALLOCATABLE,
DIMENSION(:) :: dcnum
681 LOGICAL,
INTENT(IN) :: calculate_forces
683 INTEGER :: ikind, natom, nkind, za
684 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: default_present
685 REAL(kind=
dp) :: subcells
686 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: c_radius
687 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pair_radius
698 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
701 qs_kind_set=qs_kind_set, &
702 atomic_kind_set=atomic_kind_set, &
703 particle_set=particle_set, &
705 distribution_2d=distribution_2d, &
706 local_particles=distribution_1d, &
707 molecule_set=molecule_set)
708 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
713 disp%k2 = 4._dp/3._dp
714 disp%eps_cn = 1.e-6_dp
715 disp%max_elem = maxelem
716 ALLOCATE (disp%rcov(maxelem))
717 disp%rcov(1:maxelem) =
bohr*disp%k2*rcov(1:maxelem)
721 ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
723 default_present = .true.
726 c_radius(ikind) = 4._dp*rcov(za)*
bohr
728 ALLOCATE (atom2d(nkind))
729 CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
730 molecule_set, .false., particle_set=particle_set)
731 CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
733 subcells=subcells, operator_type=
"PP", nlname=
"sab_cn")
734 disp%sab_cn => sab_cn
735 DEALLOCATE (c_radius, pair_radius, default_present)
739 CALL cnumber_init(qs_env, cnumbers, dcnum, 2, calculate_forces, disp_env=disp)
743 END SUBROUTINE get_cnumbers
766 SUBROUTINE eeq_solver(charges, lambda, eeq_energy, particle_set, kind_of, cell, &
767 chia, gam, gab, para_env, blacs_env, dft_control, eeq_sparam, &
768 totalcharge, ewald, ewald_env, ewald_pw, iounit)
770 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
771 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
772 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
773 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
775 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
776 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
781 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: totalcharge
782 LOGICAL,
INTENT(IN),
OPTIONAL :: ewald
785 INTEGER,
INTENT(IN),
OPTIONAL :: iounit
787 CHARACTER(len=*),
PARAMETER :: routinen =
'eeq_solver'
789 INTEGER :: handle, ierror, iunit, natom, nkind, ns
790 LOGICAL :: do_direct, do_displ, do_ewald, do_sparse
791 REAL(kind=
dp) :: alpha, deth, ftime, qtot
795 CALL timeset(routinen, handle)
798 IF (
PRESENT(ewald)) do_ewald = ewald
801 IF (
PRESENT(totalcharge)) qtot = totalcharge
804 IF (
PRESENT(iounit)) iunit = iounit
807 do_direct = eeq_sparam%direct
808 do_sparse = eeq_sparam%sparse
811 IF (dft_control%apply_period_efield .AND.
ASSOCIATED(dft_control%period_efield))
THEN
812 do_displ = dft_control%period_efield%displacement_field
817 CALL cp_abort(__location__,
"EEQ: Sparse option not yet available")
820 natom =
SIZE(particle_set)
824 nrow_global=ns, ncol_global=ns)
829 cpassert(
PRESENT(ewald_env))
830 cpassert(
PRESENT(ewald_pw))
835 CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
836 kind_of, cell, chia, gam, gab, qtot, &
837 ewald_env, ewald_pw, iounit)
844 CALL pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
845 kind_of, cell, chia, gam, gab, qtot, &
846 ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
847 IF (ierror /= 0)
THEN
849 CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
850 kind_of, cell, chia, gam, gab, qtot, &
851 ewald_env, ewald_pw, iounit)
855 IF (qtot /= 0._dp)
THEN
858 eeq_energy = eeq_energy - 0.5_dp*qtot**2/alpha**2/deth
861 CALL mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, &
862 cell, chia, gam, gab, qtot, ftime)
864 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Molecular solver time[s]", ftime
870 CALL timestop(handle)
889 SUBROUTINE mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, cell, &
890 chia, gam, gab, qtot, ftime)
892 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
893 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
895 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
896 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
898 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
899 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
900 REAL(kind=
dp),
INTENT(IN) :: qtot
901 REAL(kind=
dp),
INTENT(OUT) :: ftime
903 CHARACTER(len=*),
PARAMETER :: routinen =
'mi_solver'
905 INTEGER :: handle, ia, iac, iar, ic, ikind, ir, &
906 jkind, natom, ncloc, ncvloc, nkind, &
908 INTEGER,
DIMENSION(:),
POINTER :: cind, cvind, rind, rvind
909 REAL(kind=
dp) :: dr, grc, te, ti, xr
910 REAL(kind=
dp),
DIMENSION(3) :: ri, rij, rj
915 CALL timeset(routinen, handle)
918 natom =
SIZE(particle_set)
922 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
923 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
924 row_indices=rind, col_indices=cind)
926 nrow_global=ns, ncol_global=1)
928 CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
929 row_indices=rvind, col_indices=cvind)
936 IF (iar > natom) cycle
938 ri(1:3) = particle_set(iar)%r(1:3)
941 IF (iac > natom) cycle
943 rj(1:3) = particle_set(iac)%r(1:3)
945 grc = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi
947 rij(1:3) = ri(1:3) - rj(1:3)
949 dr = sqrt(sum(rij**2))
950 grc = erf(gab(ikind, jkind)*dr)/dr
952 eeq_mat%local_data(ir, ic) = grc
966 rhs_vec%local_data(ir, ic) = xr
979 IF (ia <= natom)
THEN
980 xr = rhs_vec%local_data(ir, ic)
983 lambda = rhs_vec%local_data(ir, ic)
987 CALL para_env%sum(lambda)
988 CALL para_env%sum(charges)
991 eeq_energy = 0.5*sum(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
998 CALL timestop(handle)
1000 END SUBROUTINE mi_solver
1021 SUBROUTINE pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
1022 kind_of, cell, chia, gam, gab, qtot, &
1023 ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
1025 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
1026 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
1028 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1029 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
1031 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
1032 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
1033 REAL(kind=
dp),
INTENT(IN) :: qtot
1037 INTEGER,
INTENT(OUT) :: ierror
1038 INTEGER,
OPTIONAL :: iounit
1040 CHARACTER(len=*),
PARAMETER :: routinen =
'pbc_solver'
1042 INTEGER :: ewald_type, handle, i, iac, iar, ic, ikind, info, ir, iunit, iv, ix, iy, iz, &
1043 jkind, max_diis, mdiis, natom, ncloc, ndiis, nkind, now, nrloc, ns, sdiis
1044 INTEGER,
DIMENSION(3) :: cvec, ncell, periodic
1045 INTEGER,
DIMENSION(:),
POINTER :: cind, rind
1046 REAL(kind=
dp) :: ad, alpha, astep, deth, dr, eeqn, &
1047 eps_diis, ftime, grc1, grc2, rcut, &
1048 res, resin, rmax, te, ti
1049 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: bvec, dvec
1050 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dmat, fvec, vmat, xvec
1051 REAL(kind=
dp),
DIMENSION(3) :: ri, rij, rijl, rj
1052 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1053 REAL(kind=
dp),
DIMENSION(:),
POINTER :: rhs, rv0, xv0
1058 CALL timeset(routinen, handle)
1064 IF (
PRESENT(iounit)) iunit = iounit
1066 natom =
SIZE(particle_set)
1069 CALL get_cell(cell=cell, deth=deth)
1070 CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
1073 CALL cp_abort(__location__,
"Only SPME Ewald method available with EEQ.")
1078 CALL get_cell(cell, h=hmat, periodic=periodic)
1082 IF (periodic(1) == 0) ncell(1) = 0
1083 IF (periodic(2) == 0) ncell(2) = 0
1084 IF (periodic(3) == 0) ncell(3) = 0
1086 CALL mi_solver(charges, lambda, eeqn, eeq_mat, particle_set, kind_of, cell, &
1087 chia, gam, gab, qtot, ftime)
1089 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Iterative PBC guess time[s]", ftime
1091 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
1096 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
1097 row_indices=rind, col_indices=cind)
1102 IF (iar <= natom)
THEN
1103 ikind = kind_of(iar)
1104 ri(1:3) = particle_set(iar)%r(1:3)
1108 IF (iac > natom .AND. iar > natom)
THEN
1109 eeq_mat%local_data(ir, ic) = 0.0_dp
1111 ELSE IF ((iac > natom) .OR. (iar > natom))
THEN
1112 eeq_mat%local_data(ir, ic) = 1.0_dp
1115 jkind = kind_of(iac)
1116 rj(1:3) = particle_set(iac)%r(1:3)
1117 rij(1:3) = ri(1:3) - rj(1:3)
1118 rij =
pbc(rij, cell)
1119 DO ix = -ncell(1), ncell(1)
1120 DO iy = -ncell(2), ncell(2)
1121 DO iz = -ncell(3), ncell(3)
1123 rijl = rij + matmul(hmat, cvec)
1124 dr = sqrt(sum(rijl**2))
1125 IF (dr > rmax) cycle
1126 IF (iar == iac .AND. dr < 0.00001_dp)
THEN
1127 grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi - ad
1129 grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
1131 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
1140 row_indices=rind, col_indices=cind)
1145 IF (iar <= natom)
THEN
1146 ikind = kind_of(iar)
1147 ri(1:3) = particle_set(iar)%r(1:3)
1151 IF (iac > natom .AND. iar > natom)
THEN
1152 pmat%local_data(ir, ic) = 0.0_dp
1154 ELSE IF ((iac > natom) .OR. (iar > natom))
THEN
1155 pmat%local_data(ir, ic) = 1.0_dp
1158 jkind = kind_of(iac)
1159 rj(1:3) = particle_set(iac)%r(1:3)
1160 rij(1:3) = ri(1:3) - rj(1:3)
1161 rij =
pbc(rij, cell)
1162 IF (iar == iac)
THEN
1163 grc2 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi
1165 grc2 = erf(gab(ikind, jkind)*dr)/dr
1167 pmat%local_data(ir, ic) = grc2
1177 rhs(1:natom) = chia(1:natom)
1180 ALLOCATE (xv0(ns), rv0(ns))
1182 xv0(1:natom) = charges(1:natom)
1185 max_diis = eeq_sparam%max_diis
1186 mdiis = eeq_sparam%mdiis
1187 sdiis = eeq_sparam%sdiis
1188 eps_diis = eeq_sparam%eps_diis
1189 astep = eeq_sparam%alpha
1190 ALLOCATE (xvec(ns, mdiis), fvec(ns, mdiis), bvec(ns))
1191 xvec = 0.0_dp; fvec = 0.0_dp
1192 ALLOCATE (vmat(mdiis, mdiis), dmat(mdiis + 1, mdiis + 1), dvec(mdiis + 1))
1193 dmat = 0.0_dp; dvec = 0.0_dp
1196 CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
1197 cell, particle_set, xv0, rhs, rv0)
1198 resin = sqrt(sum(rv0*rv0))
1201 res = sqrt(sum(rv0*rv0))
1202 IF (res > 10._dp*resin)
EXIT
1203 IF (res < eps_diis)
EXIT
1205 now = mod(iv - 1, mdiis) + 1
1206 ndiis = min(iv, mdiis)
1207 xvec(1:ns, now) = xv0(1:ns)
1208 fvec(1:ns, now) = rv0(1:ns)
1210 vmat(now, i) = sum(fvec(:, now)*fvec(:, i))
1211 vmat(i, now) = vmat(now, i)
1213 IF (ndiis < sdiis)
THEN
1214 xv0(1:ns) = xv0(1:ns) + astep*rv0(1:ns)
1217 dvec(ndiis + 1) = 1.0_dp
1218 dmat(1:ndiis, 1:ndiis) = vmat(1:ndiis, 1:ndiis)
1219 dmat(ndiis + 1, 1:ndiis) = 1.0_dp
1220 dmat(1:ndiis, ndiis + 1) = 1.0_dp
1221 dmat(ndiis + 1, ndiis + 1) = 0.0_dp
1222 CALL invmat(dmat(1:ndiis + 1, 1:ndiis + 1), info)
1223 dvec(1:ndiis + 1) = matmul(dmat(1:ndiis + 1, 1:ndiis + 1), dvec(1:ndiis + 1))
1224 xv0(1:ns) = matmul(xvec(1:ns, 1:ndiis), dvec(1:ndiis))
1225 xv0(1:ns) = xv0(1:ns) + matmul(fvec(1:ns, 1:ndiis), dvec(1:ndiis))
1228 CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
1229 cell, particle_set, xv0, rhs, rv0)
1231 charges(1:natom) = xv0(1:natom)
1234 IF (res > eps_diis) ierror = 1
1236 DEALLOCATE (xvec, fvec, bvec)
1237 DEALLOCATE (vmat, dmat, dvec)
1238 DEALLOCATE (xv0, rv0)
1245 IF (ierror == 1)
THEN
1246 WRITE (iunit,
'(A)')
" EEQ| PBC solver failed to converge "
1248 WRITE (iunit,
'(A,T50,I4,T61,E20.5)')
" EEQ| PBC solver: iterations/accuracy ", iv, res
1250 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Iterative PBC solver: time[s]", te - ti
1252 CALL timestop(handle)
1254 END SUBROUTINE pbc_solver
1273 SUBROUTINE fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
1274 kind_of, cell, chia, gam, gab, qtot, ewald_env, ewald_pw, iounit)
1276 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
1277 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
1279 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1280 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
1282 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
1283 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
1284 REAL(kind=
dp),
INTENT(IN) :: qtot
1287 INTEGER,
INTENT(IN),
OPTIONAL :: iounit
1289 CHARACTER(len=*),
PARAMETER :: routinen =
'fpbc_solver'
1291 INTEGER :: ewald_type, handle, ia, iac, iar, ic, &
1292 ikind, ir, iunit, ix, iy, iz, jkind, &
1293 natom, ncloc, ncvloc, nkind, nrloc, &
1295 INTEGER,
DIMENSION(3) :: cvec, ncell, periodic
1296 INTEGER,
DIMENSION(:),
POINTER :: cind, cvind, rind, rvind
1297 REAL(kind=
dp) :: ad, alpha, deth, dr, grc1, rcut, rmax, &
1299 REAL(kind=
dp),
DIMENSION(3) :: ri, rij, rijl, rj
1300 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1301 REAL(kind=
dp),
DIMENSION(:),
POINTER :: pval, xval
1306 CALL timeset(routinen, handle)
1310 IF (
PRESENT(iounit)) iunit = iounit
1312 natom =
SIZE(particle_set)
1316 CALL get_cell(cell=cell, deth=deth)
1317 CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
1320 CALL cp_abort(__location__,
"Only SPME Ewald method available with EEQ.")
1325 CALL get_cell(cell, h=hmat, periodic=periodic)
1329 IF (periodic(1) == 0) ncell(1) = 0
1330 IF (periodic(2) == 0) ncell(2) = 0
1331 IF (periodic(3) == 0) ncell(3) = 0
1333 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
1335 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
1336 row_indices=rind, col_indices=cind)
1338 nrow_global=ns, ncol_global=1)
1340 CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
1341 row_indices=rvind, col_indices=cvind)
1346 IF (iar <= natom)
THEN
1347 ikind = kind_of(iar)
1348 ri(1:3) = particle_set(iar)%r(1:3)
1352 IF (iac > natom .AND. iar > natom)
THEN
1353 eeq_mat%local_data(ir, ic) = 0.0_dp
1355 ELSE IF ((iac > natom) .OR. (iar > natom))
THEN
1356 eeq_mat%local_data(ir, ic) = 1.0_dp
1359 jkind = kind_of(iac)
1360 rj(1:3) = particle_set(iac)%r(1:3)
1361 rij(1:3) = ri(1:3) - rj(1:3)
1362 rij =
pbc(rij, cell)
1363 DO ix = -ncell(1), ncell(1)
1364 DO iy = -ncell(2), ncell(2)
1365 DO iz = -ncell(3), ncell(3)
1367 rijl = rij + matmul(hmat, cvec)
1368 dr = sqrt(sum(rijl**2))
1369 IF (dr > rmax) cycle
1370 IF (iar == iac .AND. dr < 0.0001_dp)
THEN
1371 grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi - ad
1373 grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
1375 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
1382 ALLOCATE (xval(natom), pval(natom))
1386 CALL apply_potential(ewald_env, ewald_pw, cell, particle_set, xval, pval)
1390 IF (iar /= ia) cycle
1393 IF (iac > natom) cycle
1394 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + pval(iac)
1398 DEALLOCATE (xval, pval)
1406 IF (ia > natom)
THEN
1411 rhs_vec%local_data(ir, ic) = xr
1424 IF (ia <= natom)
THEN
1425 xr = rhs_vec%local_data(ir, ic)
1428 lambda = rhs_vec%local_data(ir, ic)
1432 CALL para_env%sum(lambda)
1433 CALL para_env%sum(charges)
1436 eeq_energy = 0.5*sum(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
1443 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Direct PBC solver: time[s]", te - ti
1445 CALL timestop(handle)
1447 END SUBROUTINE fpbc_solver
1458 SUBROUTINE apply_potential(ewald_env, ewald_pw, cell, particle_set, charges, potential)
1462 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1463 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
POINTER :: charges
1464 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: potential
1470 CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges, &
1471 particle_set, potential)
1472 CALL para_env%sum(potential)
1474 END SUBROUTINE apply_potential
1489 SUBROUTINE get_energy_gradient(eeqn, fm_mat, mmat, ewald_env, ewald_pw, &
1490 cell, particle_set, charges, rhs, potential)
1491 REAL(kind=
dp),
INTENT(INOUT) :: eeqn
1496 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1497 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
POINTER :: charges
1498 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: rhs
1499 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: potential
1502 REAL(kind=
dp) :: lambda
1503 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: mvec
1510 CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges(1:na), &
1511 particle_set, potential(1:na))
1512 CALL para_env%sum(potential(1:na))
1513 CALL cp_fm_matvec(fm_mat, charges, potential, alpha=1.0_dp, beta=1.0_dp)
1514 eeqn = 0.5_dp*sum(charges(1:na)*potential(1:na)) + sum(charges(1:na)*rhs(1:na))
1515 potential(1:ns) = potential(1:ns) + rhs(1:ns)
1517 CALL cp_fm_matvec(mmat, potential, mvec, alpha=-1.0_dp, beta=0.0_dp)
1518 lambda = -sum(mvec(1:na))/real(na, kind=
dp)
1519 potential(1:na) = mvec(1:na) + lambda
1522 END SUBROUTINE get_energy_gradient
1532 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges
1533 REAL(kind=
dp),
INTENT(OUT) :: ef_energy
1535 COMPLEX(KIND=dp) :: zdeta
1536 COMPLEX(KIND=dp),
DIMENSION(3) :: zi
1537 INTEGER :: ia, idir, natom
1539 REAL(kind=
dp) :: kr, omega, q
1540 REAL(kind=
dp),
DIMENSION(3) :: ci, dfilter, fieldpol, fpolvec, kvec, &
1542 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1547 CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
1548 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1550 IF (dft_control%apply_period_efield)
THEN
1551 dfield = dft_control%period_efield%displacement_field
1553 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1554 cpabort(
"use of strength_list not implemented for eeq_efield_energy")
1557 fieldpol = dft_control%period_efield%polarisation
1558 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1559 fieldpol = -fieldpol*dft_control%period_efield%strength
1560 hmat = cell%hmat(:, :)/
twopi
1562 fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
1563 + fieldpol(3)*hmat(3, idir)
1566 zi(:) = cmplx(1._dp, 0._dp,
dp)
1569 ria = particle_set(ia)%r
1570 ria =
pbc(ria, cell)
1572 kvec(:) =
twopi*cell%h_inv(idir, :)
1573 kr = sum(kvec(:)*ria(:))
1574 zdeta = cmplx(cos(kr), sin(kr), kind=
dp)**q
1575 zi(idir) = zi(idir)*zdeta
1580 dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
1582 ci = matmul(hmat, qi)/omega
1585 ef_energy = ef_energy + dfilter(idir)*(fieldpol(idir) - 2._dp*
twopi*ci(idir))**2
1587 ef_energy = -0.25_dp*omega/
twopi*ef_energy
1589 ef_energy = sum(fpolvec(:)*qi(:))
1592 ELSE IF (dft_control%apply_efield)
THEN
1594 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1595 dft_control%efield_fields(1)%efield%strength
1599 ria = particle_set(ia)%r
1600 ria =
pbc(ria, cell)
1602 ef_energy = ef_energy - q*sum(fieldpol*ria)
1606 cpabort(
"apply field")
1618 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: efr
1620 INTEGER :: ia, idir, natom
1623 REAL(kind=
dp),
DIMENSION(3) :: fieldpol, fpolvec, kvec, ria
1624 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1629 CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
1630 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1632 IF (dft_control%apply_period_efield)
THEN
1633 dfield = dft_control%period_efield%displacement_field
1635 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1636 cpabort(
"use of strength_list not implemented for eeq_efield_pot")
1639 fieldpol = dft_control%period_efield%polarisation
1640 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1641 fieldpol = -fieldpol*dft_control%period_efield%strength
1642 hmat = cell%hmat(:, :)/
twopi
1644 fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
1645 + fieldpol(3)*hmat(3, idir)
1654 ria = particle_set(ia)%r
1655 ria =
pbc(ria, cell)
1657 kvec(:) =
twopi*cell%h_inv(idir, :)
1658 kr = sum(kvec(:)*ria(:))
1659 efr(ia) = efr(ia) + kr*fpolvec(idir)
1664 ELSE IF (dft_control%apply_efield)
THEN
1666 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1667 dft_control%efield_fields(1)%efield%strength
1670 ria = particle_set(ia)%r
1671 ria =
pbc(ria, cell)
1672 efr(ia) = -sum(fieldpol*ria)
1676 cpabort(
"apply field")
1689 SUBROUTINE eeq_dfield_pot(charges, dft_control, particle_set, cell, efr)
1690 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges
1692 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1694 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: efr
1696 COMPLEX(KIND=dp) :: zdeta
1697 COMPLEX(KIND=dp),
DIMENSION(3) :: zi
1698 INTEGER :: ia, idir, natom
1699 REAL(kind=
dp) :: kr, omega, q
1700 REAL(kind=
dp),
DIMENSION(3) :: ci, dfilter, fieldpol, kvec, qi, ria
1701 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1703 natom =
SIZE(particle_set)
1705 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1706 cpabort(
"use of strength_list not implemented for eeq_dfield_pot")
1709 dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
1710 fieldpol = dft_control%period_efield%polarisation
1711 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1712 fieldpol = -fieldpol*dft_control%period_efield%strength
1713 hmat = cell%hmat(:, :)/
twopi
1716 zi(:) = cmplx(1._dp, 0._dp,
dp)
1719 ria = particle_set(ia)%r
1720 ria =
pbc(ria, cell)
1722 kvec(:) =
twopi*cell%h_inv(idir, :)
1723 kr = sum(kvec(:)*ria(:))
1724 zdeta = cmplx(cos(kr), sin(kr), kind=
dp)**q
1725 zi(idir) = zi(idir)*zdeta
1729 ci = matmul(hmat, qi)/omega
1730 ci = dfilter*(fieldpol - 2._dp*
twopi*ci)
1732 ria = particle_set(ia)%r
1733 ria =
pbc(ria, cell)
1734 efr(ia) = efr(ia) - sum(ci*ria)
1737 END SUBROUTINE eeq_dfield_pot
1747 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges, qlag
1749 INTEGER :: atom_a, ia, iatom, ikind, natom, nkind
1750 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind
1752 REAL(kind=
dp),
DIMENSION(3) :: fieldpol
1762 dft_control=dft_control, &
1763 cell=cell, particle_set=particle_set, &
1764 nkind=nkind, natom=natom, &
1765 para_env=para_env, &
1766 local_particles=local_particles)
1768 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1769 dft_control%efield_fields(1)%efield%strength
1771 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1776 force(ikind)%efield = 0.0_dp
1777 DO ia = 1, local_particles%n_el(ikind)
1778 iatom = local_particles%list(ikind)%array(ia)
1779 q = charges(iatom) - qlag(iatom)
1780 atom_a = atom_of_kind(iatom)
1781 force(ikind)%efield(1:3, atom_a) = -q*fieldpol(1:3)
1783 CALL para_env%sum(force(ikind)%efield)
1796 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges, qlag
1798 INTEGER :: atom_a, ia, iatom, ikind, natom, nkind
1799 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind
1800 LOGICAL :: dfield, use_virial
1802 REAL(kind=
dp),
DIMENSION(3) :: fa, fieldpol, ria
1803 REAL(kind=
dp),
DIMENSION(3, 3) :: pve
1814 dft_control=dft_control, &
1815 cell=cell, particle_set=particle_set, &
1817 nkind=nkind, natom=natom, &
1818 para_env=para_env, &
1819 local_particles=local_particles)
1821 dfield = dft_control%period_efield%displacement_field
1822 cpassert(.NOT. dfield)
1824 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1825 cpabort(
"use of strength_list not implemented for eeq_efield_force_periodic")
1828 fieldpol = dft_control%period_efield%polarisation
1829 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1830 fieldpol = -fieldpol*dft_control%period_efield%strength
1832 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1834 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1840 force(ikind)%efield = 0.0_dp
1841 DO ia = 1, local_particles%n_el(ikind)
1842 iatom = local_particles%list(ikind)%array(ia)
1843 q = charges(iatom) - qlag(iatom)
1844 fa(1:3) = q*fieldpol(1:3)
1845 atom_a = atom_of_kind(iatom)
1846 force(ikind)%efield(1:3, atom_a) = fa
1847 IF (use_virial)
THEN
1848 ria = particle_set(ia)%r
1849 ria =
pbc(ria, cell)
1854 CALL para_env%sum(force(ikind)%efield)
1856 virial%pv_virial = virial%pv_virial + pve
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
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.
Holds information on atomic properties.
Handles all functions related to the CELL.
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
real(kind=dp) function, public plane_distance(h, k, l, cell)
Calculate the distance between two lattice planes as defined by a triple of Miller indices (hkl).
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_solve(matrix_a, general_a)
computes the the solution to A*b=A_general using lu decomposition
subroutine, public cp_fm_invert(matrix_a, matrix_inverse, det_a, eps_svd, eigval)
Inverts a cp_fm_type matrix, optionally returning the determinant of the input matrix.
subroutine, public cp_fm_matvec(amat, xv, yv, alpha, beta)
Calculates yv = alpha*amat*xv + beta*yv where amat: fm matrix xv : vector replicated yv : vector repl...
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
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, parameter, public medium_print_level
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
EEQ data from different sources.
subroutine, public get_eeq_data(za, model, chi, eta, kcn, rad)
...
Calculation of charge equilibration method.
subroutine, public eeq_forces(qs_env, charges, dcharges, gradient, stress, eeq_sparam, eeq_model, enshift_type, response_only)
...
subroutine, public eeq_efield_energy(qs_env, charges, ef_energy)
...
subroutine, public eeq_efield_force_periodic(qs_env, charges, qlag)
...
subroutine, public eeq_efield_pot(qs_env, efr)
...
subroutine, public eeq_charges(qs_env, charges, eeq_sparam, eeq_model, enshift_type)
...
subroutine, public eeq_print(qs_env, iounit, print_level, ext)
...
subroutine, public eeq_efield_force_loc(qs_env, charges, qlag)
...
subroutine, public eeq_solver(charges, lambda, eeq_energy, particle_set, kind_of, cell, chia, gam, gab, para_env, blacs_env, dft_control, eeq_sparam, totalcharge, ewald, ewald_env, ewald_pw, iounit)
...
subroutine, public ewald_env_set(ewald_env, ewald_type, alpha, epsilon, eps_pol, gmax, ns_max, precs, o_spline, para_env, poisson_section, interaction_cutoffs, cell_hmat)
Purpose: Set the EWALD environment.
subroutine, public ewald_env_create(ewald_env, para_env)
allocates and intitializes a ewald_env
subroutine, public ewald_env_release(ewald_env)
releases the given ewald_env (see doc/ReferenceCounting.html)
subroutine, public read_ewald_section_tb(ewald_env, ewald_section, hmat, silent, pset)
Purpose: read the EWALD section for TB methods.
subroutine, public ewald_env_get(ewald_env, ewald_type, alpha, eps_pol, epsilon, gmax, ns_max, o_spline, group, para_env, poisson_section, precs, rcut, do_multipoles, max_multipole, do_ipol, max_ipol_iter, interaction_cutoffs, cell_hmat)
Purpose: Get the EWALD environment.
subroutine, public ewald_pw_release(ewald_pw)
releases the memory used by the ewald_pw
subroutine, public ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section)
creates the structure ewald_pw_type
Defines the basic variable types.
integer, parameter, public dp
Machine interface based on Fortran 2003 and POSIX.
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition of mathematical constants and functions.
real(kind=dp), parameter, public oorootpi
real(kind=dp), parameter, public twopi
Collection of simple mathematical functions and subroutines.
subroutine, public invmat(a, info)
returns inverse of matrix using the lapack routines DGETRF and DGETRI
Interface to the message passing library MPI.
Define the data structure for the molecule information.
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public bohr
functions related to the poisson solver on regular grids
integer, parameter, public do_ewald_spme
Coordination number routines for dispersion pairpotentials.
subroutine, public cnumber_release(cnumbers, dcnum, derivatives)
...
subroutine, public cnumber_init(qs_env, cnumbers, dcnum, ftype, derivatives, disp_env)
...
Definition of disperson types for DFT calculations.
subroutine, public qs_dispersion_release(dispersion_env)
...
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, 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.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Define the neighbor list data types and the corresponding functionality.
subroutine, public release_neighbor_list_sets(nlists)
releases an array of neighbor_list_sets
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_set)
...
integer function, public neighbor_list_iterate(iterator_set, mepos)
...
subroutine, public get_iterator_info(iterator_set, mepos, ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
...
Generate the atomic neighbor lists.
subroutine, public atom2d_cleanup(atom2d)
free the internals of atom2d
subroutine, public pair_radius_setup(present_a, present_b, radius_a, radius_b, pair_radius, prmin)
...
subroutine, public build_neighbor_lists(ab_list, particle_set, atom, cell, pair_radius, subcells, mic, symmetric, molecular, subset_of_mol, current_subset, operator_type, nlname, atomb_to_keep)
Build simple pair neighbor lists.
subroutine, public atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, molecule_set, molecule_only, particle_set)
Build some distribution structure of atoms, refactored from build_qs_neighbor_lists.
Calculate the electrostatic energy by the Smooth Particle Ewald method.
subroutine, public spme_forces(ewald_env, ewald_pw, box, particle_set_a, charges_a, particle_set_b, charges_b, forces_b)
Calculate the forces on particles B for the electrostatic interaction betrween particles A and B.
subroutine, public spme_potential(ewald_env, ewald_pw, box, particle_set_a, charges_a, particle_set_b, potential)
Calculate the electrostatic potential from particles A (charge A) at positions of particles B.
subroutine, public spme_virial(ewald_env, ewald_pw, particle_set, box, mcharge, virial)
Internal Virial for 1/2 [rho||rho] (rho=mcharge)
pure subroutine, public virial_pair_force(pv_virial, f0, force, rab)
Computes the contribution to the stress tensor from two-body pair-wise forces.
Provides all information about an atomic kind.
type for the atomic properties
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
structure to store local (to a processor) ordered lists of integers.
distributes pairs on a 2d grid of processors
to build arrays of pointers
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.