LCOV - code coverage report
Current view: top level - src - eeq_method.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:24d69ee) Lines: 91.2 % 1111 1013
Test Date: 2026-09-03 07:32:15 Functions: 95.8 % 24 23

            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              :                                               int_8
      55              :    USE machine,                         ONLY: m_walltime
      56              :    USE mathconstants,                   ONLY: oorootpi,&
      57              :                                               twopi
      58              :    USE mathlib,                         ONLY: invmat
      59              :    USE message_passing,                 ONLY: mp_para_env_type
      60              :    USE molecule_types,                  ONLY: molecule_type
      61              :    USE particle_types,                  ONLY: particle_type
      62              :    USE physcon,                         ONLY: bohr
      63              :    USE pw_poisson_types,                ONLY: do_ewald_spme
      64              :    USE qs_dispersion_cnum,              ONLY: cnumber_init,&
      65              :                                               cnumber_release,&
      66              :                                               dcnum_type
      67              :    USE qs_dispersion_types,             ONLY: qs_dispersion_release,&
      68              :                                               qs_dispersion_type
      69              :    USE qs_environment_types,            ONLY: get_qs_env,&
      70              :                                               qs_environment_type
      71              :    USE qs_force_types,                  ONLY: qs_force_type
      72              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      73              :                                               qs_kind_type
      74              :    USE qs_neighbor_list_types,          ONLY: get_iterator_info,&
      75              :                                               neighbor_list_iterate,&
      76              :                                               neighbor_list_iterator_create,&
      77              :                                               neighbor_list_iterator_p_type,&
      78              :                                               neighbor_list_iterator_release,&
      79              :                                               neighbor_list_set_p_type,&
      80              :                                               release_neighbor_list_sets
      81              :    USE qs_neighbor_lists,               ONLY: atom2d_build,&
      82              :                                               atom2d_cleanup,&
      83              :                                               build_neighbor_lists,&
      84              :                                               local_atoms_type,&
      85              :                                               pair_radius_setup
      86              :    USE spme,                            ONLY: spme_forces,&
      87              :                                               spme_potential,&
      88              :                                               spme_virial
      89              :    USE util,                            ONLY: sort
      90              :    USE virial_methods,                  ONLY: virial_pair_force
      91              :    USE virial_types,                    ONLY: virial_type
      92              : #include "./base/base_uses.f90"
      93              : 
      94              :    IMPLICIT NONE
      95              : 
      96              :    PRIVATE
      97              : 
      98              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'eeq_method'
      99              : 
     100              :    INTEGER, PARAMETER                                    :: maxElem = 86
     101              : 
     102              :    TYPE eeq_sparse_matrix_type
     103              :       INTEGER, ALLOCATABLE, DIMENSION(:)                :: col, row
     104              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)          :: diag, value
     105              :       INTEGER                                           :: nactive = 0
     106              :    END TYPE eeq_sparse_matrix_type
     107              :    ! covalent radii (taken from Pyykko and Atsumi, Chem. Eur. J. 15, 2009, 188-197)
     108              :    ! values for metals decreased by 10 %
     109              :    REAL(KIND=dp), PARAMETER :: rcov(1:maxElem) = [&
     110              :       & 0.32_dp, 0.46_dp, 1.20_dp, 0.94_dp, 0.77_dp, 0.75_dp, 0.71_dp, 0.63_dp, &
     111              :       & 0.64_dp, 0.67_dp, 1.40_dp, 1.25_dp, 1.13_dp, 1.04_dp, 1.10_dp, 1.02_dp, &
     112              :       & 0.99_dp, 0.96_dp, 1.76_dp, 1.54_dp, 1.33_dp, 1.22_dp, 1.21_dp, 1.10_dp, &
     113              :       & 1.07_dp, 1.04_dp, 1.00_dp, 0.99_dp, 1.01_dp, 1.09_dp, 1.12_dp, 1.09_dp, &
     114              :       & 1.15_dp, 1.10_dp, 1.14_dp, 1.17_dp, 1.89_dp, 1.67_dp, 1.47_dp, 1.39_dp, &
     115              :       & 1.32_dp, 1.24_dp, 1.15_dp, 1.13_dp, 1.13_dp, 1.08_dp, 1.15_dp, 1.23_dp, &
     116              :       & 1.28_dp, 1.26_dp, 1.26_dp, 1.23_dp, 1.32_dp, 1.31_dp, 2.09_dp, 1.76_dp, &
     117              :       & 1.62_dp, 1.47_dp, 1.58_dp, 1.57_dp, 1.56_dp, 1.55_dp, 1.51_dp, 1.52_dp, &
     118              :       & 1.51_dp, 1.50_dp, 1.49_dp, 1.49_dp, 1.48_dp, 1.53_dp, 1.46_dp, 1.37_dp, &
     119              :       & 1.31_dp, 1.23_dp, 1.18_dp, 1.16_dp, 1.11_dp, 1.12_dp, 1.13_dp, 1.32_dp, &
     120              :       & 1.30_dp, 1.30_dp, 1.36_dp, 1.31_dp, 1.38_dp, 1.42_dp]
     121              : 
     122              :    PUBLIC :: eeq_solver, eeq_print, eeq_charges, eeq_forces, &
     123              :              eeq_efield_energy, eeq_efield_pot, eeq_efield_force_loc, eeq_efield_force_periodic
     124              : 
     125              : CONTAINS
     126              : 
     127              : ! **************************************************************************************************
     128              : !> \brief ...
     129              : !> \param qs_env ...
     130              : !> \param iounit ...
     131              : !> \param print_level ...
     132              : !> \param ext ...
     133              : ! **************************************************************************************************
     134           38 :    SUBROUTINE eeq_print(qs_env, iounit, print_level, ext)
     135              : 
     136              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     137              :       INTEGER, INTENT(IN)                                :: iounit, print_level
     138              :       LOGICAL, INTENT(IN)                                :: ext
     139              : 
     140              :       CHARACTER(LEN=2)                                   :: element_symbol
     141              :       INTEGER                                            :: enshift_type, iatom, ikind, natom
     142           38 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: charges
     143              :       TYPE(cell_type), POINTER                           :: cell
     144              :       TYPE(eeq_solver_type)                              :: eeq_sparam
     145           38 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     146              : 
     147              :       MARK_USED(print_level)
     148              : 
     149           38 :       CALL get_qs_env(qs_env, natom=natom, particle_set=particle_set, cell=cell)
     150           38 :       IF (ext) THEN
     151            0 :          NULLIFY (charges)
     152            0 :          CALL get_qs_env(qs_env, eeq=charges)
     153            0 :          CPASSERT(ASSOCIATED(charges))
     154            0 :          enshift_type = 0
     155              :       ELSE
     156          114 :          ALLOCATE (charges(natom))
     157              :          ! enforce en shift method 1 (original/molecular)
     158              :          ! method 2 from paper on PBC seems not to work
     159           38 :          enshift_type = 1
     160              :          !IF (ALL(cell%perd == 0)) enshift_type = 1
     161           38 :          CALL eeq_charges(qs_env, charges, eeq_sparam, 2, enshift_type)
     162              :       END IF
     163              : 
     164           38 :       IF (iounit > 0) THEN
     165              : 
     166           19 :          IF (enshift_type == 0) THEN
     167            0 :             WRITE (UNIT=iounit, FMT="(/,T2,A)") "EEQ Charges (External)"
     168           19 :          ELSE IF (enshift_type == 1) THEN
     169           19 :             WRITE (UNIT=iounit, FMT="(/,T2,A)") "EEQ Charges (Parametrization 2019 (Molecules))"
     170            0 :          ELSE IF (enshift_type == 2) THEN
     171            0 :             WRITE (UNIT=iounit, FMT="(/,T2,A)") "EEQ Charges (Parametrization 2019 (Crystals))"
     172              :          ELSE
     173            0 :             CPABORT("Unknown enshift_type")
     174              :          END IF
     175              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
     176           19 :             "#     Atom  Element     Kind            Atomic Charge"
     177              : 
     178          140 :          DO iatom = 1, natom
     179              :             CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, &
     180              :                                  element_symbol=element_symbol, &
     181          121 :                                  kind_number=ikind)
     182              :             WRITE (UNIT=iounit, FMT="(T4,I8,T18,A2,I10,T43,F12.4)") &
     183          140 :                iatom, element_symbol, ikind, charges(iatom)
     184              :          END DO
     185              : 
     186              :       END IF
     187              : 
     188           38 :       IF (.NOT. ext) DEALLOCATE (charges)
     189              : 
     190           38 :    END SUBROUTINE eeq_print
     191              : 
     192              : ! **************************************************************************************************
     193              : !> \brief ...
     194              : !> \param qs_env ...
     195              : !> \param charges ...
     196              : !> \param eeq_sparam ...
     197              : !> \param eeq_model ...
     198              : !> \param enshift_type ...
     199              : !> \param exclude ...
     200              : !> \param cn_max ...
     201              : ! **************************************************************************************************
     202           90 :    SUBROUTINE eeq_charges(qs_env, charges, eeq_sparam, eeq_model, enshift_type, exclude, cn_max)
     203              : 
     204              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     205              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
     206              :       TYPE(eeq_solver_type), INTENT(IN)                  :: eeq_sparam
     207              :       INTEGER, INTENT(IN)                                :: eeq_model, enshift_type
     208              :       LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL        :: exclude
     209              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: cn_max
     210              : 
     211              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'eeq_charges'
     212              : 
     213              :       INTEGER                                            :: handle, iatom, ikind, iunit, jkind, &
     214              :                                                             natom, nkind, za, zb
     215           90 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: kind_of
     216              :       INTEGER, DIMENSION(3)                              :: periodic
     217              :       LOGICAL                                            :: do_ewald
     218              :       REAL(KIND=dp)                                      :: ala, alb, eeq_energy, esg, kappa, &
     219              :                                                             lambda, scn, sgamma, totalcharge, xi
     220           90 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: chia, cnumbers, efr, gam
     221              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: gab
     222           90 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     223              :       TYPE(cell_type), POINTER                           :: cell, cell_ref
     224              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     225              :       TYPE(cp_logger_type), POINTER                      :: logger
     226           90 :       TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:)        :: dcnum
     227              :       TYPE(dft_control_type), POINTER                    :: dft_control
     228              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
     229              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
     230              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     231           90 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     232           90 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     233              :       TYPE(section_vals_type), POINTER                   :: ewald_section, poisson_section, &
     234              :                                                             print_section
     235              : 
     236           90 :       CALL timeset(routineN, handle)
     237              : 
     238              :       CALL get_qs_env(qs_env, &
     239              :                       qs_kind_set=qs_kind_set, &
     240              :                       atomic_kind_set=atomic_kind_set, &
     241              :                       particle_set=particle_set, &
     242              :                       para_env=para_env, &
     243              :                       blacs_env=blacs_env, &
     244              :                       cell=cell, &
     245           90 :                       dft_control=dft_control)
     246           90 :       CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
     247              : 
     248           90 :       logger => cp_get_default_logger()
     249           90 :       IF (para_env%is_source() .AND. logger%iter_info%print_level >= medium_print_level) THEN
     250           37 :          iunit = cp_logger_get_default_unit_nr()
     251              :       ELSE
     252           53 :          iunit = -1
     253              :       END IF
     254              : 
     255           90 :       totalcharge = dft_control%charge
     256              : 
     257           90 :       CALL get_cnumbers(qs_env, cnumbers, dcnum, .FALSE.)
     258              : 
     259              :       ! Apply smooth logistic CN cutoff to match multicharge/D4 behavior
     260           90 :       IF (PRESENT(cn_max)) THEN
     261          472 :          DO iatom = 1, natom
     262          472 :             cnumbers(iatom) = LOG(1.0_dp + EXP(cn_max)) - LOG(1.0_dp + EXP(cn_max - cnumbers(iatom)))
     263              :          END DO
     264              :       END IF
     265              : 
     266              :       ! gamma[a,b]
     267          540 :       ALLOCATE (gab(nkind, nkind), gam(nkind))
     268           90 :       gab = 0.0_dp
     269           90 :       gam = 0.0_dp
     270          286 :       DO ikind = 1, nkind
     271          196 :          CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
     272          196 :          CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
     273          750 :          DO jkind = 1, nkind
     274          464 :             CALL get_qs_kind(qs_kind_set(jkind), zatom=zb)
     275          464 :             CALL get_eeq_data(zb, eeq_model, rad=alb)
     276              :             !
     277          660 :             gab(ikind, jkind) = SQRT(1._dp/(ala*ala + alb*alb))
     278              :             !
     279              :          END DO
     280              :       END DO
     281              : 
     282              :       ! Override parameters for excluded kinds (ghost/floating atoms in BSSE):
     283              :       ! huge hardness + zero coupling -> q = 0, no influence on other atoms.
     284           90 :       IF (PRESENT(exclude)) THEN
     285          168 :          DO ikind = 1, nkind
     286          168 :             IF (exclude(ikind)) THEN
     287            8 :                gam(ikind) = 1.0e30_dp
     288           40 :                gab(ikind, :) = 0.0_dp
     289           40 :                gab(:, ikind) = 0.0_dp
     290              :             END IF
     291              :          END DO
     292              :       END IF
     293              : 
     294              :       ! Chi[a,a]
     295           90 :       sgamma = 8.0_dp ! see D4 for periodic systems paper
     296           90 :       esg = 1.0_dp + EXP(sgamma)
     297          270 :       ALLOCATE (chia(natom))
     298           90 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, kind_of=kind_of)
     299          752 :       DO iatom = 1, natom
     300          662 :          ikind = kind_of(iatom)
     301          662 :          CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
     302          662 :          CALL get_eeq_data(za, eeq_model, chi=xi, kcn=kappa)
     303              :          !
     304          662 :          IF (enshift_type == 1) THEN
     305          662 :             scn = cnumbers(iatom)/SQRT(cnumbers(iatom) + 1.0e-14_dp)
     306            0 :          ELSE IF (enshift_type == 2) THEN
     307            0 :             scn = LOG(esg/(esg - cnumbers(iatom)))
     308              :          ELSE
     309            0 :             CPABORT("Unknown enshift_type")
     310              :          END IF
     311         1414 :          chia(iatom) = xi - kappa*scn
     312              :          !
     313              :       END DO
     314              : 
     315              :       ! Zero electronegativity for excluded atoms (ghost/floating in BSSE)
     316           90 :       IF (PRESENT(exclude)) THEN
     317          472 :          DO iatom = 1, natom
     318          420 :             ikind = kind_of(iatom)
     319          472 :             IF (exclude(ikind)) chia(iatom) = 0.0_dp
     320              :          END DO
     321              :       END IF
     322              : 
     323              :       ! efield
     324           90 :       IF (dft_control%apply_period_efield .OR. dft_control%apply_efield .OR. &
     325              :           dft_control%apply_efield_field) THEN
     326            0 :          ALLOCATE (efr(natom))
     327            0 :          efr(1:natom) = 0.0_dp
     328            0 :          CALL eeq_efield_pot(qs_env, efr)
     329            0 :          chia(1:natom) = chia(1:natom) + efr(1:natom)
     330            0 :          DEALLOCATE (efr)
     331              :       END IF
     332              : 
     333           90 :       CALL cnumber_release(cnumbers, dcnum, .FALSE.)
     334              : 
     335           90 :       CALL get_cell(cell, periodic=periodic)
     336          204 :       do_ewald = .NOT. ALL(periodic == 0)
     337           90 :       IF (do_ewald) THEN
     338          832 :          ALLOCATE (ewald_env)
     339           52 :          CALL ewald_env_create(ewald_env, para_env)
     340           52 :          poisson_section => section_vals_get_subs_vals(qs_env%input, "DFT%POISSON")
     341           52 :          CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
     342           52 :          ewald_section => section_vals_get_subs_vals(poisson_section, "EWALD")
     343           52 :          print_section => section_vals_get_subs_vals(qs_env%input, "PRINT%GRID_INFORMATION")
     344           52 :          CALL get_qs_env(qs_env, cell_ref=cell_ref)
     345              :          CALL read_ewald_section_tb(ewald_env, ewald_section, cell_ref%hmat, &
     346           52 :                                     silent=.TRUE., pset="EEQ", cell_periodic=cell%perd)
     347           52 :          ALLOCATE (ewald_pw)
     348           52 :          CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
     349              :          !
     350              :          CALL eeq_solver(charges, lambda, eeq_energy, &
     351              :                          particle_set, kind_of, cell, chia, gam, gab, &
     352              :                          para_env, blacs_env, dft_control, eeq_sparam, &
     353              :                          totalcharge=totalcharge, ewald=do_ewald, &
     354           52 :                          ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit, qs_env=qs_env)
     355              :          !
     356           52 :          CALL ewald_env_release(ewald_env)
     357           52 :          CALL ewald_pw_release(ewald_pw)
     358           52 :          DEALLOCATE (ewald_env, ewald_pw)
     359              :       ELSE
     360              :          CALL eeq_solver(charges, lambda, eeq_energy, &
     361              :                          particle_set, kind_of, cell, chia, gam, gab, &
     362              :                          para_env, blacs_env, dft_control, eeq_sparam, &
     363           38 :                          totalcharge=totalcharge, iounit=iunit, qs_env=qs_env)
     364              :       END IF
     365              : 
     366           90 :       DEALLOCATE (gab, gam, chia)
     367              : 
     368           90 :       CALL timestop(handle)
     369              : 
     370          180 :    END SUBROUTINE eeq_charges
     371              : 
     372              : ! **************************************************************************************************
     373              : !> \brief ...
     374              : !> \param qs_env ...
     375              : !> \param charges ...
     376              : !> \param dcharges ...
     377              : !> \param gradient ...
     378              : !> \param stress ...
     379              : !> \param eeq_sparam ...
     380              : !> \param eeq_model ...
     381              : !> \param enshift_type ...
     382              : !> \param response_only ...
     383              : !> \param exclude ...
     384              : !> \param cn_max ...
     385              : ! **************************************************************************************************
     386           14 :    SUBROUTINE eeq_forces(qs_env, charges, dcharges, gradient, stress, &
     387           14 :                          eeq_sparam, eeq_model, enshift_type, response_only, exclude, cn_max)
     388              : 
     389              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     390              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges, dcharges
     391              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: gradient
     392              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT)      :: stress
     393              :       TYPE(eeq_solver_type), INTENT(IN)                  :: eeq_sparam
     394              :       INTEGER, INTENT(IN)                                :: eeq_model, enshift_type
     395              :       LOGICAL, INTENT(IN)                                :: response_only
     396              :       LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL        :: exclude
     397              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: cn_max
     398              : 
     399              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'eeq_forces'
     400              : 
     401              :       INTEGER                                            :: handle, i, ia, iatom, ikind, iunit, &
     402              :                                                             jatom, jkind, katom, natom, nkind, za, &
     403              :                                                             zb
     404           14 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: kind_of
     405              :       INTEGER, DIMENSION(3)                              :: periodic
     406              :       LOGICAL                                            :: do_ewald, use_virial
     407           14 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: default_present
     408              :       REAL(KIND=dp) :: ala, alb, alpha, cn, ctot, dcnpdcn, dr, dr2, drk, elag, esg, fe, gam2, &
     409              :          gama, grc, kappa, qlam, qq, qq1, qq2, rcut, scn, sgamma, subcells, totalcharge, xi
     410           14 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: c_radius, cnumbers, gam, qlag
     411           14 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: epforce, gab, pair_radius
     412              :       REAL(KIND=dp), DIMENSION(3)                        :: fdik, ri, rij, rik, rj
     413              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: pvir
     414           14 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: chrgx, dchia
     415           14 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     416              :       TYPE(atprop_type), POINTER                         :: atprop
     417              :       TYPE(cell_type), POINTER                           :: cell, cell_ref
     418              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     419              :       TYPE(cp_logger_type), POINTER                      :: logger
     420           14 :       TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:)        :: dcnum
     421              :       TYPE(dft_control_type), POINTER                    :: dft_control
     422              :       TYPE(distribution_1d_type), POINTER                :: distribution_1d, local_particles
     423              :       TYPE(distribution_2d_type), POINTER                :: distribution_2d
     424              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
     425              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
     426           14 :       TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:)  :: atom2d
     427           14 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     428              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     429              :       TYPE(neighbor_list_iterator_p_type), &
     430           14 :          DIMENSION(:), POINTER                           :: nl_iterator
     431              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     432           14 :          POINTER                                         :: sab_ew
     433           14 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     434           14 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     435           14 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     436              :       TYPE(section_vals_type), POINTER                   :: ewald_section, poisson_section, &
     437              :                                                             print_section
     438              :       TYPE(virial_type), POINTER                         :: virial
     439              : 
     440           14 :       CALL timeset(routineN, handle)
     441              : 
     442              :       CALL get_qs_env(qs_env, &
     443              :                       qs_kind_set=qs_kind_set, &
     444              :                       atomic_kind_set=atomic_kind_set, &
     445              :                       particle_set=particle_set, &
     446              :                       para_env=para_env, &
     447              :                       blacs_env=blacs_env, &
     448              :                       cell=cell, &
     449              :                       force=force, &
     450              :                       virial=virial, &
     451              :                       atprop=atprop, &
     452           14 :                       dft_control=dft_control)
     453              : 
     454           14 :       logger => cp_get_default_logger()
     455           14 :       IF (para_env%is_source() .AND. logger%iter_info%print_level >= medium_print_level) THEN
     456            4 :          iunit = cp_logger_get_default_unit_nr()
     457              :       ELSE
     458           10 :          iunit = -1
     459              :       END IF
     460              : 
     461           14 :       CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
     462           14 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     463              : 
     464           14 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, kind_of=kind_of)
     465              : 
     466           14 :       totalcharge = dft_control%charge
     467              : 
     468           14 :       CALL get_cnumbers(qs_env, cnumbers, dcnum, .TRUE.)
     469              : 
     470              :       ! Apply smooth logistic CN cutoff to match multicharge/D4 behavior
     471              :       ! Chain rule: dcn_cut/dR = (dcn_cut/dcn) * (dcn/dR)
     472           14 :       IF (PRESENT(cn_max)) THEN
     473          118 :          DO iatom = 1, natom
     474          104 :             dcnpdcn = EXP(cn_max)/(EXP(cn_max) + EXP(cnumbers(iatom)))
     475          104 :             cnumbers(iatom) = LOG(1.0_dp + EXP(cn_max)) - LOG(1.0_dp + EXP(cn_max - cnumbers(iatom)))
     476          270 :             DO i = 1, dcnum(iatom)%neighbors
     477          256 :                dcnum(iatom)%dvals(i) = dcnum(iatom)%dvals(i)*dcnpdcn
     478              :             END DO
     479              :          END DO
     480              :       END IF
     481              : 
     482              :       ! gamma[a,b]
     483           84 :       ALLOCATE (gab(nkind, nkind), gam(nkind))
     484           14 :       gab = 0.0_dp
     485           14 :       gam = 0.0_dp
     486           44 :       DO ikind = 1, nkind
     487           30 :          CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
     488           30 :          CALL get_eeq_data(za, eeq_model, eta=gam(ikind), rad=ala)
     489          114 :          DO jkind = 1, nkind
     490           70 :             CALL get_qs_kind(qs_kind_set(jkind), zatom=zb)
     491           70 :             CALL get_eeq_data(zb, eeq_model, rad=alb)
     492              :             !
     493          100 :             gab(ikind, jkind) = SQRT(1._dp/(ala*ala + alb*alb))
     494              :             !
     495              :          END DO
     496              :       END DO
     497              : 
     498              :       ! Override parameters for excluded kinds (ghost/floating atoms in BSSE)
     499           14 :       IF (PRESENT(exclude)) THEN
     500           44 :          DO ikind = 1, nkind
     501           44 :             IF (exclude(ikind)) THEN
     502            0 :                gam(ikind) = 1.0e30_dp
     503            0 :                gab(ikind, :) = 0.0_dp
     504            0 :                gab(:, ikind) = 0.0_dp
     505              :             END IF
     506              :          END DO
     507              :       END IF
     508              : 
     509           42 :       ALLOCATE (qlag(natom))
     510              : 
     511           14 :       CALL get_cell(cell, periodic=periodic)
     512           26 :       do_ewald = .NOT. ALL(periodic == 0)
     513           14 :       IF (do_ewald) THEN
     514          160 :          ALLOCATE (ewald_env)
     515           10 :          CALL ewald_env_create(ewald_env, para_env)
     516           10 :          poisson_section => section_vals_get_subs_vals(qs_env%input, "DFT%POISSON")
     517           10 :          CALL ewald_env_set(ewald_env, poisson_section=poisson_section)
     518           10 :          ewald_section => section_vals_get_subs_vals(poisson_section, "EWALD")
     519           10 :          print_section => section_vals_get_subs_vals(qs_env%input, "PRINT%GRID_INFORMATION")
     520           10 :          CALL get_qs_env(qs_env, cell_ref=cell_ref)
     521              :          CALL read_ewald_section_tb(ewald_env, ewald_section, cell_ref%hmat, &
     522           10 :                                     silent=.TRUE., pset="EEQ", cell_periodic=cell%perd)
     523           10 :          ALLOCATE (ewald_pw)
     524           10 :          CALL ewald_pw_create(ewald_pw, ewald_env, cell, cell_ref, print_section=print_section)
     525              :          !
     526              :          CALL eeq_solver(qlag, qlam, elag, &
     527              :                          particle_set, kind_of, cell, -dcharges, gam, gab, &
     528              :                          para_env, blacs_env, dft_control, eeq_sparam, &
     529           74 :                          ewald=do_ewald, ewald_env=ewald_env, ewald_pw=ewald_pw, iounit=iunit, qs_env=qs_env)
     530              :       ELSE
     531              :          CALL eeq_solver(qlag, qlam, elag, &
     532              :                          particle_set, kind_of, cell, -dcharges, gam, gab, &
     533           44 :                          para_env, blacs_env, dft_control, eeq_sparam, iounit=iunit, qs_env=qs_env)
     534              :       END IF
     535              : 
     536           14 :       sgamma = 8.0_dp ! see D4 for periodic systems paper
     537           14 :       esg = 1.0_dp + EXP(sgamma)
     538           56 :       ALLOCATE (chrgx(natom), dchia(natom))
     539          118 :       DO iatom = 1, natom
     540          104 :          ikind = kind_of(iatom)
     541          104 :          CALL get_qs_kind(qs_kind_set(ikind), zatom=za)
     542          104 :          CALL get_eeq_data(za, eeq_model, chi=xi, kcn=kappa)
     543              :          !
     544          104 :          IF (response_only) THEN
     545          104 :             ctot = -0.5_dp*qlag(iatom)
     546              :          ELSE
     547            0 :             ctot = 0.5_dp*(charges(iatom) - qlag(iatom))
     548              :          END IF
     549          222 :          IF (enshift_type == 1) THEN
     550          104 :             scn = SQRT(cnumbers(iatom)) + 1.0e-14_dp
     551          104 :             dchia(iatom) = -ctot*kappa/scn
     552            0 :          ELSE IF (enshift_type == 2) THEN
     553            0 :             cn = cnumbers(iatom)
     554            0 :             scn = 1.0_dp/(esg - cn)
     555            0 :             dchia(iatom) = -ctot*kappa*scn
     556              :          ELSE
     557            0 :             CPABORT("Unknown enshift_type")
     558              :          END IF
     559              :       END DO
     560              : 
     561              :       ! Efield
     562           14 :       IF (dft_control%apply_period_efield) THEN
     563            0 :          CALL eeq_efield_force_periodic(qs_env, charges, qlag)
     564           14 :       ELSE IF (dft_control%apply_efield) THEN
     565            0 :          CALL eeq_efield_force_loc(qs_env, charges, qlag)
     566           14 :       ELSE IF (dft_control%apply_efield_field) THEN
     567            0 :          CPABORT("apply field")
     568              :       END IF
     569              : 
     570              :       ! Forces from q*X
     571           14 :       CALL get_qs_env(qs_env=qs_env, local_particles=local_particles)
     572           44 :       DO ikind = 1, nkind
     573           96 :          DO ia = 1, local_particles%n_el(ikind)
     574           52 :             iatom = local_particles%list(ikind)%array(ia)
     575          158 :             DO i = 1, dcnum(iatom)%neighbors
     576           76 :                katom = dcnum(iatom)%nlist(i)
     577          304 :                rik = dcnum(iatom)%rik(:, i)
     578          304 :                drk = NORM2(rik)
     579          128 :                IF (drk > 1.e-3_dp) THEN
     580          304 :                   fdik(:) = dchia(iatom)*dcnum(iatom)%dvals(i)*rik(:)/drk
     581          304 :                   gradient(:, iatom) = gradient(:, iatom) - fdik(:)
     582          304 :                   gradient(:, katom) = gradient(:, katom) + fdik(:)
     583           76 :                   IF (use_virial) THEN
     584           28 :                      CALL virial_pair_force(stress, 1._dp, fdik, rik)
     585              :                   END IF
     586              :                END IF
     587              :             END DO
     588              :          END DO
     589              :       END DO
     590              : 
     591              :       ! Forces from (0.5*q+l)*dA/dR*q
     592           14 :       IF (do_ewald) THEN
     593              : 
     594              :          ! Build the neighbor lists for the CN
     595              :          CALL get_qs_env(qs_env, &
     596              :                          distribution_2d=distribution_2d, &
     597              :                          local_particles=distribution_1d, &
     598           10 :                          molecule_set=molecule_set)
     599           10 :          subcells = 2.0_dp
     600           10 :          CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut)
     601           10 :          rcut = 2.0_dp*rcut
     602           10 :          NULLIFY (sab_ew)
     603           80 :          ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
     604           32 :          c_radius(:) = rcut
     605           32 :          default_present = .TRUE.
     606           52 :          ALLOCATE (atom2d(nkind))
     607              :          CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
     608           10 :                            molecule_set, .FALSE., particle_set=particle_set)
     609           10 :          CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
     610              :          CALL build_neighbor_lists(sab_ew, particle_set, atom2d, cell, pair_radius, &
     611           10 :                                    subcells=subcells, operator_type="PP", nlname="sab_ew")
     612           10 :          DEALLOCATE (c_radius, pair_radius, default_present)
     613           10 :          CALL atom2d_cleanup(atom2d)
     614              :          !
     615           10 :          CALL neighbor_list_iterator_create(nl_iterator, sab_ew)
     616       103703 :          DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     617              :             CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     618       103693 :                                    iatom=iatom, jatom=jatom, r=rij)
     619              :             !
     620       414772 :             dr2 = SUM(rij**2)
     621       103693 :             dr = SQRT(dr2)
     622       103693 :             IF (dr > rcut .OR. dr < 1.E-6_dp) CYCLE
     623        12994 :             fe = 1.0_dp
     624        12994 :             IF (iatom == jatom) fe = 0.5_dp
     625        12994 :             IF (response_only) THEN
     626        12994 :                qq = -qlag(iatom)*charges(jatom)
     627              :             ELSE
     628        12994 :                qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
     629              :             END IF
     630        12994 :             gama = gab(ikind, jkind)
     631        12994 :             gam2 = gama*gama
     632              :             grc = 2._dp*gama*EXP(-gam2*dr2)*oorootpi/dr - erf(gama*dr)/dr2 &
     633        12994 :                   - 2._dp*alpha*EXP(-alpha**2*dr2)*oorootpi/dr + erf(alpha*dr)/dr2
     634        12994 :             IF (response_only) THEN
     635        12994 :                qq1 = -qlag(iatom)*charges(jatom)
     636        12994 :                qq2 = -qlag(jatom)*charges(iatom)
     637              :             ELSE
     638            0 :                qq1 = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
     639            0 :                qq2 = (0.5_dp*charges(jatom) - qlag(jatom))*charges(iatom)
     640              :             END IF
     641        51976 :             fdik(:) = -qq1*grc*rij(:)/dr
     642        51976 :             gradient(:, iatom) = gradient(:, iatom) + fdik(:)
     643        51976 :             gradient(:, jatom) = gradient(:, jatom) - fdik(:)
     644        12994 :             IF (use_virial) THEN
     645         8515 :                CALL virial_pair_force(stress, -fe, fdik, rij)
     646              :             END IF
     647        51976 :             fdik(:) = qq2*grc*rij(:)/dr
     648        51976 :             gradient(:, iatom) = gradient(:, iatom) - fdik(:)
     649        51976 :             gradient(:, jatom) = gradient(:, jatom) + fdik(:)
     650        13004 :             IF (use_virial) THEN
     651         8515 :                CALL virial_pair_force(stress, fe, fdik, rij)
     652              :             END IF
     653              :          END DO
     654           10 :          CALL neighbor_list_iterator_release(nl_iterator)
     655              :          !
     656           10 :          CALL release_neighbor_list_sets(sab_ew)
     657              :       ELSE
     658           12 :          DO ikind = 1, nkind
     659           32 :             DO ia = 1, local_particles%n_el(ikind)
     660           20 :                iatom = local_particles%list(ikind)%array(ia)
     661           80 :                ri(1:3) = particle_set(iatom)%r(1:3)
     662          228 :                DO jatom = 1, natom
     663          200 :                   IF (iatom == jatom) CYCLE
     664          180 :                   jkind = kind_of(jatom)
     665          180 :                   IF (response_only) THEN
     666          180 :                      qq = -qlag(iatom)*charges(jatom)
     667              :                   ELSE
     668            0 :                      qq = (0.5_dp*charges(iatom) - qlag(iatom))*charges(jatom)
     669              :                   END IF
     670          720 :                   rj(1:3) = particle_set(jatom)%r(1:3)
     671          720 :                   rij(1:3) = ri(1:3) - rj(1:3)
     672          720 :                   rij = pbc(rij, cell)
     673          720 :                   dr2 = SUM(rij**2)
     674          180 :                   dr = SQRT(dr2)
     675          180 :                   gama = gab(ikind, jkind)
     676          180 :                   gam2 = gama*gama
     677          180 :                   grc = 2._dp*gama*EXP(-gam2*dr2)*oorootpi/dr - erf(gama*dr)/dr2
     678          720 :                   fdik(:) = qq*grc*rij(:)/dr
     679          720 :                   gradient(:, iatom) = gradient(:, iatom) + fdik(:)
     680          740 :                   gradient(:, jatom) = gradient(:, jatom) - fdik(:)
     681              :                END DO
     682              :             END DO
     683              :          END DO
     684              :       END IF
     685              : 
     686              :       ! Forces from Ewald potential: (q+l)*A*q
     687           14 :       IF (do_ewald) THEN
     688           30 :          ALLOCATE (epforce(3, natom))
     689           10 :          epforce = 0.0_dp
     690           10 :          IF (response_only) THEN
     691           74 :             dchia(1:natom) = qlag(1:natom)
     692              :          ELSE
     693            0 :             dchia(1:natom) = -charges(1:natom) + qlag(1:natom)
     694              :          END IF
     695           74 :          chrgx(1:natom) = charges(1:natom)
     696              :          CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
     697           10 :                           particle_set, dchia, epforce)
     698           74 :          dchia(1:natom) = charges(1:natom)
     699           74 :          chrgx(1:natom) = qlag(1:natom)
     700              :          CALL spme_forces(ewald_env, ewald_pw, cell, particle_set, chrgx, &
     701           10 :                           particle_set, dchia, epforce)
     702          266 :          gradient(1:3, 1:natom) = gradient(1:3, 1:natom) + epforce(1:3, 1:natom)
     703           10 :          DEALLOCATE (epforce)
     704              : 
     705              :          ! virial
     706           10 :          IF (use_virial) THEN
     707           52 :             chrgx(1:natom) = charges(1:natom) - qlag(1:natom)
     708            8 :             CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
     709          104 :             stress = stress - pvir
     710           52 :             chrgx(1:natom) = qlag(1:natom)
     711            8 :             CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
     712          104 :             stress = stress + pvir
     713            8 :             IF (response_only) THEN
     714           52 :                chrgx(1:natom) = charges(1:natom)
     715            8 :                CALL spme_virial(ewald_env, ewald_pw, particle_set, cell, chrgx, pvir)
     716          104 :                stress = stress + pvir
     717              :             END IF
     718              :          END IF
     719              :          !
     720           10 :          CALL ewald_env_release(ewald_env)
     721           10 :          CALL ewald_pw_release(ewald_pw)
     722           10 :          DEALLOCATE (ewald_env, ewald_pw)
     723              :       END IF
     724              : 
     725           14 :       CALL cnumber_release(cnumbers, dcnum, .TRUE.)
     726              : 
     727           14 :       DEALLOCATE (gab, gam, qlag, chrgx, dchia)
     728              : 
     729           14 :       CALL timestop(handle)
     730              : 
     731           28 :    END SUBROUTINE eeq_forces
     732              : 
     733              : ! **************************************************************************************************
     734              : !> \brief ...
     735              : !> \param qs_env ...
     736              : !> \param cnumbers ...
     737              : !> \param dcnum ...
     738              : !> \param calculate_forces ...
     739              : ! **************************************************************************************************
     740          104 :    SUBROUTINE get_cnumbers(qs_env, cnumbers, dcnum, calculate_forces)
     741              : 
     742              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     743              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: cnumbers
     744              :       TYPE(dcnum_type), ALLOCATABLE, DIMENSION(:)        :: dcnum
     745              :       LOGICAL, INTENT(IN)                                :: calculate_forces
     746              : 
     747              :       INTEGER                                            :: ikind, natom, nkind, za
     748              :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: default_present
     749              :       REAL(KIND=dp)                                      :: subcells
     750              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: c_radius
     751              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: pair_radius
     752          104 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     753              :       TYPE(cell_type), POINTER                           :: cell
     754              :       TYPE(distribution_1d_type), POINTER                :: distribution_1d
     755              :       TYPE(distribution_2d_type), POINTER                :: distribution_2d
     756          104 :       TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:)  :: atom2d
     757          104 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     758              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     759          104 :          POINTER                                         :: sab_cn
     760          104 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     761              :       TYPE(qs_dispersion_type), POINTER                  :: disp
     762          104 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     763              : 
     764              :       CALL get_qs_env(qs_env, &
     765              :                       qs_kind_set=qs_kind_set, &
     766              :                       atomic_kind_set=atomic_kind_set, &
     767              :                       particle_set=particle_set, &
     768              :                       cell=cell, &
     769              :                       distribution_2d=distribution_2d, &
     770              :                       local_particles=distribution_1d, &
     771          104 :                       molecule_set=molecule_set)
     772          104 :       CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
     773              : 
     774              :       ! Check for dispersion_env and sab_cn needed for cnumbers
     775          520 :       ALLOCATE (disp)
     776          104 :       disp%k1 = 16.0_dp
     777          104 :       disp%k2 = 4._dp/3._dp
     778          104 :       disp%eps_cn = 1.E-6_dp
     779          104 :       disp%max_elem = maxElem
     780          104 :       ALLOCATE (disp%rcov(maxElem))
     781         9048 :       disp%rcov(1:maxElem) = bohr*disp%k2*rcov(1:maxElem)
     782          104 :       subcells = 2.0_dp
     783              :       ! Build the neighbor lists for the CN
     784          104 :       NULLIFY (sab_cn)
     785          832 :       ALLOCATE (c_radius(nkind), default_present(nkind), pair_radius(nkind, nkind))
     786          104 :       c_radius(:) = 0.0_dp
     787          330 :       default_present = .TRUE.
     788          330 :       DO ikind = 1, nkind
     789          226 :          CALL get_atomic_kind(atomic_kind_set(ikind), z=za)
     790          330 :          c_radius(ikind) = 4._dp*rcov(za)*bohr
     791              :       END DO
     792          538 :       ALLOCATE (atom2d(nkind))
     793              :       CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
     794          104 :                         molecule_set, .FALSE., particle_set=particle_set)
     795          104 :       CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
     796              :       CALL build_neighbor_lists(sab_cn, particle_set, atom2d, cell, pair_radius, &
     797          104 :                                 subcells=subcells, operator_type="PP", nlname="sab_cn")
     798          104 :       disp%sab_cn => sab_cn
     799          104 :       DEALLOCATE (c_radius, pair_radius, default_present)
     800          104 :       CALL atom2d_cleanup(atom2d)
     801              : 
     802              :       ! Calculate coordination numbers
     803          104 :       CALL cnumber_init(qs_env, cnumbers, dcnum, 2, calculate_forces, disp_env=disp)
     804              : 
     805          104 :       CALL qs_dispersion_release(disp)
     806              : 
     807          208 :    END SUBROUTINE get_cnumbers
     808              : 
     809              : ! **************************************************************************************************
     810              : !> \brief ...
     811              : !> \param charges ...
     812              : !> \param lambda ...
     813              : !> \param eeq_energy ...
     814              : !> \param particle_set ...
     815              : !> \param kind_of ...
     816              : !> \param cell ...
     817              : !> \param chia ...
     818              : !> \param gam ...
     819              : !> \param gab ...
     820              : !> \param para_env ...
     821              : !> \param blacs_env ...
     822              : !> \param dft_control ...
     823              : !> \param eeq_sparam ...
     824              : !> \param totalcharge ...
     825              : !> \param ewald ...
     826              : !> \param ewald_env ...
     827              : !> \param ewald_pw ...
     828              : !> \param iounit ...
     829              : !> \param qs_env environment used to build the sparse real-space neighbor list
     830              : ! **************************************************************************************************
     831         2334 :    SUBROUTINE eeq_solver(charges, lambda, eeq_energy, particle_set, kind_of, cell, &
     832         4668 :                          chia, gam, gab, para_env, blacs_env, dft_control, eeq_sparam, &
     833              :                          totalcharge, ewald, ewald_env, ewald_pw, iounit, qs_env)
     834              : 
     835              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
     836              :       REAL(KIND=dp), INTENT(INOUT)                       :: lambda, eeq_energy
     837              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
     838              :          POINTER                                         :: particle_set
     839              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
     840              :       TYPE(cell_type), POINTER                           :: cell
     841              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: chia, gam
     842              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
     843              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     844              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     845              :       TYPE(dft_control_type), POINTER                    :: dft_control
     846              :       TYPE(eeq_solver_type), INTENT(IN)                  :: eeq_sparam
     847              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: totalcharge
     848              :       LOGICAL, INTENT(IN), OPTIONAL                      :: ewald
     849              :       TYPE(ewald_environment_type), OPTIONAL, POINTER    :: ewald_env
     850              :       TYPE(ewald_pw_type), OPTIONAL, POINTER             :: ewald_pw
     851              :       INTEGER, INTENT(IN), OPTIONAL                      :: iounit
     852              :       TYPE(qs_environment_type), OPTIONAL, POINTER       :: qs_env
     853              : 
     854              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'eeq_solver'
     855              : 
     856              :       INTEGER                                            :: handle, ierror, iunit, natom, nkind, ns
     857              :       LOGICAL                                            :: do_direct, do_displ, do_ewald, &
     858              :                                                             do_sparse, do_sparse_auto, fm_created
     859              :       REAL(KIND=dp)                                      :: alpha, deth, ftime, qtot
     860              :       TYPE(cp_fm_struct_type), POINTER                   :: mat_struct
     861              :       TYPE(cp_fm_type)                                   :: eeq_mat
     862              : 
     863         2334 :       CALL timeset(routineN, handle)
     864              : 
     865         2334 :       do_ewald = .FALSE.
     866         2334 :       IF (PRESENT(ewald)) do_ewald = ewald
     867              :       !
     868         2334 :       qtot = 0.0_dp
     869         2334 :       IF (PRESENT(totalcharge)) qtot = totalcharge
     870              :       !
     871         2334 :       iunit = -1
     872         2334 :       IF (PRESENT(iounit)) iunit = iounit
     873              : 
     874              :       ! EEQ solver parameters
     875         2334 :       do_direct = eeq_sparam%direct
     876         2334 :       natom = SIZE(particle_set)
     877         2334 :       do_displ = .FALSE.
     878         2334 :       IF (dft_control%apply_period_efield .AND. ASSOCIATED(dft_control%period_efield)) THEN
     879          200 :          do_displ = dft_control%period_efield%displacement_field
     880              :       END IF
     881         2334 :       do_sparse_auto = eeq_sparam%sparse_threshold > 0 .AND. natom >= eeq_sparam%sparse_threshold
     882              :       ! An explicit request diagnoses unsupported displacement-field use below.
     883              :       ! Automatic selection must retain the historical dense path instead of
     884              :       ! turning a system-size threshold into a new input-dependent abort.
     885         2334 :       do_sparse = eeq_sparam%sparse .OR. (do_sparse_auto .AND. .NOT. do_displ)
     886         2334 :       fm_created = .FALSE.
     887              : 
     888         2334 :       nkind = SIZE(gam)
     889         2334 :       ns = natom + 1
     890         2334 :       IF (.NOT. (do_ewald .AND. do_sparse .AND. .NOT. do_direct)) THEN
     891              :          CALL cp_fm_struct_create(mat_struct, context=blacs_env, para_env=para_env, &
     892         2222 :                                   nrow_global=ns, ncol_global=ns)
     893         2222 :          CALL cp_fm_create(eeq_mat, mat_struct)
     894         2222 :          CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
     895         2222 :          fm_created = .TRUE.
     896              :       END IF
     897              :       !
     898         2334 :       IF (do_ewald) THEN
     899         1126 :          CPASSERT(PRESENT(ewald_env))
     900         1126 :          CPASSERT(PRESENT(ewald_pw))
     901         1126 :          IF (do_direct) THEN
     902            0 :             IF (do_displ) THEN
     903            0 :                CPABORT("NYA")
     904              :             ELSE
     905              :                CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
     906              :                                 kind_of, cell, chia, gam, gab, qtot, &
     907            0 :                                 ewald_env, ewald_pw, iounit)
     908              :             END IF
     909         1126 :          ELSE IF (do_sparse) THEN
     910          112 :             IF (do_displ) THEN
     911            0 :                CPABORT("Sparse periodic EEQ is not available with a displacement field")
     912              :             ELSE
     913          112 :                CPASSERT(PRESENT(qs_env))
     914              :                ierror = 0
     915              :                CALL pbc_sparse_solver(charges, lambda, eeq_energy, particle_set, &
     916              :                                       kind_of, cell, chia, gam, gab, qtot, &
     917          112 :                                       ewald_env, ewald_pw, eeq_sparam, qs_env, ierror, iounit)
     918          112 :                IF (ierror /= 0) THEN
     919              :                   CALL cp_fm_struct_create(mat_struct, context=blacs_env, para_env=para_env, &
     920            0 :                                            nrow_global=ns, ncol_global=ns)
     921            0 :                   CALL cp_fm_create(eeq_mat, mat_struct)
     922            0 :                   CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
     923            0 :                   fm_created = .TRUE.
     924              :                   CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
     925              :                                    kind_of, cell, chia, gam, gab, qtot, &
     926            0 :                                    ewald_env, ewald_pw, iounit)
     927              :                END IF
     928              :             END IF
     929              :          ELSE
     930         1014 :             IF (do_displ) THEN
     931            0 :                CPABORT("NYA")
     932              :             ELSE
     933              :                ierror = 0
     934              :                CALL pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
     935              :                                kind_of, cell, chia, gam, gab, qtot, &
     936         1014 :                                ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
     937         1014 :                IF (ierror /= 0) THEN
     938              :                   ! backup to non-iterative method
     939              :                   CALL fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
     940              :                                    kind_of, cell, chia, gam, gab, qtot, &
     941          892 :                                    ewald_env, ewald_pw, iounit)
     942              :                END IF
     943              :             END IF
     944              :          END IF
     945         1126 :          IF (qtot /= 0._dp) THEN
     946          104 :             CALL get_cell(cell=cell, deth=deth)
     947          104 :             CALL ewald_env_get(ewald_env, alpha=alpha)
     948          104 :             eeq_energy = eeq_energy - 0.5_dp*qtot**2/alpha**2/deth
     949              :          END IF
     950              :       ELSE
     951              :          CALL mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, &
     952         1208 :                         cell, chia, gam, gab, qtot, ftime)
     953         1208 :          IF (iounit > 0) THEN
     954         1183 :             WRITE (iunit, '(A,T67,F14.3)') " EEQ| Molecular solver time[s]", ftime
     955              :          END IF
     956              :       END IF
     957         2334 :       IF (fm_created) THEN
     958         2222 :          CALL cp_fm_struct_release(mat_struct)
     959         2222 :          CALL cp_fm_release(eeq_mat)
     960              :       END IF
     961              : 
     962         2334 :       CALL timestop(handle)
     963              : 
     964         2334 :    END SUBROUTINE eeq_solver
     965              : 
     966              : ! **************************************************************************************************
     967              : !> \brief ...
     968              : !> \param charges ...
     969              : !> \param lambda ...
     970              : !> \param eeq_energy ...
     971              : !> \param eeq_mat ...
     972              : !> \param particle_set ...
     973              : !> \param kind_of ...
     974              : !> \param cell ...
     975              : !> \param chia ...
     976              : !> \param gam ...
     977              : !> \param gab ...
     978              : !> \param qtot ...
     979              : !> \param ftime ...
     980              : ! **************************************************************************************************
     981         2222 :    SUBROUTINE mi_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, kind_of, cell, &
     982         2222 :                         chia, gam, gab, qtot, ftime)
     983              : 
     984              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
     985              :       REAL(KIND=dp), INTENT(INOUT)                       :: lambda, eeq_energy
     986              :       TYPE(cp_fm_type)                                   :: eeq_mat
     987              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
     988              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
     989              :       TYPE(cell_type), POINTER                           :: cell
     990              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: chia, gam
     991              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
     992              :       REAL(KIND=dp), INTENT(IN)                          :: qtot
     993              :       REAL(KIND=dp), INTENT(OUT)                         :: ftime
     994              : 
     995              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'mi_solver'
     996              : 
     997              :       INTEGER                                            :: handle, ia, iac, iar, ic, ikind, ir, &
     998              :                                                             jkind, natom, ncloc, ncvloc, nkind, &
     999              :                                                             nrloc, nrvloc, ns
    1000         2222 :       INTEGER, DIMENSION(:), POINTER                     :: cind, cvind, rind, rvind
    1001              :       REAL(KIND=dp)                                      :: dr, grc, te, ti, xr
    1002              :       REAL(KIND=dp), DIMENSION(3)                        :: ri, rij, rj
    1003              :       TYPE(cp_fm_struct_type), POINTER                   :: mat_struct, vec_struct
    1004              :       TYPE(cp_fm_type)                                   :: rhs_vec
    1005              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1006              : 
    1007         2222 :       CALL timeset(routineN, handle)
    1008         2222 :       ti = m_walltime()
    1009              : 
    1010         2222 :       natom = SIZE(particle_set)
    1011         2222 :       nkind = SIZE(gam)
    1012              :       !
    1013         2222 :       ns = natom + 1
    1014         2222 :       CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
    1015              :       CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
    1016         2222 :                           row_indices=rind, col_indices=cind)
    1017              :       CALL cp_fm_struct_create(vec_struct, template_fmstruct=mat_struct, &
    1018         2222 :                                nrow_global=ns, ncol_global=1)
    1019         2222 :       CALL cp_fm_create(rhs_vec, vec_struct)
    1020              :       CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
    1021         2222 :                           row_indices=rvind, col_indices=cvind)
    1022              :       !
    1023              :       ! set up matrix
    1024         2222 :       CALL cp_fm_set_all(eeq_mat, 1.0_dp, 0.0_dp)
    1025         2222 :       CALL cp_fm_set_all(rhs_vec, 0.0_dp)
    1026         8550 :       DO ir = 1, nrloc
    1027         6328 :          iar = rind(ir)
    1028         6328 :          IF (iar > natom) CYCLE
    1029         5217 :          ikind = kind_of(iar)
    1030        20868 :          ri(1:3) = particle_set(iar)%r(1:3)
    1031        46845 :          DO ic = 1, ncloc
    1032        39406 :             iac = cind(ic)
    1033        39406 :             IF (iac > natom) CYCLE
    1034        34189 :             jkind = kind_of(iac)
    1035       136756 :             rj(1:3) = particle_set(iac)%r(1:3)
    1036        34189 :             IF (iar == iac) THEN
    1037         5217 :                grc = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi
    1038              :             ELSE
    1039       115888 :                rij(1:3) = ri(1:3) - rj(1:3)
    1040       115888 :                rij = pbc(rij, cell)
    1041       115888 :                dr = NORM2(rij)
    1042        28972 :                grc = erf(gab(ikind, jkind)*dr)/dr
    1043              :             END IF
    1044        45734 :             eeq_mat%local_data(ir, ic) = grc
    1045              :          END DO
    1046              :       END DO
    1047              :       ! set up rhs vector
    1048         8550 :       DO ir = 1, nrvloc
    1049         6328 :          iar = rvind(ir)
    1050        14878 :          DO ic = 1, ncvloc
    1051         6328 :             iac = cvind(ic)
    1052         6328 :             ia = MAX(iar, iac)
    1053         6328 :             IF (ia > natom) THEN
    1054         1111 :                xr = qtot
    1055              :             ELSE
    1056         5217 :                xr = -chia(ia)
    1057              :             END IF
    1058        12656 :             rhs_vec%local_data(ir, ic) = xr
    1059              :          END DO
    1060              :       END DO
    1061              :       !
    1062         2222 :       CALL cp_fm_solve(eeq_mat, rhs_vec)
    1063              :       !
    1064        12656 :       charges = 0.0_dp
    1065         2222 :       lambda = 0.0_dp
    1066         8550 :       DO ir = 1, nrvloc
    1067         6328 :          iar = rvind(ir)
    1068        14878 :          DO ic = 1, ncvloc
    1069         6328 :             iac = cvind(ic)
    1070         6328 :             ia = MAX(iar, iac)
    1071        12656 :             IF (ia <= natom) THEN
    1072         5217 :                xr = rhs_vec%local_data(ir, ic)
    1073         5217 :                charges(ia) = xr
    1074              :             ELSE
    1075         1111 :                lambda = rhs_vec%local_data(ir, ic)
    1076              :             END IF
    1077              :          END DO
    1078              :       END DO
    1079         2222 :       CALL para_env%sum(lambda)
    1080        23090 :       CALL para_env%sum(charges)
    1081              :       !
    1082              :       ! energy:   0.5*(q^T.X - lambda*totalcharge)
    1083        12656 :       eeq_energy = 0.5*SUM(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
    1084              : 
    1085         2222 :       CALL cp_fm_struct_release(vec_struct)
    1086         2222 :       CALL cp_fm_release(rhs_vec)
    1087              : 
    1088         2222 :       te = m_walltime()
    1089         2222 :       ftime = te - ti
    1090         2222 :       CALL timestop(handle)
    1091              : 
    1092         2222 :    END SUBROUTINE mi_solver
    1093              : 
    1094              : ! **************************************************************************************************
    1095              : !> \brief Solve the periodic EEQ equations in the fixed-charge subspace with projected PCG.
    1096              : !>
    1097              : !>        The short-range Gaussian/Ewald correction is stored as a distributed sparse pair list.
    1098              : !>        The long-range Coulomb response is applied matrix-free with SPME.  A constrained diagonal
    1099              : !>        hardness preconditioner preserves the total charge exactly.
    1100              : !> \param charges converged atomic charges
    1101              : !> \param lambda charge-constraint multiplier
    1102              : !> \param eeq_energy EEQ energy
    1103              : !> \param particle_set particles
    1104              : !> \param kind_of atomic kind for every particle
    1105              : !> \param cell simulation cell
    1106              : !> \param chia electronegativities
    1107              : !> \param gam atomic hardness parameters
    1108              : !> \param gab pair Gaussian exponents
    1109              : !> \param qtot requested total charge
    1110              : !> \param ewald_env Ewald environment
    1111              : !> \param ewald_pw Ewald plane-wave data
    1112              : !> \param eeq_sparam solver settings
    1113              : !> \param qs_env environment used for the cutoff neighbor list
    1114              : !> \param ierror zero on convergence
    1115              : !> \param iounit output unit
    1116              : ! **************************************************************************************************
    1117          112 :    SUBROUTINE pbc_sparse_solver(charges, lambda, eeq_energy, particle_set, &
    1118          112 :                                 kind_of, cell, chia, gam, gab, qtot, &
    1119              :                                 ewald_env, ewald_pw, eeq_sparam, qs_env, ierror, iounit)
    1120              : 
    1121              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
    1122              :       REAL(KIND=dp), INTENT(INOUT)                       :: lambda, eeq_energy
    1123              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
    1124              :          POINTER                                         :: particle_set
    1125              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
    1126              :       TYPE(cell_type), POINTER                           :: cell
    1127              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: chia, gam
    1128              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
    1129              :       REAL(KIND=dp), INTENT(IN)                          :: qtot
    1130              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1131              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    1132              :       TYPE(eeq_solver_type), INTENT(IN)                  :: eeq_sparam
    1133              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1134              :       INTEGER, INTENT(OUT)                               :: ierror
    1135              :       INTEGER, OPTIONAL                                  :: iounit
    1136              : 
    1137              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'pbc_sparse_solver'
    1138              : 
    1139              :       INTEGER                                            :: handle, i, iter, iunit, max_iter, natom
    1140              :       REAL(KIND=dp)                                      :: alpha_cg, beta_cg, denom, eps_solver, &
    1141              :                                                             ftime, res, res_initial, rz, rz_new, &
    1142              :                                                             te, ti
    1143          112 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: ap, aq, gradient, p, precond_diag, &
    1144              :                                                             residual, work, z
    1145          112 :       TYPE(eeq_sparse_matrix_type)                       :: response
    1146              : 
    1147          112 :       CALL timeset(routineN, handle)
    1148          112 :       ti = m_walltime()
    1149              : 
    1150          112 :       iunit = -1
    1151          112 :       IF (PRESENT(iounit)) iunit = iounit
    1152          112 :       natom = SIZE(charges)
    1153          112 :       max_iter = eeq_sparam%max_diis
    1154          112 :       eps_solver = eeq_sparam%eps_diis
    1155          112 :       ierror = 0
    1156              : 
    1157              :       CALL build_sparse_pbc_response(response, qs_env, particle_set, kind_of, cell, gam, gab, &
    1158          112 :                                      ewald_env, eps_solver, iunit)
    1159              : 
    1160              :       ALLOCATE (ap(natom), aq(natom), gradient(natom), p(natom), precond_diag(natom), &
    1161         1120 :                 residual(natom), work(natom), z(natom))
    1162          968 :       DO i = 1, natom
    1163          856 :          precond_diag(i) = gam(kind_of(i)) + 2.0_dp*gab(kind_of(i), kind_of(i))*oorootpi
    1164          968 :          precond_diag(i) = MAX(precond_diag(i), SQRT(EPSILON(1.0_dp)))
    1165              :       END DO
    1166              : 
    1167              :       ! Diagonal constrained minimizer as a deterministic charge-conserving initial guess.
    1168         1824 :       lambda = (-qtot - SUM(chia/precond_diag))/SUM(1.0_dp/precond_diag)
    1169          968 :       charges = -(chia + lambda)/precond_diag
    1170         1824 :       charges = charges + (qtot - SUM(charges))/REAL(natom, KIND=dp)
    1171              : 
    1172              :       CALL apply_sparse_pbc_response(response, ewald_env, ewald_pw, cell, particle_set, &
    1173          112 :                                      charges, aq, work)
    1174          968 :       gradient(:) = aq + chia
    1175          968 :       residual(:) = -gradient
    1176          112 :       CALL project_eeq_charge_tangent(residual)
    1177          968 :       res = NORM2(residual)
    1178          112 :       res_initial = MAX(res, SQRT(EPSILON(1.0_dp)))
    1179          112 :       iter = 0
    1180              : 
    1181          112 :       IF (res >= eps_solver) THEN
    1182          112 :          CALL apply_eeq_constrained_diagonal_preconditioner(residual, precond_diag, z)
    1183          968 :          p(:) = z
    1184          968 :          rz = SUM(residual*z)
    1185              : 
    1186          632 :          DO iter = 1, max_iter
    1187              :             CALL apply_sparse_pbc_response(response, ewald_env, ewald_pw, cell, particle_set, &
    1188          632 :                                            p, ap, work)
    1189          632 :             CALL project_eeq_charge_tangent(ap)
    1190         5608 :             denom = SUM(p*ap)
    1191          632 :             IF (.NOT. (denom > SQRT(TINY(1.0_dp)) .AND. ABS(denom) < HUGE(denom))) THEN
    1192            0 :                ierror = 1
    1193            0 :                EXIT
    1194              :             END IF
    1195              : 
    1196          632 :             alpha_cg = rz/denom
    1197          632 :             IF (.NOT. (ABS(alpha_cg) < HUGE(alpha_cg))) THEN
    1198            0 :                ierror = 1
    1199            0 :                EXIT
    1200              :             END IF
    1201         5608 :             charges = charges + alpha_cg*p
    1202         5608 :             residual(:) = residual - alpha_cg*ap
    1203              :             ! Remove accumulated roundoff from both constrained spaces.
    1204        10584 :             charges = charges + (qtot - SUM(charges))/REAL(natom, KIND=dp)
    1205          632 :             CALL project_eeq_charge_tangent(residual)
    1206         5608 :             res = NORM2(residual)
    1207          632 :             IF (res < eps_solver) EXIT
    1208          520 :             IF (res > 100.0_dp*res_initial .OR. .NOT. (res < HUGE(res))) THEN
    1209            0 :                ierror = 1
    1210            0 :                EXIT
    1211              :             END IF
    1212              : 
    1213          520 :             CALL apply_eeq_constrained_diagonal_preconditioner(residual, precond_diag, z)
    1214         4640 :             rz_new = SUM(residual*z)
    1215          520 :             IF (.NOT. (rz_new > 0.0_dp .AND. ABS(rz_new) < HUGE(rz_new))) THEN
    1216            0 :                ierror = 1
    1217            0 :                EXIT
    1218              :             END IF
    1219          520 :             beta_cg = rz_new/rz
    1220         4640 :             p(:) = z + beta_cg*p
    1221          632 :             rz = rz_new
    1222              :          END DO
    1223          112 :          IF (iter > max_iter) ierror = 1
    1224              :       END IF
    1225              : 
    1226          112 :       IF (ierror == 0) THEN
    1227              :          CALL apply_sparse_pbc_response(response, ewald_env, ewald_pw, cell, particle_set, &
    1228          112 :                                         charges, aq, work)
    1229          968 :          gradient(:) = aq + chia
    1230          968 :          lambda = -SUM(gradient)/REAL(natom, KIND=dp)
    1231         1824 :          eeq_energy = 0.5_dp*SUM(charges*aq) + SUM(charges*chia)
    1232              :       END IF
    1233              : 
    1234          112 :       te = m_walltime()
    1235          112 :       ftime = te - ti
    1236          112 :       IF (iunit > 0) THEN
    1237          107 :          IF (ierror /= 0) THEN
    1238              :             WRITE (iunit, '(A,T50,I6,T61,E20.5)') &
    1239            0 :                " EEQ| Sparse PBC solver failed: iterations/accuracy ", iter, res
    1240              :          ELSE
    1241              :             WRITE (iunit, '(A,T50,I6,T61,E20.5)') &
    1242          107 :                " EEQ| Sparse PBC solver: iterations/accuracy ", iter, res
    1243              :          END IF
    1244          107 :          WRITE (iunit, '(A,T67,F14.3)') " EEQ| Sparse PBC solver: time[s]", ftime
    1245              :       END IF
    1246              : 
    1247          112 :       DEALLOCATE (ap, aq, gradient, p, precond_diag, residual, work, z)
    1248          112 :       CALL release_sparse_pbc_response(response)
    1249          112 :       CALL timestop(handle)
    1250              : 
    1251          224 :    END SUBROUTINE pbc_sparse_solver
    1252              : 
    1253              : ! **************************************************************************************************
    1254              : !> \brief Build the distributed short-range part of the periodic EEQ response.
    1255              : !> \param response ...
    1256              : !> \param qs_env ...
    1257              : !> \param particle_set ...
    1258              : !> \param kind_of ...
    1259              : !> \param cell ...
    1260              : !> \param gam ...
    1261              : !> \param gab ...
    1262              : !> \param ewald_env ...
    1263              : !> \param eps_solver ...
    1264              : !> \param iunit ...
    1265              : ! **************************************************************************************************
    1266          224 :    SUBROUTINE build_sparse_pbc_response(response, qs_env, particle_set, kind_of, cell, gam, gab, &
    1267              :                                         ewald_env, eps_solver, iunit)
    1268              : 
    1269              :       TYPE(eeq_sparse_matrix_type), INTENT(OUT)          :: response
    1270              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1271              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
    1272              :          POINTER                                         :: particle_set
    1273              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
    1274              :       TYPE(cell_type), POINTER                           :: cell
    1275              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: gam
    1276              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
    1277              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1278              :       REAL(KIND=dp), INTENT(IN)                          :: eps_solver
    1279              :       INTEGER, INTENT(IN)                                :: iunit
    1280              : 
    1281              :       INTEGER                                            :: iatom, ix, iy, iz, jatom, &
    1282              :                                                             n_candidates_global, n_pairs, &
    1283              :                                                             n_pairs_alloc, n_pairs_global, &
    1284              :                                                             n_unique, natom, owner
    1285          112 :       INTEGER(KIND=int_8), ALLOCATABLE, DIMENSION(:)     :: pair_key
    1286          112 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: pair_order
    1287              :       INTEGER, DIMENSION(3)                              :: periodic
    1288          112 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: default_present
    1289              :       REAL(KIND=dp)                                      :: drop_tolerance, neighbor_cutoff, rmax, &
    1290              :                                                             subcells, value
    1291          112 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: c_radius
    1292          112 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: pair_radius
    1293              :       REAL(KIND=dp), DIMENSION(3)                        :: cell_extent, vertex
    1294              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    1295          112 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1296              :       TYPE(distribution_1d_type), POINTER                :: distribution_1d
    1297              :       TYPE(distribution_2d_type), POINTER                :: distribution_2d
    1298          112 :       TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:)  :: atom2d
    1299          112 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
    1300              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1301              :       TYPE(neighbor_list_iterator_p_type), &
    1302          112 :          DIMENSION(:), POINTER                           :: nl_iterator
    1303              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1304          112 :          POINTER                                         :: sab_eeq
    1305              : 
    1306          112 :       NULLIFY (atomic_kind_set, distribution_1d, distribution_2d, molecule_set, nl_iterator, sab_eeq)
    1307          112 :       CALL ewald_env_get(ewald_env, rcut=rmax, para_env=para_env)
    1308          112 :       rmax = 2.0_dp*rmax
    1309          112 :       natom = SIZE(particle_set)
    1310              :       drop_tolerance = MAX(100.0_dp*EPSILON(1.0_dp), &
    1311          112 :                            eps_solver/(1000.0_dp*REAL(MAX(1, natom), KIND=dp)))
    1312              : 
    1313              :       ! A minimum-image atom pair can never be farther away than the most distant vertex of the
    1314              :       ! centered cell.  Limiting the neighbor-list radius to that bound avoids materializing many
    1315              :       ! redundant periodic images when the Ewald real-space cutoff exceeds a small simulation cell.
    1316          112 :       CALL get_cell(cell, h=hmat, periodic=periodic)
    1317          448 :       WHERE (periodic /= 0)
    1318              :          cell_extent = 0.5_dp
    1319              :       ELSE WHERE
    1320              :          cell_extent = 1.0_dp
    1321              :       END WHERE
    1322          112 :       neighbor_cutoff = 0.0_dp
    1323          336 :       DO ix = -1, 1, 2
    1324          784 :          DO iy = -1, 1, 2
    1325          672 :             DO iz = -1, 1, 2
    1326        14336 :                vertex = MATMUL(hmat, cell_extent*REAL([ix, iy, iz], KIND=dp))
    1327         3584 :                neighbor_cutoff = MAX(neighbor_cutoff, NORM2(vertex))
    1328              :             END DO
    1329              :          END DO
    1330              :       END DO
    1331              :       neighbor_cutoff = MIN(rmax, neighbor_cutoff + &
    1332          112 :                             1.0E-10_dp*MAX(1.0_dp, neighbor_cutoff))
    1333              : 
    1334              :       CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, &
    1335              :                       distribution_2d=distribution_2d, local_particles=distribution_1d, &
    1336          112 :                       molecule_set=molecule_set)
    1337              :       ALLOCATE (c_radius(SIZE(atomic_kind_set)), default_present(SIZE(atomic_kind_set)), &
    1338              :                 pair_radius(SIZE(atomic_kind_set), SIZE(atomic_kind_set)), &
    1339         1354 :                 atom2d(SIZE(atomic_kind_set)))
    1340          346 :       c_radius = 0.5_dp*neighbor_cutoff
    1341          346 :       default_present = .TRUE.
    1342          112 :       subcells = 2.0_dp
    1343              :       CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
    1344          112 :                         molecule_set, .FALSE., particle_set=particle_set)
    1345          112 :       CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
    1346              :       CALL build_neighbor_lists(sab_eeq, particle_set, atom2d, cell, pair_radius, &
    1347              :                                 subcells=subcells, mic=.FALSE., symmetric=.TRUE., &
    1348          112 :                                 operator_type="PP", nlname="sab_eeq_sparse")
    1349          112 :       DEALLOCATE (c_radius, pair_radius, default_present)
    1350          112 :       CALL atom2d_cleanup(atom2d)
    1351              : 
    1352         1192 :       ALLOCATE (response%diag(natom), source=0.0_dp)
    1353          968 :       DO iatom = 1, natom
    1354          856 :          owner = MOD(iatom - 1, para_env%num_pe)
    1355          968 :          IF (owner == para_env%mepos) THEN
    1356              :             response%diag(iatom) = eeq_short_range_element(iatom, iatom, particle_set, kind_of, &
    1357          428 :                                                            cell, gam, gab, ewald_env)
    1358              :          END IF
    1359              :       END DO
    1360              : 
    1361              :       ! Collect the canonical pair keys from the bounded image list.  Sorting removes image-cell
    1362              :       ! duplicates without an O(N_atom**2) lookup table.  The symmetric list assigns every pair to
    1363              :       ! one MPI owner; the full Ewald-cutoff image sum is evaluated once for each unique key.
    1364          112 :       n_pairs_alloc = 0
    1365          112 :       CALL neighbor_list_iterator_create(nl_iterator, sab_eeq)
    1366         6308 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
    1367         6196 :          CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom)
    1368         6308 :          IF (iatom /= jatom) n_pairs_alloc = n_pairs_alloc + 1
    1369              :       END DO
    1370          112 :       CALL neighbor_list_iterator_release(nl_iterator)
    1371              : 
    1372          560 :       ALLOCATE (pair_key(n_pairs_alloc), pair_order(n_pairs_alloc))
    1373          112 :       n_pairs_alloc = 0
    1374          112 :       CALL neighbor_list_iterator_create(nl_iterator, sab_eeq)
    1375         6308 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
    1376         6196 :          CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom)
    1377         6196 :          IF (iatom == jatom) CYCLE
    1378         5768 :          n_pairs_alloc = n_pairs_alloc + 1
    1379              :          pair_key(n_pairs_alloc) = INT(MIN(iatom, jatom) - 1, int_8)*INT(natom, int_8) + &
    1380         6308 :                                    INT(MAX(iatom, jatom), int_8)
    1381              :       END DO
    1382          112 :       CALL neighbor_list_iterator_release(nl_iterator)
    1383          112 :       CALL release_neighbor_list_sets(sab_eeq)
    1384              : 
    1385          112 :       IF (n_pairs_alloc > 0) CALL sort(pair_key, n_pairs_alloc, pair_order)
    1386          112 :       n_unique = 0
    1387         5880 :       DO iatom = 1, n_pairs_alloc
    1388         5880 :          IF (iatom == 1) THEN
    1389          112 :             n_unique = n_unique + 1
    1390         5656 :          ELSE IF (pair_key(iatom) /= pair_key(iatom - 1)) THEN
    1391         1346 :             n_unique = n_unique + 1
    1392              :          END IF
    1393              :       END DO
    1394          672 :       ALLOCATE (response%row(n_unique), response%col(n_unique), response%value(n_unique))
    1395          112 :       n_pairs = 0
    1396         5880 :       DO iatom = 1, n_pairs_alloc
    1397         5768 :          IF (iatom > 1) THEN
    1398         5656 :             IF (pair_key(iatom) == pair_key(iatom - 1)) CYCLE
    1399              :          END IF
    1400         1458 :          jatom = INT(MODULO(pair_key(iatom) - 1_int_8, INT(natom, int_8))) + 1
    1401         1458 :          owner = INT((pair_key(iatom) - 1_int_8)/INT(natom, int_8)) + 1
    1402              :          value = eeq_short_range_element(owner, jatom, particle_set, kind_of, cell, &
    1403         1458 :                                          gam, gab, ewald_env)
    1404         1458 :          IF (ABS(value) <= drop_tolerance) CYCLE
    1405         1458 :          n_pairs = n_pairs + 1
    1406         1458 :          response%row(n_pairs) = owner
    1407         1458 :          response%col(n_pairs) = jatom
    1408         5880 :          response%value(n_pairs) = value
    1409              :       END DO
    1410          112 :       DEALLOCATE (pair_key, pair_order)
    1411          112 :       response%nactive = n_pairs
    1412              : 
    1413          112 :       n_pairs_global = n_pairs
    1414          112 :       CALL para_env%sum(n_pairs_global)
    1415          112 :       n_candidates_global = n_unique
    1416          112 :       CALL para_env%sum(n_candidates_global)
    1417          112 :       IF (iunit > 0) THEN
    1418          107 :          WRITE (iunit, '(A,T54,I12)') " EEQ| Sparse short-range candidate atom pairs", n_candidates_global
    1419          107 :          WRITE (iunit, '(A,T54,I12)') " EEQ| Sparse short-range retained atom pairs", n_pairs_global
    1420          107 :          WRITE (iunit, '(A,T61,E20.5)') " EEQ| Sparse short-range drop tolerance", drop_tolerance
    1421          107 :          WRITE (iunit, '(A,T61,E20.5)') " EEQ| Sparse short-range MIC cutoff", neighbor_cutoff
    1422              :       END IF
    1423              : 
    1424          224 :    END SUBROUTINE build_sparse_pbc_response
    1425              : 
    1426              : ! **************************************************************************************************
    1427              : !> \brief Evaluate one aggregated short-range periodic EEQ response element.
    1428              : !> \param iatom ...
    1429              : !> \param jatom ...
    1430              : !> \param particle_set ...
    1431              : !> \param kind_of ...
    1432              : !> \param cell ...
    1433              : !> \param gam ...
    1434              : !> \param gab ...
    1435              : !> \param ewald_env ...
    1436              : !> \return ...
    1437              : ! **************************************************************************************************
    1438         1886 :    FUNCTION eeq_short_range_element(iatom, jatom, particle_set, kind_of, cell, gam, gab, &
    1439              :                                     ewald_env) RESULT(element)
    1440              : 
    1441              :       INTEGER, INTENT(IN)                                :: iatom, jatom
    1442              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    1443              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
    1444              :       TYPE(cell_type), POINTER                           :: cell
    1445              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: gam
    1446              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
    1447              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1448              :       REAL(KIND=dp)                                      :: element
    1449              : 
    1450              :       INTEGER                                            :: ix, iy, iz
    1451              :       INTEGER, DIMENSION(3)                              :: cvec, ncell, periodic
    1452              :       REAL(KIND=dp)                                      :: alpha, dr, rcut, rmax
    1453              :       REAL(KIND=dp), DIMENSION(3)                        :: rij, rijl
    1454              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    1455              : 
    1456         1886 :       CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut)
    1457         1886 :       rmax = 2.0_dp*rcut
    1458         1886 :       CALL get_cell(cell, h=hmat, periodic=periodic)
    1459         1886 :       ncell(1) = CEILING(rmax/plane_distance(1, 0, 0, cell))
    1460         1886 :       ncell(2) = CEILING(rmax/plane_distance(0, 1, 0, cell))
    1461         1886 :       ncell(3) = CEILING(rmax/plane_distance(0, 0, 1, cell))
    1462         7544 :       WHERE (periodic == 0) ncell = 0
    1463              : 
    1464         7544 :       rij = pbc(particle_set(iatom)%r - particle_set(jatom)%r, cell)
    1465         1886 :       element = 0.0_dp
    1466        15148 :       DO ix = -ncell(1), ncell(1)
    1467       108522 :          DO iy = -ncell(2), ncell(2)
    1468       765114 :             DO iz = -ncell(3), ncell(3)
    1469      2633912 :                cvec = [ix, iy, iz]
    1470     12511082 :                rijl = rij + MATMUL(hmat, cvec)
    1471      2633912 :                dr = NORM2(rijl)
    1472       658478 :                IF (dr > rmax) CYCLE
    1473       252838 :                IF (iatom == jatom .AND. dr < 1.0E-5_dp) THEN
    1474              :                   element = element + gam(kind_of(iatom)) + &
    1475              :                             2.0_dp*gab(kind_of(iatom), kind_of(iatom))*oorootpi - &
    1476          428 :                             2.0_dp*alpha*oorootpi
    1477       159036 :                ELSE IF (dr > 1.0E-12_dp) THEN
    1478              :                   element = element + &
    1479       159036 :                             (ERF(gab(kind_of(iatom), kind_of(jatom))*dr) - ERF(alpha*dr))/dr
    1480              :                END IF
    1481              :             END DO
    1482              :          END DO
    1483              :       END DO
    1484              : 
    1485         1886 :    END FUNCTION eeq_short_range_element
    1486              : 
    1487              : ! **************************************************************************************************
    1488              : !> \brief Apply sparse short range plus the matrix-free SPME long-range response.
    1489              : !> \param response ...
    1490              : !> \param ewald_env ...
    1491              : !> \param ewald_pw ...
    1492              : !> \param cell ...
    1493              : !> \param particle_set ...
    1494              : !> \param charges ...
    1495              : !> \param potential ...
    1496              : !> \param work ...
    1497              : ! **************************************************************************************************
    1498         2568 :    SUBROUTINE apply_sparse_pbc_response(response, ewald_env, ewald_pw, cell, particle_set, &
    1499          856 :                                         charges, potential, work)
    1500              : 
    1501              :       TYPE(eeq_sparse_matrix_type), INTENT(IN)           :: response
    1502              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1503              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    1504              :       TYPE(cell_type), POINTER                           :: cell
    1505              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    1506              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), TARGET    :: charges
    1507              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: potential, work
    1508              : 
    1509              :       INTEGER                                            :: i, ia, ja
    1510              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1511              : 
    1512          856 :       CALL ewald_env_get(ewald_env, para_env=para_env)
    1513         7544 :       potential = response%diag*charges
    1514        12400 :       DO i = 1, response%nactive
    1515        11544 :          ia = response%row(i)
    1516        11544 :          ja = response%col(i)
    1517        11544 :          potential(ia) = potential(ia) + response%value(i)*charges(ja)
    1518        12400 :          potential(ja) = potential(ja) + response%value(i)*charges(ia)
    1519              :       END DO
    1520        14232 :       CALL para_env%sum(potential)
    1521              : 
    1522          856 :       CALL apply_potential(ewald_env, ewald_pw, cell, particle_set, charges, work)
    1523         7544 :       potential = potential + work
    1524              : 
    1525          856 :    END SUBROUTINE apply_sparse_pbc_response
    1526              : 
    1527              : ! **************************************************************************************************
    1528              : !> \brief Apply a positive diagonal EEQ preconditioner in the zero-total-charge subspace.
    1529              : !> \param residual ...
    1530              : !> \param diagonal ...
    1531              : !> \param RESULT ...
    1532              : ! **************************************************************************************************
    1533          632 :    SUBROUTINE apply_eeq_constrained_diagonal_preconditioner(residual, diagonal, RESULT)
    1534              : 
    1535              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: residual, diagonal
    1536              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: result
    1537              : 
    1538              :       REAL(KIND=dp)                                      :: constraint_shift
    1539              : 
    1540         5608 :       RESULT = residual/diagonal
    1541        11216 :       constraint_shift = SUM(RESULT)/SUM(1.0_dp/diagonal)
    1542         5608 :       RESULT = RESULT - constraint_shift/diagonal
    1543              : 
    1544          632 :    END SUBROUTINE apply_eeq_constrained_diagonal_preconditioner
    1545              : 
    1546              : ! **************************************************************************************************
    1547              : !> \brief Project a vector onto the tangent space of the EEQ total-charge constraint.
    1548              : !> \param vector ...
    1549              : ! **************************************************************************************************
    1550         1376 :    SUBROUTINE project_eeq_charge_tangent(vector)
    1551              : 
    1552              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: vector
    1553              : 
    1554        22992 :       vector = vector - SUM(vector)/REAL(SIZE(vector), KIND=dp)
    1555              : 
    1556         1376 :    END SUBROUTINE project_eeq_charge_tangent
    1557              : 
    1558              : ! **************************************************************************************************
    1559              : !> \brief Release a sparse periodic EEQ response.
    1560              : !> \param response ...
    1561              : ! **************************************************************************************************
    1562          112 :    SUBROUTINE release_sparse_pbc_response(response)
    1563              : 
    1564              :       TYPE(eeq_sparse_matrix_type), INTENT(INOUT)        :: response
    1565              : 
    1566          112 :       IF (ALLOCATED(response%col)) DEALLOCATE (response%col)
    1567          112 :       IF (ALLOCATED(response%row)) DEALLOCATE (response%row)
    1568          112 :       IF (ALLOCATED(response%diag)) DEALLOCATE (response%diag)
    1569          112 :       IF (ALLOCATED(response%value)) DEALLOCATE (response%value)
    1570          112 :       response%nactive = 0
    1571              : 
    1572          112 :    END SUBROUTINE release_sparse_pbc_response
    1573              : 
    1574              : ! **************************************************************************************************
    1575              : !> \brief ...
    1576              : !> \param charges ...
    1577              : !> \param lambda ...
    1578              : !> \param eeq_energy ...
    1579              : !> \param eeq_mat ...
    1580              : !> \param particle_set ...
    1581              : !> \param kind_of ...
    1582              : !> \param cell ...
    1583              : !> \param chia ...
    1584              : !> \param gam ...
    1585              : !> \param gab ...
    1586              : !> \param qtot ...
    1587              : !> \param ewald_env ...
    1588              : !> \param ewald_pw ...
    1589              : !> \param eeq_sparam ...
    1590              : !> \param ierror ...
    1591              : !> \param iounit ...
    1592              : ! **************************************************************************************************
    1593         1014 :    SUBROUTINE pbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
    1594         1014 :                          kind_of, cell, chia, gam, gab, qtot, &
    1595              :                          ewald_env, ewald_pw, eeq_sparam, ierror, iounit)
    1596              : 
    1597              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
    1598              :       REAL(KIND=dp), INTENT(INOUT)                       :: lambda, eeq_energy
    1599              :       TYPE(cp_fm_type)                                   :: eeq_mat
    1600              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    1601              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
    1602              :       TYPE(cell_type), POINTER                           :: cell
    1603              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: chia, gam
    1604              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
    1605              :       REAL(KIND=dp), INTENT(IN)                          :: qtot
    1606              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1607              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    1608              :       TYPE(eeq_solver_type), INTENT(IN)                  :: eeq_sparam
    1609              :       INTEGER, INTENT(OUT)                               :: ierror
    1610              :       INTEGER, OPTIONAL                                  :: iounit
    1611              : 
    1612              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'pbc_solver'
    1613              : 
    1614              :       INTEGER :: ewald_type, handle, i, iac, iar, ic, ikind, info, ir, iunit, iv, ix, iy, iz, &
    1615              :          jkind, max_diis, mdiis, natom, ncloc, ndiis, nkind, now, nrloc, ns, sdiis
    1616              :       INTEGER, DIMENSION(3)                              :: cvec, ncell, periodic
    1617         1014 :       INTEGER, DIMENSION(:), POINTER                     :: cind, rind
    1618              :       REAL(KIND=dp)                                      :: ad, alpha, astep, deth, dr, eeqn, &
    1619              :                                                             eps_diis, ftime, grc1, grc2, rcut, &
    1620              :                                                             res, resin, rmax, te, ti
    1621         1014 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: bvec, dvec
    1622         1014 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: dmat, fvec, vmat, xvec
    1623              :       REAL(KIND=dp), DIMENSION(3)                        :: ri, rij, rijl, rj
    1624              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    1625         1014 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rhs, rv0, xv0
    1626              :       TYPE(cp_fm_struct_type), POINTER                   :: mat_struct
    1627              :       TYPE(cp_fm_type)                                   :: mmat, pmat
    1628              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1629              : 
    1630         1014 :       CALL timeset(routineN, handle)
    1631         1014 :       ti = m_walltime()
    1632              : 
    1633         1014 :       ierror = 0
    1634              : 
    1635         1014 :       iunit = -1
    1636         1014 :       IF (PRESENT(iounit)) iunit = iounit
    1637              : 
    1638         1014 :       natom = SIZE(particle_set)
    1639         1014 :       nkind = SIZE(gam)
    1640              :       !
    1641         1014 :       CALL get_cell(cell=cell, deth=deth)
    1642         1014 :       CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
    1643         1014 :       ad = 2.0_dp*alpha*oorootpi
    1644         1014 :       IF (ewald_type /= do_ewald_spme) THEN
    1645            0 :          CALL cp_abort(__LOCATION__, "Only SPME Ewald method available with EEQ.")
    1646              :       END IF
    1647              :       !
    1648         1014 :       rmax = 2.0_dp*rcut
    1649              :       ! max cells used
    1650         1014 :       CALL get_cell(cell, h=hmat, periodic=periodic)
    1651         1014 :       ncell(1) = CEILING(rmax/plane_distance(1, 0, 0, cell))
    1652         1014 :       ncell(2) = CEILING(rmax/plane_distance(0, 1, 0, cell))
    1653         1014 :       ncell(3) = CEILING(rmax/plane_distance(0, 0, 1, cell))
    1654         1014 :       IF (periodic(1) == 0) ncell(1) = 0
    1655         1014 :       IF (periodic(2) == 0) ncell(2) = 0
    1656         1014 :       IF (periodic(3) == 0) ncell(3) = 0
    1657              :       !
    1658              :       CALL mi_solver(charges, lambda, eeqn, eeq_mat, particle_set, kind_of, cell, &
    1659         1014 :                      chia, gam, gab, qtot, ftime)
    1660         1014 :       IF (iunit > 0) THEN
    1661          981 :          WRITE (iunit, '(A,T67,F14.3)') " EEQ| Iterative PBC guess time[s]", ftime
    1662              :       END IF
    1663         1014 :       CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
    1664         1014 :       CALL cp_fm_create(pmat, mat_struct)
    1665         1014 :       CALL cp_fm_create(mmat, mat_struct)
    1666              :       !
    1667              :       ! response matrix
    1668              :       CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
    1669         1014 :                           row_indices=rind, col_indices=cind)
    1670         1014 :       CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
    1671         4298 :       DO ir = 1, nrloc
    1672         3284 :          iar = rind(ir)
    1673         3284 :          ri = 0.0_dp
    1674         3284 :          IF (iar <= natom) THEN
    1675         2777 :             ikind = kind_of(iar)
    1676        11108 :             ri(1:3) = particle_set(iar)%r(1:3)
    1677              :          END IF
    1678        31960 :          DO ic = 1, ncloc
    1679        27662 :             iac = cind(ic)
    1680        27662 :             IF (iac > natom .AND. iar > natom) THEN
    1681          507 :                eeq_mat%local_data(ir, ic) = 0.0_dp
    1682          507 :                CYCLE
    1683        27155 :             ELSE IF ((iac > natom) .OR. (iar > natom)) THEN
    1684         5554 :                eeq_mat%local_data(ir, ic) = 1.0_dp
    1685         5554 :                CYCLE
    1686              :             END IF
    1687        21601 :             jkind = kind_of(iac)
    1688        86404 :             rj(1:3) = particle_set(iac)%r(1:3)
    1689        86404 :             rij(1:3) = ri(1:3) - rj(1:3)
    1690        86404 :             rij = pbc(rij, cell)
    1691       192202 :             DO ix = -ncell(1), ncell(1)
    1692      1128591 :                DO iy = -ncell(2), ncell(2)
    1693      7662099 :                   DO iz = -ncell(3), ncell(3)
    1694     26220436 :                      cvec = [ix, iy, iz]
    1695    124547071 :                      rijl = rij + MATMUL(hmat, cvec)
    1696     26220436 :                      dr = NORM2(rijl)
    1697      6555109 :                      IF (dr > rmax) CYCLE
    1698      1615133 :                      IF (iar == iac .AND. dr < 0.00001_dp) THEN
    1699         2777 :                         grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi - ad
    1700              :                      ELSE
    1701      1612356 :                         grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
    1702              :                      END IF
    1703      2554806 :                      eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
    1704              :                   END DO
    1705              :                END DO
    1706              :             END DO
    1707              :          END DO
    1708              :       END DO
    1709              :       !
    1710              :       ! preconditioner
    1711              :       CALL cp_fm_get_info(pmat, nrow_local=nrloc, ncol_local=ncloc, &
    1712         1014 :                           row_indices=rind, col_indices=cind)
    1713         1014 :       CALL cp_fm_set_all(pmat, 0.0_dp, 0.0_dp)
    1714         4298 :       DO ir = 1, nrloc
    1715         3284 :          iar = rind(ir)
    1716         3284 :          ri = 0.0_dp
    1717         3284 :          IF (iar <= natom) THEN
    1718         2777 :             ikind = kind_of(iar)
    1719        11108 :             ri(1:3) = particle_set(iar)%r(1:3)
    1720              :          END IF
    1721        31960 :          DO ic = 1, ncloc
    1722        27662 :             iac = cind(ic)
    1723        27662 :             IF (iac > natom .AND. iar > natom) THEN
    1724          507 :                pmat%local_data(ir, ic) = 0.0_dp
    1725          507 :                CYCLE
    1726        27155 :             ELSE IF ((iac > natom) .OR. (iar > natom)) THEN
    1727         5554 :                pmat%local_data(ir, ic) = 1.0_dp
    1728         5554 :                CYCLE
    1729              :             END IF
    1730        21601 :             jkind = kind_of(iac)
    1731        86404 :             rj(1:3) = particle_set(iac)%r(1:3)
    1732        86404 :             rij(1:3) = ri(1:3) - rj(1:3)
    1733        86404 :             rij = pbc(rij, cell)
    1734        21601 :             IF (iar == iac) THEN
    1735         2777 :                grc2 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi
    1736              :             ELSE
    1737        18824 :                grc2 = erf(gab(ikind, jkind)*dr)/dr
    1738              :             END IF
    1739        24885 :             pmat%local_data(ir, ic) = grc2
    1740              :          END DO
    1741              :       END DO
    1742         1014 :       CALL cp_fm_set_all(mmat, 0.0_dp, 0.0_dp)
    1743              :       ! preconditioner invers
    1744         1014 :       CALL cp_fm_invert(pmat, mmat)
    1745              :       !
    1746              :       ! rhs
    1747         1014 :       ns = natom + 1
    1748         3042 :       ALLOCATE (rhs(ns))
    1749         6568 :       rhs(1:natom) = chia(1:natom)
    1750         1014 :       rhs(ns) = -qtot
    1751              :       !
    1752         3042 :       ALLOCATE (xv0(ns), rv0(ns))
    1753              :       ! initial guess
    1754         6568 :       xv0(1:natom) = charges(1:natom)
    1755         1014 :       xv0(ns) = 0.0_dp
    1756              :       ! DIIS optimizer
    1757         1014 :       max_diis = eeq_sparam%max_diis
    1758         1014 :       mdiis = eeq_sparam%mdiis
    1759         1014 :       sdiis = eeq_sparam%sdiis
    1760         1014 :       eps_diis = eeq_sparam%eps_diis
    1761         1014 :       astep = eeq_sparam%alpha
    1762         7098 :       ALLOCATE (xvec(ns, mdiis), fvec(ns, mdiis), bvec(ns))
    1763         1014 :       xvec = 0.0_dp; fvec = 0.0_dp
    1764         9126 :       ALLOCATE (vmat(mdiis, mdiis), dmat(mdiis + 1, mdiis + 1), dvec(mdiis + 1))
    1765         1014 :       dmat = 0.0_dp; dvec = 0.0_dp
    1766         1014 :       ndiis = 1
    1767         1014 :       now = 1
    1768              :       CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
    1769         1014 :                                cell, particle_set, xv0, rhs, rv0)
    1770         7582 :       resin = NORM2(rv0)
    1771              :       !
    1772         9864 :       DO iv = 1, max_diis
    1773        85656 :          res = NORM2(rv0)
    1774         9864 :          IF (res > 10._dp*resin) EXIT
    1775         8972 :          IF (res < eps_diis) EXIT
    1776              :          !
    1777         8850 :          now = MOD(iv - 1, mdiis) + 1
    1778         8850 :          ndiis = MIN(iv, mdiis)
    1779        78074 :          xvec(1:ns, now) = xv0(1:ns)
    1780        78074 :          fvec(1:ns, now) = rv0(1:ns)
    1781        65160 :          DO i = 1, ndiis
    1782       547592 :             vmat(now, i) = SUM(fvec(:, now)*fvec(:, i))
    1783        65160 :             vmat(i, now) = vmat(now, i)
    1784              :          END DO
    1785         8850 :          IF (ndiis < sdiis) THEN
    1786        26956 :             xv0(1:ns) = xv0(1:ns) + astep*rv0(1:ns)
    1787              :          ELSE
    1788         6902 :             dvec = 0.0_dp
    1789         6902 :             dvec(ndiis + 1) = 1.0_dp
    1790       562846 :             dmat(1:ndiis, 1:ndiis) = vmat(1:ndiis, 1:ndiis)
    1791        60290 :             dmat(ndiis + 1, 1:ndiis) = 1.0_dp
    1792        60290 :             dmat(1:ndiis, ndiis + 1) = 1.0_dp
    1793         6902 :             dmat(ndiis + 1, ndiis + 1) = 0.0_dp
    1794         6902 :             CALL invmat(dmat(1:ndiis + 1, 1:ndiis + 1), info)
    1795       804006 :             dvec(1:ndiis + 1) = MATMUL(dmat(1:ndiis + 1, 1:ndiis + 1), dvec(1:ndiis + 1))
    1796       589536 :             xv0(1:ns) = MATMUL(xvec(1:ns, 1:ndiis), dvec(1:ndiis))
    1797       603340 :             xv0(1:ns) = xv0(1:ns) + MATMUL(fvec(1:ns, 1:ndiis), dvec(1:ndiis))
    1798              :          END IF
    1799              :          !
    1800              :          CALL get_energy_gradient(eeqn, eeq_mat, mmat, ewald_env, ewald_pw, &
    1801         9864 :                                   cell, particle_set, xv0, rhs, rv0)
    1802              :       END DO
    1803         6568 :       charges(1:natom) = xv0(1:natom)
    1804         1014 :       lambda = xv0(ns)
    1805         1014 :       eeq_energy = eeqn
    1806         1014 :       IF (res > eps_diis) ierror = 1
    1807              :       !
    1808         1014 :       DEALLOCATE (xvec, fvec, bvec)
    1809         1014 :       DEALLOCATE (vmat, dmat, dvec)
    1810         1014 :       DEALLOCATE (xv0, rv0)
    1811         1014 :       DEALLOCATE (rhs)
    1812         1014 :       CALL cp_fm_release(pmat)
    1813         1014 :       CALL cp_fm_release(mmat)
    1814              : 
    1815         1014 :       te = m_walltime()
    1816         1014 :       IF (iunit > 0) THEN
    1817          981 :          IF (ierror == 1) THEN
    1818          876 :             WRITE (iunit, '(A)') " EEQ| PBC solver failed to converge "
    1819              :          ELSE
    1820          105 :             WRITE (iunit, '(A,T50,I4,T61,E20.5)') " EEQ| PBC solver: iterations/accuracy ", iv, res
    1821              :          END IF
    1822          981 :          WRITE (iunit, '(A,T67,F14.3)') " EEQ| Iterative PBC solver: time[s]", te - ti
    1823              :       END IF
    1824         1014 :       CALL timestop(handle)
    1825              : 
    1826         4056 :    END SUBROUTINE pbc_solver
    1827              : 
    1828              : ! **************************************************************************************************
    1829              : !> \brief ...
    1830              : !> \param charges ...
    1831              : !> \param lambda ...
    1832              : !> \param eeq_energy ...
    1833              : !> \param eeq_mat ...
    1834              : !> \param particle_set ...
    1835              : !> \param kind_of ...
    1836              : !> \param cell ...
    1837              : !> \param chia ...
    1838              : !> \param gam ...
    1839              : !> \param gab ...
    1840              : !> \param qtot ...
    1841              : !> \param ewald_env ...
    1842              : !> \param ewald_pw ...
    1843              : !> \param iounit ...
    1844              : ! **************************************************************************************************
    1845          892 :    SUBROUTINE fpbc_solver(charges, lambda, eeq_energy, eeq_mat, particle_set, &
    1846          892 :                           kind_of, cell, chia, gam, gab, qtot, ewald_env, ewald_pw, iounit)
    1847              : 
    1848              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: charges
    1849              :       REAL(KIND=dp), INTENT(INOUT)                       :: lambda, eeq_energy
    1850              :       TYPE(cp_fm_type)                                   :: eeq_mat
    1851              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    1852              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: kind_of
    1853              :       TYPE(cell_type), POINTER                           :: cell
    1854              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: chia, gam
    1855              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: gab
    1856              :       REAL(KIND=dp), INTENT(IN)                          :: qtot
    1857              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    1858              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    1859              :       INTEGER, INTENT(IN), OPTIONAL                      :: iounit
    1860              : 
    1861              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'fpbc_solver'
    1862              : 
    1863              :       INTEGER                                            :: ewald_type, handle, ia, iac, iar, ic, &
    1864              :                                                             ikind, ir, iunit, ix, iy, iz, jkind, &
    1865              :                                                             natom, ncloc, ncvloc, nkind, nrloc, &
    1866              :                                                             nrvloc, ns
    1867              :       INTEGER, DIMENSION(3)                              :: cvec, ncell, periodic
    1868          892 :       INTEGER, DIMENSION(:), POINTER                     :: cind, cvind, rind, rvind
    1869              :       REAL(KIND=dp)                                      :: ad, alpha, deth, dr, grc1, rcut, rmax, &
    1870              :                                                             te, ti, xr
    1871              :       REAL(KIND=dp), DIMENSION(3)                        :: ri, rij, rijl, rj
    1872              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    1873              :       REAL(KIND=dp), DIMENSION(:), POINTER               :: pval, xval
    1874              :       TYPE(cp_fm_struct_type), POINTER                   :: mat_struct, vec_struct
    1875              :       TYPE(cp_fm_type)                                   :: rhs_vec
    1876              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1877              : 
    1878          892 :       CALL timeset(routineN, handle)
    1879          892 :       ti = m_walltime()
    1880              : 
    1881          892 :       iunit = -1
    1882          892 :       IF (PRESENT(iounit)) iunit = iounit
    1883              : 
    1884          892 :       natom = SIZE(particle_set)
    1885          892 :       nkind = SIZE(gam)
    1886          892 :       ns = natom + 1
    1887              :       !
    1888          892 :       CALL get_cell(cell=cell, deth=deth)
    1889          892 :       CALL ewald_env_get(ewald_env, alpha=alpha, rcut=rcut, ewald_type=ewald_type)
    1890          892 :       ad = 2.0_dp*alpha*oorootpi
    1891          892 :       IF (ewald_type /= do_ewald_spme) THEN
    1892            0 :          CALL cp_abort(__LOCATION__, "Only SPME Ewald method available with EEQ.")
    1893              :       END IF
    1894              :       !
    1895          892 :       rmax = 2.0_dp*rcut
    1896              :       ! max cells used
    1897          892 :       CALL get_cell(cell, h=hmat, periodic=periodic)
    1898          892 :       ncell(1) = CEILING(rmax/plane_distance(1, 0, 0, cell))
    1899          892 :       ncell(2) = CEILING(rmax/plane_distance(0, 1, 0, cell))
    1900          892 :       ncell(3) = CEILING(rmax/plane_distance(0, 0, 1, cell))
    1901          892 :       IF (periodic(1) == 0) ncell(1) = 0
    1902          892 :       IF (periodic(2) == 0) ncell(2) = 0
    1903          892 :       IF (periodic(3) == 0) ncell(3) = 0
    1904              :       !
    1905          892 :       CALL cp_fm_get_info(eeq_mat, matrix_struct=mat_struct, para_env=para_env)
    1906          892 :       CALL cp_fm_set_all(eeq_mat, 0.0_dp, 0.0_dp)
    1907              :       CALL cp_fm_get_info(eeq_mat, nrow_local=nrloc, ncol_local=ncloc, &
    1908          892 :                           row_indices=rind, col_indices=cind)
    1909              :       CALL cp_fm_struct_create(vec_struct, template_fmstruct=mat_struct, &
    1910          892 :                                nrow_global=ns, ncol_global=1)
    1911          892 :       CALL cp_fm_create(rhs_vec, vec_struct)
    1912              :       CALL cp_fm_get_info(rhs_vec, nrow_local=nrvloc, ncol_local=ncvloc, &
    1913          892 :                           row_indices=rvind, col_indices=cvind)
    1914              :       ! response matrix
    1915         3652 :       DO ir = 1, nrloc
    1916         2760 :          iar = rind(ir)
    1917         2760 :          ri = 0.0_dp
    1918         2760 :          IF (iar <= natom) THEN
    1919         2314 :             ikind = kind_of(iar)
    1920         9256 :             ri(1:3) = particle_set(iar)%r(1:3)
    1921              :          END IF
    1922        22522 :          DO ic = 1, ncloc
    1923        18870 :             iac = cind(ic)
    1924        18870 :             IF (iac > natom .AND. iar > natom) THEN
    1925          446 :                eeq_mat%local_data(ir, ic) = 0.0_dp
    1926          446 :                CYCLE
    1927        18424 :             ELSE IF ((iac > natom) .OR. (iar > natom)) THEN
    1928         4628 :                eeq_mat%local_data(ir, ic) = 1.0_dp
    1929         4628 :                CYCLE
    1930              :             END IF
    1931        13796 :             jkind = kind_of(iac)
    1932        55184 :             rj(1:3) = particle_set(iac)%r(1:3)
    1933        55184 :             rij(1:3) = ri(1:3) - rj(1:3)
    1934        55184 :             rij = pbc(rij, cell)
    1935       126476 :             DO ix = -ncell(1), ncell(1)
    1936       636248 :                DO iy = -ncell(2), ncell(2)
    1937      3959316 :                   DO iz = -ncell(3), ncell(3)
    1938     13347456 :                      cvec = [ix, iy, iz]
    1939     63400416 :                      rijl = rij + MATMUL(hmat, cvec)
    1940     13347456 :                      dr = NORM2(rijl)
    1941      3336864 :                      IF (dr > rmax) CYCLE
    1942       826540 :                      IF (iar == iac .AND. dr < 0.0001_dp) THEN
    1943         2314 :                         grc1 = gam(ikind) + 2.0_dp*gab(ikind, ikind)*oorootpi - ad
    1944              :                      ELSE
    1945       824226 :                         grc1 = erf(gab(ikind, jkind)*dr)/dr - erf(alpha*dr)/dr
    1946              :                      END IF
    1947      1339072 :                      eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + grc1
    1948              :                   END DO
    1949              :                END DO
    1950              :             END DO
    1951              :          END DO
    1952              :       END DO
    1953              :       !
    1954         3568 :       ALLOCATE (xval(natom), pval(natom))
    1955         5520 :       DO ia = 1, natom
    1956        32220 :          xval = 0.0_dp
    1957         4628 :          xval(ia) = 1.0_dp
    1958         4628 :          CALL apply_potential(ewald_env, ewald_pw, cell, particle_set, xval, pval)
    1959              :          !
    1960        21630 :          DO ir = 1, nrloc
    1961        16110 :             iar = rind(ir)
    1962        16110 :             IF (iar /= ia) CYCLE
    1963        23052 :             DO ic = 1, ncloc
    1964        16110 :                iac = cind(ic)
    1965        16110 :                IF (iac > natom) CYCLE
    1966        32220 :                eeq_mat%local_data(ir, ic) = eeq_mat%local_data(ir, ic) + pval(iac)
    1967              :             END DO
    1968              :          END DO
    1969              :       END DO
    1970          892 :       DEALLOCATE (xval, pval)
    1971              :       !
    1972              :       ! set up rhs vector
    1973         3652 :       DO ir = 1, nrvloc
    1974         2760 :          iar = rvind(ir)
    1975         6412 :          DO ic = 1, ncvloc
    1976         2760 :             iac = cvind(ic)
    1977         2760 :             ia = MAX(iar, iac)
    1978         2760 :             IF (ia > natom) THEN
    1979          446 :                xr = qtot
    1980              :             ELSE
    1981         2314 :                xr = -chia(ia)
    1982              :             END IF
    1983         5520 :             rhs_vec%local_data(ir, ic) = xr
    1984              :          END DO
    1985              :       END DO
    1986              :       !
    1987          892 :       CALL cp_fm_solve(eeq_mat, rhs_vec)
    1988              :       !
    1989         5520 :       charges = 0.0_dp
    1990          892 :       lambda = 0.0_dp
    1991         3652 :       DO ir = 1, nrvloc
    1992         2760 :          iar = rvind(ir)
    1993         6412 :          DO ic = 1, ncvloc
    1994         2760 :             iac = cvind(ic)
    1995         2760 :             ia = MAX(iar, iac)
    1996         5520 :             IF (ia <= natom) THEN
    1997         2314 :                xr = rhs_vec%local_data(ir, ic)
    1998         2314 :                charges(ia) = xr
    1999              :             ELSE
    2000          446 :                lambda = rhs_vec%local_data(ir, ic)
    2001              :             END IF
    2002              :          END DO
    2003              :       END DO
    2004          892 :       CALL para_env%sum(lambda)
    2005        10148 :       CALL para_env%sum(charges)
    2006              :       !
    2007              :       ! energy:   0.5*(q^T.X - lambda*totalcharge)
    2008         5520 :       eeq_energy = 0.5*SUM(charges(1:natom)*chia(1:natom)) - 0.5_dp*lambda*qtot
    2009              : 
    2010          892 :       CALL cp_fm_struct_release(vec_struct)
    2011          892 :       CALL cp_fm_release(rhs_vec)
    2012              : 
    2013          892 :       te = m_walltime()
    2014          892 :       IF (iunit > 0) THEN
    2015          876 :          WRITE (iunit, '(A,T67,F14.3)') " EEQ| Direct PBC solver: time[s]", te - ti
    2016              :       END IF
    2017          892 :       CALL timestop(handle)
    2018              : 
    2019         3568 :    END SUBROUTINE fpbc_solver
    2020              : 
    2021              : ! **************************************************************************************************
    2022              : !> \brief ...
    2023              : !> \param ewald_env ...
    2024              : !> \param ewald_pw ...
    2025              : !> \param cell ...
    2026              : !> \param particle_set ...
    2027              : !> \param charges ...
    2028              : !> \param potential ...
    2029              : ! **************************************************************************************************
    2030         5484 :    SUBROUTINE apply_potential(ewald_env, ewald_pw, cell, particle_set, charges, potential)
    2031              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    2032              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    2033              :       TYPE(cell_type), POINTER                           :: cell
    2034              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    2035              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), TARGET    :: charges
    2036              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: potential
    2037              : 
    2038              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2039              : 
    2040         5484 :       CALL ewald_env_get(ewald_env, para_env=para_env)
    2041        39764 :       potential = 0.0_dp
    2042              :       CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges, &
    2043         5484 :                           particle_set, potential)
    2044        74044 :       CALL para_env%sum(potential)
    2045              : 
    2046         5484 :    END SUBROUTINE apply_potential
    2047              : 
    2048              : ! **************************************************************************************************
    2049              : !> \brief ...
    2050              : !> \param eeqn ...
    2051              : !> \param fm_mat ...
    2052              : !> \param mmat ...
    2053              : !> \param ewald_env ...
    2054              : !> \param ewald_pw ...
    2055              : !> \param cell ...
    2056              : !> \param particle_set ...
    2057              : !> \param charges ...
    2058              : !> \param rhs ...
    2059              : !> \param potential ...
    2060              : ! **************************************************************************************************
    2061         9864 :    SUBROUTINE get_energy_gradient(eeqn, fm_mat, mmat, ewald_env, ewald_pw, &
    2062         9864 :                                   cell, particle_set, charges, rhs, potential)
    2063              :       REAL(KIND=dp), INTENT(INOUT)                       :: eeqn
    2064              :       TYPE(cp_fm_type), INTENT(IN)                       :: fm_mat, mmat
    2065              :       TYPE(ewald_environment_type), POINTER              :: ewald_env
    2066              :       TYPE(ewald_pw_type), POINTER                       :: ewald_pw
    2067              :       TYPE(cell_type), POINTER                           :: cell
    2068              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    2069              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), POINTER   :: charges
    2070              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: rhs
    2071              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: potential
    2072              : 
    2073              :       INTEGER                                            :: na, ns
    2074              :       REAL(KIND=dp)                                      :: lambda
    2075              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: mvec
    2076              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2077              : 
    2078         9864 :       ns = SIZE(charges)
    2079         9864 :       na = ns - 1
    2080         9864 :       CALL ewald_env_get(ewald_env, para_env=para_env)
    2081        85656 :       potential = 0.0_dp
    2082              :       CALL spme_potential(ewald_env, ewald_pw, cell, particle_set, charges(1:na), &
    2083         9864 :                           particle_set, potential(1:na))
    2084       141720 :       CALL para_env%sum(potential(1:na))
    2085         9864 :       CALL cp_fm_matvec(fm_mat, charges, potential, alpha=1.0_dp, beta=1.0_dp)
    2086       151584 :       eeqn = 0.5_dp*SUM(charges(1:na)*potential(1:na)) + SUM(charges(1:na)*rhs(1:na))
    2087        85656 :       potential(1:ns) = potential(1:ns) + rhs(1:ns)
    2088        29592 :       ALLOCATE (mvec(ns))
    2089         9864 :       CALL cp_fm_matvec(mmat, potential, mvec, alpha=-1.0_dp, beta=0.0_dp)
    2090        75792 :       lambda = -SUM(mvec(1:na))/REAL(na, KIND=dp)
    2091        75792 :       potential(1:na) = mvec(1:na) + lambda
    2092         9864 :       DEALLOCATE (mvec)
    2093              : 
    2094         9864 :    END SUBROUTINE get_energy_gradient
    2095              : 
    2096              : ! **************************************************************************************************
    2097              : !> \brief ...
    2098              : !> \param qs_env ...
    2099              : !> \param charges ...
    2100              : !> \param ef_energy ...
    2101              : ! **************************************************************************************************
    2102          332 :    SUBROUTINE eeq_efield_energy(qs_env, charges, ef_energy)
    2103              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2104              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges
    2105              :       REAL(KIND=dp), INTENT(OUT)                         :: ef_energy
    2106              : 
    2107              :       COMPLEX(KIND=dp)                                   :: zdeta
    2108              :       COMPLEX(KIND=dp), DIMENSION(3)                     :: zi
    2109              :       INTEGER                                            :: ia, idir, natom
    2110              :       LOGICAL                                            :: dfield
    2111              :       REAL(KIND=dp)                                      :: kr, omega, q
    2112              :       REAL(KIND=dp), DIMENSION(3)                        :: ci, dfilter, fieldpol, fpolvec, kvec, &
    2113              :                                                             qi, ria
    2114              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    2115              :       TYPE(cell_type), POINTER                           :: cell
    2116              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2117          332 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2118              : 
    2119          332 :       CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
    2120          332 :       CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
    2121              : 
    2122          332 :       IF (dft_control%apply_period_efield) THEN
    2123          164 :          dfield = dft_control%period_efield%displacement_field
    2124              : 
    2125          164 :          IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
    2126            0 :             CPABORT("use of strength_list not implemented for eeq_efield_energy")
    2127              :          END IF
    2128              : 
    2129          656 :          fieldpol = dft_control%period_efield%polarisation
    2130         1148 :          fieldpol = fieldpol/NORM2(fieldpol)
    2131          656 :          fieldpol = -fieldpol*dft_control%period_efield%strength
    2132         2132 :          hmat = cell%hmat(:, :)/twopi
    2133          656 :          DO idir = 1, 3
    2134              :             fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
    2135          656 :                             + fieldpol(3)*hmat(3, idir)
    2136              :          END DO
    2137              : 
    2138          656 :          zi(:) = CMPLX(1._dp, 0._dp, dp)
    2139          820 :          DO ia = 1, natom
    2140          656 :             q = charges(ia)
    2141         2624 :             ria = particle_set(ia)%r
    2142         2624 :             ria = pbc(ria, cell)
    2143         2788 :             DO idir = 1, 3
    2144         7872 :                kvec(:) = twopi*cell%h_inv(idir, :)
    2145         7872 :                kr = SUM(kvec(:)*ria(:))
    2146         1968 :                zdeta = CMPLX(COS(kr), SIN(kr), KIND=dp)**q
    2147         2624 :                zi(idir) = zi(idir)*zdeta
    2148              :             END DO
    2149              :          END DO
    2150          656 :          qi = AIMAG(LOG(zi))
    2151          164 :          IF (dfield) THEN
    2152            0 :             dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
    2153            0 :             omega = cell%deth
    2154            0 :             ci = MATMUL(hmat, qi)/omega
    2155            0 :             ef_energy = 0.0_dp
    2156            0 :             DO idir = 1, 3
    2157            0 :                ef_energy = ef_energy + dfilter(idir)*(fieldpol(idir) - 2._dp*twopi*ci(idir))**2
    2158              :             END DO
    2159            0 :             ef_energy = -0.25_dp*omega/twopi*ef_energy
    2160              :          ELSE
    2161          656 :             ef_energy = SUM(fpolvec(:)*qi(:))
    2162              :          END IF
    2163              : 
    2164          168 :       ELSE IF (dft_control%apply_efield) THEN
    2165              : 
    2166              :          fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
    2167          672 :                     dft_control%efield_fields(1)%efield%strength
    2168              : 
    2169          168 :          ef_energy = 0.0_dp
    2170          840 :          DO ia = 1, natom
    2171         2688 :             ria = particle_set(ia)%r
    2172         2688 :             ria = pbc(ria, cell)
    2173          672 :             q = charges(ia)
    2174         2856 :             ef_energy = ef_energy - q*SUM(fieldpol*ria)
    2175              :          END DO
    2176              : 
    2177              :       ELSE
    2178            0 :          CPABORT("apply field")
    2179              :       END IF
    2180              : 
    2181          332 :    END SUBROUTINE eeq_efield_energy
    2182              : 
    2183              : ! **************************************************************************************************
    2184              : !> \brief ...
    2185              : !> \param qs_env ...
    2186              : !> \param efr ...
    2187              : ! **************************************************************************************************
    2188          332 :    SUBROUTINE eeq_efield_pot(qs_env, efr)
    2189              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2190              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: efr
    2191              : 
    2192              :       INTEGER                                            :: ia, idir, natom
    2193              :       LOGICAL                                            :: dfield
    2194              :       REAL(KIND=dp)                                      :: kr
    2195              :       REAL(KIND=dp), DIMENSION(3)                        :: fieldpol, fpolvec, kvec, ria
    2196              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    2197              :       TYPE(cell_type), POINTER                           :: cell
    2198              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2199          332 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2200              : 
    2201          332 :       CALL get_qs_env(qs_env, natom=natom, dft_control=dft_control)
    2202          332 :       CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
    2203              : 
    2204          332 :       IF (dft_control%apply_period_efield) THEN
    2205          164 :          dfield = dft_control%period_efield%displacement_field
    2206              : 
    2207          164 :          IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
    2208            0 :             CPABORT("use of strength_list not implemented for eeq_efield_pot")
    2209              :          END IF
    2210              : 
    2211          656 :          fieldpol = dft_control%period_efield%polarisation
    2212         1148 :          fieldpol = fieldpol/NORM2(fieldpol)
    2213          656 :          fieldpol = -fieldpol*dft_control%period_efield%strength
    2214         2132 :          hmat = cell%hmat(:, :)/twopi
    2215          656 :          DO idir = 1, 3
    2216              :             fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) &
    2217          656 :                             + fieldpol(3)*hmat(3, idir)
    2218              :          END DO
    2219              : 
    2220          164 :          IF (dfield) THEN
    2221              :             ! dE/dq depends on q, postpone calculation
    2222            0 :             efr = 0.0_dp
    2223              :          ELSE
    2224          820 :             efr = 0.0_dp
    2225          820 :             DO ia = 1, natom
    2226         2624 :                ria = particle_set(ia)%r
    2227         2624 :                ria = pbc(ria, cell)
    2228         2788 :                DO idir = 1, 3
    2229         7872 :                   kvec(:) = twopi*cell%h_inv(idir, :)
    2230         7872 :                   kr = SUM(kvec(:)*ria(:))
    2231         2624 :                   efr(ia) = efr(ia) + kr*fpolvec(idir)
    2232              :                END DO
    2233              :             END DO
    2234              :          END IF
    2235              : 
    2236          168 :       ELSE IF (dft_control%apply_efield) THEN
    2237              : 
    2238              :          fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
    2239          672 :                     dft_control%efield_fields(1)%efield%strength
    2240              : 
    2241          840 :          DO ia = 1, natom
    2242         2688 :             ria = particle_set(ia)%r
    2243         2688 :             ria = pbc(ria, cell)
    2244         2856 :             efr(ia) = -SUM(fieldpol*ria)
    2245              :          END DO
    2246              : 
    2247              :       ELSE
    2248            0 :          CPABORT("apply field")
    2249              :       END IF
    2250              : 
    2251          332 :    END SUBROUTINE eeq_efield_pot
    2252              : 
    2253              : ! **************************************************************************************************
    2254              : !> \brief ...
    2255              : !> \param charges ...
    2256              : !> \param dft_control ...
    2257              : !> \param particle_set ...
    2258              : !> \param cell ...
    2259              : !> \param efr ...
    2260              : ! **************************************************************************************************
    2261            0 :    SUBROUTINE eeq_dfield_pot(charges, dft_control, particle_set, cell, efr)
    2262              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges
    2263              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2264              :       TYPE(particle_type), DIMENSION(:), INTENT(IN)      :: particle_set
    2265              :       TYPE(cell_type), POINTER                           :: cell
    2266              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: efr
    2267              : 
    2268              :       COMPLEX(KIND=dp)                                   :: zdeta
    2269              :       COMPLEX(KIND=dp), DIMENSION(3)                     :: zi
    2270              :       INTEGER                                            :: ia, idir, natom
    2271              :       REAL(KIND=dp)                                      :: kr, omega, q
    2272              :       REAL(KIND=dp), DIMENSION(3)                        :: ci, dfilter, fieldpol, kvec, qi, ria
    2273              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
    2274              : 
    2275            0 :       natom = SIZE(particle_set)
    2276              : 
    2277            0 :       IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
    2278            0 :          CPABORT("use of strength_list not implemented for eeq_dfield_pot")
    2279              :       END IF
    2280              : 
    2281            0 :       dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
    2282            0 :       fieldpol = dft_control%period_efield%polarisation
    2283            0 :       fieldpol = fieldpol/NORM2(fieldpol)
    2284            0 :       fieldpol = -fieldpol*dft_control%period_efield%strength
    2285            0 :       hmat = cell%hmat(:, :)/twopi
    2286            0 :       omega = cell%deth
    2287              :       !
    2288            0 :       zi(:) = CMPLX(1._dp, 0._dp, dp)
    2289            0 :       DO ia = 1, natom
    2290            0 :          q = charges(ia)
    2291            0 :          ria = particle_set(ia)%r
    2292            0 :          ria = pbc(ria, cell)
    2293            0 :          DO idir = 1, 3
    2294            0 :             kvec(:) = twopi*cell%h_inv(idir, :)
    2295            0 :             kr = SUM(kvec(:)*ria(:))
    2296            0 :             zdeta = CMPLX(COS(kr), SIN(kr), KIND=dp)**q
    2297            0 :             zi(idir) = zi(idir)*zdeta
    2298              :          END DO
    2299              :       END DO
    2300            0 :       qi = AIMAG(LOG(zi))
    2301            0 :       ci = MATMUL(hmat, qi)/omega
    2302            0 :       ci = dfilter*(fieldpol - 2._dp*twopi*ci)
    2303            0 :       DO ia = 1, natom
    2304            0 :          ria = particle_set(ia)%r
    2305            0 :          ria = pbc(ria, cell)
    2306            0 :          efr(ia) = efr(ia) - SUM(ci*ria)
    2307              :       END DO
    2308              : 
    2309            0 :    END SUBROUTINE eeq_dfield_pot
    2310              : 
    2311              : ! **************************************************************************************************
    2312              : !> \brief ...
    2313              : !> \param qs_env ...
    2314              : !> \param charges ...
    2315              : !> \param qlag ...
    2316              : ! **************************************************************************************************
    2317            8 :    SUBROUTINE eeq_efield_force_loc(qs_env, charges, qlag)
    2318              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2319              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges, qlag
    2320              : 
    2321              :       INTEGER                                            :: atom_a, ia, iatom, ikind, natom, nkind
    2322            8 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind
    2323              :       REAL(KIND=dp)                                      :: q
    2324              :       REAL(KIND=dp), DIMENSION(3)                        :: fieldpol
    2325            8 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2326              :       TYPE(cell_type), POINTER                           :: cell
    2327              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2328              :       TYPE(distribution_1d_type), POINTER                :: local_particles
    2329              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2330            8 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2331            8 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    2332              : 
    2333              :       CALL get_qs_env(qs_env=qs_env, &
    2334              :                       dft_control=dft_control, &
    2335              :                       cell=cell, particle_set=particle_set, &
    2336              :                       nkind=nkind, natom=natom, &
    2337              :                       para_env=para_env, &
    2338            8 :                       local_particles=local_particles)
    2339              : 
    2340              :       fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
    2341           32 :                  dft_control%efield_fields(1)%efield%strength
    2342              : 
    2343            8 :       CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
    2344            8 :       CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind)
    2345            8 :       CALL get_qs_env(qs_env=qs_env, force=force)
    2346              : 
    2347           32 :       DO ikind = 1, nkind
    2348          152 :          force(ikind)%efield = 0.0_dp
    2349           40 :          DO ia = 1, local_particles%n_el(ikind)
    2350           16 :             iatom = local_particles%list(ikind)%array(ia)
    2351           16 :             q = charges(iatom) - qlag(iatom)
    2352           16 :             atom_a = atom_of_kind(iatom)
    2353           88 :             force(ikind)%efield(1:3, atom_a) = -q*fieldpol(1:3)
    2354              :          END DO
    2355          288 :          CALL para_env%sum(force(ikind)%efield)
    2356              :       END DO
    2357              : 
    2358           16 :    END SUBROUTINE eeq_efield_force_loc
    2359              : 
    2360              : ! **************************************************************************************************
    2361              : !> \brief ...
    2362              : !> \param qs_env ...
    2363              : !> \param charges ...
    2364              : !> \param qlag ...
    2365              : ! **************************************************************************************************
    2366            8 :    SUBROUTINE eeq_efield_force_periodic(qs_env, charges, qlag)
    2367              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2368              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: charges, qlag
    2369              : 
    2370              :       INTEGER                                            :: atom_a, ia, iatom, ikind, natom, nkind
    2371            8 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind
    2372              :       LOGICAL                                            :: dfield, use_virial
    2373              :       REAL(KIND=dp)                                      :: q
    2374              :       REAL(KIND=dp), DIMENSION(3)                        :: fa, fieldpol, ria
    2375              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: pve
    2376            8 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2377              :       TYPE(cell_type), POINTER                           :: cell
    2378              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2379              :       TYPE(distribution_1d_type), POINTER                :: local_particles
    2380              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2381            8 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2382            8 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    2383              :       TYPE(virial_type), POINTER                         :: virial
    2384              : 
    2385              :       CALL get_qs_env(qs_env=qs_env, &
    2386              :                       dft_control=dft_control, &
    2387              :                       cell=cell, particle_set=particle_set, &
    2388              :                       virial=virial, &
    2389              :                       nkind=nkind, natom=natom, &
    2390              :                       para_env=para_env, &
    2391            8 :                       local_particles=local_particles)
    2392              : 
    2393            8 :       dfield = dft_control%period_efield%displacement_field
    2394            8 :       CPASSERT(.NOT. dfield)
    2395              : 
    2396            8 :       IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
    2397            0 :          CPABORT("use of strength_list not implemented for eeq_efield_force_periodic")
    2398              :       END IF
    2399              : 
    2400           32 :       fieldpol = dft_control%period_efield%polarisation
    2401           56 :       fieldpol = fieldpol/NORM2(fieldpol)
    2402           32 :       fieldpol = -fieldpol*dft_control%period_efield%strength
    2403              : 
    2404            8 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
    2405              : 
    2406            8 :       CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
    2407            8 :       CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind)
    2408            8 :       CALL get_qs_env(qs_env=qs_env, force=force)
    2409              : 
    2410            8 :       pve = 0.0_dp
    2411           32 :       DO ikind = 1, nkind
    2412          152 :          force(ikind)%efield = 0.0_dp
    2413           40 :          DO ia = 1, local_particles%n_el(ikind)
    2414           16 :             iatom = local_particles%list(ikind)%array(ia)
    2415           16 :             q = charges(iatom) - qlag(iatom)
    2416           64 :             fa(1:3) = q*fieldpol(1:3)
    2417           16 :             atom_a = atom_of_kind(iatom)
    2418           64 :             force(ikind)%efield(1:3, atom_a) = fa
    2419           40 :             IF (use_virial) THEN
    2420            0 :                ria = particle_set(ia)%r
    2421            0 :                ria = pbc(ria, cell)
    2422            0 :                CALL virial_pair_force(pve, -0.5_dp, fa, ria)
    2423            0 :                CALL virial_pair_force(pve, -0.5_dp, ria, fa)
    2424              :             END IF
    2425              :          END DO
    2426          288 :          CALL para_env%sum(force(ikind)%efield)
    2427              :       END DO
    2428          104 :       virial%pv_virial = virial%pv_virial + pve
    2429              : 
    2430           16 :    END SUBROUTINE eeq_efield_force_periodic
    2431              : 
    2432        13804 : END MODULE eeq_method
        

Generated by: LCOV version 2.0-1