LCOV - code coverage report
Current view: top level - src - eeq_method.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4c33f95) Lines: 765 841 91.0 %
Date: 2025-01-30 06:53:08 Functions: 14 15 93.3 %

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

Generated by: LCOV version 1.15