LCOV - code coverage report
Current view: top level - src - eeq_method.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:3db43b4) Lines: 90.5 % 885 801
Test Date: 2026-04-03 06:55:30 Functions: 93.3 % 15 14

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Calculation of charge equilibration method
      10              : !> \author JGH
      11              : ! **************************************************************************************************
      12              : MODULE eeq_method
      13              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      14              :                                               get_atomic_kind,&
      15              :                                               get_atomic_kind_set
      16              :    USE atprop_types,                    ONLY: atprop_type
      17              :    USE cell_types,                      ONLY: cell_type,&
      18              :                                               get_cell,&
      19              :                                               pbc,&
      20              :                                               plane_distance
      21              :    USE cp_blacs_env,                    ONLY: cp_blacs_env_type
      22              :    USE cp_control_types,                ONLY: dft_control_type
      23              :    USE cp_fm_basic_linalg,              ONLY: cp_fm_invert,&
      24              :                                               cp_fm_matvec,&
      25              :                                               cp_fm_solve
      26              :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      27              :                                               cp_fm_struct_release,&
      28              :                                               cp_fm_struct_type
      29              :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      30              :                                               cp_fm_get_info,&
      31              :                                               cp_fm_release,&
      32              :                                               cp_fm_set_all,&
      33              :                                               cp_fm_type
      34              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      35              :                                               cp_logger_get_default_unit_nr,&
      36              :                                               cp_logger_type
      37              :    USE cp_output_handling,              ONLY: medium_print_level
      38              :    USE distribution_1d_types,           ONLY: distribution_1d_type
      39              :    USE distribution_2d_types,           ONLY: distribution_2d_type
      40              :    USE eeq_data,                        ONLY: get_eeq_data
      41              :    USE eeq_input,                       ONLY: eeq_solver_type
      42              :    USE ewald_environment_types,         ONLY: ewald_env_create,&
      43              :                                               ewald_env_get,&
      44              :                                               ewald_env_release,&
      45              :                                               ewald_env_set,&
      46              :                                               ewald_environment_type,&
      47              :                                               read_ewald_section_tb
      48              :    USE ewald_pw_types,                  ONLY: ewald_pw_create,&
      49              :                                               ewald_pw_release,&
      50              :                                               ewald_pw_type
      51              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      52              :                                               section_vals_type
      53              :    USE kinds,                           ONLY: dp
      54              :    USE machine,                         ONLY: m_walltime
      55              :    USE mathconstants,                   ONLY: oorootpi,&
      56              :                                               twopi
      57              :    USE mathlib,                         ONLY: invmat
      58              :    USE message_passing,                 ONLY: mp_para_env_type
      59              :    USE molecule_types,                  ONLY: molecule_type
      60              :    USE particle_types,                  ONLY: particle_type
      61              :    USE physcon,                         ONLY: bohr
      62              :    USE pw_poisson_types,                ONLY: do_ewald_spme
      63              :    USE qs_dispersion_cnum,              ONLY: cnumber_init,&
      64              :                                               cnumber_release,&
      65              :                                               dcnum_type
      66              :    USE qs_dispersion_types,             ONLY: qs_dispersion_release,&
      67              :                                               qs_dispersion_type
      68              :    USE qs_environment_types,            ONLY: get_qs_env,&
      69              :                                               qs_environment_type
      70              :    USE qs_force_types,                  ONLY: qs_force_type
      71              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      72              :                                               qs_kind_type
      73              :    USE qs_neighbor_list_types,          ONLY: get_iterator_info,&
      74              :                                               neighbor_list_iterate,&
      75              :                                               neighbor_list_iterator_create,&
      76              :                                               neighbor_list_iterator_p_type,&
      77              :                                               neighbor_list_iterator_release,&
      78              :                                               neighbor_list_set_p_type,&
      79              :                                               release_neighbor_list_sets
      80              :    USE qs_neighbor_lists,               ONLY: atom2d_build,&
      81              :                                               atom2d_cleanup,&
      82              :                                               build_neighbor_lists,&
      83              :                                               local_atoms_type,&
      84              :                                               pair_radius_setup
      85              :    USE spme,                            ONLY: spme_forces,&
      86              :                                               spme_potential,&
      87              :                                               spme_virial
      88              :    USE virial_methods,                  ONLY: virial_pair_force
      89              :    USE virial_types,                    ONLY: virial_type
      90              : #include "./base/base_uses.f90"
      91              : 
      92              :    IMPLICIT NONE
      93              : 
      94              :    PRIVATE
      95              : 
      96              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'eeq_method'
      97              : 
      98              :    INTEGER, PARAMETER                                    :: maxElem = 86
      99              :    ! covalent radii (taken from Pyykko and Atsumi, Chem. Eur. J. 15, 2009, 188-197)
     100              :    ! values for metals decreased by 10 %
     101              :    REAL(KIND=dp), PARAMETER :: rcov(1:maxElem) = [&
     102              :       & 0.32_dp, 0.46_dp, 1.20_dp, 0.94_dp, 0.77_dp, 0.75_dp, 0.71_dp, 0.63_dp, &
     103              :       & 0.64_dp, 0.67_dp, 1.40_dp, 1.25_dp, 1.13_dp, 1.04_dp, 1.10_dp, 1.02_dp, &
     104              :       & 0.99_dp, 0.96_dp, 1.76_dp, 1.54_dp, 1.33_dp, 1.22_dp, 1.21_dp, 1.10_dp, &
     105              :       & 1.07_dp, 1.04_dp, 1.00_dp, 0.99_dp, 1.01_dp, 1.09_dp, 1.12_dp, 1.09_dp, &
     106              :       & 1.15_dp, 1.10_dp, 1.14_dp, 1.17_dp, 1.89_dp, 1.67_dp, 1.47_dp, 1.39_dp, &
     107              :       & 1.32_dp, 1.24_dp, 1.15_dp, 1.13_dp, 1.13_dp, 1.08_dp, 1.15_dp, 1.23_dp, &
     108              :       & 1.28_dp, 1.26_dp, 1.26_dp, 1.23_dp, 1.32_dp, 1.31_dp, 2.09_dp, 1.76_dp, &
     109              :       & 1.62_dp, 1.47_dp, 1.58_dp, 1.57_dp, 1.56_dp, 1.55_dp, 1.51_dp, 1.52_dp, &
     110              :       & 1.51_dp, 1.50_dp, 1.49_dp, 1.49_dp, 1.48_dp, 1.53_dp, 1.46_dp, 1.37_dp, &
     111              :       & 1.31_dp, 1.23_dp, 1.18_dp, 1.16_dp, 1.11_dp, 1.12_dp, 1.13_dp, 1.32_dp, &
     112              :       & 1.30_dp, 1.30_dp, 1.36_dp, 1.31_dp, 1.38_dp, 1.42_dp]
     113              : 
     114              :    PUBLIC :: eeq_solver, eeq_print, eeq_charges, eeq_forces, &
     115              :              eeq_efield_energy, eeq_efield_pot, eeq_efield_force_loc, eeq_efield_force_periodic
     116              : 
     117              : CONTAINS
     118              : 
     119              : ! **************************************************************************************************
     120              : !> \brief ...
     121              : !> \param qs_env ...
     122              : !> \param iounit ...
     123              : !> \param print_level ...
     124              : !> \param ext ...
     125              : ! **************************************************************************************************
     126           38 :    SUBROUTINE eeq_print(qs_env, iounit, print_level, ext)
     127              : 
     128              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     129              :       INTEGER, INTENT(IN)                                :: iounit, print_level
     130              :       LOGICAL, INTENT(IN)                                :: ext
     131              : 
     132              :       CHARACTER(LEN=2)                                   :: element_symbol
     133              :       INTEGER                                            :: enshift_type, iatom, ikind, natom
     134           38 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: charges
     135              :       TYPE(cell_type), POINTER                           :: cell
     136              :       TYPE(eeq_solver_type)                              :: eeq_sparam
     137           38 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     138              : 
     139              :       MARK_USED(print_level)
     140              : 
     141           38 :       CALL get_qs_env(qs_env, natom=natom, particle_set=particle_set, cell=cell)
     142           38 :       IF (ext) THEN
     143            0 :          NULLIFY (charges)
     144            0 :          CALL get_qs_env(qs_env, eeq=charges)
     145            0 :          CPASSERT(ASSOCIATED(charges))
     146            0 :          enshift_type = 0
     147              :       ELSE
     148          114 :          ALLOCATE (charges(natom))
     149              :          ! enforce en shift method 1 (original/molecular)
     150              :          ! method 2 from paper on PBC seems not to work
     151           38 :          enshift_type = 1
     152              :          !IF (ALL(cell%perd == 0)) enshift_type = 1
     153           38 :          CALL eeq_charges(qs_env, charges, eeq_sparam, 2, enshift_type)
     154              :       END IF
     155              : 
     156           38 :       IF (iounit > 0) THEN
     157              : 
     158           19 :          IF (enshift_type == 0) THEN
     159            0 :             WRITE (UNIT=iounit, FMT="(/,T2,A)") "EEQ Charges (External)"
     160           19 :          ELSE IF (enshift_type == 1) THEN
     161           19 :             WRITE (UNIT=iounit, FMT="(/,T2,A)") "EEQ Charges (Parametrization 2019 (Molecules))"
     162            0 :          ELSE IF (enshift_type == 2) THEN
     163            0 :             WRITE (UNIT=iounit, FMT="(/,T2,A)") "EEQ Charges (Parametrization 2019 (Crystals))"
     164              :          ELSE
     165            0 :             CPABORT("Unknown enshift_type")
     166              :          END IF
     167              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
     168           19 :             "#     Atom  Element     Kind            Atomic Charge"
     169              : 
     170          140 :          DO iatom = 1, natom
     171              :             CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, &
     172              :                                  element_symbol=element_symbol, &
     173          121 :                                  kind_number=ikind)
     174              :             WRITE (UNIT=iounit, FMT="(T4,I8,T18,A2,I10,T43,F12.4)") &
     175          140 :                iatom, element_symbol, ikind, charges(iatom)
     176              :          END DO
     177              : 
     178              :       END IF
     179              : 
     180           38 :       IF (.NOT. ext) DEALLOCATE (charges)
     181              : 
     182           38 :    END SUBROUTINE eeq_print
     183              : 
     184              : ! **************************************************************************************************
     185              : !> \brief ...
     186              : !> \param qs_env ...
     187              : !> \param charges ...
     188              : !> \param eeq_sparam ...
     189              : !> \param eeq_model ...
     190              : !> \param enshift_type ...
     191              : !> \param exclude ...
     192              : !> \param cn_max ...
     193              : ! **************************************************************************************************
     194           68 :    SUBROUTINE eeq_charges(qs_env, charges, eeq_sparam, eeq_model, enshift_type, exclude, cn_max)
     195              : 
     196              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     197              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
     198              :       TYPE(eeq_solver_type), INTENT(IN)                  :: eeq_sparam
     199              :       INTEGER, INTENT(IN)                                :: eeq_model, enshift_type
     200              :       LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL        :: exclude
     201              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: cn_max
     202              : 
     203              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'eeq_charges'
     204              : 
     205              :       INTEGER                                            :: handle, iatom, ikind, iunit, jkind, &
     206              :                                                             natom, nkind, za, zb
     207           68 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: kind_of
     208              :       INTEGER, DIMENSION(3)                              :: periodic
     209              :       LOGICAL                                            :: do_ewald
     210              :       REAL(KIND=dp)                                      :: ala, alb, eeq_energy, esg, kappa, &
     211              :                                                             lambda, scn, sgamma, totalcharge, xi
     212           68 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: chia, cnumbers, efr, gam
     213           68 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: gab
     214           68 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     215              :       TYPE(cell_type), POINTER                           :: cell, cell_ref
     216              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     217              :       TYPE(cp_logger_type), POINTER                      :: logger
     218           68 :       TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:)        :: dcnum
     219              :       TYPE(dft_control_type), POINTER                    :: dft_control
     220              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
     221              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
     222              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     223           68 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     224           68 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     225              :       TYPE(section_vals_type), POINTER                   :: ewald_section, poisson_section, &
     226              :                                                             print_section
     227              : 
     228           68 :       CALL timeset(routineN, handle)
     229              : 
     230              :       CALL get_qs_env(qs_env, &
     231              :                       qs_kind_set=qs_kind_set, &
     232              :                       atomic_kind_set=atomic_kind_set, &
     233              :                       particle_set=particle_set, &
     234              :                       para_env=para_env, &
     235              :                       blacs_env=blacs_env, &
     236              :                       cell=cell, &
     237           68 :                       dft_control=dft_control)
     238           68 :       CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
     239              : 
     240           68 :       logger => cp_get_default_logger()
     241           68 :       IF (para_env%is_source() .AND. logger%iter_info%print_level >= medium_print_level) THEN
     242           26 :          iunit = cp_logger_get_default_unit_nr()
     243              :       ELSE
     244           42 :          iunit = -1
     245              :       END IF
     246              : 
     247           68 :       totalcharge = dft_control%charge
     248              : 
     249           68 :       CALL get_cnumbers(qs_env, cnumbers, dcnum, .FALSE.)
     250              : 
     251              :       ! Apply smooth logistic CN cutoff to match multicharge/D4 behavior
     252           68 :       IF (PRESENT(cn_max)) THEN
     253          266 :          DO iatom = 1, natom
     254          266 :             cnumbers(iatom) = LOG(1.0_dp + EXP(cn_max)) - LOG(1.0_dp + EXP(cn_max - cnumbers(iatom)))
     255              :          END DO
     256              :       END IF
     257              : 
     258              :       ! gamma[a,b]
     259          408 :       ALLOCATE (gab(nkind, nkind), gam(nkind))
     260          560 :       gab = 0.0_dp
     261          214 :       gam = 0.0_dp
     262          214 :       DO ikind = 1, nkind
     263          146 :          CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
     264          146 :          CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
     265          560 :          DO jkind = 1, nkind
     266          346 :             CALL get_qs_kind(qs_kind_set(jkind), zatom=zb)
     267          346 :             CALL get_eeq_data(zb, eeq_model, rad=alb)
     268              :             !
     269          492 :             gab(ikind, jkind) = SQRT(1._dp/(ala*ala + alb*alb))
     270              :             !
     271              :          END DO
     272              :       END DO
     273              : 
     274              :       ! Override parameters for excluded kinds (ghost/floating atoms in BSSE):
     275              :       ! huge hardness + zero coupling -> q = 0, no influence on other atoms.
     276           68 :       IF (PRESENT(exclude)) THEN
     277           96 :          DO ikind = 1, nkind
     278           96 :             IF (exclude(ikind)) THEN
     279            8 :                gam(ikind) = 1.0e30_dp
     280           40 :                gab(ikind, :) = 0.0_dp
     281           40 :                gab(:, ikind) = 0.0_dp
     282              :             END IF
     283              :          END DO
     284              :       END IF
     285              : 
     286              :       ! Chi[a,a]
     287           68 :       sgamma = 8.0_dp ! see D4 for periodic systems paper
     288           68 :       esg = 1.0_dp + EXP(sgamma)
     289          204 :       ALLOCATE (chia(natom))
     290           68 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, kind_of=kind_of)
     291          546 :       DO iatom = 1, natom
     292          478 :          ikind = kind_of(iatom)
     293          478 :          CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
     294          478 :          CALL get_eeq_data(za, eeq_model, chi=xi, kcn=kappa)
     295              :          !
     296          478 :          IF (enshift_type == 1) THEN
     297          478 :             scn = cnumbers(iatom)/SQRT(cnumbers(iatom) + 1.0e-14_dp)
     298            0 :          ELSE IF (enshift_type == 2) THEN
     299            0 :             scn = LOG(esg/(esg - cnumbers(iatom)))
     300              :          ELSE
     301            0 :             CPABORT("Unknown enshift_type")
     302              :          END IF
     303         1024 :          chia(iatom) = xi - kappa*scn
     304              :          !
     305              :       END DO
     306              : 
     307              :       ! Zero electronegativity for excluded atoms (ghost/floating in BSSE)
     308           68 :       IF (PRESENT(exclude)) THEN
     309          266 :          DO iatom = 1, natom
     310          236 :             ikind = kind_of(iatom)
     311          266 :             IF (exclude(ikind)) chia(iatom) = 0.0_dp
     312              :          END DO
     313              :       END IF
     314              : 
     315              :       ! efield
     316           68 :       IF (dft_control%apply_period_efield .OR. dft_control%apply_efield .OR. &
     317              :           dft_control%apply_efield_field) THEN
     318            0 :          ALLOCATE (efr(natom))
     319            0 :          efr(1:natom) = 0.0_dp
     320            0 :          CALL eeq_efield_pot(qs_env, efr)
     321            0 :          chia(1:natom) = chia(1:natom) + efr(1:natom)
     322            0 :          DEALLOCATE (efr)
     323              :       END IF
     324              : 
     325           68 :       CALL cnumber_release(cnumbers, dcnum, .FALSE.)
     326              : 
     327           68 :       CALL get_cell(cell, periodic=periodic)
     328          134 :       do_ewald = .NOT. ALL(periodic == 0)
     329           68 :       IF (do_ewald) THEN
     330          736 :          ALLOCATE (ewald_env)
     331           46 :          CALL ewald_env_create(ewald_env, para_env)
     332           46 :          poisson_section => section_vals_get_subs_vals(qs_env%input, "DFT%POISSON")
     333           46 :          CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
     334           46 :          ewald_section => section_vals_get_subs_vals(poisson_section, "EWALD")
     335           46 :          print_section => section_vals_get_subs_vals(qs_env%input, "PRINT%GRID_INFORMATION")
     336           46 :          CALL get_qs_env(qs_env, cell_ref=cell_ref)
     337              :          CALL read_ewald_section_tb(ewald_env, ewald_section, cell_ref%hmat, &
     338           46 :                                     silent=.TRUE., pset="EEQ")
     339           46 :          ALLOCATE (ewald_pw)
     340           46 :          CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
     341              :          !
     342              :          CALL eeq_solver(charges, lambda, eeq_energy, &
     343              :                          particle_set, kind_of, cell, chia, gam, gab, &
     344              :                          para_env, blacs_env, dft_control, eeq_sparam, &
     345              :                          totalcharge=totalcharge, ewald=do_ewald, &
     346           46 :                          ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
     347              :          !
     348           46 :          CALL ewald_env_release(ewald_env)
     349           46 :          CALL ewald_pw_release(ewald_pw)
     350           46 :          DEALLOCATE (ewald_env, ewald_pw)
     351              :       ELSE
     352              :          CALL eeq_solver(charges, lambda, eeq_energy, &
     353              :                          particle_set, kind_of, cell, chia, gam, gab, &
     354              :                          para_env, blacs_env, dft_control, eeq_sparam, &
     355           22 :                          totalcharge=totalcharge, iounit=iunit)
     356              :       END IF
     357              : 
     358           68 :       DEALLOCATE (gab, gam, chia)
     359              : 
     360           68 :       CALL timestop(handle)
     361              : 
     362          136 :    END SUBROUTINE eeq_charges
     363              : 
     364              : ! **************************************************************************************************
     365              : !> \brief ...
     366              : !> \param qs_env ...
     367              : !> \param charges ...
     368              : !> \param dcharges ...
     369              : !> \param gradient ...
     370              : !> \param stress ...
     371              : !> \param eeq_sparam ...
     372              : !> \param eeq_model ...
     373              : !> \param enshift_type ...
     374              : !> \param response_only ...
     375              : !> \param exclude ...
     376              : !> \param cn_max ...
     377              : ! **************************************************************************************************
     378           10 :    SUBROUTINE eeq_forces(qs_env, charges, dcharges, gradient, stress, &
     379           10 :                          eeq_sparam, eeq_model, enshift_type, response_only, exclude, cn_max)
     380              : 
     381              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     382              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges, dcharges
     383              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: gradient
     384              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT)      :: stress
     385              :       TYPE(eeq_solver_type), INTENT(IN)                  :: eeq_sparam
     386              :       INTEGER, INTENT(IN)                                :: eeq_model, enshift_type
     387              :       LOGICAL, INTENT(IN)                                :: response_only
     388              :       LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL        :: exclude
     389              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: cn_max
     390              : 
     391              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'eeq_forces'
     392              : 
     393              :       INTEGER                                            :: handle, i, ia, iatom, ikind, iunit, &
     394              :                                                             jatom, jkind, katom, natom, nkind, za, &
     395              :                                                             zb
     396           10 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: kind_of
     397              :       INTEGER, DIMENSION(3)                              :: periodic
     398              :       LOGICAL                                            :: do_ewald, use_virial
     399           10 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: default_present
     400              :       REAL(KIND=dp) :: ala, alb, alpha, cn, ctot, dcnpdcn, dr, dr2, drk, elag, esg, fe, gam2, &
     401              :          gama, grc, kappa, qlam, qq, qq1, qq2, rcut, scn, sgamma, subcells, totalcharge, xi
     402           10 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: c_radius, cnumbers, gam, qlag
     403           10 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: epforce, gab, pair_radius
     404              :       REAL(KIND=dp), DIMENSION(3)                        :: fdik, ri, rij, rik, rj
     405              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: pvir
     406           10 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: chrgx, dchia
     407           10 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     408              :       TYPE(atprop_type), POINTER                         :: atprop
     409              :       TYPE(cell_type), POINTER                           :: cell, cell_ref
     410              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     411              :       TYPE(cp_logger_type), POINTER                      :: logger
     412           10 :       TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:)        :: dcnum
     413              :       TYPE(dft_control_type), POINTER                    :: dft_control
     414              :       TYPE(distribution_1d_type), POINTER                :: distribution_1d, local_particles
     415              :       TYPE(distribution_2d_type), POINTER                :: distribution_2d
     416              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
     417              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
     418           10 :       TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:)  :: atom2d
     419           10 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     420              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     421              :       TYPE(neighbor_list_iterator_p_type), &
     422           10 :          DIMENSION(:), POINTER                           :: nl_iterator
     423              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     424           10 :          POINTER                                         :: sab_ew
     425           10 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     426           10 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     427           10 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     428              :       TYPE(section_vals_type), POINTER                   :: ewald_section, poisson_section, &
     429              :                                                             print_section
     430              :       TYPE(virial_type), POINTER                         :: virial
     431              : 
     432           10 :       CALL timeset(routineN, handle)
     433              : 
     434              :       CALL get_qs_env(qs_env, &
     435              :                       qs_kind_set=qs_kind_set, &
     436              :                       atomic_kind_set=atomic_kind_set, &
     437              :                       particle_set=particle_set, &
     438              :                       para_env=para_env, &
     439              :                       blacs_env=blacs_env, &
     440              :                       cell=cell, &
     441              :                       force=force, &
     442              :                       virial=virial, &
     443              :                       atprop=atprop, &
     444           10 :                       dft_control=dft_control)
     445              : 
     446           10 :       logger => cp_get_default_logger()
     447           10 :       IF (para_env%is_source() .AND. logger%iter_info%print_level >= medium_print_level) THEN
     448            2 :          iunit = cp_logger_get_default_unit_nr()
     449              :       ELSE
     450            8 :          iunit = -1
     451              :       END IF
     452              : 
     453           10 :       CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
     454           10 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     455              : 
     456           10 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, kind_of=kind_of)
     457              : 
     458           10 :       totalcharge = dft_control%charge
     459              : 
     460           10 :       CALL get_cnumbers(qs_env, cnumbers, dcnum, .TRUE.)
     461              : 
     462              :       ! Apply smooth logistic CN cutoff to match multicharge/D4 behavior
     463              :       ! Chain rule: dcn_cut/dR = (dcn_cut/dcn) * (dcn/dR)
     464           10 :       IF (PRESENT(cn_max)) THEN
     465           98 :          DO iatom = 1, natom
     466           88 :             dcnpdcn = EXP(cn_max)/(EXP(cn_max) + EXP(cnumbers(iatom)))
     467           88 :             cnumbers(iatom) = LOG(1.0_dp + EXP(cn_max)) - LOG(1.0_dp + EXP(cn_max - cnumbers(iatom)))
     468          226 :             DO i = 1, dcnum(iatom)%neighbors
     469          216 :                dcnum(iatom)%dvals(i) = dcnum(iatom)%dvals(i)*dcnpdcn
     470              :             END DO
     471              :          END DO
     472              :       END IF
     473              : 
     474              :       ! gamma[a,b]
     475           60 :       ALLOCATE (gab(nkind, nkind), gam(nkind))
     476           62 :       gab = 0.0_dp
     477           28 :       gam = 0.0_dp
     478           28 :       DO ikind = 1, nkind
     479           18 :          CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
     480           18 :          CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
     481           62 :          DO jkind = 1, nkind
     482           34 :             CALL get_qs_kind(qs_kind_set(jkind), zatom=zb)
     483           34 :             CALL get_eeq_data(zb, eeq_model, rad=alb)
     484              :             !
     485           52 :             gab(ikind, jkind) = SQRT(1._dp/(ala*ala + alb*alb))
     486              :             !
     487              :          END DO
     488              :       END DO
     489              : 
     490              :       ! Override parameters for excluded kinds (ghost/floating atoms in BSSE)
     491           10 :       IF (PRESENT(exclude)) THEN
     492           28 :          DO ikind = 1, nkind
     493           28 :             IF (exclude(ikind)) THEN
     494            0 :                gam(ikind) = 1.0e30_dp
     495            0 :                gab(ikind, :) = 0.0_dp
     496            0 :                gab(:, ikind) = 0.0_dp
     497              :             END IF
     498              :          END DO
     499              :       END IF
     500              : 
     501           30 :       ALLOCATE (qlag(natom))
     502              : 
     503           10 :       CALL get_cell(cell, periodic=periodic)
     504           22 :       do_ewald = .NOT. ALL(periodic == 0)
     505           10 :       IF (do_ewald) THEN
     506           96 :          ALLOCATE (ewald_env)
     507            6 :          CALL ewald_env_create(ewald_env, para_env)
     508            6 :          poisson_section => section_vals_get_subs_vals(qs_env%input, "DFT%POISSON")
     509            6 :          CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
     510            6 :          ewald_section => section_vals_get_subs_vals(poisson_section, "EWALD")
     511            6 :          print_section => section_vals_get_subs_vals(qs_env%input, "PRINT%GRID_INFORMATION")
     512            6 :          CALL get_qs_env(qs_env, cell_ref=cell_ref)
     513              :          CALL read_ewald_section_tb(ewald_env, ewald_section, cell_ref%hmat, &
     514            6 :                                     silent=.TRUE., pset="EEQ")
     515            6 :          ALLOCATE (ewald_pw)
     516            6 :          CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
     517              :          !
     518              :          CALL eeq_solver(qlag, qlam, elag, &
     519              :                          particle_set, kind_of, cell, -dcharges, gam, gab, &
     520              :                          para_env, blacs_env, dft_control, eeq_sparam, &
     521           54 :                          ewald=do_ewald, ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit)
     522              :       ELSE
     523              :          CALL eeq_solver(qlag, qlam, elag, &
     524              :                          particle_set, kind_of, cell, -dcharges, gam, gab, &
     525           44 :                          para_env, blacs_env, dft_control, eeq_sparam, iounit=iunit)
     526              :       END IF
     527              : 
     528           10 :       sgamma = 8.0_dp ! see D4 for periodic systems paper
     529           10 :       esg = 1.0_dp + EXP(sgamma)
     530           40 :       ALLOCATE (chrgx(natom), dchia(natom))
     531           98 :       DO iatom = 1, natom
     532           88 :          ikind = kind_of(iatom)
     533           88 :          CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
     534           88 :          CALL get_eeq_data(za, eeq_model, chi=xi, kcn=kappa)
     535              :          !
     536           88 :          IF (response_only) THEN
     537           88 :             ctot = -0.5_dp*qlag(iatom)
     538              :          ELSE
     539            0 :             ctot = 0.5_dp*(charges(iatom) - qlag(iatom))
     540              :          END IF
     541          186 :          IF (enshift_type == 1) THEN
     542           88 :             scn = SQRT(cnumbers(iatom)) + 1.0e-14_dp
     543           88 :             dchia(iatom) = -ctot*kappa/scn
     544            0 :          ELSE IF (enshift_type == 2) THEN
     545            0 :             cn = cnumbers(iatom)
     546            0 :             scn = 1.0_dp/(esg - cn)
     547            0 :             dchia(iatom) = -ctot*kappa*scn
     548              :          ELSE
     549            0 :             CPABORT("Unknown enshift_type")
     550              :          END IF
     551              :       END DO
     552              : 
     553              :       ! Efield
     554           10 :       IF (dft_control%apply_period_efield) THEN
     555            0 :          CALL eeq_efield_force_periodic(qs_env, charges, qlag)
     556           10 :       ELSE IF (dft_control%apply_efield) THEN
     557            0 :          CALL eeq_efield_force_loc(qs_env, charges, qlag)
     558           10 :       ELSE IF (dft_control%apply_efield_field) THEN
     559            0 :          CPABORT("apply field")
     560              :       END IF
     561              : 
     562              :       ! Forces from q*X
     563           10 :       CALL get_qs_env(qs_env=qs_env, local_particles=local_particles)
     564           28 :       DO ikind = 1, nkind
     565           72 :          DO ia = 1, local_particles%n_el(ikind)
     566           44 :             iatom = local_particles%list(ikind)%array(ia)
     567          126 :             DO i = 1, dcnum(iatom)%neighbors
     568           64 :                katom = dcnum(iatom)%nlist(i)
     569          256 :                rik = dcnum(iatom)%rik(:, i)
     570          256 :                drk = SQRT(SUM(rik(:)**2))
     571          108 :                IF (drk > 1.e-3_dp) THEN
     572          256 :                   fdik(:) = dchia(iatom)*dcnum(iatom)%dvals(i)*rik(:)/drk
     573          256 :                   gradient(:, iatom) = gradient(:, iatom) - fdik(:)
     574          256 :                   gradient(:, katom) = gradient(:, katom) + fdik(:)
     575           64 :                   IF (use_virial) THEN
     576           16 :                      CALL virial_pair_force(stress, 1._dp, fdik, rik)
     577              :                   END IF
     578              :                END IF
     579              :             END DO
     580              :          END DO
     581              :       END DO
     582              : 
     583              :       ! Forces from (0.5*q+l)*dA/dR*q
     584           10 :       IF (do_ewald) THEN
     585              : 
     586              :          ! Build the neighbor lists for the CN
     587              :          CALL get_qs_env(qs_env, &
     588              :                          distribution_2d=distribution_2d, &
     589              :                          local_particles=distribution_1d, &
     590            6 :                          molecule_set=molecule_set)
     591            6 :          subcells = 2.0_dp
     592            6 :          CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut)
     593            6 :          rcut = 2.0_dp*rcut
     594            6 :          NULLIFY (sab_ew)
     595           48 :          ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
     596           16 :          c_radius(:) = rcut
     597           16 :          default_present = .TRUE.
     598           28 :          ALLOCATE (atom2d(nkind))
     599              :          CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
     600            6 :                            molecule_set, .FALSE., particle_set=particle_set)
     601            6 :          CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
     602              :          CALL build_neighbor_lists(sab_ew, particle_set, atom2d, cell, pair_radius, &
     603            6 :                                    subcells=subcells, operator_type="PP", nlname="sab_ew")
     604            6 :          DEALLOCATE (c_radius, pair_radius, default_present)
     605            6 :          CALL atom2d_cleanup(atom2d)
     606              :          !
     607            6 :          CALL neighbor_list_iterator_create(nl_iterator, sab_ew)
     608        77994 :          DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     609              :             CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     610        77988 :                                    iatom=iatom, jatom=jatom, r=rij)
     611              :             !
     612       311952 :             dr2 = SUM(rij**2)
     613        77988 :             dr = SQRT(dr2)
     614        77988 :             IF (dr > rcut .OR. dr < 1.E-6_dp) CYCLE
     615         9758 :             fe = 1.0_dp
     616         9758 :             IF (iatom == jatom) fe = 0.5_dp
     617         9758 :             IF (response_only) THEN
     618         9758 :                qq = -qlag(iatom)*charges(jatom)
     619              :             ELSE
     620         9758 :                qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
     621              :             END IF
     622         9758 :             gama = gab(ikind, jkind)
     623         9758 :             gam2 = gama*gama
     624              :             grc = 2._dp*gama*EXP(-gam2*dr2)*oorootpi/dr - erf(gama*dr)/dr2 &
     625         9758 :                   - 2._dp*alpha*EXP(-alpha**2*dr2)*oorootpi/dr + erf(alpha*dr)/dr2
     626         9758 :             IF (response_only) THEN
     627         9758 :                qq1 = -qlag(iatom)*charges(jatom)
     628         9758 :                qq2 = -qlag(jatom)*charges(iatom)
     629              :             ELSE
     630            0 :                qq1 = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
     631            0 :                qq2 = (0.5_dp*charges(jatom) - qlag(jatom))*charges(iatom)
     632              :             END IF
     633        39032 :             fdik(:) = -qq1*grc*rij(:)/dr
     634        39032 :             gradient(:, iatom) = gradient(:, iatom) + fdik(:)
     635        39032 :             gradient(:, jatom) = gradient(:, jatom) - fdik(:)
     636         9758 :             IF (use_virial) THEN
     637         5279 :                CALL virial_pair_force(stress, -fe, fdik, rij)
     638              :             END IF
     639        39032 :             fdik(:) = qq2*grc*rij(:)/dr
     640        39032 :             gradient(:, iatom) = gradient(:, iatom) - fdik(:)
     641        39032 :             gradient(:, jatom) = gradient(:, jatom) + fdik(:)
     642         9764 :             IF (use_virial) THEN
     643         5279 :                CALL virial_pair_force(stress, fe, fdik, rij)
     644              :             END IF
     645              :          END DO
     646            6 :          CALL neighbor_list_iterator_release(nl_iterator)
     647              :          !
     648            6 :          CALL release_neighbor_list_sets(sab_ew)
     649              :       ELSE
     650           12 :          DO ikind = 1, nkind
     651           32 :             DO ia = 1, local_particles%n_el(ikind)
     652           20 :                iatom = local_particles%list(ikind)%array(ia)
     653           80 :                ri(1:3) = particle_set(iatom)%r(1:3)
     654          228 :                DO jatom = 1, natom
     655          200 :                   IF (iatom == jatom) CYCLE
     656          180 :                   jkind = kind_of(jatom)
     657          180 :                   IF (response_only) THEN
     658          180 :                      qq = -qlag(iatom)*charges(jatom)
     659              :                   ELSE
     660            0 :                      qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
     661              :                   END IF
     662          720 :                   rj(1:3) = particle_set(jatom)%r(1:3)
     663          720 :                   rij(1:3) = ri(1:3) - rj(1:3)
     664          720 :                   rij = pbc(rij, cell)
     665          720 :                   dr2 = SUM(rij**2)
     666          180 :                   dr = SQRT(dr2)
     667          180 :                   gama = gab(ikind, jkind)
     668          180 :                   gam2 = gama*gama
     669          180 :                   grc = 2._dp*gama*EXP(-gam2*dr2)*oorootpi/dr - erf(gama*dr)/dr2
     670          720 :                   fdik(:) = qq*grc*rij(:)/dr
     671          720 :                   gradient(:, iatom) = gradient(:, iatom) + fdik(:)
     672          740 :                   gradient(:, jatom) = gradient(:, jatom) - fdik(:)
     673              :                END DO
     674              :             END DO
     675              :          END DO
     676              :       END IF
     677              : 
     678              :       ! Forces from Ewald potential: (q+l)*A*q
     679           10 :       IF (do_ewald) THEN
     680           18 :          ALLOCATE (epforce(3, natom))
     681          198 :          epforce = 0.0_dp
     682            6 :          IF (response_only) THEN
     683           54 :             dchia(1:natom) = qlag(1:natom)
     684              :          ELSE
     685            0 :             dchia(1:natom) = -charges(1:natom) + qlag(1:natom)
     686              :          END IF
     687           54 :          chrgx(1:natom) = charges(1:natom)
     688              :          CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
     689            6 :                           particle_set, dchia, epforce)
     690           54 :          dchia(1:natom) = charges(1:natom)
     691           54 :          chrgx(1:natom) = qlag(1:natom)
     692              :          CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
     693            6 :                           particle_set, dchia, epforce)
     694          198 :          gradient(1:3, 1:natom) = gradient(1:3, 1:natom) + epforce(1:3, 1:natom)
     695            6 :          DEALLOCATE (epforce)
     696              : 
     697              :          ! virial
     698            6 :          IF (use_virial) THEN
     699           32 :             chrgx(1:natom) = charges(1:natom) - qlag(1:natom)
     700            4 :             CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
     701           52 :             stress = stress - pvir
     702           32 :             chrgx(1:natom) = qlag(1:natom)
     703            4 :             CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
     704           52 :             stress = stress + pvir
     705            4 :             IF (response_only) THEN
     706           32 :                chrgx(1:natom) = charges(1:natom)
     707            4 :                CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
     708           52 :                stress = stress + pvir
     709              :             END IF
     710              :          END IF
     711              :          !
     712            6 :          CALL ewald_env_release(ewald_env)
     713            6 :          CALL ewald_pw_release(ewald_pw)
     714            6 :          DEALLOCATE (ewald_env, ewald_pw)
     715              :       END IF
     716              : 
     717           10 :       CALL cnumber_release(cnumbers, dcnum, .TRUE.)
     718              : 
     719           10 :       DEALLOCATE (gab, gam, qlag, chrgx, dchia)
     720              : 
     721           10 :       CALL timestop(handle)
     722              : 
     723           20 :    END SUBROUTINE eeq_forces
     724              : 
     725              : ! **************************************************************************************************
     726              : !> \brief ...
     727              : !> \param qs_env ...
     728              : !> \param cnumbers ...
     729              : !> \param dcnum ...
     730              : !> \param calculate_forces ...
     731              : ! **************************************************************************************************
     732           78 :    SUBROUTINE get_cnumbers(qs_env, cnumbers, dcnum, calculate_forces)
     733              : 
     734              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     735              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: cnumbers
     736              :       TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:)        :: dcnum
     737              :       LOGICAL, INTENT(IN)                                :: calculate_forces
     738              : 
     739              :       INTEGER                                            :: ikind, natom, nkind, za
     740              :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: default_present
     741              :       REAL(KIND=dp)                                      :: subcells
     742              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: c_radius
     743              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: pair_radius
     744           78 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     745              :       TYPE(cell_type), POINTER                           :: cell
     746              :       TYPE(distribution_1d_type), POINTER                :: distribution_1d
     747              :       TYPE(distribution_2d_type), POINTER                :: distribution_2d
     748           78 :       TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:)  :: atom2d
     749           78 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     750              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     751           78 :          POINTER                                         :: sab_cn
     752           78 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     753              :       TYPE(qs_dispersion_type), POINTER                  :: disp
     754           78 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     755              : 
     756              :       CALL get_qs_env(qs_env, &
     757              :                       qs_kind_set=qs_kind_set, &
     758              :                       atomic_kind_set=atomic_kind_set, &
     759              :                       particle_set=particle_set, &
     760              :                       cell=cell, &
     761              :                       distribution_2d=distribution_2d, &
     762              :                       local_particles=distribution_1d, &
     763           78 :                       molecule_set=molecule_set)
     764           78 :       CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
     765              : 
     766              :       ! Check for dispersion_env and sab_cn needed for cnumbers
     767          390 :       ALLOCATE (disp)
     768           78 :       disp%k1 = 16.0_dp
     769           78 :       disp%k2 = 4._dp/3._dp
     770           78 :       disp%eps_cn = 1.E-6_dp
     771           78 :       disp%max_elem = maxElem
     772           78 :       ALLOCATE (disp%rcov(maxElem))
     773         6786 :       disp%rcov(1:maxElem) = bohr*disp%k2*rcov(1:maxElem)
     774           78 :       subcells = 2.0_dp
     775              :       ! Build the neighbor lists for the CN
     776           78 :       NULLIFY (sab_cn)
     777          624 :       ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
     778          242 :       c_radius(:) = 0.0_dp
     779          242 :       default_present = .TRUE.
     780          242 :       DO ikind = 1, nkind
     781          164 :          CALL get_atomic_kind(atomic_kind_set(ikind), z=za)
     782          242 :          c_radius(ikind) = 4._dp*rcov(za)*bohr
     783              :       END DO
     784          398 :       ALLOCATE (atom2d(nkind))
     785              :       CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
     786           78 :                         molecule_set, .FALSE., particle_set=particle_set)
     787           78 :       CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
     788              :       CALL build_neighbor_lists(sab_cn, particle_set, atom2d, cell, pair_radius, &
     789           78 :                                 subcells=subcells, operator_type="PP", nlname="sab_cn")
     790           78 :       disp%sab_cn => sab_cn
     791           78 :       DEALLOCATE (c_radius, pair_radius, default_present)
     792           78 :       CALL atom2d_cleanup(atom2d)
     793              : 
     794              :       ! Calculate coordination numbers
     795           78 :       CALL cnumber_init(qs_env, cnumbers, dcnum, 2, calculate_forces, disp_env=disp)
     796              : 
     797           78 :       CALL qs_dispersion_release(disp)
     798              : 
     799          156 :    END SUBROUTINE get_cnumbers
     800              : 
     801              : ! **************************************************************************************************
     802              : !> \brief ...
     803              : !> \param charges ...
     804              : !> \param lambda ...
     805              : !> \param eeq_energy ...
     806              : !> \param particle_set ...
     807              : !> \param kind_of ...
     808              : !> \param cell ...
     809              : !> \param chia ...
     810              : !> \param gam ...
     811              : !> \param gab ...
     812              : !> \param para_env ...
     813              : !> \param blacs_env ...
     814              : !> \param dft_control ...
     815              : !> \param eeq_sparam ...
     816              : !> \param totalcharge ...
     817              : !> \param ewald ...
     818              : !> \param ewald_env ...
     819              : !> \param ewald_pw ...
     820              : !> \param iounit ...
     821              : ! **************************************************************************************************
     822         3756 :    SUBROUTINE eeq_solver(charges, lambda, eeq_energy, particle_set, kind_of, cell, &
     823         3756 :                          chia, gam, gab, para_env, blacs_env, dft_control, eeq_sparam, &
     824              :                          totalcharge, ewald, ewald_env, ewald_pw, iounit)
     825              : 
     826              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
     827              :       REAL(KIND=dp), INTENT(INOUT)                       :: lambda, eeq_energy
     828              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     829              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
     830              :       TYPE(cell_type), POINTER                           :: cell
     831              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: chia, gam
     832              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
     833              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     834              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     835              :       TYPE(dft_control_type), POINTER                    :: dft_control
     836              :       TYPE(eeq_solver_type), INTENT(IN)                  :: eeq_sparam
     837              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: totalcharge
     838              :       LOGICAL, INTENT(IN), OPTIONAL                      :: ewald
     839              :       TYPE(ewald_environment_type), OPTIONAL, POINTER    :: ewald_env
     840              :       TYPE(ewald_pw_type), OPTIONAL, POINTER             :: ewald_pw
     841              :       INTEGER, INTENT(IN), OPTIONAL                      :: iounit
     842              : 
     843              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'eeq_solver'
     844              : 
     845              :       INTEGER                                            :: handle, ierror, iunit, natom, nkind, ns
     846              :       LOGICAL                                            :: do_direct, do_displ, do_ewald, do_sparse
     847              :       REAL(KIND=dp)                                      :: alpha, deth, ftime, qtot
     848              :       TYPE(cp_fm_struct_type), POINTER                   :: mat_struct
     849              :       TYPE(cp_fm_type)                                   :: eeq_mat
     850              : 
     851         1878 :       CALL timeset(routineN, handle)
     852              : 
     853         1878 :       do_ewald = .FALSE.
     854         1878 :       IF (PRESENT(ewald)) do_ewald = ewald
     855              :       !
     856         1878 :       qtot = 0.0_dp
     857         1878 :       IF (PRESENT(totalcharge)) qtot = totalcharge
     858              :       !
     859         1878 :       iunit = -1
     860         1878 :       IF (PRESENT(iounit)) iunit = iounit
     861              : 
     862              :       ! EEQ solver parameters
     863         1878 :       do_direct = eeq_sparam%direct
     864         1878 :       do_sparse = eeq_sparam%sparse
     865              : 
     866         1878 :       do_displ = .FALSE.
     867         1878 :       IF (dft_control%apply_period_efield .AND. ASSOCIATED(dft_control%period_efield)) THEN
     868          200 :          do_displ = dft_control%period_efield%displacement_field
     869              :       END IF
     870              : 
     871              :       ! sparse option NYA
     872         1878 :       IF (do_sparse) THEN
     873            0 :          CALL cp_abort(__LOCATION__, "EEQ: Sparse option not yet available")
     874              :       END IF
     875              :       !
     876         1878 :       natom = SIZE(particle_set)
     877         1878 :       nkind = SIZE(gam)
     878         1878 :       ns = natom + 1
     879              :       CALL cp_fm_struct_create(mat_struct, context=blacs_env, para_env=para_env, &
     880         1878 :                                nrow_global=ns, ncol_global=ns)
     881         1878 :       CALL cp_fm_create(eeq_mat, mat_struct)
     882         1878 :       CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
     883              :       !
     884         1878 :       IF (do_ewald) THEN
     885          864 :          CPASSERT(PRESENT(ewald_env))
     886          864 :          CPASSERT(PRESENT(ewald_pw))
     887          864 :          IF (do_direct) THEN
     888            0 :             IF (do_displ) THEN
     889            0 :                CPABORT("NYA")
     890              :             ELSE
     891              :                CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
     892              :                                 kind_of, cell, chia, gam, gab, qtot, &
     893            0 :                                 ewald_env, ewald_pw, iounit)
     894              :             END IF
     895              :          ELSE
     896          864 :             IF (do_displ) THEN
     897            0 :                CPABORT("NYA")
     898              :             ELSE
     899              :                ierror = 0
     900              :                CALL pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
     901              :                                kind_of, cell, chia, gam, gab, qtot, &
     902          864 :                                ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
     903          864 :                IF (ierror /= 0) THEN
     904              :                   ! backup to non-iterative method
     905              :                   CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
     906              :                                    kind_of, cell, chia, gam, gab, qtot, &
     907          730 :                                    ewald_env, ewald_pw, iounit)
     908              :                END IF
     909              :             END IF
     910              :          END IF
     911          864 :          IF (qtot /= 0._dp) THEN
     912          104 :             CALL get_cell(cell=cell, deth=deth)
     913          104 :             CALL ewald_env_get(ewald_env, alpha=alpha)
     914          104 :             eeq_energy = eeq_energy - 0.5_dp*qtot**2/alpha**2/deth
     915              :          END IF
     916              :       ELSE
     917              :          CALL mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, &
     918         1014 :                         cell, chia, gam, gab, qtot, ftime)
     919         1014 :          IF (iounit > 0) THEN
     920          997 :             WRITE (iunit, '(A,T67,F14.3)') " EEQ| Molecular solver time[s]", ftime
     921              :          END IF
     922              :       END IF
     923         1878 :       CALL cp_fm_struct_release(mat_struct)
     924         1878 :       CALL cp_fm_release(eeq_mat)
     925              : 
     926         1878 :       CALL timestop(handle)
     927              : 
     928         1878 :    END SUBROUTINE eeq_solver
     929              : 
     930              : ! **************************************************************************************************
     931              : !> \brief ...
     932              : !> \param charges ...
     933              : !> \param lambda ...
     934              : !> \param eeq_energy ...
     935              : !> \param eeq_mat ...
     936              : !> \param particle_set ...
     937              : !> \param kind_of ...
     938              : !> \param cell ...
     939              : !> \param chia ...
     940              : !> \param gam ...
     941              : !> \param gab ...
     942              : !> \param qtot ...
     943              : !> \param ftime ...
     944              : ! **************************************************************************************************
     945         1878 :    SUBROUTINE mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, cell, &
     946         1878 :                         chia, gam, gab, qtot, ftime)
     947              : 
     948              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
     949              :       REAL(KIND=dp), INTENT(INOUT)                       :: lambda, eeq_energy
     950              :       TYPE(cp_fm_type)                                   :: eeq_mat
     951              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     952              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
     953              :       TYPE(cell_type), POINTER                           :: cell
     954              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: chia, gam
     955              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
     956              :       REAL(KIND=dp), INTENT(IN)                          :: qtot
     957              :       REAL(KIND=dp), INTENT(OUT)                         :: ftime
     958              : 
     959              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'mi_solver'
     960              : 
     961              :       INTEGER                                            :: handle, ia, iac, iar, ic, ikind, ir, &
     962              :                                                             jkind, natom, ncloc, ncvloc, nkind, &
     963              :                                                             nrloc, nrvloc, ns
     964         1878 :       INTEGER, DIMENSION(:), POINTER                     :: cind, cvind, rind, rvind
     965              :       REAL(KIND=dp)                                      :: dr, grc, te, ti, xr
     966              :       REAL(KIND=dp), DIMENSION(3)                        :: ri, rij, rj
     967              :       TYPE(cp_fm_struct_type), POINTER                   :: mat_struct, vec_struct
     968              :       TYPE(cp_fm_type)                                   :: rhs_vec
     969              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     970              : 
     971         1878 :       CALL timeset(routineN, handle)
     972         1878 :       ti = m_walltime()
     973              : 
     974         1878 :       natom = SIZE(particle_set)
     975         1878 :       nkind = SIZE(gam)
     976              :       !
     977         1878 :       ns = natom + 1
     978         1878 :       CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
     979              :       CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
     980         1878 :                           row_indices=rind, col_indices=cind)
     981              :       CALL cp_fm_struct_create(vec_struct, template_fmstruct=mat_struct, &
     982         1878 :                                nrow_global=ns, ncol_global=1)
     983         1878 :       CALL cp_fm_create(rhs_vec, vec_struct)
     984              :       CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
     985         1878 :                           row_indices=rvind, col_indices=cvind)
     986              :       !
     987              :       ! set up matrix
     988         1878 :       CALL cp_fm_set_all(eeq_mat, 1.0_dp, 0.0_dp)
     989         1878 :       CALL cp_fm_set_all(rhs_vec, 0.0_dp)
     990         7299 :       DO ir = 1, nrloc
     991         5421 :          iar = rind(ir)
     992         5421 :          IF (iar > natom) CYCLE
     993         4482 :          ikind = kind_of(iar)
     994        17928 :          ri(1:3) = particle_set(iar)%r(1:3)
     995        40974 :          DO ic = 1, ncloc
     996        34614 :             iac = cind(ic)
     997        34614 :             IF (iac > natom) CYCLE
     998        30132 :             jkind = kind_of(iac)
     999       120528 :             rj(1:3) = particle_set(iac)%r(1:3)
    1000        30132 :             IF (iar == iac) THEN
    1001         4482 :                grc = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi
    1002              :             ELSE
    1003       102600 :                rij(1:3) = ri(1:3) - rj(1:3)
    1004       102600 :                rij = pbc(rij, cell)
    1005       102600 :                dr = SQRT(SUM(rij**2))
    1006        25650 :                grc = erf(gab(ikind, jkind)*dr)/dr
    1007              :             END IF
    1008        40035 :             eeq_mat%local_data(ir, ic) = grc
    1009              :          END DO
    1010              :       END DO
    1011              :       ! set up rhs vector
    1012         7299 :       DO ir = 1, nrvloc
    1013         5421 :          iar = rvind(ir)
    1014        12720 :          DO ic = 1, ncvloc
    1015         5421 :             iac = cvind(ic)
    1016         5421 :             ia = MAX(iar, iac)
    1017         5421 :             IF (ia > natom) THEN
    1018          939 :                xr = qtot
    1019              :             ELSE
    1020         4482 :                xr = -chia(ia)
    1021              :             END IF
    1022        10842 :             rhs_vec%local_data(ir, ic) = xr
    1023              :          END DO
    1024              :       END DO
    1025              :       !
    1026         1878 :       CALL cp_fm_solve(eeq_mat, rhs_vec)
    1027              :       !
    1028        10842 :       charges = 0.0_dp
    1029         1878 :       lambda = 0.0_dp
    1030         7299 :       DO ir = 1, nrvloc
    1031         5421 :          iar = rvind(ir)
    1032        12720 :          DO ic = 1, ncvloc
    1033         5421 :             iac = cvind(ic)
    1034         5421 :             ia = MAX(iar, iac)
    1035        10842 :             IF (ia <= natom) THEN
    1036         4482 :                xr = rhs_vec%local_data(ir, ic)
    1037         4482 :                charges(ia) = xr
    1038              :             ELSE
    1039          939 :                lambda = rhs_vec%local_data(ir, ic)
    1040              :             END IF
    1041              :          END DO
    1042              :       END DO
    1043         1878 :       CALL para_env%sum(lambda)
    1044        19806 :       CALL para_env%sum(charges)
    1045              :       !
    1046              :       ! energy:   0.5*(q^T.X - lambda*totalcharge)
    1047        10842 :       eeq_energy = 0.5*SUM(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
    1048              : 
    1049         1878 :       CALL cp_fm_struct_release(vec_struct)
    1050         1878 :       CALL cp_fm_release(rhs_vec)
    1051              : 
    1052         1878 :       te = m_walltime()
    1053         1878 :       ftime = te - ti
    1054         1878 :       CALL timestop(handle)
    1055              : 
    1056         1878 :    END SUBROUTINE mi_solver
    1057              : 
    1058              : ! **************************************************************************************************
    1059              : !> \brief ...
    1060              : !> \param charges ...
    1061              : !> \param lambda ...
    1062              : !> \param eeq_energy ...
    1063              : !> \param eeq_mat ...
    1064              : !> \param particle_set ...
    1065              : !> \param kind_of ...
    1066              : !> \param cell ...
    1067              : !> \param chia ...
    1068              : !> \param gam ...
    1069              : !> \param gab ...
    1070              : !> \param qtot ...
    1071              : !> \param ewald_env ...
    1072              : !> \param ewald_pw ...
    1073              : !> \param eeq_sparam ...
    1074              : !> \param ierror ...
    1075              : !> \param iounit ...
    1076              : ! **************************************************************************************************
    1077          864 :    SUBROUTINE pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
    1078          864 :                          kind_of, cell, chia, gam, gab, qtot, &
    1079              :                          ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
    1080              : 
    1081              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
    1082              :       REAL(KIND=dp), INTENT(INOUT)                       :: lambda, eeq_energy
    1083              :       TYPE(cp_fm_type)                                   :: eeq_mat
    1084              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    1085              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
    1086              :       TYPE(cell_type), POINTER                           :: cell
    1087              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: chia, gam
    1088              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
    1089              :       REAL(KIND=dp), INTENT(IN)                          :: qtot
    1090              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1091              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    1092              :       TYPE(eeq_solver_type), INTENT(IN)                  :: eeq_sparam
    1093              :       INTEGER, INTENT(OUT)                               :: ierror
    1094              :       INTEGER, OPTIONAL                                  :: iounit
    1095              : 
    1096              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'pbc_solver'
    1097              : 
    1098              :       INTEGER :: ewald_type, handle, i, iac, iar, ic, ikind, info, ir, iunit, iv, ix, iy, iz, &
    1099              :          jkind, max_diis, mdiis, natom, ncloc, ndiis, nkind, now, nrloc, ns, sdiis
    1100              :       INTEGER, DIMENSION(3)                              :: cvec, ncell, periodic
    1101          864 :       INTEGER, DIMENSION(:), POINTER                     :: cind, rind
    1102              :       REAL(KIND=dp)                                      :: ad, alpha, astep, deth, dr, eeqn, &
    1103              :                                                             eps_diis, ftime, grc1, grc2, rcut, &
    1104              :                                                             res, resin, rmax, te, ti
    1105          864 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: bvec, dvec
    1106          864 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: dmat, fvec, vmat, xvec
    1107              :       REAL(KIND=dp), DIMENSION(3)                        :: ri, rij, rijl, rj
    1108              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    1109          864 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rhs, rv0, xv0
    1110              :       TYPE(cp_fm_struct_type), POINTER                   :: mat_struct
    1111              :       TYPE(cp_fm_type)                                   :: mmat, pmat
    1112              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1113              : 
    1114          864 :       CALL timeset(routineN, handle)
    1115          864 :       ti = m_walltime()
    1116              : 
    1117          864 :       ierror = 0
    1118              : 
    1119          864 :       iunit = -1
    1120          864 :       IF (PRESENT(iounit)) iunit = iounit
    1121              : 
    1122          864 :       natom = SIZE(particle_set)
    1123          864 :       nkind = SIZE(gam)
    1124              :       !
    1125          864 :       CALL get_cell(cell=cell, deth=deth)
    1126          864 :       CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
    1127          864 :       ad = 2.0_dp*alpha*oorootpi
    1128          864 :       IF (ewald_type /= do_ewald_spme) THEN
    1129            0 :          CALL cp_abort(__LOCATION__, "Only SPME Ewald method available with EEQ.")
    1130              :       END IF
    1131              :       !
    1132          864 :       rmax = 2.0_dp*rcut
    1133              :       ! max cells used
    1134          864 :       CALL get_cell(cell, h=hmat, periodic=periodic)
    1135          864 :       ncell(1) = CEILING(rmax/plane_distance(1, 0, 0, cell))
    1136          864 :       ncell(2) = CEILING(rmax/plane_distance(0, 1, 0, cell))
    1137          864 :       ncell(3) = CEILING(rmax/plane_distance(0, 0, 1, cell))
    1138          864 :       IF (periodic(1) == 0) ncell(1) = 0
    1139          864 :       IF (periodic(2) == 0) ncell(2) = 0
    1140          864 :       IF (periodic(3) == 0) ncell(3) = 0
    1141              :       !
    1142              :       CALL mi_solver(charges, lambda, eeqn, eeq_mat, particle_set, kind_of, cell, &
    1143          864 :                      chia, gam, gab, qtot, ftime)
    1144          864 :       IF (iunit > 0) THEN
    1145          831 :          WRITE (iunit, '(A,T67,F14.3)') " EEQ| Iterative PBC guess time[s]", ftime
    1146              :       END IF
    1147          864 :       CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
    1148          864 :       CALL cp_fm_create(pmat, mat_struct)
    1149          864 :       CALL cp_fm_create(mmat, mat_struct)
    1150              :       !
    1151              :       ! response matrix
    1152              :       CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
    1153          864 :                           row_indices=rind, col_indices=cind)
    1154          864 :       CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
    1155         3688 :       DO ir = 1, nrloc
    1156         2824 :          iar = rind(ir)
    1157         2824 :          ri = 0.0_dp
    1158         2824 :          IF (iar <= natom) THEN
    1159         2392 :             ikind = kind_of(iar)
    1160         9568 :             ri(1:3) = particle_set(iar)%r(1:3)
    1161              :          END IF
    1162        28070 :          DO ic = 1, ncloc
    1163        24382 :             iac = cind(ic)
    1164        24382 :             IF (iac > natom .AND. iar > natom) THEN
    1165          432 :                eeq_mat%local_data(ir, ic) = 0.0_dp
    1166          432 :                CYCLE
    1167        23950 :             ELSE IF ((iac > natom) .OR. (iar > natom)) THEN
    1168         4784 :                eeq_mat%local_data(ir, ic) = 1.0_dp
    1169         4784 :                CYCLE
    1170              :             END IF
    1171        19166 :             jkind = kind_of(iac)
    1172        76664 :             rj(1:3) = particle_set(iac)%r(1:3)
    1173        76664 :             rij(1:3) = ri(1:3) - rj(1:3)
    1174        76664 :             rij = pbc(rij, cell)
    1175       156152 :             DO ix = -ncell(1), ncell(1)
    1176      1092462 :                DO iy = -ncell(2), ncell(2)
    1177      7647234 :                   DO iz = -ncell(3), ncell(3)
    1178     26295752 :                      cvec = [ix, iy, iz]
    1179    124904822 :                      rijl = rij + MATMUL(hmat, cvec)
    1180     26295752 :                      dr = SQRT(SUM(rijl**2))
    1181      6573938 :                      IF (dr > rmax) CYCLE
    1182      1570014 :                      IF (iar == iac .AND. dr < 0.00001_dp) THEN
    1183         2392 :                         grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi - ad
    1184              :                      ELSE
    1185      1567622 :                         grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
    1186              :                      END IF
    1187      2509148 :                      eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
    1188              :                   END DO
    1189              :                END DO
    1190              :             END DO
    1191              :          END DO
    1192              :       END DO
    1193              :       !
    1194              :       ! preconditioner
    1195              :       CALL cp_fm_get_info(pmat, nrow_local=nrloc, ncol_local=ncloc, &
    1196          864 :                           row_indices=rind, col_indices=cind)
    1197          864 :       CALL cp_fm_set_all(pmat, 0.0_dp, 0.0_dp)
    1198         3688 :       DO ir = 1, nrloc
    1199         2824 :          iar = rind(ir)
    1200         2824 :          ri = 0.0_dp
    1201         2824 :          IF (iar <= natom) THEN
    1202         2392 :             ikind = kind_of(iar)
    1203         9568 :             ri(1:3) = particle_set(iar)%r(1:3)
    1204              :          END IF
    1205        28070 :          DO ic = 1, ncloc
    1206        24382 :             iac = cind(ic)
    1207        24382 :             IF (iac > natom .AND. iar > natom) THEN
    1208          432 :                pmat%local_data(ir, ic) = 0.0_dp
    1209          432 :                CYCLE
    1210        23950 :             ELSE IF ((iac > natom) .OR. (iar > natom)) THEN
    1211         4784 :                pmat%local_data(ir, ic) = 1.0_dp
    1212         4784 :                CYCLE
    1213              :             END IF
    1214        19166 :             jkind = kind_of(iac)
    1215        76664 :             rj(1:3) = particle_set(iac)%r(1:3)
    1216        76664 :             rij(1:3) = ri(1:3) - rj(1:3)
    1217        76664 :             rij = pbc(rij, cell)
    1218        19166 :             IF (iar == iac) THEN
    1219         2392 :                grc2 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi
    1220              :             ELSE
    1221        16774 :                grc2 = erf(gab(ikind, jkind)*dr)/dr
    1222              :             END IF
    1223        21990 :             pmat%local_data(ir, ic) = grc2
    1224              :          END DO
    1225              :       END DO
    1226          864 :       CALL cp_fm_set_all(mmat, 0.0_dp, 0.0_dp)
    1227              :       ! preconditioner invers
    1228          864 :       CALL cp_fm_invert(pmat, mmat)
    1229              :       !
    1230              :       ! rhs
    1231          864 :       ns = natom + 1
    1232         2592 :       ALLOCATE (rhs(ns))
    1233         5648 :       rhs(1:natom) = chia(1:natom)
    1234          864 :       rhs(ns) = -qtot
    1235              :       !
    1236         2592 :       ALLOCATE (xv0(ns), rv0(ns))
    1237              :       ! initial guess
    1238         5648 :       xv0(1:natom) = charges(1:natom)
    1239          864 :       xv0(ns) = 0.0_dp
    1240              :       ! DIIS optimizer
    1241          864 :       max_diis = eeq_sparam%max_diis
    1242          864 :       mdiis = eeq_sparam%mdiis
    1243          864 :       sdiis = eeq_sparam%sdiis
    1244          864 :       eps_diis = eeq_sparam%eps_diis
    1245          864 :       astep = eeq_sparam%alpha
    1246         6048 :       ALLOCATE (xvec(ns, mdiis), fvec(ns, mdiis), bvec(ns))
    1247       157152 :       xvec = 0.0_dp; fvec = 0.0_dp
    1248         7776 :       ALLOCATE (vmat(mdiis, mdiis), dmat(mdiis + 1, mdiis + 1), dvec(mdiis + 1))
    1249       169344 :       dmat = 0.0_dp; dvec = 0.0_dp
    1250          864 :       ndiis = 1
    1251          864 :       now = 1
    1252              :       CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
    1253          864 :                                cell, particle_set, xv0, rhs, rv0)
    1254         6512 :       resin = SQRT(SUM(rv0*rv0))
    1255              :       !
    1256         8578 :       DO iv = 1, max_diis
    1257        75160 :          res = SQRT(SUM(rv0*rv0))
    1258         8578 :          IF (res > 10._dp*resin) EXIT
    1259         7848 :          IF (res < eps_diis) EXIT
    1260              :          !
    1261         7714 :          now = MOD(iv - 1, mdiis) + 1
    1262         7714 :          ndiis = MIN(iv, mdiis)
    1263        68648 :          xvec(1:ns, now) = xv0(1:ns)
    1264        68648 :          fvec(1:ns, now) = rv0(1:ns)
    1265        56454 :          DO i = 1, ndiis
    1266       477304 :             vmat(now, i) = SUM(fvec(:, now)*fvec(:, i))
    1267        56454 :             vmat(i, now) = vmat(now, i)
    1268              :          END DO
    1269         7714 :          IF (ndiis < sdiis) THEN
    1270        24192 :             xv0(1:ns) = xv0(1:ns) + astep*rv0(1:ns)
    1271              :          ELSE
    1272        84028 :             dvec = 0.0_dp
    1273         6002 :             dvec(ndiis + 1) = 1.0_dp
    1274       484946 :             dmat(1:ndiis, 1:ndiis) = vmat(1:ndiis, 1:ndiis)
    1275        52174 :             dmat(ndiis + 1, 1:ndiis) = 1.0_dp
    1276        52174 :             dmat(1:ndiis, ndiis + 1) = 1.0_dp
    1277         6002 :             dmat(ndiis + 1, ndiis + 1) = 0.0_dp
    1278         6002 :             CALL invmat(dmat(1:ndiis + 1, 1:ndiis + 1), info)
    1279       693642 :             dvec(1:ndiis + 1) = MATMUL(dmat(1:ndiis + 1, 1:ndiis + 1), dvec(1:ndiis + 1))
    1280       513572 :             xv0(1:ns) = MATMUL(xvec(1:ns, 1:ndiis), dvec(1:ndiis))
    1281       575270 :             xv0(1:ns) = xv0(1:ns) + MATMUL(fvec(1:ns, 1:ndiis), dvec(1:ndiis))
    1282              :          END IF
    1283              :          !
    1284              :          CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
    1285         8578 :                                   cell, particle_set, xv0, rhs, rv0)
    1286              :       END DO
    1287         5648 :       charges(1:natom) = xv0(1:natom)
    1288          864 :       lambda = xv0(ns)
    1289          864 :       eeq_energy = eeqn
    1290          864 :       IF (res > eps_diis) ierror = 1
    1291              :       !
    1292          864 :       DEALLOCATE (xvec, fvec, bvec)
    1293          864 :       DEALLOCATE (vmat, dmat, dvec)
    1294          864 :       DEALLOCATE (xv0, rv0)
    1295          864 :       DEALLOCATE (rhs)
    1296          864 :       CALL cp_fm_release(pmat)
    1297          864 :       CALL cp_fm_release(mmat)
    1298              : 
    1299          864 :       te = m_walltime()
    1300          864 :       IF (iunit > 0) THEN
    1301          831 :          IF (ierror == 1) THEN
    1302          714 :             WRITE (iunit, '(A)') " EEQ| PBC solver failed to converge "
    1303              :          ELSE
    1304          117 :             WRITE (iunit, '(A,T50,I4,T61,E20.5)') " EEQ| PBC solver: iterations/accuracy ", iv, res
    1305              :          END IF
    1306          831 :          WRITE (iunit, '(A,T67,F14.3)') " EEQ| Iterative PBC solver: time[s]", te - ti
    1307              :       END IF
    1308          864 :       CALL timestop(handle)
    1309              : 
    1310         3456 :    END SUBROUTINE pbc_solver
    1311              : 
    1312              : ! **************************************************************************************************
    1313              : !> \brief ...
    1314              : !> \param charges ...
    1315              : !> \param lambda ...
    1316              : !> \param eeq_energy ...
    1317              : !> \param eeq_mat ...
    1318              : !> \param particle_set ...
    1319              : !> \param kind_of ...
    1320              : !> \param cell ...
    1321              : !> \param chia ...
    1322              : !> \param gam ...
    1323              : !> \param gab ...
    1324              : !> \param qtot ...
    1325              : !> \param ewald_env ...
    1326              : !> \param ewald_pw ...
    1327              : !> \param iounit ...
    1328              : ! **************************************************************************************************
    1329          730 :    SUBROUTINE fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
    1330          730 :                           kind_of, cell, chia, gam, gab, qtot, ewald_env, ewald_pw, iounit)
    1331              : 
    1332              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
    1333              :       REAL(KIND=dp), INTENT(INOUT)                       :: lambda, eeq_energy
    1334              :       TYPE(cp_fm_type)                                   :: eeq_mat
    1335              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    1336              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
    1337              :       TYPE(cell_type), POINTER                           :: cell
    1338              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: chia, gam
    1339              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
    1340              :       REAL(KIND=dp), INTENT(IN)                          :: qtot
    1341              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1342              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    1343              :       INTEGER, INTENT(IN), OPTIONAL                      :: iounit
    1344              : 
    1345              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'fpbc_solver'
    1346              : 
    1347              :       INTEGER                                            :: ewald_type, handle, ia, iac, iar, ic, &
    1348              :                                                             ikind, ir, iunit, ix, iy, iz, jkind, &
    1349              :                                                             natom, ncloc, ncvloc, nkind, nrloc, &
    1350              :                                                             nrvloc, ns
    1351              :       INTEGER, DIMENSION(3)                              :: cvec, ncell, periodic
    1352          730 :       INTEGER, DIMENSION(:), POINTER                     :: cind, cvind, rind, rvind
    1353              :       REAL(KIND=dp)                                      :: ad, alpha, deth, dr, grc1, rcut, rmax, &
    1354              :                                                             te, ti, xr
    1355              :       REAL(KIND=dp), DIMENSION(3)                        :: ri, rij, rijl, rj
    1356              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    1357          730 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: pval, xval
    1358              :       TYPE(cp_fm_struct_type), POINTER                   :: mat_struct, vec_struct
    1359              :       TYPE(cp_fm_type)                                   :: rhs_vec
    1360              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1361              : 
    1362          730 :       CALL timeset(routineN, handle)
    1363          730 :       ti = m_walltime()
    1364              : 
    1365          730 :       iunit = -1
    1366          730 :       IF (PRESENT(iounit)) iunit = iounit
    1367              : 
    1368          730 :       natom = SIZE(particle_set)
    1369          730 :       nkind = SIZE(gam)
    1370          730 :       ns = natom + 1
    1371              :       !
    1372          730 :       CALL get_cell(cell=cell, deth=deth)
    1373          730 :       CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
    1374          730 :       ad = 2.0_dp*alpha*oorootpi
    1375          730 :       IF (ewald_type /= do_ewald_spme) THEN
    1376            0 :          CALL cp_abort(__LOCATION__, "Only SPME Ewald method available with EEQ.")
    1377              :       END IF
    1378              :       !
    1379          730 :       rmax = 2.0_dp*rcut
    1380              :       ! max cells used
    1381          730 :       CALL get_cell(cell, h=hmat, periodic=periodic)
    1382          730 :       ncell(1) = CEILING(rmax/plane_distance(1, 0, 0, cell))
    1383          730 :       ncell(2) = CEILING(rmax/plane_distance(0, 1, 0, cell))
    1384          730 :       ncell(3) = CEILING(rmax/plane_distance(0, 0, 1, cell))
    1385          730 :       IF (periodic(1) == 0) ncell(1) = 0
    1386          730 :       IF (periodic(2) == 0) ncell(2) = 0
    1387          730 :       IF (periodic(3) == 0) ncell(3) = 0
    1388              :       !
    1389          730 :       CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
    1390          730 :       CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
    1391              :       CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
    1392          730 :                           row_indices=rind, col_indices=cind)
    1393              :       CALL cp_fm_struct_create(vec_struct, template_fmstruct=mat_struct, &
    1394          730 :                                nrow_global=ns, ncol_global=1)
    1395          730 :       CALL cp_fm_create(rhs_vec, vec_struct)
    1396              :       CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
    1397          730 :                           row_indices=rvind, col_indices=cvind)
    1398              :       ! response matrix
    1399         3051 :       DO ir = 1, nrloc
    1400         2321 :          iar = rind(ir)
    1401         2321 :          ri = 0.0_dp
    1402         2321 :          IF (iar <= natom) THEN
    1403         1956 :             ikind = kind_of(iar)
    1404         7824 :             ri(1:3) = particle_set(iar)%r(1:3)
    1405              :          END IF
    1406        19210 :          DO ic = 1, ncloc
    1407        16159 :             iac = cind(ic)
    1408        16159 :             IF (iac > natom .AND. iar > natom) THEN
    1409          365 :                eeq_mat%local_data(ir, ic) = 0.0_dp
    1410          365 :                CYCLE
    1411        15794 :             ELSE IF ((iac > natom) .OR. (iar > natom)) THEN
    1412         3912 :                eeq_mat%local_data(ir, ic) = 1.0_dp
    1413         3912 :                CYCLE
    1414              :             END IF
    1415        11882 :             jkind = kind_of(iac)
    1416        47528 :             rj(1:3) = particle_set(iac)%r(1:3)
    1417        47528 :             rij(1:3) = ri(1:3) - rj(1:3)
    1418        47528 :             rij = pbc(rij, cell)
    1419        97377 :             DO ix = -ncell(1), ncell(1)
    1420       677274 :                DO iy = -ncell(2), ncell(2)
    1421      4740918 :                   DO iz = -ncell(3), ncell(3)
    1422     16302104 :                      cvec = [ix, iy, iz]
    1423     77434994 :                      rijl = rij + MATMUL(hmat, cvec)
    1424     16302104 :                      dr = SQRT(SUM(rijl**2))
    1425      4075526 :                      IF (dr > rmax) CYCLE
    1426       972848 :                      IF (iar == iac .AND. dr < 0.0001_dp) THEN
    1427         1956 :                         grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi - ad
    1428              :                      ELSE
    1429       970892 :                         grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
    1430              :                      END IF
    1431      1555066 :                      eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
    1432              :                   END DO
    1433              :                END DO
    1434              :             END DO
    1435              :          END DO
    1436              :       END DO
    1437              :       !
    1438         2920 :       ALLOCATE (xval(natom), pval(natom))
    1439         4642 :       DO ia = 1, natom
    1440        27676 :          xval = 0.0_dp
    1441         3912 :          xval(ia) = 1.0_dp
    1442         3912 :          CALL apply_potential(ewald_env, ewald_pw, cell, particle_set, xval, pval)
    1443              :          !
    1444        18480 :          DO ir = 1, nrloc
    1445        13838 :             iar = rind(ir)
    1446        13838 :             IF (iar /= ia) CYCLE
    1447        19706 :             DO ic = 1, ncloc
    1448        13838 :                iac = cind(ic)
    1449        13838 :                IF (iac > natom) CYCLE
    1450        27676 :                eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + pval(iac)
    1451              :             END DO
    1452              :          END DO
    1453              :       END DO
    1454          730 :       DEALLOCATE (xval, pval)
    1455              :       !
    1456              :       ! set up rhs vector
    1457         3051 :       DO ir = 1, nrvloc
    1458         2321 :          iar = rvind(ir)
    1459         5372 :          DO ic = 1, ncvloc
    1460         2321 :             iac = cvind(ic)
    1461         2321 :             ia = MAX(iar, iac)
    1462         2321 :             IF (ia > natom) THEN
    1463          365 :                xr = qtot
    1464              :             ELSE
    1465         1956 :                xr = -chia(ia)
    1466              :             END IF
    1467         4642 :             rhs_vec%local_data(ir, ic) = xr
    1468              :          END DO
    1469              :       END DO
    1470              :       !
    1471          730 :       CALL cp_fm_solve(eeq_mat, rhs_vec)
    1472              :       !
    1473         4642 :       charges = 0.0_dp
    1474          730 :       lambda = 0.0_dp
    1475         3051 :       DO ir = 1, nrvloc
    1476         2321 :          iar = rvind(ir)
    1477         5372 :          DO ic = 1, ncvloc
    1478         2321 :             iac = cvind(ic)
    1479         2321 :             ia = MAX(iar, iac)
    1480         4642 :             IF (ia <= natom) THEN
    1481         1956 :                xr = rhs_vec%local_data(ir, ic)
    1482         1956 :                charges(ia) = xr
    1483              :             ELSE
    1484          365 :                lambda = rhs_vec%local_data(ir, ic)
    1485              :             END IF
    1486              :          END DO
    1487              :       END DO
    1488          730 :       CALL para_env%sum(lambda)
    1489         8554 :       CALL para_env%sum(charges)
    1490              :       !
    1491              :       ! energy:   0.5*(q^T.X - lambda*totalcharge)
    1492         4642 :       eeq_energy = 0.5*SUM(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
    1493              : 
    1494          730 :       CALL cp_fm_struct_release(vec_struct)
    1495          730 :       CALL cp_fm_release(rhs_vec)
    1496              : 
    1497          730 :       te = m_walltime()
    1498          730 :       IF (iunit > 0) THEN
    1499          714 :          WRITE (iunit, '(A,T67,F14.3)') " EEQ| Direct PBC solver: time[s]", te - ti
    1500              :       END IF
    1501          730 :       CALL timestop(handle)
    1502              : 
    1503         2920 :    END SUBROUTINE fpbc_solver
    1504              : 
    1505              : ! **************************************************************************************************
    1506              : !> \brief ...
    1507              : !> \param ewald_env ...
    1508              : !> \param ewald_pw ...
    1509              : !> \param cell ...
    1510              : !> \param particle_set ...
    1511              : !> \param charges ...
    1512              : !> \param potential ...
    1513              : ! **************************************************************************************************
    1514         3912 :    SUBROUTINE apply_potential(ewald_env, ewald_pw, cell, particle_set, charges, potential)
    1515              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1516              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    1517              :       TYPE(cell_type), POINTER                           :: cell
    1518              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    1519              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), POINTER   :: charges
    1520              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: potential
    1521              : 
    1522              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1523              : 
    1524         3912 :       CALL ewald_env_get(ewald_env, para_env=para_env)
    1525        27676 :       potential = 0.0_dp
    1526              :       CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges, &
    1527         3912 :                           particle_set, potential)
    1528        51440 :       CALL para_env%sum(potential)
    1529              : 
    1530         3912 :    END SUBROUTINE apply_potential
    1531              : 
    1532              : ! **************************************************************************************************
    1533              : !> \brief ...
    1534              : !> \param eeqn ...
    1535              : !> \param fm_mat ...
    1536              : !> \param mmat ...
    1537              : !> \param ewald_env ...
    1538              : !> \param ewald_pw ...
    1539              : !> \param cell ...
    1540              : !> \param particle_set ...
    1541              : !> \param charges ...
    1542              : !> \param rhs ...
    1543              : !> \param potential ...
    1544              : ! **************************************************************************************************
    1545         8578 :    SUBROUTINE get_energy_gradient(eeqn, fm_mat, mmat, ewald_env, ewald_pw, &
    1546         8578 :                                   cell, particle_set, charges, rhs, potential)
    1547              :       REAL(KIND=dp), INTENT(INOUT)                       :: eeqn
    1548              :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mat, mmat
    1549              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1550              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    1551              :       TYPE(cell_type), POINTER                           :: cell
    1552              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    1553              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), POINTER   :: charges
    1554              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: rhs
    1555              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: potential
    1556              : 
    1557              :       INTEGER                                            :: na, ns
    1558              :       REAL(KIND=dp)                                      :: lambda
    1559              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: mvec
    1560              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1561              : 
    1562         8578 :       ns = SIZE(charges)
    1563         8578 :       na = ns - 1
    1564         8578 :       CALL ewald_env_get(ewald_env, para_env=para_env)
    1565        75160 :       potential = 0.0_dp
    1566              :       CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges(1:na), &
    1567         8578 :                           particle_set, potential(1:na))
    1568       124586 :       CALL para_env%sum(potential(1:na))
    1569         8578 :       CALL cp_fm_matvec(fm_mat, charges, potential, alpha=1.0_dp, beta=1.0_dp)
    1570       133164 :       eeqn = 0.5_dp*SUM(charges(1:na)*potential(1:na)) + SUM(charges(1:na)*rhs(1:na))
    1571        75160 :       potential(1:ns) = potential(1:ns) + rhs(1:ns)
    1572        25734 :       ALLOCATE (mvec(ns))
    1573         8578 :       CALL cp_fm_matvec(mmat, potential, mvec, alpha=-1.0_dp, beta=0.0_dp)
    1574        66582 :       lambda = -SUM(mvec(1:na))/REAL(na, KIND=dp)
    1575        66582 :       potential(1:na) = mvec(1:na) + lambda
    1576         8578 :       DEALLOCATE (mvec)
    1577              : 
    1578         8578 :    END SUBROUTINE get_energy_gradient
    1579              : 
    1580              : ! **************************************************************************************************
    1581              : !> \brief ...
    1582              : !> \param qs_env ...
    1583              : !> \param charges ...
    1584              : !> \param ef_energy ...
    1585              : ! **************************************************************************************************
    1586          328 :    SUBROUTINE eeq_efield_energy(qs_env, charges, ef_energy)
    1587              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1588              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges
    1589              :       REAL(KIND=dp), INTENT(OUT)                         :: ef_energy
    1590              : 
    1591              :       COMPLEX(KIND=dp)                                   :: zdeta
    1592              :       COMPLEX(KIND=dp), DIMENSION(3)                     :: zi
    1593              :       INTEGER                                            :: ia, idir, natom
    1594              :       LOGICAL                                            :: dfield
    1595              :       REAL(KIND=dp)                                      :: kr, omega, q
    1596              :       REAL(KIND=dp), DIMENSION(3)                        :: ci, dfilter, fieldpol, fpolvec, kvec, &
    1597              :                                                             qi, ria
    1598              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    1599              :       TYPE(cell_type), POINTER                           :: cell
    1600              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1601          328 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1602              : 
    1603          328 :       CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
    1604          328 :       CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
    1605              : 
    1606          328 :       IF (dft_control%apply_period_efield) THEN
    1607          164 :          dfield = dft_control%period_efield%displacement_field
    1608              : 
    1609          164 :          IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
    1610            0 :             CPABORT("use of strength_list not implemented for eeq_efield_energy")
    1611              :          END IF
    1612              : 
    1613          656 :          fieldpol = dft_control%period_efield%polarisation
    1614         1148 :          fieldpol = fieldpol/SQRT(DOT_PRODUCT(fieldpol, fieldpol))
    1615          656 :          fieldpol = -fieldpol*dft_control%period_efield%strength
    1616         2132 :          hmat = cell%hmat(:, :)/twopi
    1617          656 :          DO idir = 1, 3
    1618              :             fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
    1619          656 :                             + fieldpol(3)*hmat(3, idir)
    1620              :          END DO
    1621              : 
    1622          656 :          zi(:) = CMPLX(1._dp, 0._dp, dp)
    1623          820 :          DO ia = 1, natom
    1624          656 :             q = charges(ia)
    1625         2624 :             ria = particle_set(ia)%r
    1626         2624 :             ria = pbc(ria, cell)
    1627         2788 :             DO idir = 1, 3
    1628         7872 :                kvec(:) = twopi*cell%h_inv(idir, :)
    1629         7872 :                kr = SUM(kvec(:)*ria(:))
    1630         1968 :                zdeta = CMPLX(COS(kr), SIN(kr), KIND=dp)**q
    1631         2624 :                zi(idir) = zi(idir)*zdeta
    1632              :             END DO
    1633              :          END DO
    1634          656 :          qi = AIMAG(LOG(zi))
    1635          164 :          IF (dfield) THEN
    1636            0 :             dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
    1637            0 :             omega = cell%deth
    1638            0 :             ci = MATMUL(hmat, qi)/omega
    1639            0 :             ef_energy = 0.0_dp
    1640            0 :             DO idir = 1, 3
    1641            0 :                ef_energy = ef_energy + dfilter(idir)*(fieldpol(idir) - 2._dp*twopi*ci(idir))**2
    1642              :             END DO
    1643            0 :             ef_energy = -0.25_dp*omega/twopi*ef_energy
    1644              :          ELSE
    1645          656 :             ef_energy = SUM(fpolvec(:)*qi(:))
    1646              :          END IF
    1647              : 
    1648          164 :       ELSE IF (dft_control%apply_efield) THEN
    1649              : 
    1650              :          fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
    1651          656 :                     dft_control%efield_fields(1)%efield%strength
    1652              : 
    1653          164 :          ef_energy = 0.0_dp
    1654          820 :          DO ia = 1, natom
    1655         2624 :             ria = particle_set(ia)%r
    1656         2624 :             ria = pbc(ria, cell)
    1657          656 :             q = charges(ia)
    1658         2788 :             ef_energy = ef_energy - q*SUM(fieldpol*ria)
    1659              :          END DO
    1660              : 
    1661              :       ELSE
    1662            0 :          CPABORT("apply field")
    1663              :       END IF
    1664              : 
    1665          328 :    END SUBROUTINE eeq_efield_energy
    1666              : 
    1667              : ! **************************************************************************************************
    1668              : !> \brief ...
    1669              : !> \param qs_env ...
    1670              : !> \param efr ...
    1671              : ! **************************************************************************************************
    1672          328 :    SUBROUTINE eeq_efield_pot(qs_env, efr)
    1673              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1674              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: efr
    1675              : 
    1676              :       INTEGER                                            :: ia, idir, natom
    1677              :       LOGICAL                                            :: dfield
    1678              :       REAL(KIND=dp)                                      :: kr
    1679              :       REAL(KIND=dp), DIMENSION(3)                        :: fieldpol, fpolvec, kvec, ria
    1680              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    1681              :       TYPE(cell_type), POINTER                           :: cell
    1682              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1683          328 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1684              : 
    1685          328 :       CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
    1686          328 :       CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
    1687              : 
    1688          328 :       IF (dft_control%apply_period_efield) THEN
    1689          164 :          dfield = dft_control%period_efield%displacement_field
    1690              : 
    1691          164 :          IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
    1692            0 :             CPABORT("use of strength_list not implemented for eeq_efield_pot")
    1693              :          END IF
    1694              : 
    1695          656 :          fieldpol = dft_control%period_efield%polarisation
    1696         1148 :          fieldpol = fieldpol/SQRT(DOT_PRODUCT(fieldpol, fieldpol))
    1697          656 :          fieldpol = -fieldpol*dft_control%period_efield%strength
    1698         2132 :          hmat = cell%hmat(:, :)/twopi
    1699          656 :          DO idir = 1, 3
    1700              :             fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
    1701          656 :                             + fieldpol(3)*hmat(3, idir)
    1702              :          END DO
    1703              : 
    1704          164 :          IF (dfield) THEN
    1705              :             ! dE/dq depends on q, postpone calculation
    1706            0 :             efr = 0.0_dp
    1707              :          ELSE
    1708          820 :             efr = 0.0_dp
    1709          820 :             DO ia = 1, natom
    1710         2624 :                ria = particle_set(ia)%r
    1711         2624 :                ria = pbc(ria, cell)
    1712         2788 :                DO idir = 1, 3
    1713         7872 :                   kvec(:) = twopi*cell%h_inv(idir, :)
    1714         7872 :                   kr = SUM(kvec(:)*ria(:))
    1715         2624 :                   efr(ia) = efr(ia) + kr*fpolvec(idir)
    1716              :                END DO
    1717              :             END DO
    1718              :          END IF
    1719              : 
    1720          164 :       ELSE IF (dft_control%apply_efield) THEN
    1721              : 
    1722              :          fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
    1723          656 :                     dft_control%efield_fields(1)%efield%strength
    1724              : 
    1725          820 :          DO ia = 1, natom
    1726         2624 :             ria = particle_set(ia)%r
    1727         2624 :             ria = pbc(ria, cell)
    1728         2788 :             efr(ia) = -SUM(fieldpol*ria)
    1729              :          END DO
    1730              : 
    1731              :       ELSE
    1732            0 :          CPABORT("apply field")
    1733              :       END IF
    1734              : 
    1735          328 :    END SUBROUTINE eeq_efield_pot
    1736              : 
    1737              : ! **************************************************************************************************
    1738              : !> \brief ...
    1739              : !> \param charges ...
    1740              : !> \param dft_control ...
    1741              : !> \param particle_set ...
    1742              : !> \param cell ...
    1743              : !> \param efr ...
    1744              : ! **************************************************************************************************
    1745            0 :    SUBROUTINE eeq_dfield_pot(charges, dft_control, particle_set, cell, efr)
    1746              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges
    1747              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1748              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    1749              :       TYPE(cell_type), POINTER                           :: cell
    1750              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: efr
    1751              : 
    1752              :       COMPLEX(KIND=dp)                                   :: zdeta
    1753              :       COMPLEX(KIND=dp), DIMENSION(3)                     :: zi
    1754              :       INTEGER                                            :: ia, idir, natom
    1755              :       REAL(KIND=dp)                                      :: kr, omega, q
    1756              :       REAL(KIND=dp), DIMENSION(3)                        :: ci, dfilter, fieldpol, kvec, qi, ria
    1757              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    1758              : 
    1759            0 :       natom = SIZE(particle_set)
    1760              : 
    1761            0 :       IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
    1762            0 :          CPABORT("use of strength_list not implemented for eeq_dfield_pot")
    1763              :       END IF
    1764              : 
    1765            0 :       dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
    1766            0 :       fieldpol = dft_control%period_efield%polarisation
    1767            0 :       fieldpol = fieldpol/SQRT(DOT_PRODUCT(fieldpol, fieldpol))
    1768            0 :       fieldpol = -fieldpol*dft_control%period_efield%strength
    1769            0 :       hmat = cell%hmat(:, :)/twopi
    1770            0 :       omega = cell%deth
    1771              :       !
    1772            0 :       zi(:) = CMPLX(1._dp, 0._dp, dp)
    1773            0 :       DO ia = 1, natom
    1774            0 :          q = charges(ia)
    1775            0 :          ria = particle_set(ia)%r
    1776            0 :          ria = pbc(ria, cell)
    1777            0 :          DO idir = 1, 3
    1778            0 :             kvec(:) = twopi*cell%h_inv(idir, :)
    1779            0 :             kr = SUM(kvec(:)*ria(:))
    1780            0 :             zdeta = CMPLX(COS(kr), SIN(kr), KIND=dp)**q
    1781            0 :             zi(idir) = zi(idir)*zdeta
    1782              :          END DO
    1783              :       END DO
    1784            0 :       qi = AIMAG(LOG(zi))
    1785            0 :       ci = MATMUL(hmat, qi)/omega
    1786            0 :       ci = dfilter*(fieldpol - 2._dp*twopi*ci)
    1787            0 :       DO ia = 1, natom
    1788            0 :          ria = particle_set(ia)%r
    1789            0 :          ria = pbc(ria, cell)
    1790            0 :          efr(ia) = efr(ia) - SUM(ci*ria)
    1791              :       END DO
    1792              : 
    1793            0 :    END SUBROUTINE eeq_dfield_pot
    1794              : 
    1795              : ! **************************************************************************************************
    1796              : !> \brief ...
    1797              : !> \param qs_env ...
    1798              : !> \param charges ...
    1799              : !> \param qlag ...
    1800              : ! **************************************************************************************************
    1801            8 :    SUBROUTINE eeq_efield_force_loc(qs_env, charges, qlag)
    1802              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1803              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges, qlag
    1804              : 
    1805              :       INTEGER                                            :: atom_a, ia, iatom, ikind, natom, nkind
    1806            8 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind
    1807              :       REAL(KIND=dp)                                      :: q
    1808              :       REAL(KIND=dp), DIMENSION(3)                        :: fieldpol
    1809            8 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1810              :       TYPE(cell_type), POINTER                           :: cell
    1811              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1812              :       TYPE(distribution_1d_type), POINTER                :: local_particles
    1813              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1814            8 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1815            8 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    1816              : 
    1817              :       CALL get_qs_env(qs_env=qs_env, &
    1818              :                       dft_control=dft_control, &
    1819              :                       cell=cell, particle_set=particle_set, &
    1820              :                       nkind=nkind, natom=natom, &
    1821              :                       para_env=para_env, &
    1822            8 :                       local_particles=local_particles)
    1823              : 
    1824              :       fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
    1825           32 :                  dft_control%efield_fields(1)%efield%strength
    1826              : 
    1827            8 :       CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
    1828            8 :       CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind)
    1829            8 :       CALL get_qs_env(qs_env=qs_env, force=force)
    1830              : 
    1831           32 :       DO ikind = 1, nkind
    1832          152 :          force(ikind)%efield = 0.0_dp
    1833           40 :          DO ia = 1, local_particles%n_el(ikind)
    1834           16 :             iatom = local_particles%list(ikind)%array(ia)
    1835           16 :             q = charges(iatom) - qlag(iatom)
    1836           16 :             atom_a = atom_of_kind(iatom)
    1837           88 :             force(ikind)%efield(1:3, atom_a) = -q*fieldpol(1:3)
    1838              :          END DO
    1839          288 :          CALL para_env%sum(force(ikind)%efield)
    1840              :       END DO
    1841              : 
    1842           16 :    END SUBROUTINE eeq_efield_force_loc
    1843              : 
    1844              : ! **************************************************************************************************
    1845              : !> \brief ...
    1846              : !> \param qs_env ...
    1847              : !> \param charges ...
    1848              : !> \param qlag ...
    1849              : ! **************************************************************************************************
    1850            8 :    SUBROUTINE eeq_efield_force_periodic(qs_env, charges, qlag)
    1851              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1852              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges, qlag
    1853              : 
    1854              :       INTEGER                                            :: atom_a, ia, iatom, ikind, natom, nkind
    1855            8 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind
    1856              :       LOGICAL                                            :: dfield, use_virial
    1857              :       REAL(KIND=dp)                                      :: q
    1858              :       REAL(KIND=dp), DIMENSION(3)                        :: fa, fieldpol, ria
    1859              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: pve
    1860            8 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1861              :       TYPE(cell_type), POINTER                           :: cell
    1862              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1863              :       TYPE(distribution_1d_type), POINTER                :: local_particles
    1864              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1865            8 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1866            8 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    1867              :       TYPE(virial_type), POINTER                         :: virial
    1868              : 
    1869              :       CALL get_qs_env(qs_env=qs_env, &
    1870              :                       dft_control=dft_control, &
    1871              :                       cell=cell, particle_set=particle_set, &
    1872              :                       virial=virial, &
    1873              :                       nkind=nkind, natom=natom, &
    1874              :                       para_env=para_env, &
    1875            8 :                       local_particles=local_particles)
    1876              : 
    1877            8 :       dfield = dft_control%period_efield%displacement_field
    1878            8 :       CPASSERT(.NOT. dfield)
    1879              : 
    1880            8 :       IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
    1881            0 :          CPABORT("use of strength_list not implemented for eeq_efield_force_periodic")
    1882              :       END IF
    1883              : 
    1884           32 :       fieldpol = dft_control%period_efield%polarisation
    1885           56 :       fieldpol = fieldpol/SQRT(DOT_PRODUCT(fieldpol, fieldpol))
    1886           32 :       fieldpol = -fieldpol*dft_control%period_efield%strength
    1887              : 
    1888            8 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
    1889              : 
    1890            8 :       CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
    1891            8 :       CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind)
    1892            8 :       CALL get_qs_env(qs_env=qs_env, force=force)
    1893              : 
    1894            8 :       pve = 0.0_dp
    1895           32 :       DO ikind = 1, nkind
    1896          152 :          force(ikind)%efield = 0.0_dp
    1897           40 :          DO ia = 1, local_particles%n_el(ikind)
    1898           16 :             iatom = local_particles%list(ikind)%array(ia)
    1899           16 :             q = charges(iatom) - qlag(iatom)
    1900           64 :             fa(1:3) = q*fieldpol(1:3)
    1901           16 :             atom_a = atom_of_kind(iatom)
    1902           64 :             force(ikind)%efield(1:3, atom_a) = fa
    1903           40 :             IF (use_virial) THEN
    1904            0 :                ria = particle_set(ia)%r
    1905            0 :                ria = pbc(ria, cell)
    1906            0 :                CALL virial_pair_force(pve, -0.5_dp, fa, ria)
    1907            0 :                CALL virial_pair_force(pve, -0.5_dp, ria, fa)
    1908              :             END IF
    1909              :          END DO
    1910          288 :          CALL para_env%sum(force(ikind)%efield)
    1911              :       END DO
    1912          104 :       virial%pv_virial = virial%pv_virial + pve
    1913              : 
    1914           16 :    END SUBROUTINE eeq_efield_force_periodic
    1915              : 
    1916        12004 : END MODULE eeq_method
        

Generated by: LCOV version 2.0-1