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_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
796 CALL cp_abort(__location__,
"EEQ: Sparse option not yet available")
799 natom =
SIZE(particle_set)
803 nrow_global=ns, ncol_global=ns)
808 cpassert(
PRESENT(ewald_env))
809 cpassert(
PRESENT(ewald_pw))
811 IF (dft_control%apply_period_efield .AND. dft_control%period_efield%displacement_field)
THEN
814 CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
815 kind_of, cell, chia, gam, gab, qtot, &
816 ewald_env, ewald_pw, iounit)
819 IF (dft_control%apply_period_efield .AND. dft_control%period_efield%displacement_field)
THEN
823 CALL pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
824 kind_of, cell, chia, gam, gab, qtot, &
825 ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
826 IF (ierror /= 0)
THEN
828 CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
829 kind_of, cell, chia, gam, gab, qtot, &
830 ewald_env, ewald_pw, iounit)
834 IF (qtot /= 0._dp)
THEN
837 eeq_energy = eeq_energy - 0.5_dp*qtot**2/alpha**2/deth
840 CALL mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, &
841 cell, chia, gam, gab, qtot, ftime)
843 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Molecular solver time[s]", ftime
849 CALL timestop(handle)
868 SUBROUTINE mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, cell, &
869 chia, gam, gab, qtot, ftime)
871 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
872 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
874 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
875 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
877 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
878 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
879 REAL(kind=
dp),
INTENT(IN) :: qtot
880 REAL(kind=
dp),
INTENT(OUT) :: ftime
882 CHARACTER(len=*),
PARAMETER :: routinen =
'mi_solver'
884 INTEGER :: handle, ia, iac, iar, ic, ikind, ir, &
885 jkind, natom, ncloc, ncvloc, nkind, &
887 INTEGER,
DIMENSION(:),
POINTER :: cind, cvind, rind, rvind
888 REAL(kind=
dp) :: dr, grc, te, ti, xr
889 REAL(kind=
dp),
DIMENSION(3) :: ri, rij, rj
894 CALL timeset(routinen, handle)
897 natom =
SIZE(particle_set)
901 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
902 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
903 row_indices=rind, col_indices=cind)
905 nrow_global=ns, ncol_global=1)
907 CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
908 row_indices=rvind, col_indices=cvind)
915 IF (iar > natom) cycle
917 ri(1:3) = particle_set(iar)%r(1:3)
920 IF (iac > natom) cycle
922 rj(1:3) = particle_set(iac)%r(1:3)
924 grc = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi
926 rij(1:3) = ri(1:3) - rj(1:3)
928 dr = sqrt(sum(rij**2))
929 grc = erf(gab(ikind, jkind)*dr)/dr
931 eeq_mat%local_data(ir, ic) = grc
945 rhs_vec%local_data(ir, ic) = xr
958 IF (ia <= natom)
THEN
959 xr = rhs_vec%local_data(ir, ic)
962 lambda = rhs_vec%local_data(ir, ic)
966 CALL para_env%sum(lambda)
967 CALL para_env%sum(charges)
970 eeq_energy = 0.5*sum(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
977 CALL timestop(handle)
979 END SUBROUTINE mi_solver
1000 SUBROUTINE pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
1001 kind_of, cell, chia, gam, gab, qtot, &
1002 ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
1004 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
1005 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
1007 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1008 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
1010 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
1011 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
1012 REAL(kind=
dp),
INTENT(IN) :: qtot
1016 INTEGER,
INTENT(OUT) :: ierror
1017 INTEGER,
OPTIONAL :: iounit
1019 CHARACTER(len=*),
PARAMETER :: routinen =
'pbc_solver'
1021 INTEGER :: ewald_type, handle, i, iac, iar, ic, ikind, info, ir, iunit, iv, ix, iy, iz, &
1022 jkind, max_diis, mdiis, natom, ncloc, ndiis, nkind, now, nrloc, ns, sdiis
1023 INTEGER,
DIMENSION(3) :: cvec, ncell, periodic
1024 INTEGER,
DIMENSION(:),
POINTER :: cind, rind
1025 REAL(kind=
dp) :: ad, alpha, astep, deth, dr, eeqn, &
1026 eps_diis, ftime, grc1, grc2, rcut, &
1027 res, resin, rmax, te, ti
1028 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: bvec, dvec
1029 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dmat, fvec, vmat, xvec
1030 REAL(kind=
dp),
DIMENSION(3) :: ri, rij, rijl, rj
1031 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1032 REAL(kind=
dp),
DIMENSION(:),
POINTER :: rhs, rv0, xv0
1037 CALL timeset(routinen, handle)
1043 IF (
PRESENT(iounit)) iunit = iounit
1045 natom =
SIZE(particle_set)
1048 CALL get_cell(cell=cell, deth=deth)
1049 CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
1052 CALL cp_abort(__location__,
"Only SPME Ewald method available with EEQ.")
1057 CALL get_cell(cell, h=hmat, periodic=periodic)
1061 IF (periodic(1) == 0) ncell(1) = 0
1062 IF (periodic(2) == 0) ncell(2) = 0
1063 IF (periodic(3) == 0) ncell(3) = 0
1065 CALL mi_solver(charges, lambda, eeqn, eeq_mat, particle_set, kind_of, cell, &
1066 chia, gam, gab, qtot, ftime)
1068 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Iterative PBC guess time[s]", ftime
1070 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
1075 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
1076 row_indices=rind, col_indices=cind)
1081 IF (iar <= natom)
THEN
1082 ikind = kind_of(iar)
1083 ri(1:3) = particle_set(iar)%r(1:3)
1087 IF (iac > natom .AND. iar > natom)
THEN
1088 eeq_mat%local_data(ir, ic) = 0.0_dp
1090 ELSE IF ((iac > natom) .OR. (iar > natom))
THEN
1091 eeq_mat%local_data(ir, ic) = 1.0_dp
1094 jkind = kind_of(iac)
1095 rj(1:3) = particle_set(iac)%r(1:3)
1096 rij(1:3) = ri(1:3) - rj(1:3)
1097 rij =
pbc(rij, cell)
1098 DO ix = -ncell(1), ncell(1)
1099 DO iy = -ncell(2), ncell(2)
1100 DO iz = -ncell(3), ncell(3)
1102 rijl = rij + matmul(hmat, cvec)
1103 dr = sqrt(sum(rijl**2))
1104 IF (dr > rmax) cycle
1105 IF (iar == iac .AND. dr < 0.00001_dp)
THEN
1106 grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi - ad
1108 grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
1110 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
1119 row_indices=rind, col_indices=cind)
1124 IF (iar <= natom)
THEN
1125 ikind = kind_of(iar)
1126 ri(1:3) = particle_set(iar)%r(1:3)
1130 IF (iac > natom .AND. iar > natom)
THEN
1131 pmat%local_data(ir, ic) = 0.0_dp
1133 ELSE IF ((iac > natom) .OR. (iar > natom))
THEN
1134 pmat%local_data(ir, ic) = 1.0_dp
1137 jkind = kind_of(iac)
1138 rj(1:3) = particle_set(iac)%r(1:3)
1139 rij(1:3) = ri(1:3) - rj(1:3)
1140 rij =
pbc(rij, cell)
1141 IF (iar == iac)
THEN
1142 grc2 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi
1144 grc2 = erf(gab(ikind, jkind)*dr)/dr
1146 pmat%local_data(ir, ic) = grc2
1156 rhs(1:natom) = chia(1:natom)
1159 ALLOCATE (xv0(ns), rv0(ns))
1161 xv0(1:natom) = charges(1:natom)
1164 max_diis = eeq_sparam%max_diis
1165 mdiis = eeq_sparam%mdiis
1166 sdiis = eeq_sparam%sdiis
1167 eps_diis = eeq_sparam%eps_diis
1168 astep = eeq_sparam%alpha
1169 ALLOCATE (xvec(ns, mdiis), fvec(ns, mdiis), bvec(ns))
1170 xvec = 0.0_dp; fvec = 0.0_dp
1171 ALLOCATE (vmat(mdiis, mdiis), dmat(mdiis + 1, mdiis + 1), dvec(mdiis + 1))
1172 dmat = 0.0_dp; dvec = 0.0_dp
1175 CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
1176 cell, particle_set, xv0, rhs, rv0)
1177 resin = sqrt(sum(rv0*rv0))
1180 res = sqrt(sum(rv0*rv0))
1181 IF (res > 10._dp*resin)
EXIT
1182 IF (res < eps_diis)
EXIT
1184 now = mod(iv - 1, mdiis) + 1
1185 ndiis = min(iv, mdiis)
1186 xvec(1:ns, now) = xv0(1:ns)
1187 fvec(1:ns, now) = rv0(1:ns)
1189 vmat(now, i) = sum(fvec(:, now)*fvec(:, i))
1190 vmat(i, now) = vmat(now, i)
1192 IF (ndiis < sdiis)
THEN
1193 xv0(1:ns) = xv0(1:ns) + astep*rv0(1:ns)
1196 dvec(ndiis + 1) = 1.0_dp
1197 dmat(1:ndiis, 1:ndiis) = vmat(1:ndiis, 1:ndiis)
1198 dmat(ndiis + 1, 1:ndiis) = 1.0_dp
1199 dmat(1:ndiis, ndiis + 1) = 1.0_dp
1200 dmat(ndiis + 1, ndiis + 1) = 0.0_dp
1201 CALL invmat(dmat(1:ndiis + 1, 1:ndiis + 1), info)
1202 dvec(1:ndiis + 1) = matmul(dmat(1:ndiis + 1, 1:ndiis + 1), dvec(1:ndiis + 1))
1203 xv0(1:ns) = matmul(xvec(1:ns, 1:ndiis), dvec(1:ndiis))
1204 xv0(1:ns) = xv0(1:ns) + matmul(fvec(1:ns, 1:ndiis), dvec(1:ndiis))
1207 CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
1208 cell, particle_set, xv0, rhs, rv0)
1210 charges(1:natom) = xv0(1:natom)
1213 IF (res > eps_diis) ierror = 1
1215 DEALLOCATE (xvec, fvec, bvec)
1216 DEALLOCATE (vmat, dmat, dvec)
1217 DEALLOCATE (xv0, rv0)
1224 IF (ierror == 1)
THEN
1225 WRITE (iunit,
'(A)')
" EEQ| PBC solver failed to converge "
1227 WRITE (iunit,
'(A,T50,I4,T61,E20.5)')
" EEQ| PBC solver: iterations/accuracy ", iv, res
1229 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Iterative PBC solver: time[s]", te - ti
1231 CALL timestop(handle)
1233 END SUBROUTINE pbc_solver
1252 SUBROUTINE fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
1253 kind_of, cell, chia, gam, gab, qtot, ewald_env, ewald_pw, iounit)
1255 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: charges
1256 REAL(kind=
dp),
INTENT(INOUT) :: lambda, eeq_energy
1258 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1259 INTEGER,
DIMENSION(:),
INTENT(IN) :: kind_of
1261 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: chia, gam
1262 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gab
1263 REAL(kind=
dp),
INTENT(IN) :: qtot
1266 INTEGER,
INTENT(IN),
OPTIONAL :: iounit
1268 CHARACTER(len=*),
PARAMETER :: routinen =
'fpbc_solver'
1270 INTEGER :: ewald_type, handle, ia, iac, iar, ic, &
1271 ikind, ir, iunit, ix, iy, iz, jkind, &
1272 natom, ncloc, ncvloc, nkind, nrloc, &
1274 INTEGER,
DIMENSION(3) :: cvec, ncell, periodic
1275 INTEGER,
DIMENSION(:),
POINTER :: cind, cvind, rind, rvind
1276 REAL(kind=
dp) :: ad, alpha, deth, dr, grc1, rcut, rmax, &
1278 REAL(kind=
dp),
DIMENSION(3) :: ri, rij, rijl, rj
1279 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1280 REAL(kind=
dp),
DIMENSION(:),
POINTER :: pval, xval
1285 CALL timeset(routinen, handle)
1289 IF (
PRESENT(iounit)) iunit = iounit
1291 natom =
SIZE(particle_set)
1295 CALL get_cell(cell=cell, deth=deth)
1296 CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
1299 CALL cp_abort(__location__,
"Only SPME Ewald method available with EEQ.")
1304 CALL get_cell(cell, h=hmat, periodic=periodic)
1308 IF (periodic(1) == 0) ncell(1) = 0
1309 IF (periodic(2) == 0) ncell(2) = 0
1310 IF (periodic(3) == 0) ncell(3) = 0
1312 CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
1314 CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
1315 row_indices=rind, col_indices=cind)
1317 nrow_global=ns, ncol_global=1)
1319 CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
1320 row_indices=rvind, col_indices=cvind)
1325 IF (iar <= natom)
THEN
1326 ikind = kind_of(iar)
1327 ri(1:3) = particle_set(iar)%r(1:3)
1331 IF (iac > natom .AND. iar > natom)
THEN
1332 eeq_mat%local_data(ir, ic) = 0.0_dp
1334 ELSE IF ((iac > natom) .OR. (iar > natom))
THEN
1335 eeq_mat%local_data(ir, ic) = 1.0_dp
1338 jkind = kind_of(iac)
1339 rj(1:3) = particle_set(iac)%r(1:3)
1340 rij(1:3) = ri(1:3) - rj(1:3)
1341 rij =
pbc(rij, cell)
1342 DO ix = -ncell(1), ncell(1)
1343 DO iy = -ncell(2), ncell(2)
1344 DO iz = -ncell(3), ncell(3)
1346 rijl = rij + matmul(hmat, cvec)
1347 dr = sqrt(sum(rijl**2))
1348 IF (dr > rmax) cycle
1349 IF (iar == iac .AND. dr < 0.0001_dp)
THEN
1350 grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*
oorootpi - ad
1352 grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
1354 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
1361 ALLOCATE (xval(natom), pval(natom))
1365 CALL apply_potential(ewald_env, ewald_pw, cell, particle_set, xval, pval)
1369 IF (iar /= ia) cycle
1372 IF (iac > natom) cycle
1373 eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + pval(iac)
1377 DEALLOCATE (xval, pval)
1385 IF (ia > natom)
THEN
1390 rhs_vec%local_data(ir, ic) = xr
1403 IF (ia <= natom)
THEN
1404 xr = rhs_vec%local_data(ir, ic)
1407 lambda = rhs_vec%local_data(ir, ic)
1411 CALL para_env%sum(lambda)
1412 CALL para_env%sum(charges)
1415 eeq_energy = 0.5*sum(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
1422 WRITE (iunit,
'(A,T67,F14.3)')
" EEQ| Direct PBC solver: time[s]", te - ti
1424 CALL timestop(handle)
1426 END SUBROUTINE fpbc_solver
1437 SUBROUTINE apply_potential(ewald_env, ewald_pw, cell, particle_set, charges, potential)
1441 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1442 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
POINTER :: charges
1443 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: potential
1449 CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges, &
1450 particle_set, potential)
1451 CALL para_env%sum(potential)
1453 END SUBROUTINE apply_potential
1468 SUBROUTINE get_energy_gradient(eeqn, fm_mat, mmat, ewald_env, ewald_pw, &
1469 cell, particle_set, charges, rhs, potential)
1470 REAL(kind=
dp),
INTENT(INOUT) :: eeqn
1475 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1476 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
POINTER :: charges
1477 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: rhs
1478 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: potential
1481 REAL(kind=
dp) :: lambda
1482 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: mvec
1489 CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges(1:na), &
1490 particle_set, potential(1:na))
1491 CALL para_env%sum(potential(1:na))
1492 CALL cp_fm_matvec(fm_mat, charges, potential, alpha=1.0_dp, beta=1.0_dp)
1493 eeqn = 0.5_dp*sum(charges(1:na)*potential(1:na)) + sum(charges(1:na)*rhs(1:na))
1494 potential(1:ns) = potential(1:ns) + rhs(1:ns)
1496 CALL cp_fm_matvec(mmat, potential, mvec, alpha=-1.0_dp, beta=0.0_dp)
1497 lambda = -sum(mvec(1:na))/real(na, kind=
dp)
1498 potential(1:na) = mvec(1:na) + lambda
1501 END SUBROUTINE get_energy_gradient
1511 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges
1512 REAL(kind=
dp),
INTENT(OUT) :: ef_energy
1514 COMPLEX(KIND=dp) :: zdeta
1515 COMPLEX(KIND=dp),
DIMENSION(3) :: zi
1516 INTEGER :: ia, idir, natom
1518 REAL(kind=
dp) :: kr, omega, q
1519 REAL(kind=
dp),
DIMENSION(3) :: ci, dfilter, fieldpol, fpolvec, kvec, &
1521 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1526 CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
1527 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1529 IF (dft_control%apply_period_efield)
THEN
1530 dfield = dft_control%period_efield%displacement_field
1532 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1533 cpabort(
"use of strength_list not implemented for eeq_efield_energy")
1536 fieldpol = dft_control%period_efield%polarisation
1537 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1538 fieldpol = -fieldpol*dft_control%period_efield%strength
1539 hmat = cell%hmat(:, :)/
twopi
1541 fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
1542 + fieldpol(3)*hmat(3, idir)
1545 zi(:) = cmplx(1._dp, 0._dp,
dp)
1548 ria = particle_set(ia)%r
1549 ria =
pbc(ria, cell)
1551 kvec(:) =
twopi*cell%h_inv(idir, :)
1552 kr = sum(kvec(:)*ria(:))
1553 zdeta = cmplx(cos(kr), sin(kr), kind=
dp)**q
1554 zi(idir) = zi(idir)*zdeta
1559 dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
1561 ci = matmul(hmat, qi)/omega
1564 ef_energy = ef_energy + dfilter(idir)*(fieldpol(idir) - 2._dp*
twopi*ci(idir))**2
1566 ef_energy = -0.25_dp*omega/
twopi*ef_energy
1568 ef_energy = sum(fpolvec(:)*qi(:))
1571 ELSE IF (dft_control%apply_efield)
THEN
1573 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1574 dft_control%efield_fields(1)%efield%strength
1578 ria = particle_set(ia)%r
1579 ria =
pbc(ria, cell)
1581 ef_energy = ef_energy - q*sum(fieldpol*ria)
1585 cpabort(
"apply field")
1597 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: efr
1599 INTEGER :: ia, idir, natom
1602 REAL(kind=
dp),
DIMENSION(3) :: fieldpol, fpolvec, kvec, ria
1603 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1608 CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
1609 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1611 IF (dft_control%apply_period_efield)
THEN
1612 dfield = dft_control%period_efield%displacement_field
1614 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1615 cpabort(
"use of strength_list not implemented for eeq_efield_pot")
1618 fieldpol = dft_control%period_efield%polarisation
1619 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1620 fieldpol = -fieldpol*dft_control%period_efield%strength
1621 hmat = cell%hmat(:, :)/
twopi
1623 fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
1624 + fieldpol(3)*hmat(3, idir)
1633 ria = particle_set(ia)%r
1634 ria =
pbc(ria, cell)
1636 kvec(:) =
twopi*cell%h_inv(idir, :)
1637 kr = sum(kvec(:)*ria(:))
1638 efr(ia) = efr(ia) + kr*fpolvec(idir)
1643 ELSE IF (dft_control%apply_efield)
THEN
1645 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1646 dft_control%efield_fields(1)%efield%strength
1649 ria = particle_set(ia)%r
1650 ria =
pbc(ria, cell)
1651 efr(ia) = -sum(fieldpol*ria)
1655 cpabort(
"apply field")
1668 SUBROUTINE eeq_dfield_pot(charges, dft_control, particle_set, cell, efr)
1669 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges
1671 TYPE(
particle_type),
DIMENSION(:),
INTENT(IN) :: particle_set
1673 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: efr
1675 COMPLEX(KIND=dp) :: zdeta
1676 COMPLEX(KIND=dp),
DIMENSION(3) :: zi
1677 INTEGER :: ia, idir, natom
1678 REAL(kind=
dp) :: kr, omega, q
1679 REAL(kind=
dp),
DIMENSION(3) :: ci, dfilter, fieldpol, kvec, qi, ria
1680 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat
1682 natom =
SIZE(particle_set)
1684 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1685 cpabort(
"use of strength_list not implemented for eeq_dfield_pot")
1688 dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
1689 fieldpol = dft_control%period_efield%polarisation
1690 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1691 fieldpol = -fieldpol*dft_control%period_efield%strength
1692 hmat = cell%hmat(:, :)/
twopi
1695 zi(:) = cmplx(1._dp, 0._dp,
dp)
1698 ria = particle_set(ia)%r
1699 ria =
pbc(ria, cell)
1701 kvec(:) =
twopi*cell%h_inv(idir, :)
1702 kr = sum(kvec(:)*ria(:))
1703 zdeta = cmplx(cos(kr), sin(kr), kind=
dp)**q
1704 zi(idir) = zi(idir)*zdeta
1708 ci = matmul(hmat, qi)/omega
1709 ci = dfilter*(fieldpol - 2._dp*
twopi*ci)
1711 ria = particle_set(ia)%r
1712 ria =
pbc(ria, cell)
1713 efr(ia) = efr(ia) - sum(ci*ria)
1716 END SUBROUTINE eeq_dfield_pot
1726 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges, qlag
1728 INTEGER :: atom_a, ia, iatom, ikind, natom, nkind
1729 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind
1731 REAL(kind=
dp),
DIMENSION(3) :: fieldpol
1741 dft_control=dft_control, &
1742 cell=cell, particle_set=particle_set, &
1743 nkind=nkind, natom=natom, &
1744 para_env=para_env, &
1745 local_particles=local_particles)
1747 fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
1748 dft_control%efield_fields(1)%efield%strength
1750 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1755 force(ikind)%efield = 0.0_dp
1756 DO ia = 1, local_particles%n_el(ikind)
1757 iatom = local_particles%list(ikind)%array(ia)
1758 q = charges(iatom) - qlag(iatom)
1759 atom_a = atom_of_kind(iatom)
1760 force(ikind)%efield(1:3, atom_a) = -q*fieldpol(1:3)
1762 CALL para_env%sum(force(ikind)%efield)
1775 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: charges, qlag
1777 INTEGER :: atom_a, ia, iatom, ikind, natom, nkind
1778 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind
1779 LOGICAL :: dfield, use_virial
1781 REAL(kind=
dp),
DIMENSION(3) :: fa, fieldpol, ria
1782 REAL(kind=
dp),
DIMENSION(3, 3) :: pve
1793 dft_control=dft_control, &
1794 cell=cell, particle_set=particle_set, &
1796 nkind=nkind, natom=natom, &
1797 para_env=para_env, &
1798 local_particles=local_particles)
1800 dfield = dft_control%period_efield%displacement_field
1801 cpassert(.NOT. dfield)
1803 IF (
ALLOCATED(dft_control%period_efield%strength_list))
THEN
1804 cpabort(
"use of strength_list not implemented for eeq_efield_force_periodic")
1807 fieldpol = dft_control%period_efield%polarisation
1808 fieldpol = fieldpol/sqrt(dot_product(fieldpol, fieldpol))
1809 fieldpol = -fieldpol*dft_control%period_efield%strength
1811 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1813 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1819 force(ikind)%efield = 0.0_dp
1820 DO ia = 1, local_particles%n_el(ikind)
1821 iatom = local_particles%list(ikind)%array(ia)
1822 q = charges(iatom) - qlag(iatom)
1823 fa(1:3) = q*fieldpol(1:3)
1824 atom_a = atom_of_kind(iatom)
1825 force(ikind)%efield(1:3, atom_a) = fa
1826 IF (use_virial)
THEN
1827 ria = particle_set(ia)%r
1828 ria =
pbc(ria, cell)
1833 CALL para_env%sum(force(ikind)%efield)
1835 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)
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.