87#include "./base/base_uses.f90"
93 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'eeq_method'
95 INTEGER,
PARAMETER :: maxElem = 86
98 REAL(KIND=
dp),
PARAMETER :: rcov(1:maxelem) = [&
99 & 0.32_dp, 0.46_dp, 1.20_dp, 0.94_dp, 0.77_dp, 0.75_dp, 0.71_dp, 0.63_dp, &
100 & 0.64_dp, 0.67_dp, 1.40_dp, 1.25_dp, 1.13_dp, 1.04_dp, 1.10_dp, 1.02_dp, &
101 & 0.99_dp, 0.96_dp, 1.76_dp, 1.54_dp, 1.33_dp, 1.22_dp, 1.21_dp, 1.10_dp, &
102 & 1.07_dp, 1.04_dp, 1.00_dp, 0.99_dp, 1.01_dp, 1.09_dp, 1.12_dp, 1.09_dp, &
103 & 1.15_dp, 1.10_dp, 1.14_dp, 1.17_dp, 1.89_dp, 1.67_dp, 1.47_dp, 1.39_dp, &
104 & 1.32_dp, 1.24_dp, 1.15_dp, 1.13_dp, 1.13_dp, 1.08_dp, 1.15_dp, 1.23_dp, &
105 & 1.28_dp, 1.26_dp, 1.26_dp, 1.23_dp, 1.32_dp, 1.31_dp, 2.09_dp, 1.76_dp, &
106 & 1.62_dp, 1.47_dp, 1.58_dp, 1.57_dp, 1.56_dp, 1.55_dp, 1.51_dp, 1.52_dp, &
107 & 1.51_dp, 1.50_dp, 1.49_dp, 1.49_dp, 1.48_dp, 1.53_dp, 1.46_dp, 1.37_dp, &
108 & 1.31_dp, 1.23_dp, 1.18_dp, 1.16_dp, 1.11_dp, 1.12_dp, 1.13_dp, 1.32_dp, &
109 & 1.30_dp, 1.30_dp, 1.36_dp, 1.31_dp, 1.38_dp, 1.42_dp]
126 INTEGER,
INTENT(IN) :: iounit, print_level
127 LOGICAL,
INTENT(IN) :: ext
129 CHARACTER(LEN=2) :: element_symbol
130 INTEGER :: enshift_type, iatom, ikind, natom
131 REAL(kind=
dp),
DIMENSION(:),
POINTER :: charges
136 mark_used(print_level)
138 CALL get_qs_env(qs_env, natom=natom, particle_set=particle_set, cell=cell)
142 cpassert(
ASSOCIATED(charges))
145 ALLOCATE (charges(natom))
150 CALL eeq_charges(qs_env, charges, eeq_sparam, 2, enshift_type)
155 IF (enshift_type == 0)
THEN
156 WRITE (unit=iounit, fmt=
"(/,T2,A)")
"EEQ Charges (External)"
157 ELSE IF (enshift_type == 1)
THEN
158 WRITE (unit=iounit, fmt=
"(/,T2,A)")
"EEQ Charges (Parametrization 2019 (Molecules))"
159 ELSE IF (enshift_type == 2)
THEN
160 WRITE (unit=iounit, fmt=
"(/,T2,A)")
"EEQ Charges (Parametrization 2019 (Crystals))"
162 cpabort(
"Unknown enshift_type")
164 WRITE (unit=iounit, fmt=
"(/,T2,A)") &
165 "# Atom Element Kind Atomic Charge"
169 element_symbol=element_symbol, &
171 WRITE (unit=iounit, fmt=
"(T4,I8,T18,A2,I10,T43,F12.4)") &
172 iatom, element_symbol, ikind, charges(iatom)
177 IF (.NOT. ext)
DEALLOCATE (charges)
189 SUBROUTINE eeq_charges(qs_env, charges, eeq_sparam, eeq_model, enshift_type)
192 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
194 INTEGER,
INTENT(IN) :: eeq_model, enshift_type
196 CHARACTER(len=*),
PARAMETER :: routinen =
'eeq_charges'
198 INTEGER :: handle, iatom, ikind, iunit, jkind, &
200 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of
201 INTEGER,
DIMENSION(3) :: periodic
203 REAL(kind=
dp) :: ala, alb, eeq_energy, esg, kappa, &
204 lambda, scn, sgamma, totalcharge, xi
205 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: chia, cnumbers, efr, gam
206 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: gab
208 TYPE(
cell_type),
POINTER :: cell, cell_ref
210 TYPE(
dcnum_type),
ALLOCATABLE,
DIMENSION(:) :: dcnum
216 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
220 CALL timeset(routinen, handle)
225 qs_kind_set=qs_kind_set, &
226 atomic_kind_set=atomic_kind_set, &
227 particle_set=particle_set, &
229 blacs_env=blacs_env, &
231 dft_control=dft_control)
232 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
234 totalcharge = dft_control%charge
236 CALL get_cnumbers(qs_env, cnumbers, dcnum, .false.)
239 ALLOCATE (gab(nkind, nkind), gam(nkind))
244 CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
249 gab(ikind, jkind) = sqrt(1._dp/(ala*ala + alb*alb))
256 esg = 1.0_dp + exp(sgamma)
257 ALLOCATE (chia(natom))
260 ikind = kind_of(iatom)
264 IF (enshift_type == 1)
THEN
265 scn = cnumbers(iatom)/sqrt(cnumbers(iatom) + 1.0e-14_dp)
266 ELSE IF (enshift_type == 2)
THEN
267 scn = log(esg/(esg - cnumbers(iatom)))
269 cpabort(
"Unknown enshift_type")
271 chia(iatom) = xi - kappa*scn
276 IF (dft_control%apply_period_efield .OR. dft_control%apply_efield .OR. &
277 dft_control%apply_efield_field)
THEN
278 ALLOCATE (efr(natom))
279 efr(1:natom) = 0.0_dp
281 chia(1:natom) = chia(1:natom) + efr(1:natom)
287 CALL get_cell(cell, periodic=periodic)
288 do_ewald = .NOT. all(periodic == 0)
293 CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
298 silent=.true., pset=
"EEQ")
300 CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
302 CALL eeq_solver(charges, lambda, eeq_energy, &
303 particle_set, kind_of, cell, chia, gam, gab, &
304 para_env, blacs_env, dft_control, eeq_sparam, &
305 totalcharge=totalcharge, ewald=do_ewald, &
306 ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
310 DEALLOCATE (ewald_env, ewald_pw)
312 CALL eeq_solver(charges, lambda, eeq_energy, &
313 particle_set, kind_of, cell, chia, gam, gab, &
314 para_env, blacs_env, dft_control, eeq_sparam, &
315 totalcharge=totalcharge, iounit=iunit)
318 DEALLOCATE (gab, gam, chia)
320 CALL timestop(handle)
336 SUBROUTINE eeq_forces(qs_env, charges, dcharges, gradient, stress, &
337 eeq_sparam, eeq_model, enshift_type, response_only)
340 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges, dcharges
341 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: gradient
342 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(INOUT) :: stress
344 INTEGER,
INTENT(IN) :: eeq_model, enshift_type
345 LOGICAL,
INTENT(IN) :: response_only
347 CHARACTER(len=*),
PARAMETER :: routinen =
'eeq_forces'
349 INTEGER :: handle, i, ia, iatom, ikind, iunit, &
350 jatom, jkind, katom, natom, nkind, za, &
352 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of
353 INTEGER,
DIMENSION(3) :: periodic
354 LOGICAL :: do_ewald, use_virial
355 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: default_present
356 REAL(kind=
dp) :: ala, alb, alpha, cn, ctot, dr, dr2, drk, &
357 elag, esg, fe, gam2, gama, grc, kappa, &
358 qlam, qq, qq1, qq2, rcut, scn, sgamma, &
359 subcells, totalcharge, xi
360 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: c_radius, cnumbers, gam, qlag
361 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: epforce, gab, pair_radius
362 REAL(kind=
dp),
DIMENSION(3) :: fdik, ri, rij, rik, rj
363 REAL(kind=
dp),
DIMENSION(3, 3) :: pvir
364 REAL(kind=
dp),
DIMENSION(:),
POINTER :: chrgx, dchia
367 TYPE(
cell_type),
POINTER :: cell, cell_ref
369 TYPE(
dcnum_type),
ALLOCATABLE,
DIMENSION(:) :: dcnum
379 DIMENSION(:),
POINTER :: nl_iterator
384 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
389 CALL timeset(routinen, handle)
394 qs_kind_set=qs_kind_set, &
395 atomic_kind_set=atomic_kind_set, &
396 particle_set=particle_set, &
398 blacs_env=blacs_env, &
403 dft_control=dft_control)
404 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
405 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
409 totalcharge = dft_control%charge
411 CALL get_cnumbers(qs_env, cnumbers, dcnum, .true.)
414 ALLOCATE (gab(nkind, nkind), gam(nkind))
419 CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
424 gab(ikind, jkind) = sqrt(1._dp/(ala*ala + alb*alb))
429 ALLOCATE (qlag(natom))
431 CALL get_cell(cell, periodic=periodic)
432 do_ewald = .NOT. all(periodic == 0)
437 CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
442 silent=.true., pset=
"EEQ")
444 CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
447 particle_set, kind_of, cell, -dcharges, gam, gab, &
448 para_env, blacs_env, dft_control, eeq_sparam, &
449 ewald=do_ewald, ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
452 particle_set, kind_of, cell, -dcharges, gam, gab, &
453 para_env, blacs_env, dft_control, eeq_sparam, iounit=iunit)
457 esg = 1.0_dp + exp(sgamma)
458 ALLOCATE (chrgx(natom), dchia(natom))
460 ikind = kind_of(iatom)
464 IF (response_only)
THEN
465 ctot = -0.5_dp*qlag(iatom)
467 ctot = 0.5_dp*(charges(iatom) - qlag(iatom))
469 IF (enshift_type == 1)
THEN
470 scn = sqrt(cnumbers(iatom)) + 1.0e-14_dp
471 dchia(iatom) = -ctot*kappa/scn
472 ELSE IF (enshift_type == 2)
THEN
474 scn = 1.0_dp/(esg - cn)
475 dchia(iatom) = -ctot*kappa*scn
477 cpabort(
"Unknown enshift_type")
482 IF (dft_control%apply_period_efield)
THEN
484 ELSE IF (dft_control%apply_efield)
THEN
486 ELSE IF (dft_control%apply_efield_field)
THEN
487 cpabort(
"apply field")
491 CALL get_qs_env(qs_env=qs_env, local_particles=local_particles)
493 DO ia = 1, local_particles%n_el(ikind)
494 iatom = local_particles%list(ikind)%array(ia)
495 DO i = 1, dcnum(iatom)%neighbors
496 katom = dcnum(iatom)%nlist(i)
497 rik = dcnum(iatom)%rik(:, i)
498 drk = sqrt(sum(rik(:)**2))
499 IF (drk > 1.e-3_dp)
THEN
500 fdik(:) = dchia(iatom)*dcnum(iatom)%dvals(i)*rik(:)/drk
501 gradient(:, iatom) = gradient(:, iatom) - fdik(:)
502 gradient(:, katom) = gradient(:, katom) + fdik(:)
516 distribution_2d=distribution_2d, &
517 local_particles=distribution_1d, &
518 molecule_set=molecule_set)
523 ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
525 default_present = .true.
526 ALLOCATE (atom2d(nkind))
527 CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
528 molecule_set, .false., particle_set=particle_set)
529 CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
531 subcells=subcells, operator_type=
"PP", nlname=
"sab_ew")
532 DEALLOCATE (c_radius, pair_radius, default_present)
538 iatom=iatom, jatom=jatom, r=rij)
542 IF (dr > rcut .OR. dr < 1.e-6_dp) cycle
544 IF (iatom == jatom) fe = 0.5_dp
545 IF (response_only)
THEN
546 qq = -qlag(iatom)*charges(jatom)
548 qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
550 gama = gab(ikind, jkind)
552 grc = 2._dp*gama*exp(-gam2*dr2)*
oorootpi/dr - erf(gama*dr)/dr2 &
553 - 2._dp*alpha*exp(-alpha**2*dr2)*
oorootpi/dr + erf(alpha*dr)/dr2
554 IF (response_only)
THEN
555 qq1 = -qlag(iatom)*charges(jatom)
556 qq2 = -qlag(jatom)*charges(iatom)
558 qq1 = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
559 qq2 = (0.5_dp*charges(jatom) - qlag(jatom))*charges(iatom)
561 fdik(:) = -qq1*grc*rij(:)/dr
562 gradient(:, iatom) = gradient(:, iatom) + fdik(:)
563 gradient(:, jatom) = gradient(:, jatom) - fdik(:)
567 fdik(:) = qq2*grc*rij(:)/dr
568 gradient(:, iatom) = gradient(:, iatom) - fdik(:)
569 gradient(:, jatom) = gradient(:, jatom) + fdik(:)
579 DO ia = 1, local_particles%n_el(ikind)
580 iatom = local_particles%list(ikind)%array(ia)
581 ri(1:3) = particle_set(iatom)%r(1:3)
583 IF (iatom == jatom) cycle
584 jkind = kind_of(jatom)
585 IF (response_only)
THEN
586 qq = -qlag(iatom)*charges(jatom)
588 qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
590 rj(1:3) = particle_set(jatom)%r(1:3)
591 rij(1:3) = ri(1:3) - rj(1:3)
595 gama = gab(ikind, jkind)
597 grc = 2._dp*gama*exp(-gam2*dr2)*
oorootpi/dr - erf(gama*dr)/dr2
598 fdik(:) = qq*grc*rij(:)/dr
599 gradient(:, iatom) = gradient(:, iatom) + fdik(:)
600 gradient(:, jatom) = gradient(:, jatom) - fdik(:)
608 ALLOCATE (epforce(3, natom))
610 IF (response_only)
THEN
611 dchia(1:natom) = qlag(1:natom)
613 dchia(1:natom) = -charges(1:natom) + qlag(1:natom)
615 chrgx(1:natom) = charges(1:natom)
616 CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
617 particle_set, dchia, epforce)
618 dchia(1:natom) = charges(1:natom)
619 chrgx(1:natom) = qlag(1:natom)
620 CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
621 particle_set, dchia, epforce)
622 gradient(1:3, 1:natom) = gradient(1:3, 1:natom) + epforce(1:3, 1:natom)
627 chrgx(1:natom) = charges(1:natom) - qlag(1:natom)
628 CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
629 stress = stress - pvir
630 chrgx(1:natom) = qlag(1:natom)
631 CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
632 stress = stress + pvir
633 IF (response_only)
THEN
634 chrgx(1:natom) = charges(1:natom)
635 CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
636 stress = stress + pvir
642 DEALLOCATE (ewald_env, ewald_pw)
647 DEALLOCATE (gab, gam, qlag, chrgx, dchia)
649 CALL timestop(handle)
660 SUBROUTINE get_cnumbers(qs_env, cnumbers, dcnum, calculate_forces)
663 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cnumbers
664 TYPE(
dcnum_type),
ALLOCATABLE,
DIMENSION(:) :: dcnum
665 LOGICAL,
INTENT(IN) :: calculate_forces
667 INTEGER :: ikind, natom, nkind, za
668 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: default_present
669 REAL(kind=
dp) :: subcells
670 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: c_radius
671 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: pair_radius
682 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
685 qs_kind_set=qs_kind_set, &
686 atomic_kind_set=atomic_kind_set, &
687 particle_set=particle_set, &
689 distribution_2d=distribution_2d, &
690 local_particles=distribution_1d, &
691 molecule_set=molecule_set)
692 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
697 disp%k2 = 4._dp/3._dp
698 disp%eps_cn = 1.e-6_dp
699 disp%max_elem = maxelem
700 ALLOCATE (disp%rcov(maxelem))
701 disp%rcov(1:maxelem) =
bohr*disp%k2*rcov(1:maxelem)
705 ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
707 default_present = .true.
710 c_radius(ikind) = 4._dp*rcov(za)*
bohr
712 ALLOCATE (atom2d(nkind))
713 CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
714 molecule_set, .false., particle_set=particle_set)
715 CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
717 subcells=subcells, operator_type=
"PP", nlname=
"sab_cn")
718 disp%sab_cn => sab_cn
719 DEALLOCATE (c_radius, pair_radius, default_present)
723 CALL cnumber_init(qs_env, cnumbers, dcnum, 2, calculate_forces, disp_env=disp)
727 END SUBROUTINE get_cnumbers
750 SUBROUTINE eeq_solver(charges, lambda, eeq_energy, particle_set, kind_of, cell, &
751 chia, gam, gab, para_env, blacs_env, dft_control, eeq_sparam, &
752 totalcharge, ewald, ewald_env, ewald_pw, iounit)
754 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
755 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
756 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
757 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
759 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
760 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
765 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: totalcharge
766 LOGICAL,
INTENT(IN),
OPTIONAL :: ewald
769 INTEGER,
INTENT(IN),
OPTIONAL :: iounit
771 CHARACTER(len=*),
PARAMETER :: routinen =
'eeq_solver'
773 INTEGER :: handle, ierror, iunit, natom, nkind, ns
774 LOGICAL :: do_direct, do_displ, do_ewald, do_sparse
775 REAL(kind=
dp) :: alpha, deth, ftime, qtot
779 CALL timeset(routinen, handle)
782 IF (
PRESENT(ewald)) do_ewald = ewald
785 IF (
PRESENT(totalcharge)) qtot = totalcharge
788 IF (
PRESENT(iounit)) iunit = iounit
791 do_direct = eeq_sparam%direct
792 do_sparse = eeq_sparam%sparse
795 IF (dft_control%apply_period_efield .AND.
ASSOCIATED(dft_control%period_efield))
THEN
796 do_displ = dft_control%period_efield%displacement_field
801 CALL cp_abort(__location__,
"EEQ: Sparse option not yet available")
804 natom =
SIZE(particle_set)
808 nrow_global=ns, ncol_global=ns)
813 cpassert(
PRESENT(ewald_env))
814 cpassert(
PRESENT(ewald_pw))
819 CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
820 kind_of, cell, chia, gam, gab, qtot, &
821 ewald_env, ewald_pw, iounit)
828 CALL pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
829 kind_of, cell, chia, gam, gab, qtot, &
830 ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
831 IF (ierror /= 0)
THEN
833 CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
834 kind_of, cell, chia, gam, gab, qtot, &
835 ewald_env, ewald_pw, iounit)
839 IF (qtot /= 0._dp)
THEN
842 eeq_energy = eeq_energy - 0.5_dp*qtot**2/alpha**2/deth
845 CALL mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, &
846 cell, chia, gam, gab, qtot, ftime)
848 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Molecular solver time[s]", ftime
854 CALL timestop(handle)
873 SUBROUTINE mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, cell, &
874 chia, gam, gab, qtot, ftime)
876 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
877 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
879 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
880 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
882 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
883 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
884 REAL(kind=
dp),
INTENT(IN) :: qtot
885 REAL(kind=
dp),
INTENT(OUT) :: ftime
887 CHARACTER(len=*),
PARAMETER :: routinen =
'mi_solver'
889 INTEGER :: handle, ia, iac, iar, ic, ikind, ir, &
890 jkind, natom, ncloc, ncvloc, nkind, &
892 INTEGER,
DIMENSION(:),
POINTER :: cind, cvind, rind, rvind
893 REAL(kind=
dp) :: dr, grc, te, ti, xr
894 REAL(kind=
dp),
DIMENSION(3) :: ri, rij, rj
899 CALL timeset(routinen, handle)
902 natom =
SIZE(particle_set)
906 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
907 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
908 row_indices=rind, col_indices=cind)
910 nrow_global=ns, ncol_global=1)
912 CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
913 row_indices=rvind, col_indices=cvind)
920 IF (iar > natom) cycle
922 ri(1:3) = particle_set(iar)%r(1:3)
925 IF (iac > natom) cycle
927 rj(1:3) = particle_set(iac)%r(1:3)
929 grc = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi
931 rij(1:3) = ri(1:3) - rj(1:3)
933 dr = sqrt(sum(rij**2))
934 grc = erf(gab(ikind, jkind)*dr)/dr
936 eeq_mat%local_data(ir, ic) = grc
950 rhs_vec%local_data(ir, ic) = xr
963 IF (ia <= natom)
THEN
964 xr = rhs_vec%local_data(ir, ic)
967 lambda = rhs_vec%local_data(ir, ic)
971 CALL para_env%sum(lambda)
972 CALL para_env%sum(charges)
975 eeq_energy = 0.5*sum(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
982 CALL timestop(handle)
984 END SUBROUTINE mi_solver
1005 SUBROUTINE pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
1006 kind_of, cell, chia, gam, gab, qtot, &
1007 ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
1009 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
1010 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
1012 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1013 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
1015 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
1016 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
1017 REAL(kind=
dp),
INTENT(IN) :: qtot
1021 INTEGER,
INTENT(OUT) :: ierror
1022 INTEGER,
OPTIONAL :: iounit
1024 CHARACTER(len=*),
PARAMETER :: routinen =
'pbc_solver'
1026 INTEGER :: ewald_type, handle, i, iac, iar, ic, ikind, info, ir, iunit, iv, ix, iy, iz, &
1027 jkind, max_diis, mdiis, natom, ncloc, ndiis, nkind, now, nrloc, ns, sdiis
1028 INTEGER,
DIMENSION(3) :: cvec, ncell, periodic
1029 INTEGER,
DIMENSION(:),
POINTER :: cind, rind
1030 REAL(kind=
dp) :: ad, alpha, astep, deth, dr, eeqn, &
1031 eps_diis, ftime, grc1, grc2, rcut, &
1032 res, resin, rmax, te, ti
1033 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: bvec, dvec
1034 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dmat, fvec, vmat, xvec
1035 REAL(kind=
dp),
DIMENSION(3) :: ri, rij, rijl, rj
1036 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1037 REAL(kind=
dp),
DIMENSION(:),
POINTER :: rhs, rv0, xv0
1042 CALL timeset(routinen, handle)
1048 IF (
PRESENT(iounit)) iunit = iounit
1050 natom =
SIZE(particle_set)
1053 CALL get_cell(cell=cell, deth=deth)
1054 CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
1057 CALL cp_abort(__location__,
"Only SPME Ewald method available with EEQ.")
1062 CALL get_cell(cell, h=hmat, periodic=periodic)
1066 IF (periodic(1) == 0) ncell(1) = 0
1067 IF (periodic(2) == 0) ncell(2) = 0
1068 IF (periodic(3) == 0) ncell(3) = 0
1070 CALL mi_solver(charges, lambda, eeqn, eeq_mat, particle_set, kind_of, cell, &
1071 chia, gam, gab, qtot, ftime)
1073 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Iterative PBC guess time[s]", ftime
1075 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
1080 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
1081 row_indices=rind, col_indices=cind)
1086 IF (iar <= natom)
THEN
1087 ikind = kind_of(iar)
1088 ri(1:3) = particle_set(iar)%r(1:3)
1092 IF (iac > natom .AND. iar > natom)
THEN
1093 eeq_mat%local_data(ir, ic) = 0.0_dp
1095 ELSE IF ((iac > natom) .OR. (iar > natom))
THEN
1096 eeq_mat%local_data(ir, ic) = 1.0_dp
1099 jkind = kind_of(iac)
1100 rj(1:3) = particle_set(iac)%r(1:3)
1101 rij(1:3) = ri(1:3) - rj(1:3)
1102 rij =
pbc(rij, cell)
1103 DO ix = -ncell(1), ncell(1)
1104 DO iy = -ncell(2), ncell(2)
1105 DO iz = -ncell(3), ncell(3)
1107 rijl = rij + matmul(hmat, cvec)
1108 dr = sqrt(sum(rijl**2))
1109 IF (dr > rmax) cycle
1110 IF (iar == iac .AND. dr < 0.00001_dp)
THEN
1111 grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi - ad
1113 grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
1115 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
1124 row_indices=rind, col_indices=cind)
1129 IF (iar <= natom)
THEN
1130 ikind = kind_of(iar)
1131 ri(1:3) = particle_set(iar)%r(1:3)
1135 IF (iac > natom .AND. iar > natom)
THEN
1136 pmat%local_data(ir, ic) = 0.0_dp
1138 ELSE IF ((iac > natom) .OR. (iar > natom))
THEN
1139 pmat%local_data(ir, ic) = 1.0_dp
1142 jkind = kind_of(iac)
1143 rj(1:3) = particle_set(iac)%r(1:3)
1144 rij(1:3) = ri(1:3) - rj(1:3)
1145 rij =
pbc(rij, cell)
1146 IF (iar == iac)
THEN
1147 grc2 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi
1149 grc2 = erf(gab(ikind, jkind)*dr)/dr
1151 pmat%local_data(ir, ic) = grc2
1161 rhs(1:natom) = chia(1:natom)
1164 ALLOCATE (xv0(ns), rv0(ns))
1166 xv0(1:natom) = charges(1:natom)
1169 max_diis = eeq_sparam%max_diis
1170 mdiis = eeq_sparam%mdiis
1171 sdiis = eeq_sparam%sdiis
1172 eps_diis = eeq_sparam%eps_diis
1173 astep = eeq_sparam%alpha
1174 ALLOCATE (xvec(ns, mdiis), fvec(ns, mdiis), bvec(ns))
1175 xvec = 0.0_dp; fvec = 0.0_dp
1176 ALLOCATE (vmat(mdiis, mdiis), dmat(mdiis + 1, mdiis + 1), dvec(mdiis + 1))
1177 dmat = 0.0_dp; dvec = 0.0_dp
1180 CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
1181 cell, particle_set, xv0, rhs, rv0)
1182 resin = sqrt(sum(rv0*rv0))
1185 res = sqrt(sum(rv0*rv0))
1186 IF (res > 10._dp*resin)
EXIT
1187 IF (res < eps_diis)
EXIT
1189 now = mod(iv - 1, mdiis) + 1
1190 ndiis = min(iv, mdiis)
1191 xvec(1:ns, now) = xv0(1:ns)
1192 fvec(1:ns, now) = rv0(1:ns)
1194 vmat(now, i) = sum(fvec(:, now)*fvec(:, i))
1195 vmat(i, now) = vmat(now, i)
1197 IF (ndiis < sdiis)
THEN
1198 xv0(1:ns) = xv0(1:ns) + astep*rv0(1:ns)
1201 dvec(ndiis + 1) = 1.0_dp
1202 dmat(1:ndiis, 1:ndiis) = vmat(1:ndiis, 1:ndiis)
1203 dmat(ndiis + 1, 1:ndiis) = 1.0_dp
1204 dmat(1:ndiis, ndiis + 1) = 1.0_dp
1205 dmat(ndiis + 1, ndiis + 1) = 0.0_dp
1206 CALL invmat(dmat(1:ndiis + 1, 1:ndiis + 1), info)
1207 dvec(1:ndiis + 1) = matmul(dmat(1:ndiis + 1, 1:ndiis + 1), dvec(1:ndiis + 1))
1208 xv0(1:ns) = matmul(xvec(1:ns, 1:ndiis), dvec(1:ndiis))
1209 xv0(1:ns) = xv0(1:ns) + matmul(fvec(1:ns, 1:ndiis), dvec(1:ndiis))
1212 CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
1213 cell, particle_set, xv0, rhs, rv0)
1215 charges(1:natom) = xv0(1:natom)
1218 IF (res > eps_diis) ierror = 1
1220 DEALLOCATE (xvec, fvec, bvec)
1221 DEALLOCATE (vmat, dmat, dvec)
1222 DEALLOCATE (xv0, rv0)
1229 IF (ierror == 1)
THEN
1230 WRITE (iunit,
'(A)')
" EEQ| PBC solver failed to converge "
1232 WRITE (iunit,
'(A,T50,I4,T61,E20.5)')
" EEQ| PBC solver: iterations/accuracy ", iv, res
1234 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Iterative PBC solver: time[s]", te - ti
1236 CALL timestop(handle)
1238 END SUBROUTINE pbc_solver
1257 SUBROUTINE fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
1258 kind_of, cell, chia, gam, gab, qtot, ewald_env, ewald_pw, iounit)
1260 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
1261 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
1263 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1264 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
1266 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
1267 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
1268 REAL(kind=
dp),
INTENT(IN) :: qtot
1271 INTEGER,
INTENT(IN),
OPTIONAL :: iounit
1273 CHARACTER(len=*),
PARAMETER :: routinen =
'fpbc_solver'
1275 INTEGER :: ewald_type, handle, ia, iac, iar, ic, &
1276 ikind, ir, iunit, ix, iy, iz, jkind, &
1277 natom, ncloc, ncvloc, nkind, nrloc, &
1279 INTEGER,
DIMENSION(3) :: cvec, ncell, periodic
1280 INTEGER,
DIMENSION(:),
POINTER :: cind, cvind, rind, rvind
1281 REAL(kind=
dp) :: ad, alpha, deth, dr, grc1, rcut, rmax, &
1283 REAL(kind=
dp),
DIMENSION(3) :: ri, rij, rijl, rj
1284 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1285 REAL(kind=
dp),
DIMENSION(:),
POINTER :: pval, xval
1290 CALL timeset(routinen, handle)
1294 IF (
PRESENT(iounit)) iunit = iounit
1296 natom =
SIZE(particle_set)
1300 CALL get_cell(cell=cell, deth=deth)
1301 CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
1304 CALL cp_abort(__location__,
"Only SPME Ewald method available with EEQ.")
1309 CALL get_cell(cell, h=hmat, periodic=periodic)
1313 IF (periodic(1) == 0) ncell(1) = 0
1314 IF (periodic(2) == 0) ncell(2) = 0
1315 IF (periodic(3) == 0) ncell(3) = 0
1317 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
1319 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
1320 row_indices=rind, col_indices=cind)
1322 nrow_global=ns, ncol_global=1)
1324 CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
1325 row_indices=rvind, col_indices=cvind)
1330 IF (iar <= natom)
THEN
1331 ikind = kind_of(iar)
1332 ri(1:3) = particle_set(iar)%r(1:3)
1336 IF (iac > natom .AND. iar > natom)
THEN
1337 eeq_mat%local_data(ir, ic) = 0.0_dp
1339 ELSE IF ((iac > natom) .OR. (iar > natom))
THEN
1340 eeq_mat%local_data(ir, ic) = 1.0_dp
1343 jkind = kind_of(iac)
1344 rj(1:3) = particle_set(iac)%r(1:3)
1345 rij(1:3) = ri(1:3) - rj(1:3)
1346 rij =
pbc(rij, cell)
1347 DO ix = -ncell(1), ncell(1)
1348 DO iy = -ncell(2), ncell(2)
1349 DO iz = -ncell(3), ncell(3)
1351 rijl = rij + matmul(hmat, cvec)
1352 dr = sqrt(sum(rijl**2))
1353 IF (dr > rmax) cycle
1354 IF (iar == iac .AND. dr < 0.0001_dp)
THEN
1355 grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi - ad
1357 grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
1359 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
1366 ALLOCATE (xval(natom), pval(natom))
1370 CALL apply_potential(ewald_env, ewald_pw, cell, particle_set, xval, pval)
1374 IF (iar /= ia) cycle
1377 IF (iac > natom) cycle
1378 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + pval(iac)
1382 DEALLOCATE (xval, pval)
1390 IF (ia > natom)
THEN
1395 rhs_vec%local_data(ir, ic) = xr
1408 IF (ia <= natom)
THEN
1409 xr = rhs_vec%local_data(ir, ic)
1412 lambda = rhs_vec%local_data(ir, ic)
1416 CALL para_env%sum(lambda)
1417 CALL para_env%sum(charges)
1420 eeq_energy = 0.5*sum(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
1427 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Direct PBC solver: time[s]", te - ti
1429 CALL timestop(handle)
1431 END SUBROUTINE fpbc_solver
1442 SUBROUTINE apply_potential(ewald_env, ewald_pw, cell, particle_set, charges, potential)
1446 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1447 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
POINTER :: charges
1448 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: potential
1454 CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges, &
1455 particle_set, potential)
1456 CALL para_env%sum(potential)
1458 END SUBROUTINE apply_potential
1473 SUBROUTINE get_energy_gradient(eeqn, fm_mat, mmat, ewald_env, ewald_pw, &
1474 cell, particle_set, charges, rhs, potential)
1475 REAL(kind=
dp),
INTENT(INOUT) :: eeqn
1480 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1481 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
POINTER :: charges
1482 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: rhs
1483 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: potential
1486 REAL(kind=
dp) :: lambda
1487 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: mvec
1494 CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges(1:na), &
1495 particle_set, potential(1:na))
1496 CALL para_env%sum(potential(1:na))
1497 CALL cp_fm_matvec(fm_mat, charges, potential, alpha=1.0_dp, beta=1.0_dp)
1498 eeqn = 0.5_dp*sum(charges(1:na)*potential(1:na)) + sum(charges(1:na)*rhs(1:na))
1499 potential(1:ns) = potential(1:ns) + rhs(1:ns)
1501 CALL cp_fm_matvec(mmat, potential, mvec, alpha=-1.0_dp, beta=0.0_dp)
1502 lambda = -sum(mvec(1:na))/real(na, kind=
dp)
1503 potential(1:na) = mvec(1:na) + lambda
1506 END SUBROUTINE get_energy_gradient
1516 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges
1517 REAL(kind=
dp),
INTENT(OUT) :: ef_energy
1519 COMPLEX(KIND=dp) :: zdeta
1520 COMPLEX(KIND=dp),
DIMENSION(3) :: zi
1521 INTEGER :: ia, idir, natom
1523 REAL(kind=
dp) :: kr, omega, q
1524 REAL(kind=
dp),
DIMENSION(3) :: ci, dfilter, fieldpol, fpolvec, kvec, &
1526 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1531 CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
1532 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1534 IF (dft_control%apply_period_efield)
THEN
1535 dfield = dft_control%period_efield%displacement_field
1537 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1538 cpabort(
"use of strength_list not implemented for eeq_efield_energy")
1541 fieldpol = dft_control%period_efield%polarisation
1542 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1543 fieldpol = -fieldpol*dft_control%period_efield%strength
1544 hmat = cell%hmat(:, :)/
twopi
1546 fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
1547 + fieldpol(3)*hmat(3, idir)
1550 zi(:) = cmplx(1._dp, 0._dp,
dp)
1553 ria = particle_set(ia)%r
1554 ria =
pbc(ria, cell)
1556 kvec(:) =
twopi*cell%h_inv(idir, :)
1557 kr = sum(kvec(:)*ria(:))
1558 zdeta = cmplx(cos(kr), sin(kr), kind=
dp)**q
1559 zi(idir) = zi(idir)*zdeta
1564 dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
1566 ci = matmul(hmat, qi)/omega
1569 ef_energy = ef_energy + dfilter(idir)*(fieldpol(idir) - 2._dp*
twopi*ci(idir))**2
1571 ef_energy = -0.25_dp*omega/
twopi*ef_energy
1573 ef_energy = sum(fpolvec(:)*qi(:))
1576 ELSE IF (dft_control%apply_efield)
THEN
1578 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1579 dft_control%efield_fields(1)%efield%strength
1583 ria = particle_set(ia)%r
1584 ria =
pbc(ria, cell)
1586 ef_energy = ef_energy - q*sum(fieldpol*ria)
1590 cpabort(
"apply field")
1602 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: efr
1604 INTEGER :: ia, idir, natom
1607 REAL(kind=
dp),
DIMENSION(3) :: fieldpol, fpolvec, kvec, ria
1608 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1613 CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
1614 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1616 IF (dft_control%apply_period_efield)
THEN
1617 dfield = dft_control%period_efield%displacement_field
1619 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1620 cpabort(
"use of strength_list not implemented for eeq_efield_pot")
1623 fieldpol = dft_control%period_efield%polarisation
1624 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1625 fieldpol = -fieldpol*dft_control%period_efield%strength
1626 hmat = cell%hmat(:, :)/
twopi
1628 fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
1629 + fieldpol(3)*hmat(3, idir)
1638 ria = particle_set(ia)%r
1639 ria =
pbc(ria, cell)
1641 kvec(:) =
twopi*cell%h_inv(idir, :)
1642 kr = sum(kvec(:)*ria(:))
1643 efr(ia) = efr(ia) + kr*fpolvec(idir)
1648 ELSE IF (dft_control%apply_efield)
THEN
1650 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1651 dft_control%efield_fields(1)%efield%strength
1654 ria = particle_set(ia)%r
1655 ria =
pbc(ria, cell)
1656 efr(ia) = -sum(fieldpol*ria)
1660 cpabort(
"apply field")
1673 SUBROUTINE eeq_dfield_pot(charges, dft_control, particle_set, cell, efr)
1674 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges
1676 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1678 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: efr
1680 COMPLEX(KIND=dp) :: zdeta
1681 COMPLEX(KIND=dp),
DIMENSION(3) :: zi
1682 INTEGER :: ia, idir, natom
1683 REAL(kind=
dp) :: kr, omega, q
1684 REAL(kind=
dp),
DIMENSION(3) :: ci, dfilter, fieldpol, kvec, qi, ria
1685 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1687 natom =
SIZE(particle_set)
1689 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1690 cpabort(
"use of strength_list not implemented for eeq_dfield_pot")
1693 dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
1694 fieldpol = dft_control%period_efield%polarisation
1695 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1696 fieldpol = -fieldpol*dft_control%period_efield%strength
1697 hmat = cell%hmat(:, :)/
twopi
1700 zi(:) = cmplx(1._dp, 0._dp,
dp)
1703 ria = particle_set(ia)%r
1704 ria =
pbc(ria, cell)
1706 kvec(:) =
twopi*cell%h_inv(idir, :)
1707 kr = sum(kvec(:)*ria(:))
1708 zdeta = cmplx(cos(kr), sin(kr), kind=
dp)**q
1709 zi(idir) = zi(idir)*zdeta
1713 ci = matmul(hmat, qi)/omega
1714 ci = dfilter*(fieldpol - 2._dp*
twopi*ci)
1716 ria = particle_set(ia)%r
1717 ria =
pbc(ria, cell)
1718 efr(ia) = efr(ia) - sum(ci*ria)
1721 END SUBROUTINE eeq_dfield_pot
1731 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges, qlag
1733 INTEGER :: atom_a, ia, iatom, ikind, natom, nkind
1734 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind
1736 REAL(kind=
dp),
DIMENSION(3) :: fieldpol
1746 dft_control=dft_control, &
1747 cell=cell, particle_set=particle_set, &
1748 nkind=nkind, natom=natom, &
1749 para_env=para_env, &
1750 local_particles=local_particles)
1752 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1753 dft_control%efield_fields(1)%efield%strength
1755 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1760 force(ikind)%efield = 0.0_dp
1761 DO ia = 1, local_particles%n_el(ikind)
1762 iatom = local_particles%list(ikind)%array(ia)
1763 q = charges(iatom) - qlag(iatom)
1764 atom_a = atom_of_kind(iatom)
1765 force(ikind)%efield(1:3, atom_a) = -q*fieldpol(1:3)
1767 CALL para_env%sum(force(ikind)%efield)
1780 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges, qlag
1782 INTEGER :: atom_a, ia, iatom, ikind, natom, nkind
1783 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind
1784 LOGICAL :: dfield, use_virial
1786 REAL(kind=
dp),
DIMENSION(3) :: fa, fieldpol, ria
1787 REAL(kind=
dp),
DIMENSION(3, 3) :: pve
1798 dft_control=dft_control, &
1799 cell=cell, particle_set=particle_set, &
1801 nkind=nkind, natom=natom, &
1802 para_env=para_env, &
1803 local_particles=local_particles)
1805 dfield = dft_control%period_efield%displacement_field
1806 cpassert(.NOT. dfield)
1808 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1809 cpabort(
"use of strength_list not implemented for eeq_efield_force_periodic")
1812 fieldpol = dft_control%period_efield%polarisation
1813 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1814 fieldpol = -fieldpol*dft_control%period_efield%strength
1816 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1818 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1824 force(ikind)%efield = 0.0_dp
1825 DO ia = 1, local_particles%n_el(ikind)
1826 iatom = local_particles%list(ikind)%array(ia)
1827 q = charges(iatom) - qlag(iatom)
1828 fa(1:3) = q*fieldpol(1:3)
1829 atom_a = atom_of_kind(iatom)
1830 force(ikind)%efield(1:3, atom_a) = fa
1831 IF (use_virial)
THEN
1832 ria = particle_set(ia)%r
1833 ria =
pbc(ria, cell)
1838 CALL para_env%sum(force(ikind)%efield)
1840 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_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
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
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, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, 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, 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, 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
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.