LCOV - code coverage report
Current view: top level - src - qs_dftb_matrices.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:06f838d) Lines: 95.8 % 475 455
Test Date: 2026-06-05 07:04:50 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         4092 :    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         4092 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind
     113              :       INTEGER, DIMENSION(3)                              :: cell
     114         4092 :       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         8184 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: dfblock, dsblock, fblock, fmatij, &
     124         4092 :                                                             fmatji, pblock, sblock, scoeff, &
     125         4092 :                                                             smatij, smatji, spxr, wblock
     126         4092 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     127              :       TYPE(atprop_type), POINTER                         :: atprop
     128        16368 :       TYPE(block_p_type), DIMENSION(2:4)                 :: dsblocks
     129              :       TYPE(cp_logger_type), POINTER                      :: logger
     130         4092 :       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         4092 :          DIMENSION(:), POINTER                           :: nl_iterator
     136              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     137         4092 :          POINTER                                         :: sab_orb
     138         4092 :       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         4092 :          POINTER                                         :: dftb_potential
     142              :       TYPE(qs_dftb_pairpot_type), POINTER                :: dftb_param_ij, dftb_param_ji
     143              :       TYPE(qs_energy_type), POINTER                      :: energy
     144         4092 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     145         4092 :       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         4092 :       CALL timeset(routineN, handle)
     151              : 
     152              :       ! set pointers
     153         4092 :       iptr = 0
     154        20460 :       DO la = 0, 3
     155        85932 :          DO lb = 0, 3
     156        65472 :             llm = 0
     157       286440 :             DO l1 = 0, MAX(la, lb)
     158       597432 :                DO l2 = 0, MIN(l1, la, lb)
     159      1018908 :                   DO m = 0, l2
     160       486948 :                      llm = llm + 1
     161       814308 :                      iptr(l1, l2, m, la, lb) = llm
     162              :                   END DO
     163              :                END DO
     164              :             END DO
     165              :          END DO
     166              :       END DO
     167              : 
     168         4092 :       NULLIFY (logger, virial, atprop)
     169         4092 :       logger => cp_get_default_logger()
     170              : 
     171         4092 :       NULLIFY (matrix_h, matrix_s, matrix_p, matrix_w, atomic_kind_set, &
     172         4092 :                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         4092 :                       ks_env=ks_env)
     183              : 
     184         4092 :       dftb_control => dft_control%qs_control%dftb_control
     185         4092 :       nimg = dft_control%nimages
     186              :       ! Allocate the overlap and Hamiltonian matrix
     187         4092 :       CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb)
     188         4092 :       nderivatives = 0
     189         4092 :       IF (dftb_control%self_consistent .AND. calculate_forces) nderivatives = 1
     190         4092 :       CALL setup_matrices2(qs_env, nderivatives, nimg, matrix_s, "OVERLAP", sab_orb)
     191         4092 :       CALL setup_matrices2(qs_env, 0, nimg, matrix_h, "CORE HAMILTONIAN", sab_orb)
     192         4092 :       CALL set_ks_env(ks_env, matrix_s_kp=matrix_s)
     193         4092 :       CALL set_ks_env(ks_env, matrix_h_kp=matrix_h)
     194              : 
     195         4092 :       NULLIFY (dftb_potential)
     196         4092 :       CALL get_qs_env(qs_env=qs_env, dftb_potential=dftb_potential)
     197         4092 :       NULLIFY (particle_set)
     198         4092 :       CALL get_qs_env(qs_env=qs_env, particle_set=particle_set)
     199              : 
     200         4092 :       IF (calculate_forces) THEN
     201          786 :          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          786 :                          force=force)
     207          786 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     208              : 
     209          786 :          IF (SIZE(matrix_p, 1) == 2) THEN
     210          340 :             DO img = 1, nimg
     211              :                CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, &
     212          170 :                               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          340 :                               alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     215              :             END DO
     216              :          END IF
     217          786 :          CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
     218          786 :          use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     219              :       END IF
     220              :       ! atomic energy decomposition
     221         4092 :       IF (atprop%energy) THEN
     222          162 :          CALL atprop_array_init(atprop%atecc, natom=SIZE(particle_set))
     223              :       END IF
     224              : 
     225         4092 :       NULLIFY (cell_to_index)
     226         4092 :       IF (nimg > 1) THEN
     227          960 :          CALL get_ks_env(ks_env=ks_env, kpoints=kpoints)
     228          960 :          CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
     229              :       END IF
     230              : 
     231         4092 :       erep = 0._dp
     232              : 
     233         4092 :       nkind = SIZE(atomic_kind_set)
     234              : 
     235         4092 :       CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
     236       773367 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     237              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     238       769275 :                                 iatom=iatom, jatom=jatom, r=rij, cell=cell)
     239       769275 :          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       769275 :                                   eta=eta_a, natorb=natorb_a)
     243       769275 :          IF (.NOT. defined .OR. natorb_a < 1) CYCLE
     244       769275 :          CALL get_qs_kind(qs_kind_set(jkind), dftb_parameter=dftb_kind_b)
     245              :          CALL get_dftb_atom_param(dftb_kind_b, &
     246       769275 :                                   defined=defined, lmax=lmaxj, eta=eta_b, natorb=natorb_b)
     247              : 
     248       769275 :          IF (.NOT. defined .OR. natorb_b < 1) CYCLE
     249              : 
     250              :          ! retrieve information on F and S matrix
     251       769275 :          dftb_param_ij => dftb_potential(ikind, jkind)
     252       769275 :          dftb_param_ji => dftb_potential(jkind, ikind)
     253              :          ! assume table size and type is symmetric
     254       769275 :          ngrd = dftb_param_ij%ngrd
     255       769275 :          ngrdcut = dftb_param_ij%ngrdcut
     256       769275 :          dgrd = dftb_param_ij%dgrd
     257       769275 :          ddr = dgrd*dftb_fd_deriv_step
     258       769275 :          CPASSERT(dftb_param_ij%llm == dftb_param_ji%llm)
     259       769275 :          llm = dftb_param_ij%llm
     260       769275 :          fmatij => dftb_param_ij%fmat
     261       769275 :          smatij => dftb_param_ij%smat
     262       769275 :          fmatji => dftb_param_ji%fmat
     263       769275 :          smatji => dftb_param_ji%smat
     264              :          ! repulsive pair potential
     265       769275 :          n_urpoly = dftb_param_ij%n_urpoly
     266       769275 :          urep_cut = dftb_param_ij%urep_cut
     267      8462025 :          urep = dftb_param_ij%urep
     268       769275 :          spxr => dftb_param_ij%spxr
     269       769275 :          scoeff => dftb_param_ij%scoeff
     270       769275 :          spdim = dftb_param_ij%spdim
     271       769275 :          s_cut = dftb_param_ij%s_cut
     272      3077100 :          srep = dftb_param_ij%srep
     273      2307825 :          surr = dftb_param_ij%surr
     274              : 
     275      3077100 :          dr = SQRT(SUM(rij(:)**2))
     276       769275 :          IF (NINT(dr/dgrd) <= ngrdcut) THEN
     277              : 
     278       767613 :             IF (nimg == 1) THEN
     279              :                ic = 1
     280              :             ELSE
     281        74862 :                ic = cell_to_index(cell(1), cell(2), cell(3))
     282        74862 :                CPASSERT(ic > 0)
     283              :             END IF
     284              : 
     285       767613 :             icol = MAX(iatom, jatom)
     286       767613 :             irow = MIN(iatom, jatom)
     287       767613 :             NULLIFY (sblock, fblock)
     288              :             CALL dbcsr_get_block_p(matrix=matrix_s(1, ic)%matrix, &
     289       767613 :                                    row=irow, col=icol, BLOCK=sblock, found=found)
     290       767613 :             CPASSERT(found)
     291              :             CALL dbcsr_get_block_p(matrix=matrix_h(1, ic)%matrix, &
     292       767613 :                                    row=irow, col=icol, BLOCK=fblock, found=found)
     293       767613 :             CPASSERT(found)
     294              : 
     295       767613 :             IF (calculate_forces) THEN
     296       314670 :                NULLIFY (pblock)
     297              :                CALL dbcsr_get_block_p(matrix=matrix_p(1, ic)%matrix, &
     298       314670 :                                       row=irow, col=icol, block=pblock, found=found)
     299       314670 :                CPASSERT(ASSOCIATED(pblock))
     300       314670 :                NULLIFY (wblock)
     301              :                CALL dbcsr_get_block_p(matrix=matrix_w(1, ic)%matrix, &
     302       314670 :                                       row=irow, col=icol, block=wblock, found=found)
     303       314670 :                CPASSERT(ASSOCIATED(wblock))
     304       314670 :                IF (dftb_control%self_consistent) THEN
     305      1047392 :                   DO i = 2, 4
     306       785544 :                      NULLIFY (dsblocks(i)%block)
     307              :                      CALL dbcsr_get_block_p(matrix=matrix_s(i, ic)%matrix, &
     308       785544 :                                             row=irow, col=icol, BLOCK=dsblocks(i)%block, found=found)
     309      1047392 :                      CPASSERT(found)
     310              :                   END DO
     311              :                END IF
     312              :             END IF
     313              : 
     314       767613 :             IF (iatom == jatom .AND. dr < 0.001_dp) THEN
     315              :                ! diagonal block
     316        82055 :                DO i = 1, natorb_a
     317        57115 :                   sblock(i, i) = sblock(i, i) + 1._dp
     318        82055 :                   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       742673 :                                      llm, lmaxi, lmaxj, irow, iatom)
     324              :                CALL compute_block_sk(fblock, fmatij, fmatji, rij, ngrd, ngrdcut, dgrd, &
     325       742673 :                                      llm, lmaxi, lmaxj, irow, iatom)
     326       742673 :                IF (calculate_forces) THEN
     327       306072 :                   force_ab = 0._dp
     328       306072 :                   force_w = 0._dp
     329       306072 :                   n1 = SIZE(fblock, 1)
     330       306072 :                   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       306072 :                   f0 = 1.0_dp
     334       306072 :                   IF (irow == iatom) f0 = -1.0_dp
     335              : 
     336      1836432 :                   ALLOCATE (dfblock(n1, n2), dsblock(n1, n2))
     337              : 
     338      1224288 :                   DO i = 1, 3
     339       918216 :                      drij = rij
     340     12505326 :                      dfblock = 0._dp; dsblock = 0._dp
     341              : 
     342       918216 :                      drij(i) = rij(i) - ddr*f0
     343              :                      CALL compute_block_sk(dsblock, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     344       918216 :                                            llm, lmaxi, lmaxj, irow, iatom)
     345              :                      CALL compute_block_sk(dfblock, fmatij, fmatji, drij, ngrd, ngrdcut, dgrd, &
     346       918216 :                                            llm, lmaxi, lmaxj, irow, iatom)
     347              : 
     348      6711771 :                      dsblock = -dsblock
     349      6711771 :                      dfblock = -dfblock
     350              : 
     351       918216 :                      drij(i) = rij(i) + ddr*f0
     352              :                      CALL compute_block_sk(dsblock, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     353       918216 :                                            llm, lmaxi, lmaxj, irow, iatom)
     354              :                      CALL compute_block_sk(dfblock, fmatij, fmatji, drij, ngrd, ngrdcut, dgrd, &
     355       918216 :                                            llm, lmaxi, lmaxj, irow, iatom)
     356              : 
     357      6711771 :                      dfblock = dfblock/(2.0_dp*ddr)
     358      6711771 :                      dsblock = dsblock/(2.0_dp*ddr)
     359              : 
     360      6711771 :                      foab = 2.0_dp*SUM(dfblock*pblock)
     361      6711771 :                      fow = -2.0_dp*SUM(dsblock*wblock)
     362              : 
     363       918216 :                      force_ab(i) = force_ab(i) + foab
     364       918216 :                      force_w(i) = force_w(i) + fow
     365      1224288 :                      IF (dftb_control%self_consistent) THEN
     366       763953 :                         CPASSERT(ASSOCIATED(dsblocks(i + 1)%block))
     367      5559807 :                         dsblocks(i + 1)%block = dsblocks(i + 1)%block + dsblock
     368              :                      END IF
     369              :                   END DO
     370       306072 :                   IF (use_virial) THEN
     371       190621 :                      IF (iatom == jatom) f0 = 0.5_dp*f0
     372       190621 :                      CALL virial_pair_force(virial%pv_virial, -f0, force_ab, rij)
     373       190621 :                      CALL virial_pair_force(virial%pv_virial, -f0, force_w, rij)
     374              :                   END IF
     375       306072 :                   DEALLOCATE (dfblock, dsblock)
     376              :                END IF
     377              :             END IF
     378              : 
     379       767613 :             IF (calculate_forces .AND. (iatom /= jatom .OR. dr > 0.001_dp)) THEN
     380       306072 :                atom_a = atom_of_kind(iatom)
     381       306072 :                atom_b = atom_of_kind(jatom)
     382       763029 :                IF (irow == iatom) force_ab = -force_ab
     383       763029 :                IF (irow == iatom) force_w = -force_w
     384      1224288 :                force(ikind)%all_potential(:, atom_a) = force(ikind)%all_potential(:, atom_a) - force_ab(:)
     385      1224288 :                force(jkind)%all_potential(:, atom_b) = force(jkind)%all_potential(:, atom_b) + force_ab(:)
     386      1224288 :                force(ikind)%overlap(:, atom_a) = force(ikind)%overlap(:, atom_a) - force_w(:)
     387      1232886 :                force(jkind)%overlap(:, atom_b) = force(jkind)%overlap(:, atom_b) + force_w(:)
     388              :             END IF
     389              : 
     390              :          END IF
     391              : 
     392              :          ! repulsive potential
     393       773367 :          IF ((dr <= urep_cut .OR. spdim > 0) .AND. dr > 0.001_dp) THEN
     394       581197 :             erepij = 0._dp
     395              :             CALL urep_egr(rij, dr, erepij, force_rr, &
     396       581197 :                           n_urpoly, urep, spdim, s_cut, srep, spxr, scoeff, surr, calculate_forces)
     397       581197 :             erep = erep + erepij
     398       581197 :             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       581197 :             IF (calculate_forces .AND. (iatom /= jatom .OR. dr > 0.001_dp)) THEN
     403       257129 :                atom_a = atom_of_kind(iatom)
     404       257129 :                atom_b = atom_of_kind(jatom)
     405              :                force(ikind)%repulsive(:, atom_a) = &
     406      1028516 :                   force(ikind)%repulsive(:, atom_a) - force_rr(:)
     407              :                force(jkind)%repulsive(:, atom_b) = &
     408      1028516 :                   force(jkind)%repulsive(:, atom_b) + force_rr(:)
     409       257129 :                IF (use_virial) THEN
     410       171808 :                   f0 = -1.0_dp
     411       171808 :                   IF (iatom == jatom) f0 = -0.5_dp
     412       171808 :                   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         4092 :       CALL neighbor_list_iterator_release(nl_iterator)
     419              : 
     420        10176 :       DO i = 1, SIZE(matrix_s, 1)
     421        36150 :          DO img = 1, nimg
     422        32058 :             CALL dbcsr_finalize(matrix_s(i, img)%matrix)
     423              :          END DO
     424              :       END DO
     425         8184 :       DO i = 1, SIZE(matrix_h, 1)
     426        28488 :          DO img = 1, nimg
     427        24396 :             CALL dbcsr_finalize(matrix_h(i, img)%matrix)
     428              :          END DO
     429              :       END DO
     430              : 
     431              :       ! set repulsive energy
     432         4092 :       CALL para_env%sum(erep)
     433         4092 :       energy%repulsive = erep
     434              : 
     435         4092 :       CALL section_vals_val_get(qs_env%input, "DFT%PRINT%AO_MATRICES%OMIT_HEADERS", l_val=omit_headers)
     436         4092 :       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         4092 :       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         4092 :       IF (calculate_forces) THEN
     475          786 :          IF (SIZE(matrix_p, 1) == 2) THEN
     476          340 :             DO img = 1, nimg
     477              :                CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, alpha_scalar=1.0_dp, &
     478          170 :                               beta_scalar=-1.0_dp)
     479              :                CALL dbcsr_add(matrix_w(1, img)%matrix, matrix_w(2, img)%matrix, alpha_scalar=1.0_dp, &
     480          340 :                               beta_scalar=-1.0_dp)
     481              :             END DO
     482              :          END IF
     483              :       END IF
     484              : 
     485         4092 :       CALL timestop(handle)
     486              : 
     487        12276 :    END SUBROUTINE build_dftb_matrices
     488              : 
     489              : ! **************************************************************************************************
     490              : !> \brief ...
     491              : !> \param qs_env ...
     492              : !> \param calculate_forces ...
     493              : !> \param just_energy ...
     494              : ! **************************************************************************************************
     495        29784 :    SUBROUTINE build_dftb_ks_matrix(qs_env, calculate_forces, just_energy)
     496              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     497              :       LOGICAL, INTENT(in)                                :: calculate_forces, just_energy
     498              : 
     499              :       CHARACTER(len=*), PARAMETER :: routineN = 'build_dftb_ks_matrix'
     500              : 
     501              :       INTEGER                                            :: atom_a, handle, iatom, ikind, img, &
     502              :                                                             ispin, natom, nkind, nspins, &
     503              :                                                             output_unit
     504              :       REAL(KIND=dp)                                      :: pc_ener, qmmm_el, zeff
     505        29784 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: mix_charge
     506        29784 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: mcharge, occupation_numbers
     507        29784 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: charges
     508        29784 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     509              :       TYPE(cp_logger_type), POINTER                      :: logger
     510        29784 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_p1, mo_derivs
     511        29784 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix, matrix_h, matrix_p, matrix_s
     512              :       TYPE(dbcsr_type), POINTER                          :: mo_coeff
     513              :       TYPE(dft_control_type), POINTER                    :: dft_control
     514              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     515        29784 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     516              :       TYPE(qs_dftb_atom_type), POINTER                   :: dftb_kind
     517              :       TYPE(qs_energy_type), POINTER                      :: energy
     518        29784 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     519              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     520              :       TYPE(qs_rho_type), POINTER                         :: rho
     521              :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     522              :       TYPE(section_vals_type), POINTER                   :: scf_section
     523              : 
     524        29784 :       CALL timeset(routineN, handle)
     525        29784 :       NULLIFY (dft_control, logger, scf_section, matrix_p, particle_set, ks_env, &
     526        29784 :                ks_matrix, rho, energy, scf_env)
     527        29784 :       logger => cp_get_default_logger()
     528        29784 :       CPASSERT(ASSOCIATED(qs_env))
     529              : 
     530              :       CALL get_qs_env(qs_env, &
     531              :                       dft_control=dft_control, &
     532              :                       atomic_kind_set=atomic_kind_set, &
     533              :                       qs_kind_set=qs_kind_set, &
     534              :                       matrix_h_kp=matrix_h, &
     535              :                       para_env=para_env, &
     536              :                       ks_env=ks_env, &
     537              :                       matrix_ks_kp=ks_matrix, &
     538              :                       rho=rho, &
     539        29784 :                       energy=energy)
     540              : 
     541        29784 :       energy%hartree = 0.0_dp
     542        29784 :       energy%qmmm_el = 0.0_dp
     543              : 
     544        29784 :       scf_section => section_vals_get_subs_vals(qs_env%input, "DFT%SCF")
     545        29784 :       nspins = dft_control%nspins
     546        29784 :       CPASSERT(ASSOCIATED(matrix_h))
     547        29784 :       CPASSERT(ASSOCIATED(rho))
     548        89352 :       CPASSERT(SIZE(ks_matrix) > 0)
     549              : 
     550        61612 :       DO ispin = 1, nspins
     551       268994 :          DO img = 1, SIZE(ks_matrix, 2)
     552              :             ! copy the core matrix into the fock matrix
     553       239210 :             CALL dbcsr_copy(ks_matrix(ispin, img)%matrix, matrix_h(1, img)%matrix)
     554              :          END DO
     555              :       END DO
     556              : 
     557        29784 :       IF (dft_control%qs_control%dftb_control%self_consistent) THEN
     558              :          ! Mulliken charges
     559              :          CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, &
     560        28054 :                          matrix_s_kp=matrix_s)
     561        28054 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     562        28054 :          natom = SIZE(particle_set)
     563       112216 :          ALLOCATE (charges(natom, nspins))
     564              :          !
     565        28054 :          CALL mulliken_charges(matrix_p, matrix_s, para_env, charges)
     566              :          !
     567        84162 :          ALLOCATE (mcharge(natom))
     568        28054 :          nkind = SIZE(atomic_kind_set)
     569        87464 :          DO ikind = 1, nkind
     570        59410 :             CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom)
     571        59410 :             CALL get_qs_kind(qs_kind_set(ikind), dftb_parameter=dftb_kind)
     572        59410 :             CALL get_dftb_atom_param(dftb_kind, zeff=zeff)
     573       365596 :             DO iatom = 1, natom
     574       218722 :                atom_a = atomic_kind_set(ikind)%atom_list(iatom)
     575       504182 :                mcharge(atom_a) = zeff - SUM(charges(atom_a, 1:nspins))
     576              :             END DO
     577              :          END DO
     578        28054 :          DEALLOCATE (charges)
     579              : 
     580        28054 :          IF ((.NOT. dft_control%qs_control%do_ls_scf) .AND. &
     581              :              (dft_control%qs_control%dftb_control%tblite_scc_mixer /= tblite_scc_mixer_auto)) THEN
     582         1944 :             CALL get_qs_env(qs_env=qs_env, scf_env=scf_env)
     583         5832 :             ALLOCATE (mix_charge(SIZE(mcharge), 1))
     584        16832 :             mix_charge(:, 1) = mcharge(:)
     585              :             CALL charge_mixing(scf_env%mixing_method, scf_env%mixing_store, &
     586              :                                mix_charge, para_env, scf_env%iter_count, &
     587              :                                scc_mixer=dft_control%qs_control%dftb_control%tblite_scc_mixer, &
     588              :                                tblite_mixer_iterations= &
     589              :                                dft_control%qs_control%dftb_control%tblite_mixer_iterations, &
     590              :                                tblite_mixer_damping=dft_control%qs_control%dftb_control%tblite_mixer_damping, &
     591              :                                tblite_mixer_memory=dft_control%qs_control%dftb_control%tblite_mixer_memory, &
     592              :                                tblite_mixer_omega0=dft_control%qs_control%dftb_control%tblite_mixer_omega0, &
     593              :                                tblite_mixer_min_weight= &
     594              :                                dft_control%qs_control%dftb_control%tblite_mixer_min_weight, &
     595              :                                tblite_mixer_max_weight= &
     596              :                                dft_control%qs_control%dftb_control%tblite_mixer_max_weight, &
     597              :                                tblite_mixer_weight_factor= &
     598         1944 :                                dft_control%qs_control%dftb_control%tblite_mixer_weight_factor)
     599        16832 :             mcharge(:) = mix_charge(:, 1)
     600         1944 :             DEALLOCATE (mix_charge)
     601              :          END IF
     602              : 
     603              :          CALL build_dftb_coulomb(qs_env, ks_matrix, rho, mcharge, energy, &
     604        28054 :                                  calculate_forces, just_energy)
     605              : 
     606              :          CALL efield_tb_matrix(qs_env, ks_matrix, rho, mcharge, energy, &
     607        28054 :                                calculate_forces, just_energy)
     608              : 
     609        28054 :          DEALLOCATE (mcharge)
     610              : 
     611              :       END IF
     612              : 
     613        29784 :       IF (qs_env%qmmm) THEN
     614         4808 :          CPASSERT(SIZE(ks_matrix, 2) == 1)
     615         9616 :          DO ispin = 1, nspins
     616              :             ! If QM/MM sumup the 1el Hamiltonian
     617              :             CALL dbcsr_add(ks_matrix(ispin, 1)%matrix, qs_env%ks_qmmm_env%matrix_h(1)%matrix, &
     618         4808 :                            1.0_dp, 1.0_dp)
     619         4808 :             CALL qs_rho_get(rho, rho_ao=matrix_p1)
     620              :             ! Compute QM/MM Energy
     621              :             CALL dbcsr_dot(qs_env%ks_qmmm_env%matrix_h(1)%matrix, &
     622         4808 :                            matrix_p1(ispin)%matrix, qmmm_el)
     623         9616 :             energy%qmmm_el = energy%qmmm_el + qmmm_el
     624              :          END DO
     625         4808 :          pc_ener = qs_env%ks_qmmm_env%pc_ener
     626         4808 :          energy%qmmm_el = energy%qmmm_el + pc_ener
     627              :       END IF
     628              : 
     629              :       energy%total = energy%core + energy%hartree + energy%qmmm_el + energy%efield + &
     630        29784 :                      energy%repulsive + energy%dispersion + energy%dftb3
     631              : 
     632        29784 :       IF (dft_control%qs_control%dftb_control%self_consistent) THEN
     633              :          output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DETAILED_ENERGY", &
     634        28054 :                                             extension=".scfLog")
     635        28054 :          IF (output_unit > 0) THEN
     636              :             WRITE (UNIT=output_unit, FMT="(/,(T9,A,T60,F20.10))") &
     637           15 :                "Repulsive pair potential energy:               ", energy%repulsive, &
     638           15 :                "Zeroth order Hamiltonian energy:               ", energy%core, &
     639           15 :                "Charge fluctuation energy:                     ", energy%hartree, &
     640           30 :                "London dispersion energy:                      ", energy%dispersion
     641           15 :             IF (ABS(energy%efield) > 1.e-12_dp) THEN
     642              :                WRITE (UNIT=output_unit, FMT="(T9,A,T60,F20.10)") &
     643            0 :                   "Electric field interaction energy:             ", energy%efield
     644              :             END IF
     645           15 :             IF (dft_control%qs_control%dftb_control%dftb3_diagonal) THEN
     646              :                WRITE (UNIT=output_unit, FMT="(T9,A,T60,F20.10)") &
     647            0 :                   "DFTB3 3rd Order Energy Correction              ", energy%dftb3
     648              :             END IF
     649           15 :             IF (qs_env%qmmm) THEN
     650              :                WRITE (UNIT=output_unit, FMT="(T9,A,T60,F20.10)") &
     651            0 :                   "QM/MM Electrostatic energy:                    ", energy%qmmm_el
     652              :             END IF
     653              :          END IF
     654              :          CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
     655        28054 :                                            "PRINT%DETAILED_ENERGY")
     656              :       END IF
     657              :       ! here we compute dE/dC if needed. Assumes dE/dC is H_{ks}C (plus occupation numbers)
     658        29784 :       IF (qs_env%requires_mo_derivs .AND. .NOT. just_energy) THEN
     659          386 :          CPASSERT(SIZE(ks_matrix, 2) == 1)
     660              :          BLOCK
     661          386 :             TYPE(mo_set_type), DIMENSION(:), POINTER :: mo_array
     662          386 :             CALL get_qs_env(qs_env, mo_derivs=mo_derivs, mos=mo_array)
     663          800 :             DO ispin = 1, SIZE(mo_derivs)
     664              :                CALL get_mo_set(mo_set=mo_array(ispin), &
     665          414 :                                mo_coeff_b=mo_coeff, occupation_numbers=occupation_numbers)
     666          414 :                IF (.NOT. mo_array(ispin)%use_mo_coeff_b) THEN
     667            0 :                   CPABORT("")
     668              :                END IF
     669              :                CALL dbcsr_multiply('n', 'n', 1.0_dp, ks_matrix(ispin, 1)%matrix, mo_coeff, &
     670          800 :                                    0.0_dp, mo_derivs(ispin)%matrix)
     671              :             END DO
     672              :          END BLOCK
     673              :       END IF
     674              : 
     675        29784 :       CALL timestop(handle)
     676              : 
     677        59568 :    END SUBROUTINE build_dftb_ks_matrix
     678              : 
     679              : ! **************************************************************************************************
     680              : !> \brief ...
     681              : !> \param qs_env ...
     682              : !> \param nderivative ...
     683              : !> \param matrix_s ...
     684              : ! **************************************************************************************************
     685         1792 :    SUBROUTINE build_dftb_overlap(qs_env, nderivative, matrix_s)
     686              : 
     687              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     688              :       INTEGER, INTENT(IN)                                :: nderivative
     689              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     690              : 
     691              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_dftb_overlap'
     692              : 
     693              :       INTEGER :: handle, i, iatom, icol, ikind, indder, irow, j, jatom, jkind, l1, l2, la, lb, &
     694              :          llm, lmaxi, lmaxj, m, n1, n2, natom, natorb_a, natorb_b, ngrd, ngrdcut, nkind
     695              :       LOGICAL                                            :: defined, found
     696              :       REAL(KIND=dp)                                      :: ddr, dgrd, dr, f0
     697              :       REAL(KIND=dp), DIMENSION(0:3)                      :: skself
     698              :       REAL(KIND=dp), DIMENSION(3)                        :: drij, rij
     699         1792 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: dsblock, dsblockm, sblock, smatij, smatji
     700          896 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: dsblock1
     701          896 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     702         8960 :       TYPE(block_p_type), DIMENSION(2:10)                :: dsblocks
     703              :       TYPE(cp_logger_type), POINTER                      :: logger
     704              :       TYPE(dft_control_type), POINTER                    :: dft_control
     705              :       TYPE(dftb_control_type), POINTER                   :: dftb_control
     706              :       TYPE(neighbor_list_iterator_p_type), &
     707          896 :          DIMENSION(:), POINTER                           :: nl_iterator
     708              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     709          896 :          POINTER                                         :: sab_orb
     710              :       TYPE(qs_dftb_atom_type), POINTER                   :: dftb_kind_a, dftb_kind_b
     711              :       TYPE(qs_dftb_pairpot_type), DIMENSION(:, :), &
     712          896 :          POINTER                                         :: dftb_potential
     713              :       TYPE(qs_dftb_pairpot_type), POINTER                :: dftb_param_ij, dftb_param_ji
     714          896 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     715              : 
     716          896 :       CALL timeset(routineN, handle)
     717              : 
     718              :       ! set pointers
     719          896 :       iptr = 0
     720         4480 :       DO la = 0, 3
     721        18816 :          DO lb = 0, 3
     722        14336 :             llm = 0
     723        62720 :             DO l1 = 0, MAX(la, lb)
     724       130816 :                DO l2 = 0, MIN(l1, la, lb)
     725       223104 :                   DO m = 0, l2
     726       106624 :                      llm = llm + 1
     727       178304 :                      iptr(l1, l2, m, la, lb) = llm
     728              :                   END DO
     729              :                END DO
     730              :             END DO
     731              :          END DO
     732              :       END DO
     733              : 
     734          896 :       NULLIFY (logger)
     735          896 :       logger => cp_get_default_logger()
     736              : 
     737          896 :       NULLIFY (atomic_kind_set, qs_kind_set, sab_orb)
     738              : 
     739              :       CALL get_qs_env(qs_env=qs_env, &
     740              :                       atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set, &
     741          896 :                       dft_control=dft_control)
     742              : 
     743          896 :       dftb_control => dft_control%qs_control%dftb_control
     744              : 
     745          896 :       NULLIFY (dftb_potential)
     746              :       CALL get_qs_env(qs_env=qs_env, &
     747          896 :                       dftb_potential=dftb_potential)
     748              : 
     749          896 :       nkind = SIZE(atomic_kind_set)
     750              : 
     751              :       ! Allocate the overlap matrix
     752          896 :       CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb)
     753          896 :       CALL setup_matrices1(qs_env, nderivative, matrix_s, 'OVERLAP', sab_orb)
     754              : 
     755          896 :       CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
     756         3668 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     757              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
     758         2772 :                                 iatom=iatom, jatom=jatom, r=rij)
     759              : 
     760         2772 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom)
     761         2772 :          CALL get_qs_kind(qs_kind_set(ikind), dftb_parameter=dftb_kind_a)
     762              :          CALL get_dftb_atom_param(dftb_kind_a, &
     763              :                                   defined=defined, lmax=lmaxi, skself=skself, &
     764         2772 :                                   natorb=natorb_a)
     765              : 
     766         2772 :          IF (.NOT. defined .OR. natorb_a < 1) CYCLE
     767              : 
     768         2772 :          CALL get_qs_kind(qs_kind_set(jkind), dftb_parameter=dftb_kind_b)
     769              :          CALL get_dftb_atom_param(dftb_kind_b, &
     770         2772 :                                   defined=defined, lmax=lmaxj, natorb=natorb_b)
     771              : 
     772         2772 :          IF (.NOT. defined .OR. natorb_b < 1) CYCLE
     773              : 
     774              :          ! retrieve information on F and S matrix
     775         2772 :          dftb_param_ij => dftb_potential(ikind, jkind)
     776         2772 :          dftb_param_ji => dftb_potential(jkind, ikind)
     777              :          ! assume table size and type is symmetric
     778         2772 :          ngrd = dftb_param_ij%ngrd
     779         2772 :          ngrdcut = dftb_param_ij%ngrdcut
     780         2772 :          dgrd = dftb_param_ij%dgrd
     781         2772 :          ddr = dgrd*dftb_fd_deriv_step
     782         2772 :          CPASSERT(dftb_param_ij%llm == dftb_param_ji%llm)
     783         2772 :          llm = dftb_param_ij%llm
     784         2772 :          smatij => dftb_param_ij%smat
     785         2772 :          smatji => dftb_param_ji%smat
     786              : 
     787        11088 :          dr = SQRT(SUM(rij(:)**2))
     788         3668 :          IF (NINT(dr/dgrd) <= ngrdcut) THEN
     789              : 
     790         2772 :             icol = MAX(iatom, jatom); irow = MIN(iatom, jatom)
     791              : 
     792         2772 :             NULLIFY (sblock)
     793              :             CALL dbcsr_get_block_p(matrix=matrix_s(1)%matrix, &
     794         2772 :                                    row=irow, col=icol, BLOCK=sblock, found=found)
     795         2772 :             CPASSERT(found)
     796              : 
     797         2772 :             IF (nderivative > 0) THEN
     798         3672 :                DO i = 2, SIZE(matrix_s, 1)
     799         3258 :                   NULLIFY (dsblocks(i)%block)
     800              :                   CALL dbcsr_get_block_p(matrix=matrix_s(i)%matrix, &
     801         3672 :                                          row=irow, col=icol, BLOCK=dsblocks(i)%block, found=found)
     802              :                END DO
     803              :             END IF
     804              : 
     805         2772 :             IF (iatom == jatom .AND. dr < 0.001_dp) THEN
     806              :                ! diagonal block
     807         4137 :                DO i = 1, natorb_a
     808         4137 :                   sblock(i, i) = sblock(i, i) + 1._dp
     809              :                END DO
     810              :             ELSE
     811              :                ! off-diagonal block
     812              :                CALL compute_block_sk(sblock, smatij, smatji, rij, ngrd, ngrdcut, dgrd, &
     813         1407 :                                      llm, lmaxi, lmaxj, irow, iatom)
     814              : 
     815         1407 :                IF (nderivative >= 1) THEN
     816          228 :                   n1 = SIZE(sblock, 1); n2 = SIZE(sblock, 2)
     817          228 :                   indder = 1 ! used to put the 2nd derivatives in the correct matric (5=xx,8=yy,10=zz)
     818              : 
     819         2280 :                   ALLOCATE (dsblock1(n1, n2, 3), dsblock(n1, n2), dsblockm(n1, n2))
     820         5394 :                   dsblock1 = 0.0_dp
     821          912 :                   DO i = 1, 3
     822         9648 :                      dsblock = 0._dp; dsblockm = 0.0_dp
     823          684 :                      drij = rij
     824          684 :                      f0 = 1.0_dp; IF (irow == iatom) f0 = -1.0_dp
     825              : 
     826          684 :                      drij(i) = rij(i) - ddr*f0
     827              :                      CALL compute_block_sk(dsblockm, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     828          684 :                                            llm, lmaxi, lmaxj, irow, iatom)
     829              : 
     830          684 :                      drij(i) = rij(i) + ddr*f0
     831              :                      CALL compute_block_sk(dsblock, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     832          684 :                                            llm, lmaxi, lmaxj, irow, iatom)
     833              : 
     834         9648 :                      dsblock1(:, :, i) = (dsblock + dsblockm)
     835         9648 :                      dsblock = dsblock - dsblockm
     836         5166 :                      dsblock = dsblock/(2.0_dp*ddr)
     837              : 
     838          684 :                      CPASSERT(ASSOCIATED(dsblocks(i + 1)%block))
     839         5166 :                      dsblocks(i + 1)%block = dsblocks(i + 1)%block + dsblock
     840          912 :                      IF (nderivative > 1) THEN
     841          567 :                         indder = indder + 5 - i
     842         4347 :                         dsblocks(indder)%block = 0.0_dp
     843              :                         dsblocks(indder)%block = dsblocks(indder)%block + &
     844         4347 :                                                  (dsblock1(:, :, i) - 2.0_dp*sblock)/ddr**2
     845              :                      END IF
     846              :                   END DO
     847              : 
     848          228 :                   IF (nderivative > 1) THEN
     849          567 :                      DO i = 1, 2
     850         1134 :                         DO j = i + 1, 3
     851         8127 :                            dsblock = 0._dp; dsblockm = 0.0_dp
     852          567 :                            drij = rij
     853          567 :                            f0 = 1.0_dp; IF (irow == iatom) f0 = -1.0_dp
     854              : 
     855          567 :                            drij(i) = rij(i) - ddr*f0; drij(j) = rij(j) - ddr*f0
     856              :                            CALL compute_block_sk(dsblockm, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     857          567 :                                                  llm, lmaxi, lmaxj, irow, iatom)
     858              : 
     859          567 :                            drij(i) = rij(i) + ddr*f0; drij(j) = rij(j) + ddr*f0
     860              :                            CALL compute_block_sk(dsblock, smatij, smatji, drij, ngrd, ngrdcut, dgrd, &
     861          567 :                                                  llm, lmaxi, lmaxj, irow, iatom)
     862              : 
     863          567 :                            indder = 2 + 2*i + j
     864         4347 :                            dsblocks(indder)%block = 0.0_dp
     865              :                            dsblocks(indder)%block = &
     866              :                               dsblocks(indder)%block + ( &
     867         4725 :                               dsblock + dsblockm - dsblock1(:, :, i) - dsblock1(:, :, j) + 2.0_dp*sblock)/(2.0_dp*ddr**2)
     868              :                         END DO
     869              :                      END DO
     870              :                   END IF
     871              : 
     872          228 :                   DEALLOCATE (dsblock1, dsblock, dsblockm)
     873              :                END IF
     874              :             END IF
     875              :          END IF
     876              :       END DO
     877          896 :       CALL neighbor_list_iterator_release(nl_iterator)
     878              : 
     879         2626 :       DO i = 1, SIZE(matrix_s, 1)
     880         2626 :          CALL dbcsr_finalize(matrix_s(i)%matrix)
     881              :       END DO
     882              : 
     883          896 :       CALL timestop(handle)
     884              : 
     885         1792 :    END SUBROUTINE build_dftb_overlap
     886              : 
     887              : ! **************************************************************************************************
     888              : !> \brief ...
     889              : !> \param qs_env ...
     890              : !> \param nderivative ...
     891              : !> \param matrices ...
     892              : !> \param mnames ...
     893              : !> \param sab_nl ...
     894              : ! **************************************************************************************************
     895          896 :    SUBROUTINE setup_matrices1(qs_env, nderivative, matrices, mnames, sab_nl)
     896              : 
     897              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     898              :       INTEGER, INTENT(IN)                                :: nderivative
     899              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrices
     900              :       CHARACTER(LEN=*)                                   :: mnames
     901              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     902              :          POINTER                                         :: sab_nl
     903              : 
     904              :       CHARACTER(1)                                       :: symmetry_type
     905              :       CHARACTER(LEN=default_string_length)               :: matnames
     906              :       INTEGER                                            :: i, natom, neighbor_list_id, nkind, nmat, &
     907              :                                                             nsgf
     908              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: first_sgf, last_sgf
     909          896 :       INTEGER, DIMENSION(:), POINTER                     :: row_blk_sizes
     910          896 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     911              :       TYPE(dbcsr_distribution_type), POINTER             :: dbcsr_dist
     912          896 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     913          896 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     914              : 
     915          896 :       NULLIFY (particle_set, atomic_kind_set)
     916              : 
     917              :       CALL get_qs_env(qs_env=qs_env, &
     918              :                       atomic_kind_set=atomic_kind_set, &
     919              :                       qs_kind_set=qs_kind_set, &
     920              :                       particle_set=particle_set, &
     921              :                       dbcsr_dist=dbcsr_dist, &
     922          896 :                       neighbor_list_id=neighbor_list_id)
     923              : 
     924          896 :       nkind = SIZE(atomic_kind_set)
     925          896 :       natom = SIZE(particle_set)
     926              : 
     927          896 :       CALL get_qs_kind_set(qs_kind_set, nsgf=nsgf)
     928              : 
     929         2688 :       ALLOCATE (first_sgf(natom))
     930         1792 :       ALLOCATE (last_sgf(natom))
     931              : 
     932              :       CALL get_particle_set(particle_set, qs_kind_set, &
     933              :                             first_sgf=first_sgf, &
     934          896 :                             last_sgf=last_sgf)
     935              : 
     936          896 :       nmat = 0
     937          896 :       IF (nderivative == 0) nmat = 1
     938          896 :       IF (nderivative == 1) nmat = 4
     939          896 :       IF (nderivative == 2) nmat = 10
     940          896 :       CPASSERT(nmat > 0)
     941              : 
     942         1792 :       ALLOCATE (row_blk_sizes(natom))
     943          896 :       CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
     944              : 
     945          896 :       CALL dbcsr_allocate_matrix_set(matrices, nmat)
     946              : 
     947              :       ! Up to 2nd derivative take care to get the symmetries correct
     948         2626 :       DO i = 1, nmat
     949         1730 :          IF (i > 1) THEN
     950          834 :             matnames = TRIM(mnames)//" DERIVATIVE MATRIX DFTB"
     951          834 :             symmetry_type = dbcsr_type_antisymmetric
     952          834 :             IF (i > 4) symmetry_type = dbcsr_type_symmetric
     953              :          ELSE
     954          896 :             symmetry_type = dbcsr_type_symmetric
     955          896 :             matnames = TRIM(mnames)//" MATRIX DFTB"
     956              :          END IF
     957         1730 :          ALLOCATE (matrices(i)%matrix)
     958              :          CALL dbcsr_create(matrix=matrices(i)%matrix, &
     959              :                            name=TRIM(matnames), &
     960              :                            dist=dbcsr_dist, matrix_type=symmetry_type, &
     961              :                            row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
     962         1730 :                            mutable_work=.TRUE.)
     963         2626 :          CALL cp_dbcsr_alloc_block_from_nbl(matrices(i)%matrix, sab_nl)
     964              :       END DO
     965              : 
     966          896 :       DEALLOCATE (first_sgf)
     967          896 :       DEALLOCATE (last_sgf)
     968              : 
     969          896 :       DEALLOCATE (row_blk_sizes)
     970              : 
     971          896 :    END SUBROUTINE setup_matrices1
     972              : 
     973              : ! **************************************************************************************************
     974              : !> \brief ...
     975              : !> \param qs_env ...
     976              : !> \param nderivative ...
     977              : !> \param nimg ...
     978              : !> \param matrices ...
     979              : !> \param mnames ...
     980              : !> \param sab_nl ...
     981              : ! **************************************************************************************************
     982         8184 :    SUBROUTINE setup_matrices2(qs_env, nderivative, nimg, matrices, mnames, sab_nl)
     983              : 
     984              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     985              :       INTEGER, INTENT(IN)                                :: nderivative, nimg
     986              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrices
     987              :       CHARACTER(LEN=*)                                   :: mnames
     988              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     989              :          POINTER                                         :: sab_nl
     990              : 
     991              :       CHARACTER(1)                                       :: symmetry_type
     992              :       CHARACTER(LEN=default_string_length)               :: matnames
     993              :       INTEGER                                            :: i, img, natom, neighbor_list_id, nkind, &
     994              :                                                             nmat, nsgf
     995              :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: first_sgf, last_sgf
     996         8184 :       INTEGER, DIMENSION(:), POINTER                     :: row_blk_sizes
     997         8184 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     998              :       TYPE(dbcsr_distribution_type), POINTER             :: dbcsr_dist
     999         8184 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1000         8184 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1001              : 
    1002         8184 :       NULLIFY (particle_set, atomic_kind_set)
    1003              : 
    1004              :       CALL get_qs_env(qs_env=qs_env, &
    1005              :                       atomic_kind_set=atomic_kind_set, &
    1006              :                       qs_kind_set=qs_kind_set, &
    1007              :                       particle_set=particle_set, &
    1008              :                       dbcsr_dist=dbcsr_dist, &
    1009         8184 :                       neighbor_list_id=neighbor_list_id)
    1010              : 
    1011         8184 :       nkind = SIZE(atomic_kind_set)
    1012         8184 :       natom = SIZE(particle_set)
    1013              : 
    1014         8184 :       CALL get_qs_kind_set(qs_kind_set, nsgf=nsgf)
    1015              : 
    1016        24552 :       ALLOCATE (first_sgf(natom))
    1017        16368 :       ALLOCATE (last_sgf(natom))
    1018              : 
    1019              :       CALL get_particle_set(particle_set, qs_kind_set, &
    1020              :                             first_sgf=first_sgf, &
    1021         8184 :                             last_sgf=last_sgf)
    1022              : 
    1023         8184 :       nmat = 0
    1024         8184 :       IF (nderivative == 0) nmat = 1
    1025         8184 :       IF (nderivative == 1) nmat = 4
    1026         8184 :       IF (nderivative == 2) nmat = 10
    1027         8184 :       CPASSERT(nmat > 0)
    1028              : 
    1029        16368 :       ALLOCATE (row_blk_sizes(natom))
    1030         8184 :       CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
    1031              : 
    1032         8184 :       CALL dbcsr_allocate_matrix_set(matrices, nmat, nimg)
    1033              : 
    1034              :       ! Up to 2nd derivative take care to get the symmetries correct
    1035        48792 :       DO img = 1, nimg
    1036        95070 :          DO i = 1, nmat
    1037        46278 :             IF (i > 1) THEN
    1038         5670 :                matnames = TRIM(mnames)//" DERIVATIVE MATRIX DFTB"
    1039         5670 :                symmetry_type = dbcsr_type_antisymmetric
    1040         5670 :                IF (i > 4) symmetry_type = dbcsr_type_symmetric
    1041              :             ELSE
    1042        40608 :                symmetry_type = dbcsr_type_symmetric
    1043        40608 :                matnames = TRIM(mnames)//" MATRIX DFTB"
    1044              :             END IF
    1045        46278 :             ALLOCATE (matrices(i, img)%matrix)
    1046              :             CALL dbcsr_create(matrix=matrices(i, img)%matrix, &
    1047              :                               name=TRIM(matnames), &
    1048              :                               dist=dbcsr_dist, matrix_type=symmetry_type, &
    1049              :                               row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
    1050        46278 :                               mutable_work=.TRUE.)
    1051        86886 :             CALL cp_dbcsr_alloc_block_from_nbl(matrices(i, img)%matrix, sab_nl)
    1052              :          END DO
    1053              :       END DO
    1054              : 
    1055         8184 :       DEALLOCATE (first_sgf)
    1056         8184 :       DEALLOCATE (last_sgf)
    1057              : 
    1058         8184 :       DEALLOCATE (row_blk_sizes)
    1059              : 
    1060         8184 :    END SUBROUTINE setup_matrices2
    1061              : 
    1062              : END MODULE qs_dftb_matrices
        

Generated by: LCOV version 2.0-1