LCOV - code coverage report
Current view: top level - src - qs_dftb_matrices.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:cccd2f3) Lines: 95.8 % 474 454
Test Date: 2026-05-06 07:07:47 Functions: 100.0 % 5 5

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Calculation of Overlap and Hamiltonian matrices in DFTB
      10              : !> \author JGH
      11              : ! **************************************************************************************************
      12              : MODULE qs_dftb_matrices
      13              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      14              :                                               get_atomic_kind,&
      15              :                                               get_atomic_kind_set
      16              :    USE atprop_types,                    ONLY: atprop_array_init,&
      17              :                                               atprop_type
      18              :    USE block_p_types,                   ONLY: block_p_type
      19              :    USE cp_control_types,                ONLY: dft_control_type,&
      20              :                                               dftb_control_type
      21              :    USE cp_dbcsr_api,                    ONLY: &
      22              :         dbcsr_add, dbcsr_convert_offsets_to_sizes, dbcsr_copy, dbcsr_create, &
      23              :         dbcsr_distribution_type, dbcsr_finalize, dbcsr_get_block_p, dbcsr_multiply, dbcsr_p_type, &
      24              :         dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_symmetric
      25              :    USE cp_dbcsr_contrib,                ONLY: dbcsr_dot
      26              :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      27              :    USE cp_dbcsr_operations,             ONLY: dbcsr_allocate_matrix_set
      28              :    USE cp_dbcsr_output,                 ONLY: cp_dbcsr_write_sparse_matrix
      29              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      30              :                                               cp_logger_type
      31              :    USE cp_output_handling,              ONLY: cp_p_file,&
      32              :                                               cp_print_key_finished_output,&
      33              :                                               cp_print_key_should_output,&
      34              :                                               cp_print_key_unit_nr
      35              :    USE efield_tb_methods,               ONLY: efield_tb_matrix
      36              :    USE input_constants,                 ONLY: tblite_scc_mixer_auto
      37              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      38              :                                               section_vals_type,&
      39              :                                               section_vals_val_get
      40              :    USE kinds,                           ONLY: default_string_length,&
      41              :                                               dp
      42              :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      43              :                                               kpoint_type
      44              :    USE message_passing,                 ONLY: mp_para_env_type
      45              :    USE mulliken,                        ONLY: mulliken_charges
      46              :    USE particle_methods,                ONLY: get_particle_set
      47              :    USE particle_types,                  ONLY: particle_type
      48              :    USE qs_charge_mixing,                ONLY: charge_mixing
      49              :    USE qs_dftb_coulomb,                 ONLY: build_dftb_coulomb
      50              :    USE qs_dftb_types,                   ONLY: qs_dftb_atom_type,&
      51              :                                               qs_dftb_pairpot_type
      52              :    USE qs_dftb_utils,                   ONLY: compute_block_sk,&
      53              :                                               get_dftb_atom_param,&
      54              :                                               iptr,&
      55              :                                               urep_egr
      56              :    USE qs_energy_types,                 ONLY: qs_energy_type
      57              :    USE qs_environment_types,            ONLY: get_qs_env,&
      58              :                                               qs_environment_type
      59              :    USE qs_force_types,                  ONLY: qs_force_type
      60              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      61              :                                               get_qs_kind_set,&
      62              :                                               qs_kind_type
      63              :    USE qs_ks_types,                     ONLY: get_ks_env,&
      64              :                                               qs_ks_env_type,&
      65              :                                               set_ks_env
      66              :    USE qs_mo_types,                     ONLY: get_mo_set,&
      67              :                                               mo_set_type
      68              :    USE qs_neighbor_list_types,          ONLY: get_iterator_info,&
      69              :                                               neighbor_list_iterate,&
      70              :                                               neighbor_list_iterator_create,&
      71              :                                               neighbor_list_iterator_p_type,&
      72              :                                               neighbor_list_iterator_release,&
      73              :                                               neighbor_list_set_p_type
      74              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      75              :                                               qs_rho_type
      76              :    USE qs_scf_types,                    ONLY: qs_scf_env_type
      77              :    USE virial_methods,                  ONLY: virial_pair_force
      78              :    USE virial_types,                    ONLY: virial_type
      79              : #include "./base/base_uses.f90"
      80              : 
      81              :    IMPLICIT NONE
      82              : 
      83              :    INTEGER, DIMENSION(16), PARAMETER        :: orbptr = [0, 1, 1, 1, &
      84              :                                                          2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3]
      85              : 
      86              :    PRIVATE
      87              : 
      88              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_dftb_matrices'
      89              :    REAL(KIND=dp), PARAMETER, PRIVATE     :: dftb_fd_deriv_step = 1.0e-3_dp
      90              : 
      91              :    PUBLIC :: build_dftb_matrices, build_dftb_ks_matrix, build_dftb_overlap
      92              : 
      93              : CONTAINS
      94              : 
      95              : ! **************************************************************************************************
      96              : !> \brief ...
      97              : !> \param qs_env ...
      98              : !> \param para_env ...
      99              : !> \param calculate_forces ...
     100              : ! **************************************************************************************************
     101         3246 :    SUBROUTINE build_dftb_matrices(qs_env, para_env, calculate_forces)
     102              : 
     103              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     104              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     105              :       LOGICAL, INTENT(IN)                                :: calculate_forces
     106              : 
     107              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_dftb_matrices'
     108              : 
     109              :       INTEGER :: after, atom_a, atom_b, handle, i, iatom, ic, icol, ikind, img, irow, iw, jatom, &
     110              :          jkind, l1, l2, la, lb, llm, lmaxi, lmaxj, m, n1, n2, n_urpoly, natorb_a, natorb_b, &
     111              :          nderivatives, ngrd, ngrdcut, nimg, nkind, spdim
     112         3246 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind
     113              :       INTEGER, DIMENSION(3)                              :: cell
     114         3246 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
     115              :       LOGICAL                                            :: defined, found, omit_headers, use_virial
     116              :       REAL(KIND=dp)                                      :: ddr, dgrd, dr, erep, erepij, f0, foab, &
     117              :                                                             fow, s_cut, urep_cut
     118              :       REAL(KIND=dp), DIMENSION(0:3)                      :: eta_a, eta_b, skself
     119              :       REAL(KIND=dp), DIMENSION(10)                       :: urep
     120              :       REAL(KIND=dp), DIMENSION(2)                        :: surr
     121              :       REAL(KIND=dp), DIMENSION(3)                        :: drij, force_ab, force_rr, force_w, rij, &
     122              :                                                             srep
     123         6492 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: dfblock, dsblock, fblock, fmatij, &
     124         3246 :                                                             fmatji, pblock, sblock, scoeff, &
     125         3246 :                                                             smatij, smatji, spxr, wblock
     126         3246 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     127              :       TYPE(atprop_type), POINTER                         :: atprop
     128        12984 :       TYPE(block_p_type), DIMENSION(2:4)                 :: dsblocks
     129              :       TYPE(cp_logger_type), POINTER                      :: logger
     130         3246 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_h, matrix_p, matrix_s, matrix_w
     131              :       TYPE(dft_control_type), POINTER                    :: dft_control
     132              :       TYPE(dftb_control_type), POINTER                   :: dftb_control
     133              :       TYPE(kpoint_type), POINTER                         :: kpoints
     134              :       TYPE(neighbor_list_iterator_p_type), &
     135         3246 :          DIMENSION(:), POINTER                           :: nl_iterator
     136              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     137         3246 :          POINTER                                         :: sab_orb
     138         3246 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     139              :       TYPE(qs_dftb_atom_type), POINTER                   :: dftb_kind_a, dftb_kind_b
     140              :       TYPE(qs_dftb_pairpot_type), DIMENSION(:, :), &
     141         3246 :          POINTER                                         :: dftb_potential
     142              :       TYPE(qs_dftb_pairpot_type), POINTER                :: dftb_param_ij, dftb_param_ji
     143              :       TYPE(qs_energy_type), POINTER                      :: energy
     144         3246 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     145         3246 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     146              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     147              :       TYPE(qs_rho_type), POINTER                         :: rho
     148              :       TYPE(virial_type), POINTER                         :: virial
     149              : 
     150         3246 :       CALL timeset(routineN, handle)
     151              : 
     152              :       ! set pointers
     153         3246 :       iptr = 0
     154        16230 :       DO la = 0, 3
     155        68166 :          DO lb = 0, 3
     156        51936 :             llm = 0
     157       227220 :             DO l1 = 0, MAX(la, lb)
     158       473916 :                DO l2 = 0, MIN(l1, la, lb)
     159       808254 :                   DO m = 0, l2
     160       386274 :                      llm = llm + 1
     161       645954 :                      iptr(l1, l2, m, la, lb) = llm
     162              :                   END DO
     163              :                END DO
     164              :             END DO
     165              :          END DO
     166              :       END DO
     167              : 
     168         3246 :       NULLIFY (logger, virial, atprop)
     169         3246 :       logger => cp_get_default_logger()
     170              : 
     171         3246 :       NULLIFY (matrix_h, matrix_s, matrix_p, matrix_w, atomic_kind_set, &
     172         3246 :                qs_kind_set, sab_orb, ks_env)
     173              : 
     174              :       CALL get_qs_env(qs_env=qs_env, &
     175              :                       energy=energy, &
     176              :                       atomic_kind_set=atomic_kind_set, &
     177              :                       qs_kind_set=qs_kind_set, &
     178              :                       matrix_h_kp=matrix_h, &
     179              :                       matrix_s_kp=matrix_s, &
     180              :                       atprop=atprop, &
     181              :                       dft_control=dft_control, &
     182         3246 :                       ks_env=ks_env)
     183              : 
     184         3246 :       dftb_control => dft_control%qs_control%dftb_control
     185         3246 :       nimg = dft_control%nimages
     186              :       ! Allocate the overlap and Hamiltonian matrix
     187         3246 :       CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb)
     188         3246 :       nderivatives = 0
     189         3246 :       IF (dftb_control%self_consistent .AND. calculate_forces) nderivatives = 1
     190         3246 :       CALL setup_matrices2(qs_env, nderivatives, nimg, matrix_s, "OVERLAP", sab_orb)
     191         3246 :       CALL setup_matrices2(qs_env, 0, nimg, matrix_h, "CORE HAMILTONIAN", sab_orb)
     192         3246 :       CALL set_ks_env(ks_env, matrix_s_kp=matrix_s)
     193         3246 :       CALL set_ks_env(ks_env, matrix_h_kp=matrix_h)
     194              : 
     195         3246 :       NULLIFY (dftb_potential)
     196         3246 :       CALL get_qs_env(qs_env=qs_env, dftb_potential=dftb_potential)
     197         3246 :       NULLIFY (particle_set)
     198         3246 :       CALL get_qs_env(qs_env=qs_env, particle_set=particle_set)
     199              : 
     200         3246 :       IF (calculate_forces) THEN
     201          744 :          NULLIFY (rho, force, matrix_w)
     202              :          CALL get_qs_env(qs_env=qs_env, &
     203              :                          rho=rho, &
     204              :                          matrix_w_kp=matrix_w, &
     205              :                          virial=virial, &
     206          744 :                          force=force)
     207          744 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     208              : 
     209          744 :          IF (SIZE(matrix_p, 1) == 2) THEN
     210          328 :             DO img = 1, nimg
     211              :                CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, &
     212          164 :                               alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     213              :                CALL dbcsr_add(matrix_w(1, img)%matrix, matrix_w(2, img)%matrix, &
     214          328 :                               alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     215              :             END DO
     216              :          END IF
     217          744 :          CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
     218          744 :          use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     219              :       END IF
     220              :       ! atomic energy decomposition
     221         3246 :       IF (atprop%energy) THEN
     222          162 :          CALL atprop_array_init(atprop%atecc, natom=SIZE(particle_set))
     223              :       END IF
     224              : 
     225         3246 :       NULLIFY (cell_to_index)
     226         3246 :       IF (nimg > 1) THEN
     227          526 :          CALL get_ks_env(ks_env=ks_env, kpoints=kpoints)
     228          526 :          CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
     229              :       END IF
     230              : 
     231         3246 :       erep = 0._dp
     232              : 
     233         3246 :       nkind = SIZE(atomic_kind_set)
     234              : 
     235         3246 :       CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
     236       764405 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     237              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     238       761159 :                                 iatom=iatom, jatom=jatom, r=rij, cell=cell)
     239       761159 :          CALL get_qs_kind(qs_kind_set(ikind), dftb_parameter=dftb_kind_a)
     240              :          CALL get_dftb_atom_param(dftb_kind_a, &
     241              :                                   defined=defined, lmax=lmaxi, skself=skself, &
     242       761159 :                                   eta=eta_a, natorb=natorb_a)
     243       761159 :          IF (.NOT. defined .OR. natorb_a < 1) CYCLE
     244       761159 :          CALL get_qs_kind(qs_kind_set(jkind), dftb_parameter=dftb_kind_b)
     245              :          CALL get_dftb_atom_param(dftb_kind_b, &
     246       761159 :                                   defined=defined, lmax=lmaxj, eta=eta_b, natorb=natorb_b)
     247              : 
     248       761159 :          IF (.NOT. defined .OR. natorb_b < 1) CYCLE
     249              : 
     250              :          ! retrieve information on F and S matrix
     251       761159 :          dftb_param_ij => dftb_potential(ikind, jkind)
     252       761159 :          dftb_param_ji => dftb_potential(jkind, ikind)
     253              :          ! assume table size and type is symmetric
     254       761159 :          ngrd = dftb_param_ij%ngrd
     255       761159 :          ngrdcut = dftb_param_ij%ngrdcut
     256       761159 :          dgrd = dftb_param_ij%dgrd
     257       761159 :          ddr = dgrd*dftb_fd_deriv_step
     258       761159 :          CPASSERT(dftb_param_ij%llm == dftb_param_ji%llm)
     259       761159 :          llm = dftb_param_ij%llm
     260       761159 :          fmatij => dftb_param_ij%fmat
     261       761159 :          smatij => dftb_param_ij%smat
     262       761159 :          fmatji => dftb_param_ji%fmat
     263       761159 :          smatji => dftb_param_ji%smat
     264              :          ! repulsive pair potential
     265       761159 :          n_urpoly = dftb_param_ij%n_urpoly
     266       761159 :          urep_cut = dftb_param_ij%urep_cut
     267      8372749 :          urep = dftb_param_ij%urep
     268       761159 :          spxr => dftb_param_ij%spxr
     269       761159 :          scoeff => dftb_param_ij%scoeff
     270       761159 :          spdim = dftb_param_ij%spdim
     271       761159 :          s_cut = dftb_param_ij%s_cut
     272      3044636 :          srep = dftb_param_ij%srep
     273      2283477 :          surr = dftb_param_ij%surr
     274              : 
     275      3044636 :          dr = SQRT(SUM(rij(:)**2))
     276       761159 :          IF (NINT(dr/dgrd) <= ngrdcut) THEN
     277              : 
     278       759497 :             IF (nimg == 1) THEN
     279              :                ic = 1
     280              :             ELSE
     281        69041 :                ic = cell_to_index(cell(1), cell(2), cell(3))
     282        69041 :                CPASSERT(ic > 0)
     283              :             END IF
     284              : 
     285       759497 :             icol = MAX(iatom, jatom)
     286       759497 :             irow = MIN(iatom, jatom)
     287       759497 :             NULLIFY (sblock, fblock)
     288              :             CALL dbcsr_get_block_p(matrix=matrix_s(1, ic)%matrix, &
     289       759497 :                                    row=irow, col=icol, BLOCK=sblock, found=found)
     290       759497 :             CPASSERT(found)
     291              :             CALL dbcsr_get_block_p(matrix=matrix_h(1, ic)%matrix, &
     292       759497 :                                    row=irow, col=icol, BLOCK=fblock, found=found)
     293       759497 :             CPASSERT(found)
     294              : 
     295       759497 :             IF (calculate_forces) THEN
     296       314314 :                NULLIFY (pblock)
     297              :                CALL dbcsr_get_block_p(matrix=matrix_p(1, ic)%matrix, &
     298       314314 :                                       row=irow, col=icol, block=pblock, found=found)
     299       314314 :                CPASSERT(ASSOCIATED(pblock))
     300       314314 :                NULLIFY (wblock)
     301              :                CALL dbcsr_get_block_p(matrix=matrix_w(1, ic)%matrix, &
     302       314314 :                                       row=irow, col=icol, block=wblock, found=found)
     303       314314 :                CPASSERT(ASSOCIATED(wblock))
     304       314314 :                IF (dftb_control%self_consistent) THEN
     305      1046208 :                   DO i = 2, 4
     306       784656 :                      NULLIFY (dsblocks(i)%block)
     307              :                      CALL dbcsr_get_block_p(matrix=matrix_s(i, ic)%matrix, &
     308       784656 :                                             row=irow, col=icol, BLOCK=dsblocks(i)%block, found=found)
     309      1046208 :                      CPASSERT(found)
     310              :                   END DO
     311              :                END IF
     312              :             END IF
     313              : 
     314       759497 :             IF (iatom == jatom .AND. dr < 0.001_dp) THEN
     315              :                ! diagonal block
     316        77465 :                DO i = 1, natorb_a
     317        53939 :                   sblock(i, i) = sblock(i, i) + 1._dp
     318        77465 :                   fblock(i, i) = fblock(i, i) + skself(orbptr(i))
     319              :                END DO
     320              :             ELSE
     321              :                ! off-diagonal block
     322              :                CALL compute_block_sk(sblock, smatij, smatji, rij, ngrd, ngrdcut, dgrd, &
     323       735971 :                                      llm, lmaxi, lmaxj, irow, iatom)
     324              :                CALL compute_block_sk(fblock, fmatij, fmatji, rij, ngrd, ngrdcut, dgrd, &
     325       735971 :                                      llm, lmaxi, lmaxj, irow, iatom)
     326       735971 :                IF (calculate_forces) THEN
     327       305785 :                   force_ab = 0._dp
     328       305785 :                   force_w = 0._dp
     329       305785 :                   n1 = SIZE(fblock, 1)
     330       305785 :                   n2 = SIZE(fblock, 2)
     331              :                   ! make sure that displacement is in the correct direction depending on the position
     332              :                   ! of the block (upper or lower triangle)
     333       305785 :                   f0 = 1.0_dp
     334       305785 :                   IF (irow == iatom) f0 = -1.0_dp
     335              : 
     336      1834710 :                   ALLOCATE (dfblock(n1, n2), dsblock(n1, n2))
     337              : 
     338      1223140 :                   DO i = 1, 3
     339       917355 :                      drij = rij
     340     12494001 :                      dfblock = 0._dp; dsblock = 0._dp
     341              : 
     342       917355 :                      drij(i) = rij(i) - ddr*f0
     343              :                      CALL compute_block_sk(dsblock, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     344       917355 :                                            llm, lmaxi, lmaxj, irow, iatom)
     345              :                      CALL compute_block_sk(dfblock, fmatij, fmatji, drij, ngrd, ngrdcut, dgrd, &
     346       917355 :                                            llm, lmaxi, lmaxj, irow, iatom)
     347              : 
     348      6705678 :                      dsblock = -dsblock
     349      6705678 :                      dfblock = -dfblock
     350              : 
     351       917355 :                      drij(i) = rij(i) + ddr*f0
     352              :                      CALL compute_block_sk(dsblock, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     353       917355 :                                            llm, lmaxi, lmaxj, irow, iatom)
     354              :                      CALL compute_block_sk(dfblock, fmatij, fmatji, drij, ngrd, ngrdcut, dgrd, &
     355       917355 :                                            llm, lmaxi, lmaxj, irow, iatom)
     356              : 
     357      6705678 :                      dfblock = dfblock/(2.0_dp*ddr)
     358      6705678 :                      dsblock = dsblock/(2.0_dp*ddr)
     359              : 
     360      6705678 :                      foab = 2.0_dp*SUM(dfblock*pblock)
     361      6705678 :                      fow = -2.0_dp*SUM(dsblock*wblock)
     362              : 
     363       917355 :                      force_ab(i) = force_ab(i) + foab
     364       917355 :                      force_w(i) = force_w(i) + fow
     365      1223140 :                      IF (dftb_control%self_consistent) THEN
     366       763212 :                         CPASSERT(ASSOCIATED(dsblocks(i + 1)%block))
     367      5554704 :                         dsblocks(i + 1)%block = dsblocks(i + 1)%block + dsblock
     368              :                      END IF
     369              :                   END DO
     370       305785 :                   IF (use_virial) THEN
     371       190485 :                      IF (iatom == jatom) f0 = 0.5_dp*f0
     372       190485 :                      CALL virial_pair_force(virial%pv_virial, -f0, force_ab, rij)
     373       190485 :                      CALL virial_pair_force(virial%pv_virial, -f0, force_w, rij)
     374              :                   END IF
     375       305785 :                   DEALLOCATE (dfblock, dsblock)
     376              :                END IF
     377              :             END IF
     378              : 
     379       759497 :             IF (calculate_forces .AND. (iatom /= jatom .OR. dr > 0.001_dp)) THEN
     380       305785 :                atom_a = atom_of_kind(iatom)
     381       305785 :                atom_b = atom_of_kind(jatom)
     382       762229 :                IF (irow == iatom) force_ab = -force_ab
     383       762229 :                IF (irow == iatom) force_w = -force_w
     384      1223140 :                force(ikind)%all_potential(:, atom_a) = force(ikind)%all_potential(:, atom_a) - force_ab(:)
     385      1223140 :                force(jkind)%all_potential(:, atom_b) = force(jkind)%all_potential(:, atom_b) + force_ab(:)
     386      1223140 :                force(ikind)%overlap(:, atom_a) = force(ikind)%overlap(:, atom_a) - force_w(:)
     387      1231669 :                force(jkind)%overlap(:, atom_b) = force(jkind)%overlap(:, atom_b) + force_w(:)
     388              :             END IF
     389              : 
     390              :          END IF
     391              : 
     392              :          ! repulsive potential
     393       764405 :          IF ((dr <= urep_cut .OR. spdim > 0) .AND. dr > 0.001_dp) THEN
     394       574994 :             erepij = 0._dp
     395              :             CALL urep_egr(rij, dr, erepij, force_rr, &
     396       574994 :                           n_urpoly, urep, spdim, s_cut, srep, spxr, scoeff, surr, calculate_forces)
     397       574994 :             erep = erep + erepij
     398       574994 :             IF (atprop%energy) THEN
     399       228665 :                atprop%atecc(iatom) = atprop%atecc(iatom) + 0.5_dp*erepij
     400       228665 :                atprop%atecc(jatom) = atprop%atecc(jatom) + 0.5_dp*erepij
     401              :             END IF
     402       574994 :             IF (calculate_forces .AND. (iatom /= jatom .OR. dr > 0.001_dp)) THEN
     403       256867 :                atom_a = atom_of_kind(iatom)
     404       256867 :                atom_b = atom_of_kind(jatom)
     405              :                force(ikind)%repulsive(:, atom_a) = &
     406      1027468 :                   force(ikind)%repulsive(:, atom_a) - force_rr(:)
     407              :                force(jkind)%repulsive(:, atom_b) = &
     408      1027468 :                   force(jkind)%repulsive(:, atom_b) + force_rr(:)
     409       256867 :                IF (use_virial) THEN
     410       171683 :                   f0 = -1.0_dp
     411       171683 :                   IF (iatom == jatom) f0 = -0.5_dp
     412       171683 :                   CALL virial_pair_force(virial%pv_virial, f0, force_rr, rij)
     413              :                END IF
     414              :             END IF
     415              :          END IF
     416              : 
     417              :       END DO
     418         3246 :       CALL neighbor_list_iterator_release(nl_iterator)
     419              : 
     420         8388 :       DO i = 1, SIZE(matrix_s, 1)
     421        30880 :          DO img = 1, nimg
     422        27634 :             CALL dbcsr_finalize(matrix_s(i, img)%matrix)
     423              :          END DO
     424              :       END DO
     425         6492 :       DO i = 1, SIZE(matrix_h, 1)
     426        23722 :          DO img = 1, nimg
     427        20476 :             CALL dbcsr_finalize(matrix_h(i, img)%matrix)
     428              :          END DO
     429              :       END DO
     430              : 
     431              :       ! set repulsive energy
     432         3246 :       CALL para_env%sum(erep)
     433         3246 :       energy%repulsive = erep
     434              : 
     435         3246 :       CALL section_vals_val_get(qs_env%input, "DFT%PRINT%AO_MATRICES%OMIT_HEADERS", l_val=omit_headers)
     436         3246 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, &
     437              :                                            qs_env%input, "DFT%PRINT%AO_MATRICES/CORE_HAMILTONIAN"), cp_p_file)) THEN
     438              :          iw = cp_print_key_unit_nr(logger, qs_env%input, "DFT%PRINT%AO_MATRICES/CORE_HAMILTONIAN", &
     439            0 :                                    extension=".Log")
     440            0 :          CALL section_vals_val_get(qs_env%input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
     441            0 :          after = MIN(MAX(after, 1), 16)
     442            0 :          DO img = 1, nimg
     443              :             CALL cp_dbcsr_write_sparse_matrix(matrix_h(1, img)%matrix, 4, after, qs_env, para_env, &
     444            0 :                                               output_unit=iw, omit_headers=omit_headers)
     445              :          END DO
     446              : 
     447              :          CALL cp_print_key_finished_output(iw, logger, qs_env%input, &
     448            0 :                                            "DFT%PRINT%AO_MATRICES/CORE_HAMILTONIAN")
     449              :       END IF
     450              : 
     451         3246 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, &
     452              :                                            qs_env%input, "DFT%PRINT%AO_MATRICES/OVERLAP"), cp_p_file)) THEN
     453              :          iw = cp_print_key_unit_nr(logger, qs_env%input, "DFT%PRINT%AO_MATRICES/OVERLAP", &
     454            0 :                                    extension=".Log")
     455            0 :          CALL section_vals_val_get(qs_env%input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
     456            0 :          after = MIN(MAX(after, 1), 16)
     457            0 :          DO img = 1, nimg
     458              :             CALL cp_dbcsr_write_sparse_matrix(matrix_s(1, img)%matrix, 4, after, qs_env, para_env, &
     459            0 :                                               output_unit=iw, omit_headers=omit_headers)
     460              : 
     461            0 :             IF (BTEST(cp_print_key_should_output(logger%iter_info, &
     462            0 :                                                  qs_env%input, "DFT%PRINT%AO_MATRICES/DERIVATIVES"), cp_p_file)) THEN
     463            0 :                DO i = 2, SIZE(matrix_s, 1)
     464              :                   CALL cp_dbcsr_write_sparse_matrix(matrix_s(i, img)%matrix, 4, after, qs_env, para_env, &
     465            0 :                                                     output_unit=iw, omit_headers=omit_headers)
     466              :                END DO
     467              :             END IF
     468              :          END DO
     469              : 
     470              :          CALL cp_print_key_finished_output(iw, logger, qs_env%input, &
     471            0 :                                            "DFT%PRINT%AO_MATRICES/OVERLAP")
     472              :       END IF
     473              : 
     474         3246 :       IF (calculate_forces) THEN
     475          744 :          IF (SIZE(matrix_p, 1) == 2) THEN
     476          328 :             DO img = 1, nimg
     477              :                CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, alpha_scalar=1.0_dp, &
     478          328 :                               beta_scalar=-1.0_dp)
     479              :             END DO
     480              :          END IF
     481              :       END IF
     482              : 
     483         3246 :       CALL timestop(handle)
     484              : 
     485         9738 :    END SUBROUTINE build_dftb_matrices
     486              : 
     487              : ! **************************************************************************************************
     488              : !> \brief ...
     489              : !> \param qs_env ...
     490              : !> \param calculate_forces ...
     491              : !> \param just_energy ...
     492              : ! **************************************************************************************************
     493        18026 :    SUBROUTINE build_dftb_ks_matrix(qs_env, calculate_forces, just_energy)
     494              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     495              :       LOGICAL, INTENT(in)                                :: calculate_forces, just_energy
     496              : 
     497              :       CHARACTER(len=*), PARAMETER :: routineN = 'build_dftb_ks_matrix'
     498              : 
     499              :       INTEGER                                            :: atom_a, handle, iatom, ikind, img, &
     500              :                                                             ispin, natom, nkind, nspins, &
     501              :                                                             output_unit
     502              :       REAL(KIND=dp)                                      :: pc_ener, qmmm_el, zeff
     503        18026 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: mix_charge
     504        18026 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: mcharge, occupation_numbers
     505        18026 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: charges
     506        18026 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     507              :       TYPE(cp_logger_type), POINTER                      :: logger
     508        18026 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_p1, mo_derivs
     509        18026 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix, matrix_h, matrix_p, matrix_s
     510              :       TYPE(dbcsr_type), POINTER                          :: mo_coeff
     511              :       TYPE(dft_control_type), POINTER                    :: dft_control
     512              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     513        18026 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     514              :       TYPE(qs_dftb_atom_type), POINTER                   :: dftb_kind
     515              :       TYPE(qs_energy_type), POINTER                      :: energy
     516        18026 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     517              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     518              :       TYPE(qs_rho_type), POINTER                         :: rho
     519              :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     520              :       TYPE(section_vals_type), POINTER                   :: scf_section
     521              : 
     522        18026 :       CALL timeset(routineN, handle)
     523        18026 :       NULLIFY (dft_control, logger, scf_section, matrix_p, particle_set, ks_env, &
     524        18026 :                ks_matrix, rho, energy, scf_env)
     525        18026 :       logger => cp_get_default_logger()
     526        18026 :       CPASSERT(ASSOCIATED(qs_env))
     527              : 
     528              :       CALL get_qs_env(qs_env, &
     529              :                       dft_control=dft_control, &
     530              :                       atomic_kind_set=atomic_kind_set, &
     531              :                       qs_kind_set=qs_kind_set, &
     532              :                       matrix_h_kp=matrix_h, &
     533              :                       para_env=para_env, &
     534              :                       ks_env=ks_env, &
     535              :                       matrix_ks_kp=ks_matrix, &
     536              :                       rho=rho, &
     537        18026 :                       energy=energy)
     538              : 
     539        18026 :       energy%hartree = 0.0_dp
     540        18026 :       energy%qmmm_el = 0.0_dp
     541              : 
     542        18026 :       scf_section => section_vals_get_subs_vals(qs_env%input, "DFT%SCF")
     543        18026 :       nspins = dft_control%nspins
     544        18026 :       CPASSERT(ASSOCIATED(matrix_h))
     545        18026 :       CPASSERT(ASSOCIATED(rho))
     546        54078 :       CPASSERT(SIZE(ks_matrix) > 0)
     547              : 
     548        36332 :       DO ispin = 1, nspins
     549       178024 :          DO img = 1, SIZE(ks_matrix, 2)
     550              :             ! copy the core matrix into the fock matrix
     551       159998 :             CALL dbcsr_copy(ks_matrix(ispin, img)%matrix, matrix_h(1, img)%matrix)
     552              :          END DO
     553              :       END DO
     554              : 
     555        18026 :       IF (dft_control%qs_control%dftb_control%self_consistent) THEN
     556              :          ! Mulliken charges
     557              :          CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, &
     558        16708 :                          matrix_s_kp=matrix_s)
     559        16708 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     560        16708 :          natom = SIZE(particle_set)
     561        66832 :          ALLOCATE (charges(natom, nspins))
     562              :          !
     563        16708 :          CALL mulliken_charges(matrix_p, matrix_s, para_env, charges)
     564              :          !
     565        50124 :          ALLOCATE (mcharge(natom))
     566        16708 :          nkind = SIZE(atomic_kind_set)
     567        52466 :          DO ikind = 1, nkind
     568        35758 :             CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom)
     569        35758 :             CALL get_qs_kind(qs_kind_set(ikind), dftb_parameter=dftb_kind)
     570        35758 :             CALL get_dftb_atom_param(dftb_kind, zeff=zeff)
     571       271138 :             DO iatom = 1, natom
     572       182914 :                atom_a = atomic_kind_set(ikind)%atom_list(iatom)
     573       402706 :                mcharge(atom_a) = zeff - SUM(charges(atom_a, 1:nspins))
     574              :             END DO
     575              :          END DO
     576        16708 :          DEALLOCATE (charges)
     577              : 
     578        16708 :          IF ((.NOT. dft_control%qs_control%do_ls_scf) .AND. &
     579              :              (dft_control%qs_control%dftb_control%tblite_scc_mixer /= tblite_scc_mixer_auto)) THEN
     580         1802 :             CALL get_qs_env(qs_env=qs_env, scf_env=scf_env)
     581         5406 :             ALLOCATE (mix_charge(SIZE(mcharge), 1))
     582        15194 :             mix_charge(:, 1) = mcharge(:)
     583              :             CALL charge_mixing(scf_env%mixing_method, scf_env%mixing_store, &
     584              :                                mix_charge, para_env, scf_env%iter_count, &
     585              :                                scc_mixer=dft_control%qs_control%dftb_control%tblite_scc_mixer, &
     586              :                                tblite_mixer_damping=dft_control%qs_control%dftb_control%tblite_mixer_damping, &
     587         1802 :                                tblite_mixer_memory=qs_env%scf_control%max_scf)
     588        15194 :             mcharge(:) = mix_charge(:, 1)
     589         1802 :             DEALLOCATE (mix_charge)
     590              :          END IF
     591              : 
     592              :          CALL build_dftb_coulomb(qs_env, ks_matrix, rho, mcharge, energy, &
     593        16708 :                                  calculate_forces, just_energy)
     594              : 
     595              :          CALL efield_tb_matrix(qs_env, ks_matrix, rho, mcharge, energy, &
     596        16708 :                                calculate_forces, just_energy)
     597              : 
     598        16708 :          DEALLOCATE (mcharge)
     599              : 
     600              :       END IF
     601              : 
     602        18026 :       IF (qs_env%qmmm) THEN
     603         4808 :          CPASSERT(SIZE(ks_matrix, 2) == 1)
     604         9616 :          DO ispin = 1, nspins
     605              :             ! If QM/MM sumup the 1el Hamiltonian
     606              :             CALL dbcsr_add(ks_matrix(ispin, 1)%matrix, qs_env%ks_qmmm_env%matrix_h(1)%matrix, &
     607         4808 :                            1.0_dp, 1.0_dp)
     608         4808 :             CALL qs_rho_get(rho, rho_ao=matrix_p1)
     609              :             ! Compute QM/MM Energy
     610              :             CALL dbcsr_dot(qs_env%ks_qmmm_env%matrix_h(1)%matrix, &
     611         4808 :                            matrix_p1(ispin)%matrix, qmmm_el)
     612         9616 :             energy%qmmm_el = energy%qmmm_el + qmmm_el
     613              :          END DO
     614         4808 :          pc_ener = qs_env%ks_qmmm_env%pc_ener
     615         4808 :          energy%qmmm_el = energy%qmmm_el + pc_ener
     616              :       END IF
     617              : 
     618              :       energy%total = energy%core + energy%hartree + energy%qmmm_el + energy%efield + &
     619        18026 :                      energy%repulsive + energy%dispersion + energy%dftb3
     620              : 
     621        18026 :       IF (dft_control%qs_control%dftb_control%self_consistent) THEN
     622              :          output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DETAILED_ENERGY", &
     623        16708 :                                             extension=".scfLog")
     624        16708 :          IF (output_unit > 0) THEN
     625              :             WRITE (UNIT=output_unit, FMT="(/,(T9,A,T60,F20.10))") &
     626           15 :                "Repulsive pair potential energy:               ", energy%repulsive, &
     627           15 :                "Zeroth order Hamiltonian energy:               ", energy%core, &
     628           15 :                "Charge fluctuation energy:                     ", energy%hartree, &
     629           30 :                "London dispersion energy:                      ", energy%dispersion
     630           15 :             IF (ABS(energy%efield) > 1.e-12_dp) THEN
     631              :                WRITE (UNIT=output_unit, FMT="(T9,A,T60,F20.10)") &
     632            0 :                   "Electric field interaction energy:             ", energy%efield
     633              :             END IF
     634           15 :             IF (dft_control%qs_control%dftb_control%dftb3_diagonal) THEN
     635              :                WRITE (UNIT=output_unit, FMT="(T9,A,T60,F20.10)") &
     636            0 :                   "DFTB3 3rd Order Energy Correction              ", energy%dftb3
     637              :             END IF
     638           15 :             IF (qs_env%qmmm) THEN
     639              :                WRITE (UNIT=output_unit, FMT="(T9,A,T60,F20.10)") &
     640            0 :                   "QM/MM Electrostatic energy:                    ", energy%qmmm_el
     641              :             END IF
     642              :          END IF
     643              :          CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
     644        16708 :                                            "PRINT%DETAILED_ENERGY")
     645              :       END IF
     646              :       ! here we compute dE/dC if needed. Assumes dE/dC is H_{ks}C (plus occupation numbers)
     647        18026 :       IF (qs_env%requires_mo_derivs .AND. .NOT. just_energy) THEN
     648          388 :          CPASSERT(SIZE(ks_matrix, 2) == 1)
     649              :          BLOCK
     650          388 :             TYPE(mo_set_type), DIMENSION(:), POINTER :: mo_array
     651          388 :             CALL get_qs_env(qs_env, mo_derivs=mo_derivs, mos=mo_array)
     652          804 :             DO ispin = 1, SIZE(mo_derivs)
     653              :                CALL get_mo_set(mo_set=mo_array(ispin), &
     654          416 :                                mo_coeff_b=mo_coeff, occupation_numbers=occupation_numbers)
     655          416 :                IF (.NOT. mo_array(ispin)%use_mo_coeff_b) THEN
     656            0 :                   CPABORT("")
     657              :                END IF
     658              :                CALL dbcsr_multiply('n', 'n', 1.0_dp, ks_matrix(ispin, 1)%matrix, mo_coeff, &
     659          804 :                                    0.0_dp, mo_derivs(ispin)%matrix)
     660              :             END DO
     661              :          END BLOCK
     662              :       END IF
     663              : 
     664        18026 :       CALL timestop(handle)
     665              : 
     666        36052 :    END SUBROUTINE build_dftb_ks_matrix
     667              : 
     668              : ! **************************************************************************************************
     669              : !> \brief ...
     670              : !> \param qs_env ...
     671              : !> \param nderivative ...
     672              : !> \param matrix_s ...
     673              : ! **************************************************************************************************
     674         1792 :    SUBROUTINE build_dftb_overlap(qs_env, nderivative, matrix_s)
     675              : 
     676              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     677              :       INTEGER, INTENT(IN)                                :: nderivative
     678              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     679              : 
     680              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_dftb_overlap'
     681              : 
     682              :       INTEGER :: handle, i, iatom, icol, ikind, indder, irow, j, jatom, jkind, l1, l2, la, lb, &
     683              :          llm, lmaxi, lmaxj, m, n1, n2, natom, natorb_a, natorb_b, ngrd, ngrdcut, nkind
     684              :       LOGICAL                                            :: defined, found
     685              :       REAL(KIND=dp)                                      :: ddr, dgrd, dr, f0
     686              :       REAL(KIND=dp), DIMENSION(0:3)                      :: skself
     687              :       REAL(KIND=dp), DIMENSION(3)                        :: drij, rij
     688         1792 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: dsblock, dsblockm, sblock, smatij, smatji
     689          896 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: dsblock1
     690          896 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     691         8960 :       TYPE(block_p_type), DIMENSION(2:10)                :: dsblocks
     692              :       TYPE(cp_logger_type), POINTER                      :: logger
     693              :       TYPE(dft_control_type), POINTER                    :: dft_control
     694              :       TYPE(dftb_control_type), POINTER                   :: dftb_control
     695              :       TYPE(neighbor_list_iterator_p_type), &
     696          896 :          DIMENSION(:), POINTER                           :: nl_iterator
     697              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     698          896 :          POINTER                                         :: sab_orb
     699              :       TYPE(qs_dftb_atom_type), POINTER                   :: dftb_kind_a, dftb_kind_b
     700              :       TYPE(qs_dftb_pairpot_type), DIMENSION(:, :), &
     701          896 :          POINTER                                         :: dftb_potential
     702              :       TYPE(qs_dftb_pairpot_type), POINTER                :: dftb_param_ij, dftb_param_ji
     703          896 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     704              : 
     705          896 :       CALL timeset(routineN, handle)
     706              : 
     707              :       ! set pointers
     708          896 :       iptr = 0
     709         4480 :       DO la = 0, 3
     710        18816 :          DO lb = 0, 3
     711        14336 :             llm = 0
     712        62720 :             DO l1 = 0, MAX(la, lb)
     713       130816 :                DO l2 = 0, MIN(l1, la, lb)
     714       223104 :                   DO m = 0, l2
     715       106624 :                      llm = llm + 1
     716       178304 :                      iptr(l1, l2, m, la, lb) = llm
     717              :                   END DO
     718              :                END DO
     719              :             END DO
     720              :          END DO
     721              :       END DO
     722              : 
     723          896 :       NULLIFY (logger)
     724          896 :       logger => cp_get_default_logger()
     725              : 
     726          896 :       NULLIFY (atomic_kind_set, qs_kind_set, sab_orb)
     727              : 
     728              :       CALL get_qs_env(qs_env=qs_env, &
     729              :                       atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set, &
     730          896 :                       dft_control=dft_control)
     731              : 
     732          896 :       dftb_control => dft_control%qs_control%dftb_control
     733              : 
     734          896 :       NULLIFY (dftb_potential)
     735              :       CALL get_qs_env(qs_env=qs_env, &
     736          896 :                       dftb_potential=dftb_potential)
     737              : 
     738          896 :       nkind = SIZE(atomic_kind_set)
     739              : 
     740              :       ! Allocate the overlap matrix
     741          896 :       CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb)
     742          896 :       CALL setup_matrices1(qs_env, nderivative, matrix_s, 'OVERLAP', sab_orb)
     743              : 
     744          896 :       CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
     745         3668 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     746              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     747         2772 :                                 iatom=iatom, jatom=jatom, r=rij)
     748              : 
     749         2772 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom)
     750         2772 :          CALL get_qs_kind(qs_kind_set(ikind), dftb_parameter=dftb_kind_a)
     751              :          CALL get_dftb_atom_param(dftb_kind_a, &
     752              :                                   defined=defined, lmax=lmaxi, skself=skself, &
     753         2772 :                                   natorb=natorb_a)
     754              : 
     755         2772 :          IF (.NOT. defined .OR. natorb_a < 1) CYCLE
     756              : 
     757         2772 :          CALL get_qs_kind(qs_kind_set(jkind), dftb_parameter=dftb_kind_b)
     758              :          CALL get_dftb_atom_param(dftb_kind_b, &
     759         2772 :                                   defined=defined, lmax=lmaxj, natorb=natorb_b)
     760              : 
     761         2772 :          IF (.NOT. defined .OR. natorb_b < 1) CYCLE
     762              : 
     763              :          ! retrieve information on F and S matrix
     764         2772 :          dftb_param_ij => dftb_potential(ikind, jkind)
     765         2772 :          dftb_param_ji => dftb_potential(jkind, ikind)
     766              :          ! assume table size and type is symmetric
     767         2772 :          ngrd = dftb_param_ij%ngrd
     768         2772 :          ngrdcut = dftb_param_ij%ngrdcut
     769         2772 :          dgrd = dftb_param_ij%dgrd
     770         2772 :          ddr = dgrd*dftb_fd_deriv_step
     771         2772 :          CPASSERT(dftb_param_ij%llm == dftb_param_ji%llm)
     772         2772 :          llm = dftb_param_ij%llm
     773         2772 :          smatij => dftb_param_ij%smat
     774         2772 :          smatji => dftb_param_ji%smat
     775              : 
     776        11088 :          dr = SQRT(SUM(rij(:)**2))
     777         3668 :          IF (NINT(dr/dgrd) <= ngrdcut) THEN
     778              : 
     779         2772 :             icol = MAX(iatom, jatom); irow = MIN(iatom, jatom)
     780              : 
     781         2772 :             NULLIFY (sblock)
     782              :             CALL dbcsr_get_block_p(matrix=matrix_s(1)%matrix, &
     783         2772 :                                    row=irow, col=icol, BLOCK=sblock, found=found)
     784         2772 :             CPASSERT(found)
     785              : 
     786         2772 :             IF (nderivative > 0) THEN
     787         3672 :                DO i = 2, SIZE(matrix_s, 1)
     788         3258 :                   NULLIFY (dsblocks(i)%block)
     789              :                   CALL dbcsr_get_block_p(matrix=matrix_s(i)%matrix, &
     790         3672 :                                          row=irow, col=icol, BLOCK=dsblocks(i)%block, found=found)
     791              :                END DO
     792              :             END IF
     793              : 
     794         2772 :             IF (iatom == jatom .AND. dr < 0.001_dp) THEN
     795              :                ! diagonal block
     796         4137 :                DO i = 1, natorb_a
     797         4137 :                   sblock(i, i) = sblock(i, i) + 1._dp
     798              :                END DO
     799              :             ELSE
     800              :                ! off-diagonal block
     801              :                CALL compute_block_sk(sblock, smatij, smatji, rij, ngrd, ngrdcut, dgrd, &
     802         1407 :                                      llm, lmaxi, lmaxj, irow, iatom)
     803              : 
     804         1407 :                IF (nderivative >= 1) THEN
     805          228 :                   n1 = SIZE(sblock, 1); n2 = SIZE(sblock, 2)
     806          228 :                   indder = 1 ! used to put the 2nd derivatives in the correct matric (5=xx,8=yy,10=zz)
     807              : 
     808         2280 :                   ALLOCATE (dsblock1(n1, n2, 3), dsblock(n1, n2), dsblockm(n1, n2))
     809         5394 :                   dsblock1 = 0.0_dp
     810          912 :                   DO i = 1, 3
     811         9648 :                      dsblock = 0._dp; dsblockm = 0.0_dp
     812          684 :                      drij = rij
     813          684 :                      f0 = 1.0_dp; IF (irow == iatom) f0 = -1.0_dp
     814              : 
     815          684 :                      drij(i) = rij(i) - ddr*f0
     816              :                      CALL compute_block_sk(dsblockm, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     817          684 :                                            llm, lmaxi, lmaxj, irow, iatom)
     818              : 
     819          684 :                      drij(i) = rij(i) + ddr*f0
     820              :                      CALL compute_block_sk(dsblock, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     821          684 :                                            llm, lmaxi, lmaxj, irow, iatom)
     822              : 
     823         9648 :                      dsblock1(:, :, i) = (dsblock + dsblockm)
     824         9648 :                      dsblock = dsblock - dsblockm
     825         5166 :                      dsblock = dsblock/(2.0_dp*ddr)
     826              : 
     827          684 :                      CPASSERT(ASSOCIATED(dsblocks(i + 1)%block))
     828         5166 :                      dsblocks(i + 1)%block = dsblocks(i + 1)%block + dsblock
     829          912 :                      IF (nderivative > 1) THEN
     830          567 :                         indder = indder + 5 - i
     831         4347 :                         dsblocks(indder)%block = 0.0_dp
     832              :                         dsblocks(indder)%block = dsblocks(indder)%block + &
     833         4347 :                                                  (dsblock1(:, :, i) - 2.0_dp*sblock)/ddr**2
     834              :                      END IF
     835              :                   END DO
     836              : 
     837          228 :                   IF (nderivative > 1) THEN
     838          567 :                      DO i = 1, 2
     839         1134 :                         DO j = i + 1, 3
     840         8127 :                            dsblock = 0._dp; dsblockm = 0.0_dp
     841          567 :                            drij = rij
     842          567 :                            f0 = 1.0_dp; IF (irow == iatom) f0 = -1.0_dp
     843              : 
     844          567 :                            drij(i) = rij(i) - ddr*f0; drij(j) = rij(j) - ddr*f0
     845              :                            CALL compute_block_sk(dsblockm, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     846          567 :                                                  llm, lmaxi, lmaxj, irow, iatom)
     847              : 
     848          567 :                            drij(i) = rij(i) + ddr*f0; drij(j) = rij(j) + ddr*f0
     849              :                            CALL compute_block_sk(dsblock, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     850          567 :                                                  llm, lmaxi, lmaxj, irow, iatom)
     851              : 
     852          567 :                            indder = 2 + 2*i + j
     853         4347 :                            dsblocks(indder)%block = 0.0_dp
     854              :                            dsblocks(indder)%block = &
     855              :                               dsblocks(indder)%block + ( &
     856         4725 :                               dsblock + dsblockm - dsblock1(:, :, i) - dsblock1(:, :, j) + 2.0_dp*sblock)/(2.0_dp*ddr**2)
     857              :                         END DO
     858              :                      END DO
     859              :                   END IF
     860              : 
     861          228 :                   DEALLOCATE (dsblock1, dsblock, dsblockm)
     862              :                END IF
     863              :             END IF
     864              :          END IF
     865              :       END DO
     866          896 :       CALL neighbor_list_iterator_release(nl_iterator)
     867              : 
     868         2626 :       DO i = 1, SIZE(matrix_s, 1)
     869         2626 :          CALL dbcsr_finalize(matrix_s(i)%matrix)
     870              :       END DO
     871              : 
     872          896 :       CALL timestop(handle)
     873              : 
     874         1792 :    END SUBROUTINE build_dftb_overlap
     875              : 
     876              : ! **************************************************************************************************
     877              : !> \brief ...
     878              : !> \param qs_env ...
     879              : !> \param nderivative ...
     880              : !> \param matrices ...
     881              : !> \param mnames ...
     882              : !> \param sab_nl ...
     883              : ! **************************************************************************************************
     884          896 :    SUBROUTINE setup_matrices1(qs_env, nderivative, matrices, mnames, sab_nl)
     885              : 
     886              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     887              :       INTEGER, INTENT(IN)                                :: nderivative
     888              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrices
     889              :       CHARACTER(LEN=*)                                   :: mnames
     890              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     891              :          POINTER                                         :: sab_nl
     892              : 
     893              :       CHARACTER(1)                                       :: symmetry_type
     894              :       CHARACTER(LEN=default_string_length)               :: matnames
     895              :       INTEGER                                            :: i, natom, neighbor_list_id, nkind, nmat, &
     896              :                                                             nsgf
     897              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: first_sgf, last_sgf
     898          896 :       INTEGER, DIMENSION(:), POINTER                     :: row_blk_sizes
     899          896 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     900              :       TYPE(dbcsr_distribution_type), POINTER             :: dbcsr_dist
     901          896 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     902          896 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     903              : 
     904          896 :       NULLIFY (particle_set, atomic_kind_set)
     905              : 
     906              :       CALL get_qs_env(qs_env=qs_env, &
     907              :                       atomic_kind_set=atomic_kind_set, &
     908              :                       qs_kind_set=qs_kind_set, &
     909              :                       particle_set=particle_set, &
     910              :                       dbcsr_dist=dbcsr_dist, &
     911          896 :                       neighbor_list_id=neighbor_list_id)
     912              : 
     913          896 :       nkind = SIZE(atomic_kind_set)
     914          896 :       natom = SIZE(particle_set)
     915              : 
     916          896 :       CALL get_qs_kind_set(qs_kind_set, nsgf=nsgf)
     917              : 
     918         2688 :       ALLOCATE (first_sgf(natom))
     919         1792 :       ALLOCATE (last_sgf(natom))
     920              : 
     921              :       CALL get_particle_set(particle_set, qs_kind_set, &
     922              :                             first_sgf=first_sgf, &
     923          896 :                             last_sgf=last_sgf)
     924              : 
     925          896 :       nmat = 0
     926          896 :       IF (nderivative == 0) nmat = 1
     927          896 :       IF (nderivative == 1) nmat = 4
     928          896 :       IF (nderivative == 2) nmat = 10
     929          896 :       CPASSERT(nmat > 0)
     930              : 
     931         1792 :       ALLOCATE (row_blk_sizes(natom))
     932          896 :       CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
     933              : 
     934          896 :       CALL dbcsr_allocate_matrix_set(matrices, nmat)
     935              : 
     936              :       ! Up to 2nd derivative take care to get the symmetries correct
     937         2626 :       DO i = 1, nmat
     938         1730 :          IF (i > 1) THEN
     939          834 :             matnames = TRIM(mnames)//" DERIVATIVE MATRIX DFTB"
     940          834 :             symmetry_type = dbcsr_type_antisymmetric
     941          834 :             IF (i > 4) symmetry_type = dbcsr_type_symmetric
     942              :          ELSE
     943          896 :             symmetry_type = dbcsr_type_symmetric
     944          896 :             matnames = TRIM(mnames)//" MATRIX DFTB"
     945              :          END IF
     946         1730 :          ALLOCATE (matrices(i)%matrix)
     947              :          CALL dbcsr_create(matrix=matrices(i)%matrix, &
     948              :                            name=TRIM(matnames), &
     949              :                            dist=dbcsr_dist, matrix_type=symmetry_type, &
     950              :                            row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
     951         1730 :                            mutable_work=.TRUE.)
     952         2626 :          CALL cp_dbcsr_alloc_block_from_nbl(matrices(i)%matrix, sab_nl)
     953              :       END DO
     954              : 
     955          896 :       DEALLOCATE (first_sgf)
     956          896 :       DEALLOCATE (last_sgf)
     957              : 
     958          896 :       DEALLOCATE (row_blk_sizes)
     959              : 
     960          896 :    END SUBROUTINE setup_matrices1
     961              : 
     962              : ! **************************************************************************************************
     963              : !> \brief ...
     964              : !> \param qs_env ...
     965              : !> \param nderivative ...
     966              : !> \param nimg ...
     967              : !> \param matrices ...
     968              : !> \param mnames ...
     969              : !> \param sab_nl ...
     970              : ! **************************************************************************************************
     971         6492 :    SUBROUTINE setup_matrices2(qs_env, nderivative, nimg, matrices, mnames, sab_nl)
     972              : 
     973              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     974              :       INTEGER, INTENT(IN)                                :: nderivative, nimg
     975              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrices
     976              :       CHARACTER(LEN=*)                                   :: mnames
     977              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     978              :          POINTER                                         :: sab_nl
     979              : 
     980              :       CHARACTER(1)                                       :: symmetry_type
     981              :       CHARACTER(LEN=default_string_length)               :: matnames
     982              :       INTEGER                                            :: i, img, natom, neighbor_list_id, nkind, &
     983              :                                                             nmat, nsgf
     984              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: first_sgf, last_sgf
     985         6492 :       INTEGER, DIMENSION(:), POINTER                     :: row_blk_sizes
     986         6492 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     987              :       TYPE(dbcsr_distribution_type), POINTER             :: dbcsr_dist
     988         6492 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     989         6492 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     990              : 
     991         6492 :       NULLIFY (particle_set, atomic_kind_set)
     992              : 
     993              :       CALL get_qs_env(qs_env=qs_env, &
     994              :                       atomic_kind_set=atomic_kind_set, &
     995              :                       qs_kind_set=qs_kind_set, &
     996              :                       particle_set=particle_set, &
     997              :                       dbcsr_dist=dbcsr_dist, &
     998         6492 :                       neighbor_list_id=neighbor_list_id)
     999              : 
    1000         6492 :       nkind = SIZE(atomic_kind_set)
    1001         6492 :       natom = SIZE(particle_set)
    1002              : 
    1003         6492 :       CALL get_qs_kind_set(qs_kind_set, nsgf=nsgf)
    1004              : 
    1005        19476 :       ALLOCATE (first_sgf(natom))
    1006        12984 :       ALLOCATE (last_sgf(natom))
    1007              : 
    1008              :       CALL get_particle_set(particle_set, qs_kind_set, &
    1009              :                             first_sgf=first_sgf, &
    1010         6492 :                             last_sgf=last_sgf)
    1011              : 
    1012         6492 :       nmat = 0
    1013         6492 :       IF (nderivative == 0) nmat = 1
    1014         6492 :       IF (nderivative == 1) nmat = 4
    1015         6492 :       IF (nderivative == 2) nmat = 10
    1016         6492 :       CPASSERT(nmat > 0)
    1017              : 
    1018        12984 :       ALLOCATE (row_blk_sizes(natom))
    1019         6492 :       CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
    1020              : 
    1021         6492 :       CALL dbcsr_allocate_matrix_set(matrices, nmat, nimg)
    1022              : 
    1023              :       ! Up to 2nd derivative take care to get the symmetries correct
    1024        40952 :       DO img = 1, nimg
    1025        80674 :          DO i = 1, nmat
    1026        39722 :             IF (i > 1) THEN
    1027         5262 :                matnames = TRIM(mnames)//" DERIVATIVE MATRIX DFTB"
    1028         5262 :                symmetry_type = dbcsr_type_antisymmetric
    1029         5262 :                IF (i > 4) symmetry_type = dbcsr_type_symmetric
    1030              :             ELSE
    1031        34460 :                symmetry_type = dbcsr_type_symmetric
    1032        34460 :                matnames = TRIM(mnames)//" MATRIX DFTB"
    1033              :             END IF
    1034        39722 :             ALLOCATE (matrices(i, img)%matrix)
    1035              :             CALL dbcsr_create(matrix=matrices(i, img)%matrix, &
    1036              :                               name=TRIM(matnames), &
    1037              :                               dist=dbcsr_dist, matrix_type=symmetry_type, &
    1038              :                               row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
    1039        39722 :                               mutable_work=.TRUE.)
    1040        74182 :             CALL cp_dbcsr_alloc_block_from_nbl(matrices(i, img)%matrix, sab_nl)
    1041              :          END DO
    1042              :       END DO
    1043              : 
    1044         6492 :       DEALLOCATE (first_sgf)
    1045         6492 :       DEALLOCATE (last_sgf)
    1046              : 
    1047         6492 :       DEALLOCATE (row_blk_sizes)
    1048              : 
    1049         6492 :    END SUBROUTINE setup_matrices2
    1050              : 
    1051              : END MODULE qs_dftb_matrices
        

Generated by: LCOV version 2.0-1