LCOV - code coverage report
Current view: top level - src - efield_tb_methods.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:b4bd748) Lines: 413 474 87.1 %
Date: 2025-03-09 07:56:22 Functions: 4 4 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Calculation of electric field contributions in TB
      10             : !> \author JGH
      11             : ! **************************************************************************************************
      12             : MODULE efield_tb_methods
      13             :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      14             :                                               get_atomic_kind_set
      15             :    USE cell_types,                      ONLY: cell_type,&
      16             :                                               pbc
      17             :    USE cp_control_types,                ONLY: dft_control_type
      18             :    USE cp_dbcsr_api,                    ONLY: dbcsr_get_block_p,&
      19             :                                               dbcsr_iterator_blocks_left,&
      20             :                                               dbcsr_iterator_next_block,&
      21             :                                               dbcsr_iterator_start,&
      22             :                                               dbcsr_iterator_stop,&
      23             :                                               dbcsr_iterator_type,&
      24             :                                               dbcsr_p_type
      25             :    USE kinds,                           ONLY: dp
      26             :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      27             :                                               kpoint_type
      28             :    USE mathconstants,                   ONLY: pi,&
      29             :                                               twopi
      30             :    USE message_passing,                 ONLY: mp_para_env_type
      31             :    USE particle_types,                  ONLY: particle_type
      32             :    USE qs_energy_types,                 ONLY: qs_energy_type
      33             :    USE qs_environment_types,            ONLY: get_qs_env,&
      34             :                                               qs_environment_type,&
      35             :                                               set_qs_env
      36             :    USE qs_force_types,                  ONLY: qs_force_type
      37             :    USE qs_kind_types,                   ONLY: qs_kind_type
      38             :    USE qs_neighbor_list_types,          ONLY: get_iterator_info,&
      39             :                                               neighbor_list_iterate,&
      40             :                                               neighbor_list_iterator_create,&
      41             :                                               neighbor_list_iterator_p_type,&
      42             :                                               neighbor_list_iterator_release,&
      43             :                                               neighbor_list_set_p_type
      44             :    USE qs_period_efield_types,          ONLY: efield_berry_type,&
      45             :                                               init_efield_matrices
      46             :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      47             :                                               qs_rho_type
      48             :    USE sap_kind_types,                  ONLY: release_sap_int,&
      49             :                                               sap_int_type
      50             :    USE virial_methods,                  ONLY: virial_pair_force
      51             :    USE virial_types,                    ONLY: virial_type
      52             :    USE xtb_coulomb,                     ONLY: xtb_dsint_list
      53             : #include "./base/base_uses.f90"
      54             : 
      55             :    IMPLICIT NONE
      56             : 
      57             :    PRIVATE
      58             : 
      59             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'efield_tb_methods'
      60             : 
      61             :    PUBLIC :: efield_tb_matrix
      62             : 
      63             : CONTAINS
      64             : 
      65             : ! **************************************************************************************************
      66             : !> \brief ...
      67             : !> \param qs_env ...
      68             : !> \param ks_matrix ...
      69             : !> \param rho ...
      70             : !> \param mcharge ...
      71             : !> \param energy ...
      72             : !> \param calculate_forces ...
      73             : !> \param just_energy ...
      74             : ! **************************************************************************************************
      75       19200 :    SUBROUTINE efield_tb_matrix(qs_env, ks_matrix, rho, mcharge, energy, calculate_forces, just_energy)
      76             : 
      77             :       TYPE(qs_environment_type), POINTER                 :: qs_env
      78             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix
      79             :       TYPE(qs_rho_type), POINTER                         :: rho
      80             :       REAL(dp), DIMENSION(:), INTENT(in)                 :: mcharge
      81             :       TYPE(qs_energy_type), POINTER                      :: energy
      82             :       LOGICAL, INTENT(in)                                :: calculate_forces, just_energy
      83             : 
      84             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'efield_tb_matrix'
      85             : 
      86             :       INTEGER                                            :: handle
      87             :       TYPE(dft_control_type), POINTER                    :: dft_control
      88             : 
      89       19200 :       CALL timeset(routineN, handle)
      90             : 
      91       19200 :       energy%efield = 0.0_dp
      92       19200 :       CALL get_qs_env(qs_env, dft_control=dft_control)
      93       19200 :       IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb) THEN
      94       19200 :          IF (dft_control%apply_period_efield) THEN
      95             :             ! check if the periodic efield should be applied in the current step
      96        5116 :             IF (dft_control%period_efield%start_frame <= qs_env%sim_step .AND. &
      97             :                 (dft_control%period_efield%end_frame == -1 .OR. dft_control%period_efield%end_frame >= qs_env%sim_step)) THEN
      98             : 
      99        5116 :                IF (dft_control%period_efield%displacement_field) THEN
     100         332 :                   CALL dfield_tb_berry(qs_env, ks_matrix, rho, mcharge, energy, calculate_forces, just_energy)
     101             :                ELSE
     102        4784 :                   CALL efield_tb_berry(qs_env, ks_matrix, rho, mcharge, energy, calculate_forces, just_energy)
     103             :                END IF
     104             :             END IF
     105       14084 :          ELSE IF (dft_control%apply_efield) THEN
     106        2742 :             CALL efield_tb_local(qs_env, ks_matrix, rho, mcharge, energy, calculate_forces, just_energy)
     107       11342 :          ELSE IF (dft_control%apply_efield_field) THEN
     108           0 :             CPABORT("efield_filed")
     109             :          END IF
     110             :       ELSE
     111           0 :          CPABORT("This routine should only be called from TB")
     112             :       END IF
     113             : 
     114       19200 :       CALL timestop(handle)
     115             : 
     116       19200 :    END SUBROUTINE efield_tb_matrix
     117             : 
     118             : ! **************************************************************************************************
     119             : !> \brief ...
     120             : !> \param qs_env ...
     121             : !> \param ks_matrix ...
     122             : !> \param rho ...
     123             : !> \param mcharge ...
     124             : !> \param energy ...
     125             : !> \param calculate_forces ...
     126             : !> \param just_energy ...
     127             : ! **************************************************************************************************
     128        2742 :    SUBROUTINE efield_tb_local(qs_env, ks_matrix, rho, mcharge, energy, calculate_forces, just_energy)
     129             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     130             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix
     131             :       TYPE(qs_rho_type), POINTER                         :: rho
     132             :       REAL(dp), DIMENSION(:), INTENT(in)                 :: mcharge
     133             :       TYPE(qs_energy_type), POINTER                      :: energy
     134             :       LOGICAL, INTENT(in)                                :: calculate_forces, just_energy
     135             : 
     136             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'efield_tb_local'
     137             : 
     138             :       INTEGER                                            :: atom_a, atom_b, handle, ia, icol, idir, &
     139             :                                                             ikind, irow, ispin, jkind, natom, nspin
     140        2742 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind, kind_of
     141             :       LOGICAL                                            :: do_kpoints, found, use_virial
     142             :       REAL(dp)                                           :: charge, fdir
     143             :       REAL(dp), DIMENSION(3)                             :: ci, fieldpol, fij, ria, rib
     144        2742 :       REAL(dp), DIMENSION(:, :), POINTER                 :: ds_block, ks_block, p_block, s_block
     145        2742 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     146             :       TYPE(cell_type), POINTER                           :: cell
     147             :       TYPE(dbcsr_iterator_type)                          :: iter
     148        2742 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_p, matrix_s
     149             :       TYPE(dft_control_type), POINTER                    :: dft_control
     150             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     151        2742 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     152        2742 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     153        2742 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     154             :       TYPE(virial_type), POINTER                         :: virial
     155             : 
     156        2742 :       CALL timeset(routineN, handle)
     157             : 
     158        2742 :       CALL get_qs_env(qs_env, dft_control=dft_control, cell=cell, particle_set=particle_set)
     159        2742 :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, energy=energy, para_env=para_env)
     160        2742 :       CALL get_qs_env(qs_env=qs_env, do_kpoints=do_kpoints, virial=virial)
     161        2742 :       IF (do_kpoints) THEN
     162           0 :          CPABORT("Local electric field with kpoints not possible. Use Berry phase periodic version")
     163             :       END IF
     164             :       ! disable stress calculation
     165        2742 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     166             :       IF (use_virial) THEN
     167           0 :          CPABORT("Stress tensor for non-periodic E-field not possible")
     168             :       END IF
     169             : 
     170             :       fieldpol = dft_control%efield_fields(1)%efield%polarisation* &
     171       10968 :                  dft_control%efield_fields(1)%efield%strength
     172             : 
     173        2742 :       natom = SIZE(particle_set)
     174        2742 :       ci = 0.0_dp
     175       13430 :       DO ia = 1, natom
     176       10688 :          charge = mcharge(ia)
     177       42752 :          ria = particle_set(ia)%r
     178       42752 :          ria = pbc(ria, cell)
     179       45494 :          ci(:) = ci(:) + charge*ria(:)
     180             :       END DO
     181       10968 :       energy%efield = -SUM(ci(:)*fieldpol(:))
     182             : 
     183        2742 :       IF (.NOT. just_energy) THEN
     184             : 
     185        2742 :          IF (calculate_forces) THEN
     186          36 :             CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, force=force)
     187          36 :             CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
     188          36 :             IF (para_env%mepos == 0) THEN
     189          84 :                DO ia = 1, natom
     190          66 :                   charge = mcharge(ia)
     191          66 :                   ikind = kind_of(ia)
     192          66 :                   atom_a = atom_of_kind(ia)
     193         282 :                   force(ikind)%efield(1:3, atom_a) = -charge*fieldpol(:)
     194             :                END DO
     195             :             ELSE
     196          84 :                DO ia = 1, natom
     197          66 :                   ikind = kind_of(ia)
     198          66 :                   atom_a = atom_of_kind(ia)
     199         282 :                   force(ikind)%efield(1:3, atom_a) = 0.0_dp
     200             :                END DO
     201             :             END IF
     202          36 :             CALL qs_rho_get(rho, rho_ao=matrix_p)
     203             :          END IF
     204             : 
     205             :          ! Update KS matrix
     206        2742 :          nspin = SIZE(ks_matrix, 1)
     207        2742 :          NULLIFY (matrix_s)
     208        2742 :          CALL get_qs_env(qs_env=qs_env, matrix_s=matrix_s)
     209        2742 :          CALL dbcsr_iterator_start(iter, matrix_s(1)%matrix)
     210       16150 :          DO WHILE (dbcsr_iterator_blocks_left(iter))
     211       13408 :             NULLIFY (ks_block, s_block, p_block)
     212       13408 :             CALL dbcsr_iterator_next_block(iter, irow, icol, s_block)
     213       53632 :             ria = particle_set(irow)%r
     214       53632 :             ria = pbc(ria, cell)
     215       53632 :             rib = particle_set(icol)%r
     216       53632 :             rib = pbc(rib, cell)
     217       53632 :             fdir = 0.5_dp*SUM(fieldpol(1:3)*(ria(1:3) + rib(1:3)))
     218       26816 :             DO ispin = 1, nspin
     219             :                CALL dbcsr_get_block_p(matrix=ks_matrix(ispin, 1)%matrix, &
     220       13408 :                                       row=irow, col=icol, BLOCK=ks_block, found=found)
     221      359280 :                ks_block = ks_block + fdir*s_block
     222       40224 :                CPASSERT(found)
     223             :             END DO
     224       16150 :             IF (calculate_forces) THEN
     225         163 :                ikind = kind_of(irow)
     226         163 :                jkind = kind_of(icol)
     227         163 :                atom_a = atom_of_kind(irow)
     228         163 :                atom_b = atom_of_kind(icol)
     229         163 :                fij = 0.0_dp
     230         326 :                DO ispin = 1, nspin
     231             :                   CALL dbcsr_get_block_p(matrix=matrix_p(ispin)%matrix, &
     232         163 :                                          row=irow, col=icol, BLOCK=p_block, found=found)
     233         163 :                   CPASSERT(found)
     234         978 :                   DO idir = 1, 3
     235             :                      CALL dbcsr_get_block_p(matrix=matrix_s(idir + 1)%matrix, &
     236         489 :                                             row=irow, col=icol, BLOCK=ds_block, found=found)
     237         489 :                      CPASSERT(found)
     238        7639 :                      fij(idir) = fij(idir) + SUM(p_block*ds_block)
     239             :                   END DO
     240             :                END DO
     241         652 :                fdir = SUM(ria(1:3)*fieldpol(1:3))
     242         652 :                force(ikind)%efield(1:3, atom_a) = force(ikind)%efield(1:3, atom_a) + fdir*fij(1:3)
     243         652 :                force(jkind)%efield(1:3, atom_b) = force(jkind)%efield(1:3, atom_b) - fdir*fij(1:3)
     244         652 :                fdir = SUM(rib(1:3)*fieldpol(1:3))
     245         652 :                force(ikind)%efield(1:3, atom_a) = force(ikind)%efield(1:3, atom_a) + fdir*fij(1:3)
     246         652 :                force(jkind)%efield(1:3, atom_b) = force(jkind)%efield(1:3, atom_b) - fdir*fij(1:3)
     247             :             END IF
     248             :          END DO
     249        2742 :          CALL dbcsr_iterator_stop(iter)
     250             : 
     251        2742 :          IF (calculate_forces) THEN
     252         138 :             DO ikind = 1, SIZE(atomic_kind_set)
     253        1194 :                CALL para_env%sum(force(ikind)%efield)
     254             :             END DO
     255             :          END IF
     256             : 
     257             :       END IF
     258             : 
     259        2742 :       CALL timestop(handle)
     260             : 
     261        5484 :    END SUBROUTINE efield_tb_local
     262             : 
     263             : ! **************************************************************************************************
     264             : !> \brief ...
     265             : !> \param qs_env ...
     266             : !> \param ks_matrix ...
     267             : !> \param rho ...
     268             : !> \param mcharge ...
     269             : !> \param energy ...
     270             : !> \param calculate_forces ...
     271             : !> \param just_energy ...
     272             : ! **************************************************************************************************
     273        4784 :    SUBROUTINE efield_tb_berry(qs_env, ks_matrix, rho, mcharge, energy, calculate_forces, just_energy)
     274             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     275             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix
     276             :       TYPE(qs_rho_type), POINTER                         :: rho
     277             :       REAL(dp), DIMENSION(:), INTENT(in)                 :: mcharge
     278             :       TYPE(qs_energy_type), POINTER                      :: energy
     279             :       LOGICAL, INTENT(in)                                :: calculate_forces, just_energy
     280             : 
     281             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'efield_tb_berry'
     282             : 
     283             :       COMPLEX(KIND=dp)                                   :: zdeta
     284             :       COMPLEX(KIND=dp), DIMENSION(3)                     :: zi(3)
     285             :       INTEGER                                            :: atom_a, atom_b, handle, ia, iac, iatom, &
     286             :                                                             ic, icol, idir, ikind, irow, is, &
     287             :                                                             ispin, jatom, jkind, natom, nimg, &
     288             :                                                             nkind, nspin
     289        4784 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind, kind_of
     290             :       INTEGER, DIMENSION(3)                              :: cellind
     291        4784 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
     292             :       LOGICAL                                            :: found, use_virial
     293             :       REAL(KIND=dp)                                      :: charge, dd, dr, fdir, fi, strength
     294             :       REAL(KIND=dp), DIMENSION(3)                        :: fieldpol, fij, forcea, fpolvec, kvec, &
     295             :                                                             qi, rab, ria, rib, rij
     296             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
     297        4784 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: ds_block, ks_block, p_block, s_block
     298        4784 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: dsint
     299        4784 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     300             :       TYPE(cell_type), POINTER                           :: cell
     301             :       TYPE(dbcsr_iterator_type)                          :: iter
     302        4784 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_s
     303             :       TYPE(dft_control_type), POINTER                    :: dft_control
     304             :       TYPE(kpoint_type), POINTER                         :: kpoints
     305             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     306             :       TYPE(neighbor_list_iterator_p_type), &
     307        4784 :          DIMENSION(:), POINTER                           :: nl_iterator
     308             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     309        4784 :          POINTER                                         :: sab_orb
     310        4784 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     311        4784 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     312        4784 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     313        4784 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
     314             :       TYPE(virial_type), POINTER                         :: virial
     315             : 
     316        4784 :       CALL timeset(routineN, handle)
     317             : 
     318        4784 :       NULLIFY (dft_control, cell, particle_set)
     319             :       CALL get_qs_env(qs_env, dft_control=dft_control, cell=cell, &
     320        4784 :                       particle_set=particle_set, virial=virial)
     321        4784 :       NULLIFY (qs_kind_set, para_env, sab_orb)
     322             :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, &
     323        4784 :                       energy=energy, para_env=para_env, sab_orb=sab_orb)
     324             : 
     325             :       ! calculate stress only if forces requested also
     326        4920 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     327         146 :       use_virial = use_virial .AND. calculate_forces
     328             : 
     329             :       ! if an intensities list is given, select the value for the current step
     330        4784 :       strength = dft_control%period_efield%strength
     331        4784 :       IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
     332             :          strength = dft_control%period_efield%strength_list(MOD(qs_env%sim_step &
     333           0 :                                         - dft_control%period_efield%start_frame, SIZE(dft_control%period_efield%strength_list)) + 1)
     334             :       END IF
     335             : 
     336       19136 :       fieldpol = dft_control%period_efield%polarisation
     337       33488 :       fieldpol = fieldpol/SQRT(DOT_PRODUCT(fieldpol, fieldpol))
     338       19136 :       fieldpol = -fieldpol*strength
     339       62192 :       hmat = cell%hmat(:, :)/twopi
     340       19136 :       DO idir = 1, 3
     341       19136 :          fpolvec(idir) = fieldpol(1)*hmat(1, idir) + fieldpol(2)*hmat(2, idir) + fieldpol(3)*hmat(3, idir)
     342             :       END DO
     343             : 
     344        4784 :       natom = SIZE(particle_set)
     345        4784 :       nspin = SIZE(ks_matrix, 1)
     346             : 
     347       19136 :       zi(:) = CMPLX(1._dp, 0._dp, dp)
     348       22598 :       DO ia = 1, natom
     349       17814 :          charge = mcharge(ia)
     350       71256 :          ria = particle_set(ia)%r
     351       76040 :          DO idir = 1, 3
     352      213768 :             kvec(:) = twopi*cell%h_inv(idir, :)
     353      213768 :             dd = SUM(kvec(:)*ria(:))
     354       53442 :             zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)**charge
     355       71256 :             zi(idir) = zi(idir)*zdeta
     356             :          END DO
     357             :       END DO
     358       19136 :       qi = AIMAG(LOG(zi))
     359       19136 :       energy%efield = SUM(fpolvec(:)*qi(:))
     360             : 
     361        4784 :       IF (.NOT. just_energy) THEN
     362        4784 :          CALL get_qs_env(qs_env=qs_env, matrix_s_kp=matrix_s)
     363        4784 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     364             : 
     365        4784 :          nimg = dft_control%nimages
     366        4784 :          NULLIFY (cell_to_index)
     367        4784 :          IF (nimg > 1) THEN
     368        1870 :             NULLIFY (kpoints)
     369        1870 :             CALL get_qs_env(qs_env=qs_env, kpoints=kpoints)
     370        1870 :             CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
     371             :          END IF
     372             : 
     373        4784 :          IF (calculate_forces) THEN
     374          54 :             CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, force=force)
     375          54 :             CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
     376          54 :             IF (para_env%mepos == 0) THEN
     377         114 :                DO ia = 1, natom
     378          87 :                   charge = mcharge(ia)
     379          87 :                   iatom = atom_of_kind(ia)
     380          87 :                   ikind = kind_of(ia)
     381         348 :                   force(ikind)%efield(:, iatom) = fieldpol(:)*charge
     382         114 :                   IF (use_virial) THEN
     383          80 :                      ria = particle_set(ia)%r
     384          80 :                      ria = pbc(ria, cell)
     385          80 :                      forcea(1:3) = fieldpol(1:3)*charge
     386          20 :                      CALL virial_pair_force(virial%pv_virial, -0.5_dp, forcea, ria)
     387          20 :                      CALL virial_pair_force(virial%pv_virial, -0.5_dp, ria, forcea)
     388             :                   END IF
     389             :                END DO
     390             :             ELSE
     391         114 :                DO ia = 1, natom
     392          87 :                   iatom = atom_of_kind(ia)
     393          87 :                   ikind = kind_of(ia)
     394         375 :                   force(ikind)%efield(:, iatom) = 0.0_dp
     395             :                END DO
     396             :             END IF
     397             :          END IF
     398             : 
     399        4784 :          IF (nimg == 1) THEN
     400             :             ! no k-points; all matrices have been transformed to periodic bsf
     401        2914 :             CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
     402       16173 :             DO WHILE (dbcsr_iterator_blocks_left(iter))
     403       13259 :                CALL dbcsr_iterator_next_block(iter, irow, icol, s_block)
     404             : 
     405       13259 :                fdir = 0.0_dp
     406       53036 :                ria = particle_set(irow)%r
     407       53036 :                rib = particle_set(icol)%r
     408       53036 :                DO idir = 1, 3
     409      159108 :                   kvec(:) = twopi*cell%h_inv(idir, :)
     410      159108 :                   dd = SUM(kvec(:)*ria(:))
     411       39777 :                   zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     412       39777 :                   fdir = fdir + fpolvec(idir)*AIMAG(LOG(zdeta))
     413      159108 :                   dd = SUM(kvec(:)*rib(:))
     414       39777 :                   zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     415       53036 :                   fdir = fdir + fpolvec(idir)*AIMAG(LOG(zdeta))
     416             :                END DO
     417             : 
     418       30910 :                DO is = 1, nspin
     419       17651 :                   NULLIFY (ks_block)
     420             :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, 1)%matrix, &
     421       17651 :                                          row=irow, col=icol, block=ks_block, found=found)
     422       17651 :                   CPASSERT(found)
     423      464305 :                   ks_block = ks_block - 0.5_dp*fdir*s_block
     424             :                END DO
     425       16173 :                IF (calculate_forces .AND. irow /= icol) THEN
     426          66 :                   ikind = kind_of(irow)
     427          66 :                   jkind = kind_of(icol)
     428          66 :                   atom_a = atom_of_kind(irow)
     429          66 :                   atom_b = atom_of_kind(icol)
     430          66 :                   fij = 0.0_dp
     431         156 :                   DO ispin = 1, nspin
     432             :                      CALL dbcsr_get_block_p(matrix=matrix_p(ispin, 1)%matrix, &
     433          90 :                                             row=irow, col=icol, BLOCK=p_block, found=found)
     434          90 :                      CPASSERT(found)
     435         516 :                      DO idir = 1, 3
     436             :                         CALL dbcsr_get_block_p(matrix=matrix_s(idir + 1, 1)%matrix, &
     437         270 :                                                row=irow, col=icol, BLOCK=ds_block, found=found)
     438         270 :                         CPASSERT(found)
     439        3444 :                         fij(idir) = fij(idir) - SUM(p_block*ds_block)
     440             :                      END DO
     441             :                   END DO
     442         264 :                   force(ikind)%efield(1:3, atom_a) = force(ikind)%efield(1:3, atom_a) + fdir*fij(1:3)
     443         264 :                   force(jkind)%efield(1:3, atom_b) = force(jkind)%efield(1:3, atom_b) - fdir*fij(1:3)
     444             :                END IF
     445             :             END DO
     446        2914 :             CALL dbcsr_iterator_stop(iter)
     447             :             !
     448             :             ! stress tensor for Gamma point needs to recalculate overlap integral derivatives
     449             :             !
     450        2914 :             IF (use_virial) THEN
     451             :                ! derivative overlap integral (non collapsed)
     452           6 :                NULLIFY (sap_int)
     453           6 :                IF (dft_control%qs_control%dftb) THEN
     454           0 :                   CPABORT("DFTB stress tensor for periodic efield not implemented")
     455           6 :                ELSEIF (dft_control%qs_control%xtb) THEN
     456           6 :                   CALL xtb_dsint_list(qs_env, sap_int)
     457             :                ELSE
     458           0 :                   CPABORT("TB method unknown")
     459             :                END IF
     460             :                !
     461           6 :                CALL get_qs_env(qs_env, nkind=nkind)
     462          24 :                DO ikind = 1, nkind
     463          78 :                   DO jkind = 1, nkind
     464          54 :                      iac = ikind + nkind*(jkind - 1)
     465          54 :                      IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
     466          72 :                      DO ia = 1, sap_int(iac)%nalist
     467          27 :                         IF (.NOT. ASSOCIATED(sap_int(iac)%alist(ia)%clist)) CYCLE
     468          27 :                         iatom = sap_int(iac)%alist(ia)%aatom
     469        1463 :                         DO ic = 1, sap_int(iac)%alist(ia)%nclist
     470        1382 :                            jatom = sap_int(iac)%alist(ia)%clist(ic)%catom
     471        5528 :                            rij = sap_int(iac)%alist(ia)%clist(ic)%rac
     472        5528 :                            dr = SQRT(SUM(rij(:)**2))
     473        1409 :                            IF (dr > 1.e-6_dp) THEN
     474        1370 :                               dsint => sap_int(iac)%alist(ia)%clist(ic)%acint
     475        1370 :                               icol = MAX(iatom, jatom)
     476        1370 :                               irow = MIN(iatom, jatom)
     477        3737 :                               IF (irow == iatom) rij = -rij
     478        1370 :                               fdir = 0.0_dp
     479        5480 :                               ria = particle_set(irow)%r
     480        5480 :                               rib = particle_set(icol)%r
     481        5480 :                               DO idir = 1, 3
     482       16440 :                                  kvec(:) = twopi*cell%h_inv(idir, :)
     483       16440 :                                  dd = SUM(kvec(:)*ria(:))
     484        4110 :                                  zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     485        4110 :                                  fdir = fdir - fpolvec(idir)*AIMAG(LOG(zdeta))
     486       16440 :                                  dd = SUM(kvec(:)*rib(:))
     487        4110 :                                  zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     488        5480 :                                  fdir = fdir - fpolvec(idir)*AIMAG(LOG(zdeta))
     489             :                               END DO
     490        1370 :                               fi = 1.0_dp
     491        1370 :                               IF (iatom == jatom) fi = 0.5_dp
     492        3406 :                               DO ispin = 1, nspin
     493        2036 :                                  NULLIFY (p_block)
     494             :                                  CALL dbcsr_get_block_p(matrix=matrix_p(ispin, 1)%matrix, &
     495        2036 :                                                         row=irow, col=icol, block=p_block, found=found)
     496        2036 :                                  CPASSERT(found)
     497        2036 :                                  fij = 0.0_dp
     498        8144 :                                  DO idir = 1, 3
     499        8144 :                                     IF (irow == iatom) THEN
     500       40725 :                                        fij(idir) = SUM(p_block*dsint(:, :, idir))
     501             :                                     ELSE
     502       32265 :                                        fij(idir) = SUM(TRANSPOSE(p_block)*dsint(:, :, idir))
     503             :                                     END IF
     504             :                                  END DO
     505        5555 :                                  IF (irow == iatom) fij = -fij
     506       11550 :                                  CALL virial_pair_force(virial%pv_virial, fi, fdir*fij(1:3), rij)
     507             :                               END DO
     508             :                            END IF
     509             :                         END DO
     510             :                      END DO
     511             :                   END DO
     512             :                END DO
     513           6 :                CALL release_sap_int(sap_int)
     514             :             END IF
     515             :          ELSE
     516        1870 :             CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
     517      498343 :             DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     518             :                CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     519      496473 :                                       iatom=iatom, jatom=jatom, r=rab, cell=cellind)
     520             : 
     521      496473 :                icol = MAX(iatom, jatom)
     522      496473 :                irow = MIN(iatom, jatom)
     523             : 
     524      496473 :                ic = cell_to_index(cellind(1), cellind(2), cellind(3))
     525      496473 :                CPASSERT(ic > 0)
     526             : 
     527      496473 :                fdir = 0.0_dp
     528     1985892 :                ria = particle_set(irow)%r
     529     1985892 :                rib = particle_set(icol)%r
     530     1985892 :                DO idir = 1, 3
     531     5957676 :                   kvec(:) = twopi*cell%h_inv(idir, :)
     532     5957676 :                   dd = SUM(kvec(:)*ria(:))
     533     1489419 :                   zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     534     1489419 :                   fdir = fdir + fpolvec(idir)*AIMAG(LOG(zdeta))
     535     5957676 :                   dd = SUM(kvec(:)*rib(:))
     536     1489419 :                   zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     537     1985892 :                   fdir = fdir + fpolvec(idir)*AIMAG(LOG(zdeta))
     538             :                END DO
     539             : 
     540      496473 :                NULLIFY (s_block)
     541             :                CALL dbcsr_get_block_p(matrix=matrix_s(1, ic)%matrix, &
     542      496473 :                                       row=irow, col=icol, block=s_block, found=found)
     543      496473 :                CPASSERT(found)
     544     1180546 :                DO is = 1, nspin
     545      684073 :                   NULLIFY (ks_block)
     546             :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, ic)%matrix, &
     547      684073 :                                          row=irow, col=icol, block=ks_block, found=found)
     548      684073 :                   CPASSERT(found)
     549    16026019 :                   ks_block = ks_block - 0.5_dp*fdir*s_block
     550             :                END DO
     551      498343 :                IF (calculate_forces) THEN
     552        3323 :                   atom_a = atom_of_kind(iatom)
     553        3323 :                   atom_b = atom_of_kind(jatom)
     554        3323 :                   fij = 0.0_dp
     555        7986 :                   DO ispin = 1, nspin
     556             :                      CALL dbcsr_get_block_p(matrix=matrix_p(ispin, ic)%matrix, &
     557        4663 :                                             row=irow, col=icol, BLOCK=p_block, found=found)
     558        4663 :                      CPASSERT(found)
     559       26638 :                      DO idir = 1, 3
     560             :                         CALL dbcsr_get_block_p(matrix=matrix_s(idir + 1, ic)%matrix, &
     561       13989 :                                                row=irow, col=icol, BLOCK=ds_block, found=found)
     562       13989 :                         CPASSERT(found)
     563      176149 :                         fij(idir) = fij(idir) - SUM(p_block*ds_block)
     564             :                      END DO
     565             :                   END DO
     566        9197 :                   IF (irow == iatom) fij = -fij
     567       13292 :                   force(ikind)%efield(1:3, atom_a) = force(ikind)%efield(1:3, atom_a) - fdir*fij(1:3)
     568       13292 :                   force(jkind)%efield(1:3, atom_b) = force(jkind)%efield(1:3, atom_b) + fdir*fij(1:3)
     569        3323 :                   IF (use_virial) THEN
     570        5360 :                      dr = SQRT(SUM(rab(:)**2))
     571        1340 :                      IF (dr > 1.e-6_dp) THEN
     572        1332 :                         fi = 1.0_dp
     573        1332 :                         IF (iatom == jatom) fi = 0.5_dp
     574        5328 :                         CALL virial_pair_force(virial%pv_virial, fi, -fdir*fij(1:3), rab)
     575             :                      END IF
     576             :                   END IF
     577             :                END IF
     578             :             END DO
     579        1870 :             CALL neighbor_list_iterator_release(nl_iterator)
     580             :          END IF
     581             : 
     582        4784 :          IF (calculate_forces) THEN
     583         186 :             DO ikind = 1, SIZE(atomic_kind_set)
     584        1578 :                CALL para_env%sum(force(ikind)%efield)
     585             :             END DO
     586             :          END IF
     587             : 
     588             :       END IF
     589             : 
     590        4784 :       CALL timestop(handle)
     591             : 
     592        9568 :    END SUBROUTINE efield_tb_berry
     593             : 
     594             : ! **************************************************************************************************
     595             : !> \brief ...
     596             : !> \param qs_env ...
     597             : !> \param ks_matrix ...
     598             : !> \param rho ...
     599             : !> \param mcharge ...
     600             : !> \param energy ...
     601             : !> \param calculate_forces ...
     602             : !> \param just_energy ...
     603             : ! **************************************************************************************************
     604         332 :    SUBROUTINE dfield_tb_berry(qs_env, ks_matrix, rho, mcharge, energy, calculate_forces, just_energy)
     605             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     606             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix
     607             :       TYPE(qs_rho_type), POINTER                         :: rho
     608             :       REAL(dp), DIMENSION(:), INTENT(in)                 :: mcharge
     609             :       TYPE(qs_energy_type), POINTER                      :: energy
     610             :       LOGICAL, INTENT(in)                                :: calculate_forces, just_energy
     611             : 
     612             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'dfield_tb_berry'
     613             : 
     614             :       COMPLEX(KIND=dp)                                   :: zdeta
     615             :       COMPLEX(KIND=dp), DIMENSION(3)                     :: zi(3)
     616             :       INTEGER                                            :: atom_a, atom_b, handle, i, ia, iatom, &
     617             :                                                             ic, icol, idir, ikind, irow, is, &
     618             :                                                             ispin, jatom, jkind, natom, nimg, nspin
     619         332 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind, kind_of
     620             :       INTEGER, DIMENSION(3)                              :: cellind
     621         332 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
     622             :       LOGICAL                                            :: found, use_virial
     623             :       REAL(KIND=dp)                                      :: charge, dd, ener_field, fdir, omega, &
     624             :                                                             strength
     625             :       REAL(KIND=dp), DIMENSION(3)                        :: ci, cqi, dfilter, di, fieldpol, fij, &
     626             :                                                             hdi, kvec, qi, rab, ria, rib
     627             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat
     628         332 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: ds_block, ks_block, p_block, s_block
     629         332 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     630             :       TYPE(cell_type), POINTER                           :: cell
     631             :       TYPE(dbcsr_iterator_type)                          :: iter
     632         332 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_s
     633             :       TYPE(dft_control_type), POINTER                    :: dft_control
     634             :       TYPE(efield_berry_type), POINTER                   :: efield
     635             :       TYPE(kpoint_type), POINTER                         :: kpoints
     636             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     637             :       TYPE(neighbor_list_iterator_p_type), &
     638         332 :          DIMENSION(:), POINTER                           :: nl_iterator
     639             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     640         332 :          POINTER                                         :: sab_orb
     641         332 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     642         332 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     643         332 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     644             :       TYPE(virial_type), POINTER                         :: virial
     645             : 
     646         332 :       CALL timeset(routineN, handle)
     647             : 
     648         332 :       NULLIFY (dft_control, cell, particle_set)
     649             :       CALL get_qs_env(qs_env, dft_control=dft_control, cell=cell, &
     650         332 :                       particle_set=particle_set, virial=virial)
     651         332 :       NULLIFY (qs_kind_set, para_env, sab_orb)
     652             :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, &
     653         332 :                       efield=efield, energy=energy, para_env=para_env, sab_orb=sab_orb)
     654             : 
     655             :       ! efield history
     656         332 :       CALL init_efield_matrices(efield)
     657         332 :       CALL set_qs_env(qs_env, efield=efield)
     658             : 
     659             :       ! calculate stress only if forces requested also
     660         332 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     661           0 :       use_virial = use_virial .AND. calculate_forces
     662             :       ! disable stress calculation
     663             :       IF (use_virial) THEN
     664           0 :          CPABORT("Stress tensor for periodic D-field not implemented")
     665             :       END IF
     666             : 
     667        1328 :       dfilter(1:3) = dft_control%period_efield%d_filter(1:3)
     668             : 
     669             :       ! if an intensities list is given, select the value for the current step
     670         332 :       strength = dft_control%period_efield%strength
     671         332 :       IF (ALLOCATED(dft_control%period_efield%strength_list)) THEN
     672             :          strength = dft_control%period_efield%strength_list(MOD(qs_env%sim_step &
     673           0 :                                         - dft_control%period_efield%start_frame, SIZE(dft_control%period_efield%strength_list)) + 1)
     674             :       END IF
     675             : 
     676        1328 :       fieldpol = dft_control%period_efield%polarisation
     677        2324 :       fieldpol = fieldpol/SQRT(DOT_PRODUCT(fieldpol, fieldpol))
     678        1328 :       fieldpol = fieldpol*strength
     679             : 
     680         332 :       omega = cell%deth
     681        4316 :       hmat = cell%hmat(:, :)/twopi
     682             : 
     683         332 :       natom = SIZE(particle_set)
     684         332 :       nspin = SIZE(ks_matrix, 1)
     685             : 
     686        1328 :       zi(:) = CMPLX(1._dp, 0._dp, dp)
     687         996 :       DO ia = 1, natom
     688         664 :          charge = mcharge(ia)
     689        2656 :          ria = particle_set(ia)%r
     690        2988 :          DO idir = 1, 3
     691        7968 :             kvec(:) = twopi*cell%h_inv(idir, :)
     692        7968 :             dd = SUM(kvec(:)*ria(:))
     693        1992 :             zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)**charge
     694        2656 :             zi(idir) = zi(idir)*zdeta
     695             :          END DO
     696             :       END DO
     697        1328 :       qi = AIMAG(LOG(zi))
     698             : 
     699             :       ! make sure the total normalized polarization is within [-1:1]
     700        1328 :       DO idir = 1, 3
     701         996 :          cqi(idir) = qi(idir)/omega
     702         996 :          IF (cqi(idir) > pi) cqi(idir) = cqi(idir) - twopi
     703         996 :          IF (cqi(idir) < -pi) cqi(idir) = cqi(idir) + twopi
     704             :          ! now check for log branch
     705         996 :          IF (calculate_forces) THEN
     706          30 :             IF (ABS(efield%polarisation(idir) - cqi(idir)) > pi) THEN
     707           0 :                di(idir) = (efield%polarisation(idir) - cqi(idir))/pi
     708           0 :                DO i = 1, 10
     709           0 :                   cqi(idir) = cqi(idir) + SIGN(1.0_dp, di(idir))*twopi
     710           0 :                   IF (ABS(efield%polarisation(idir) - cqi(idir)) < pi) EXIT
     711             :                END DO
     712             :             END IF
     713             :          END IF
     714        1328 :          cqi(idir) = cqi(idir)*omega
     715             :       END DO
     716        1328 :       DO idir = 1, 3
     717         996 :          ci(idir) = 0.0_dp
     718        4316 :          DO i = 1, 3
     719        3984 :             ci(idir) = ci(idir) + hmat(idir, i)*cqi(i)
     720             :          END DO
     721             :       END DO
     722             :       ! update the references
     723         332 :       IF (calculate_forces) THEN
     724          40 :          ener_field = SUM(ci)
     725             :          ! check for smoothness of energy surface
     726         130 :          IF (ABS(efield%field_energy - ener_field) > pi*ABS(SUM(hmat))) THEN
     727           0 :             CPWARN("Large change of e-field energy detected. Correct for non-smooth energy surface")
     728             :          END IF
     729          10 :          efield%field_energy = ener_field
     730          40 :          efield%polarisation(:) = cqi(:)/omega
     731             :       END IF
     732             : 
     733             :       ! Energy
     734         332 :       ener_field = 0.0_dp
     735        1328 :       DO idir = 1, 3
     736        1328 :          ener_field = ener_field + dfilter(idir)*(fieldpol(idir) - 2._dp*twopi/omega*ci(idir))**2
     737             :       END DO
     738         332 :       energy%efield = 0.25_dp/twopi*ener_field
     739             : 
     740         332 :       IF (.NOT. just_energy) THEN
     741        1328 :          di(:) = -(fieldpol(:) - 2._dp*twopi/omega*ci(:))*dfilter(:)/omega
     742             : 
     743         332 :          CALL get_qs_env(qs_env=qs_env, matrix_s_kp=matrix_s)
     744         332 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     745             : 
     746         332 :          nimg = dft_control%nimages
     747         332 :          NULLIFY (cell_to_index)
     748         332 :          IF (nimg > 1) THEN
     749           0 :             NULLIFY (kpoints)
     750           0 :             CALL get_qs_env(qs_env=qs_env, kpoints=kpoints)
     751           0 :             CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
     752             :          END IF
     753             : 
     754         332 :          IF (calculate_forces) THEN
     755          10 :             CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, force=force)
     756          10 :             CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
     757          10 :             IF (para_env%mepos == 0) THEN
     758          15 :                DO ia = 1, natom
     759          10 :                   charge = mcharge(ia)
     760          10 :                   iatom = atom_of_kind(ia)
     761          10 :                   ikind = kind_of(ia)
     762          45 :                   force(ikind)%efield(:, iatom) = force(ikind)%efield(:, iatom) + di(:)*charge
     763             :                END DO
     764             :             END IF
     765             :          END IF
     766             : 
     767         332 :          IF (nimg == 1) THEN
     768             :             ! no k-points; all matrices have been transformed to periodic bsf
     769         332 :             CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
     770         830 :             DO WHILE (dbcsr_iterator_blocks_left(iter))
     771         498 :                CALL dbcsr_iterator_next_block(iter, irow, icol, s_block)
     772             : 
     773        1992 :                DO idir = 1, 3
     774        6474 :                   hdi(idir) = -SUM(di(1:3)*hmat(1:3, idir))
     775             :                END DO
     776         498 :                fdir = 0.0_dp
     777        1992 :                ria = particle_set(irow)%r
     778        1992 :                rib = particle_set(icol)%r
     779        1992 :                DO idir = 1, 3
     780        5976 :                   kvec(:) = twopi*cell%h_inv(idir, :)
     781        5976 :                   dd = SUM(kvec(:)*ria(:))
     782        1494 :                   zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     783        1494 :                   fdir = fdir + hdi(idir)*AIMAG(LOG(zdeta))
     784        5976 :                   dd = SUM(kvec(:)*rib(:))
     785        1494 :                   zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     786        1992 :                   fdir = fdir + hdi(idir)*AIMAG(LOG(zdeta))
     787             :                END DO
     788             : 
     789         996 :                DO is = 1, nspin
     790         498 :                   NULLIFY (ks_block)
     791             :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, 1)%matrix, &
     792         498 :                                          row=irow, col=icol, block=ks_block, found=found)
     793         498 :                   CPASSERT(found)
     794       14110 :                   ks_block = ks_block + 0.5_dp*fdir*s_block
     795             :                END DO
     796         830 :                IF (calculate_forces) THEN
     797          15 :                   ikind = kind_of(irow)
     798          15 :                   jkind = kind_of(icol)
     799          15 :                   atom_a = atom_of_kind(irow)
     800          15 :                   atom_b = atom_of_kind(icol)
     801          15 :                   fij = 0.0_dp
     802          30 :                   DO ispin = 1, nspin
     803             :                      CALL dbcsr_get_block_p(matrix=matrix_p(ispin, 1)%matrix, &
     804          15 :                                             row=irow, col=icol, BLOCK=p_block, found=found)
     805          15 :                      CPASSERT(found)
     806          90 :                      DO idir = 1, 3
     807             :                         CALL dbcsr_get_block_p(matrix=matrix_s(idir + 1, 1)%matrix, &
     808          45 :                                                row=irow, col=icol, BLOCK=ds_block, found=found)
     809          45 :                         CPASSERT(found)
     810         675 :                         fij(idir) = fij(idir) + SUM(p_block*ds_block)
     811             :                      END DO
     812             :                   END DO
     813          60 :                   force(ikind)%efield(1:3, atom_a) = force(ikind)%efield(1:3, atom_a) + fdir*fij(1:3)
     814          60 :                   force(jkind)%efield(1:3, atom_b) = force(jkind)%efield(1:3, atom_b) - fdir*fij(1:3)
     815             :                END IF
     816             : 
     817             :             END DO
     818         332 :             CALL dbcsr_iterator_stop(iter)
     819             :          ELSE
     820           0 :             CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
     821           0 :             DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     822             :                CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     823           0 :                                       iatom=iatom, jatom=jatom, r=rab, cell=cellind)
     824             : 
     825           0 :                icol = MAX(iatom, jatom)
     826           0 :                irow = MIN(iatom, jatom)
     827             : 
     828           0 :                ic = cell_to_index(cellind(1), cellind(2), cellind(3))
     829           0 :                CPASSERT(ic > 0)
     830             : 
     831           0 :                DO idir = 1, 3
     832           0 :                   hdi(idir) = -SUM(di(1:3)*hmat(1:3, idir))
     833             :                END DO
     834           0 :                fdir = 0.0_dp
     835           0 :                ria = particle_set(irow)%r
     836           0 :                rib = particle_set(icol)%r
     837           0 :                DO idir = 1, 3
     838           0 :                   kvec(:) = twopi*cell%h_inv(idir, :)
     839           0 :                   dd = SUM(kvec(:)*ria(:))
     840           0 :                   zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     841           0 :                   fdir = fdir + hdi(idir)*AIMAG(LOG(zdeta))
     842           0 :                   dd = SUM(kvec(:)*rib(:))
     843           0 :                   zdeta = CMPLX(COS(dd), SIN(dd), KIND=dp)
     844           0 :                   fdir = fdir + hdi(idir)*AIMAG(LOG(zdeta))
     845             :                END DO
     846             : 
     847           0 :                NULLIFY (s_block)
     848             :                CALL dbcsr_get_block_p(matrix=matrix_s(1, ic)%matrix, &
     849           0 :                                       row=irow, col=icol, block=s_block, found=found)
     850           0 :                CPASSERT(found)
     851           0 :                DO is = 1, nspin
     852           0 :                   NULLIFY (ks_block)
     853             :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, ic)%matrix, &
     854           0 :                                          row=irow, col=icol, block=ks_block, found=found)
     855           0 :                   CPASSERT(found)
     856           0 :                   ks_block = ks_block + 0.5_dp*fdir*s_block
     857             :                END DO
     858           0 :                IF (calculate_forces) THEN
     859           0 :                   atom_a = atom_of_kind(iatom)
     860           0 :                   atom_b = atom_of_kind(jatom)
     861           0 :                   fij = 0.0_dp
     862           0 :                   DO ispin = 1, nspin
     863             :                      CALL dbcsr_get_block_p(matrix=matrix_p(ispin, ic)%matrix, &
     864           0 :                                             row=irow, col=icol, BLOCK=p_block, found=found)
     865           0 :                      CPASSERT(found)
     866           0 :                      DO idir = 1, 3
     867             :                         CALL dbcsr_get_block_p(matrix=matrix_s(idir + 1, ic)%matrix, &
     868           0 :                                                row=irow, col=icol, BLOCK=ds_block, found=found)
     869           0 :                         CPASSERT(found)
     870           0 :                         fij(idir) = fij(idir) + SUM(p_block*ds_block)
     871             :                      END DO
     872             :                   END DO
     873           0 :                   IF (irow == iatom) fij = -fij
     874           0 :                   force(ikind)%efield(1:3, atom_a) = force(ikind)%efield(1:3, atom_a) - fdir*fij(1:3)
     875           0 :                   force(jkind)%efield(1:3, atom_b) = force(jkind)%efield(1:3, atom_b) + fdir*fij(1:3)
     876             :                END IF
     877             : 
     878             :             END DO
     879           0 :             CALL neighbor_list_iterator_release(nl_iterator)
     880             :          END IF
     881             : 
     882             :       END IF
     883             : 
     884         332 :       CALL timestop(handle)
     885             : 
     886         664 :    END SUBROUTINE dfield_tb_berry
     887             : 
     888             : END MODULE efield_tb_methods

Generated by: LCOV version 1.15