LCOV - code coverage report
Current view: top level - src - eeq_method.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:262480d) Lines: 758 826 91.8 %
Date: 2024-11-22 07:00:40 Functions: 14 15 93.3 %

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

Generated by: LCOV version 1.15