LCOV - code coverage report
Current view: top level - src - tblite_interface.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:06f838d) Lines: 84.0 % 2187 1836
Test Date: 2026-06-05 07:04:50 Functions: 80.0 % 50 40

            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 interface to tblite
      10              : !> \author JVP
      11              : !> \history creation 09.2024
      12              : ! **************************************************************************************************
      13              : 
      14              : MODULE tblite_interface
      15              : 
      16              : #if defined(__TBLITE)
      17              :    USE mctc_env, ONLY: error_type
      18              :    USE mctc_io, ONLY: structure_type, new
      19              :    USE mctc_io_symbols, ONLY: symbol_to_number
      20              :    USE tblite_adjlist, ONLY: adjacency_list, new_adjacency_list
      21              :    USE tblite_basis_type, ONLY: get_cutoff
      22              :    USE tblite_container, ONLY: container_cache
      23              :    USE tblite_container_type, ONLY: container_type
      24              :    USE tblite_cutoff, ONLY: get_lattice_points
      25              :    USE tblite_data_spin, ONLY: get_spin_constant
      26              :    USE tblite_integral_multipole, ONLY: multipole_cgto, multipole_grad_cgto, maxl, msao
      27              :    USE tblite_integral_type, ONLY: integral_type, new_integral
      28              :    USE tblite_scf, ONLY: get_mixer_dimension
      29              :    USE tblite_scf_info, ONLY: scf_info, atom_resolved, shell_resolved, &
      30              :                               orbital_resolved, not_used
      31              :    USE tblite_scf_potential, ONLY: potential_type, new_potential, add_pot_to_h1
      32              :    USE tblite_spin, ONLY: spin_polarization, new_spin_polarization
      33              :    USE tblite_wavefunction_type, ONLY: wavefunction_type, new_wavefunction
      34              :    USE tblite_xtb_calculator, ONLY: xtb_calculator, new_xtb_calculator
      35              :    USE tblite_xtb_gfn1, ONLY: new_gfn1_calculator
      36              :    USE tblite_xtb_gfn2, ONLY: new_gfn2_calculator
      37              :    USE tblite_xtb_h0, ONLY: get_selfenergy, get_hamiltonian, get_occupation, &
      38              :                             get_hamiltonian_gradient, tb_hamiltonian
      39              :    USE tblite_xtb_ipea1, ONLY: new_ipea1_calculator
      40              : #endif
      41              :    USE ai_contraction, ONLY: block_add, &
      42              :                              contraction
      43              :    USE ai_overlap, ONLY: overlap_ab
      44              :    USE atomic_kind_types, ONLY: atomic_kind_type, get_atomic_kind, get_atomic_kind_set
      45              :    USE atprop_types, ONLY: atprop_type
      46              :    USE basis_set_types, ONLY: gto_basis_set_type, gto_basis_set_p_type, &
      47              :                               & allocate_gto_basis_set, write_gto_basis_set, process_gto_basis
      48              :    USE cell_types, ONLY: cell_type, get_cell
      49              :    USE cp_blacs_env, ONLY: cp_blacs_env_type
      50              :    USE cp_control_types, ONLY: dft_control_type, xtb_reference_cli_type
      51              :    USE cp_dbcsr_api, ONLY: dbcsr_type, dbcsr_p_type, dbcsr_create, dbcsr_add, dbcsr_copy, &
      52              :                            dbcsr_get_block_p, dbcsr_finalize, &
      53              :                            dbcsr_iterator_type, dbcsr_iterator_blocks_left, &
      54              :                            dbcsr_iterator_start, dbcsr_iterator_stop, &
      55              :                            dbcsr_iterator_next_block
      56              :    USE cp_dbcsr_contrib, ONLY: dbcsr_print
      57              :    USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
      58              :    USE cp_dbcsr_operations, ONLY: dbcsr_allocate_matrix_set, dbcsr_deallocate_matrix_set
      59              :    USE cp_log_handling, ONLY: cp_get_default_logger, &
      60              :                               cp_logger_type, cp_logger_get_default_io_unit
      61              :    USE cp_output_handling, ONLY: cp_print_key_should_output, &
      62              :                                  cp_print_key_unit_nr, cp_print_key_finished_output, &
      63              :                                  debug_print_level, high_print_level, silent_print_level
      64              :    USE cp_units, ONLY: cp_unit_from_cp2k
      65              :    USE input_constants, ONLY: gfn1xtb, gfn2xtb, ipea1xtb, smear_energy_window, &
      66              :                               smear_fermi_dirac, smear_gaussian, smear_list, smear_mp, smear_mv, &
      67              :                               tblite_cli_born_kernel_auto, tblite_cli_born_kernel_p16, &
      68              :                               tblite_cli_born_kernel_still, tblite_cli_solution_state_bar1mol, &
      69              :                               tblite_cli_solution_state_gsolv, tblite_cli_solution_state_reference, &
      70              :                               tblite_cli_solvation_alpb, tblite_cli_solvation_cpcm, &
      71              :                               tblite_cli_solvation_gb, tblite_cli_solvation_gbe, &
      72              :                               tblite_cli_solvation_gbsa, &
      73              :                               tblite_guess_ceh, tblite_guess_eeq, tblite_guess_sad, &
      74              :                               tblite_mixer_damping_default, &
      75              :                               tblite_mixer_max_weight_default, tblite_mixer_min_weight_default, &
      76              :                               tblite_mixer_omega0_default, tblite_mixer_weight_factor_default, &
      77              :                               tblite_scc_mixer_auto, tblite_scc_mixer_cp2k, &
      78              :                               tblite_scc_mixer_none, tblite_scc_mixer_tblite, &
      79              :                               tblite_solver_gvd, tblite_solver_gvr
      80              :    USE input_section_types, ONLY: section_vals_val_get
      81              :    USE kinds, ONLY: default_path_length, default_string_length, dp, int_8
      82              :    USE kpoint_types, ONLY: get_kpoint_info, kpoint_type
      83              :    USE memory_utilities, ONLY: reallocate
      84              :    USE message_passing, ONLY: mp_para_env_type
      85              :    USE mulliken, ONLY: ao_charges
      86              :    USE orbital_pointers, ONLY: ncoset
      87              :    USE particle_types, ONLY: particle_type
      88              :    USE qs_charge_mixing, ONLY: charge_mixing
      89              :    USE qs_condnum, ONLY: overlap_condnum
      90              :    USE qs_energy_types, ONLY: qs_energy_type
      91              :    USE qs_environment_types, ONLY: get_qs_env, qs_environment_type
      92              :    USE qs_force_types, ONLY: qs_force_type, total_qs_force
      93              :    USE qs_integral_utils, ONLY: basis_set_list_setup, get_memory_usage
      94              :    USE qs_kind_types, ONLY: get_qs_kind, qs_kind_type, get_qs_kind_set
      95              :    USE qs_ks_types, ONLY: get_ks_env, qs_ks_env_type, set_ks_env
      96              :    USE qs_neighbor_list_types, ONLY: neighbor_list_iterator_create, neighbor_list_iterate, &
      97              :                                      get_iterator_info, neighbor_list_set_p_type, &
      98              :                                      neighbor_list_iterator_p_type, neighbor_list_iterator_release
      99              :    USE qs_overlap, ONLY: create_sab_matrix
     100              :    USE cp_dbcsr_output, ONLY: cp_dbcsr_write_sparse_matrix
     101              :    USE qs_rho_types, ONLY: qs_rho_get, qs_rho_type
     102              :    USE qs_scf_types, ONLY: qs_scf_env_type
     103              :    USE scf_control_types, ONLY: scf_control_type
     104              :    USE input_section_types, ONLY: section_vals_get_subs_vals, section_vals_type
     105              :    USE string_utilities, ONLY: integer_to_string
     106              : #if defined(__TBLITE)
     107              :    USE tblite_scc_mixer, ONLY: new_cp2k_tblite_mixer
     108              : #endif
     109              :    USE tblite_types, ONLY: tblite_type, deallocate_tblite_type, allocate_tblite_type
     110              :    USE virial_types, ONLY: virial_type
     111              :    USE xtb_types, ONLY: get_xtb_atom_param, xtb_atom_type
     112              :    USE xtb_types, ONLY: xtb_atom_type
     113              : 
     114              : !$ USE OMP_LIB, ONLY: omp_destroy_lock, omp_init_lock, omp_set_lock, &
     115              : !$                    omp_unset_lock, omp_lock_kind
     116              : 
     117              : #include "./base/base_uses.f90"
     118              :    IMPLICIT NONE
     119              : 
     120              :    PRIVATE
     121              : 
     122              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'tblite_interface'
     123              : 
     124              :    INTEGER, PARAMETER                                 :: dip_n = 3
     125              :    INTEGER, PARAMETER                                 :: quad_n = 6
     126              :    REAL(KIND=dp), PARAMETER                           :: same_atom = 0.00001_dp
     127              :    REAL(KIND=dp), PARAMETER                           :: tblite_scc_pconv = 2.0E-5_dp
     128              : 
     129              :    PUBLIC :: tb_set_calculator, tb_init_geometry, tb_init_wf
     130              :    PUBLIC :: tb_get_basis, build_tblite_matrices
     131              :    PUBLIC :: tb_get_energy, tb_update_charges, tb_ham_add_coulomb
     132              :    PUBLIC :: tb_native_scc_mixer_active
     133              :    PUBLIC :: tb_scf_mixer_error
     134              :    PUBLIC :: tb_get_multipole
     135              :    PUBLIC :: tb_derive_dH_diag, tb_derive_dH_off
     136              :    PUBLIC :: tb_reference_cli_compare
     137              : 
     138              : CONTAINS
     139              : 
     140              : #if defined(__TBLITE)
     141              : ! **************************************************************************************************
     142              : !> \brief Project a tblite charge/magnetization quantity to a CP2K spin channel.
     143              : !> \param values ...
     144              : !> \param ispin ...
     145              : !> \return ...
     146              : ! **************************************************************************************************
     147     46551350 :    PURE FUNCTION tb_spin_project(values, ispin) RESULT(value)
     148              : 
     149              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: values
     150              :       INTEGER, INTENT(IN)                                :: ispin
     151              :       REAL(KIND=dp)                                      :: value
     152              : 
     153     46551350 :       value = values(1)
     154     46551350 :       IF (SIZE(values) > 1) THEN
     155       434982 :          SELECT CASE (ispin)
     156              :          CASE (1)
     157       144994 :             value = values(1) + values(2)
     158              :          CASE (2)
     159       144994 :             value = values(1) - values(2)
     160              :          CASE DEFAULT
     161       289988 :             value = values(1)
     162              :          END SELECT
     163              :       END IF
     164              : 
     165     46551350 :    END FUNCTION tb_spin_project
     166              : 
     167              : ! **************************************************************************************************
     168              : !> \brief Store a private copy of the converged density for tblite force derivatives.
     169              : !> \param tb ...
     170              : !> \param matrix_p ...
     171              : ! **************************************************************************************************
     172         4870 :    SUBROUTINE tb_store_density_ref(tb, matrix_p)
     173              : 
     174              :       TYPE(tblite_type), POINTER                         :: tb
     175              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p
     176              : 
     177              :       INTEGER                                            :: img, ispin, nimg, nspin
     178              : 
     179         4870 :       nspin = SIZE(matrix_p, 1)
     180         4870 :       nimg = SIZE(matrix_p, 2)
     181         4870 :       IF (ASSOCIATED(tb%rho_ao_kp_ref)) THEN
     182         4842 :          IF (SIZE(tb%rho_ao_kp_ref, 1) /= nspin .OR. SIZE(tb%rho_ao_kp_ref, 2) /= nimg) &
     183            0 :             CALL dbcsr_deallocate_matrix_set(tb%rho_ao_kp_ref)
     184              :       END IF
     185         4870 :       IF (.NOT. ASSOCIATED(tb%rho_ao_kp_ref)) THEN
     186           28 :          CALL dbcsr_allocate_matrix_set(tb%rho_ao_kp_ref, nspin, nimg)
     187           56 :          DO img = 1, nimg
     188          112 :             DO ispin = 1, nspin
     189           84 :                ALLOCATE (tb%rho_ao_kp_ref(ispin, img)%matrix)
     190              :             END DO
     191              :          END DO
     192              :       END IF
     193         9740 :       DO img = 1, nimg
     194        19480 :          DO ispin = 1, nspin
     195        14610 :             CALL dbcsr_copy(tb%rho_ao_kp_ref(ispin, img)%matrix, matrix_p(ispin, img)%matrix)
     196              :          END DO
     197              :       END DO
     198              : 
     199         4870 :    END SUBROUTINE tb_store_density_ref
     200              : #endif
     201              : 
     202              : ! **************************************************************************************************
     203              : !> \brief intialize geometry objects ...
     204              : !> \param qs_env ...
     205              : !> \param tb ...
     206              : ! **************************************************************************************************
     207          152 :    SUBROUTINE tb_init_geometry(qs_env, tb)
     208              : 
     209              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     210              :       TYPE(tblite_type), POINTER                         :: tb
     211              : 
     212              : #if defined(__TBLITE)
     213              : 
     214              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tblite_init_geometry'
     215              : 
     216              :       TYPE(cell_type), POINTER                           :: cell
     217          152 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     218          152 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     219              :       INTEGER                                            :: iatom, natom
     220              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: xyz
     221              :       INTEGER                                            :: handle, ikind
     222              :       INTEGER, DIMENSION(3)                              :: periodic
     223              :       LOGICAL, DIMENSION(3)                              :: lperiod
     224              : 
     225          152 :       CALL timeset(routineN, handle)
     226              : 
     227              :       !get info from environment vaiarable
     228          152 :       CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell, qs_kind_set=qs_kind_set)
     229              : 
     230              :       !get information about particles
     231          152 :       natom = SIZE(particle_set)
     232          456 :       ALLOCATE (xyz(3, natom))
     233          152 :       CALL allocate_tblite_type(tb)
     234          456 :       ALLOCATE (tb%el_num(natom))
     235          806 :       tb%el_num = -9
     236          806 :       DO iatom = 1, natom
     237         2616 :          xyz(:, iatom) = particle_set(iatom)%r(:)
     238          654 :          CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
     239          654 :          CALL get_qs_kind(qs_kind_set(ikind), zatom=tb%el_num(iatom))
     240         1460 :          IF (tb%el_num(iatom) < 1 .OR. tb%el_num(iatom) > 85) THEN
     241            0 :             CPABORT("only elements 1-85 are supported by tblite")
     242              :          END IF
     243              :       END DO
     244              : 
     245              :       !get information about cell / lattice
     246          152 :       CALL get_cell(cell=cell, periodic=periodic)
     247          152 :       lperiod(1) = periodic(1) == 1
     248          152 :       lperiod(2) = periodic(2) == 1
     249          152 :       lperiod(3) = periodic(3) == 1
     250              : 
     251              :       !prepare for the call to the dispersion function
     252          152 :       CALL new(tb%mol, tb%el_num, xyz, lattice=cell%hmat, periodic=lperiod)
     253              : 
     254          152 :       DEALLOCATE (xyz)
     255              : 
     256          152 :       CALL timestop(handle)
     257              : 
     258              : #else
     259              :       MARK_USED(qs_env)
     260              :       MARK_USED(tb)
     261              :       CPABORT("Built without TBLITE")
     262              : #endif
     263              : 
     264          152 :    END SUBROUTINE tb_init_geometry
     265              : 
     266              : ! **************************************************************************************************
     267              : !> \brief updating coordinates...
     268              : !> \param qs_env ...
     269              : !> \param tb ...
     270              : ! **************************************************************************************************
     271         2396 :    SUBROUTINE tb_update_geometry(qs_env, tb)
     272              : 
     273              :       TYPE(qs_environment_type)                          :: qs_env
     274              :       TYPE(tblite_type)                                  :: tb
     275              : 
     276              : #if defined(__TBLITE)
     277              : 
     278              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tblite_update_geometry'
     279              : 
     280              :       TYPE(cell_type), POINTER                           :: cell
     281         2396 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     282              :       INTEGER                                            :: iatom, natom
     283         2396 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: xyz
     284              :       INTEGER                                            :: handle
     285              : 
     286         2396 :       CALL timeset(routineN, handle)
     287              : 
     288              :       !get info from environment vaiarable
     289         2396 :       NULLIFY (cell)
     290         2396 :       CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
     291              : 
     292              :       !get information about particles
     293         2396 :       natom = SIZE(particle_set)
     294         7188 :       ALLOCATE (xyz(3, natom))
     295        12920 :       DO iatom = 1, natom
     296        44492 :          xyz(:, iatom) = particle_set(iatom)%r(:)
     297              :       END DO
     298        44492 :       tb%mol%xyz(:, :) = xyz
     299        31148 :       tb%mol%lattice(:, :) = cell%hmat
     300              : 
     301         2396 :       DEALLOCATE (xyz)
     302              : 
     303         2396 :       CALL timestop(handle)
     304              : 
     305              : #else
     306              :       MARK_USED(qs_env)
     307              :       MARK_USED(tb)
     308              :       CPABORT("Built without TBLITE")
     309              : #endif
     310              : 
     311         2396 :    END SUBROUTINE tb_update_geometry
     312              : 
     313              : ! **************************************************************************************************
     314              : !> \brief initialize wavefunction ...
     315              : !> \param tb ...
     316              : !> \param dft_control ...
     317              : ! **************************************************************************************************
     318          152 :    SUBROUTINE tb_init_wf(tb, dft_control)
     319              : 
     320              :       TYPE(tblite_type), POINTER                         :: tb
     321              :       TYPE(dft_control_type), POINTER                    :: dft_control
     322              : 
     323              : #if defined(__TBLITE)
     324              : 
     325              :       INTEGER                                            :: nSpin
     326              : 
     327              :       TYPE(scf_info)                                     :: info
     328              : 
     329          152 :       nSpin = dft_control%nspins
     330            0 :       IF (nSpin /= 1 .AND. nSpin /= 2) CPABORT("tblite supports only one or two spin channels")
     331              : 
     332          152 :       tb%mol%charge = dft_control%charge
     333          152 :       tb%mol%uhf = MAX(0, dft_control%multiplicity - 1)
     334          152 :       IF (nSpin == 2) CALL tb_add_spin_polarization(tb)
     335              : 
     336          152 :       info = tb%calc%variable_info()
     337          152 :       IF (info%charge > shell_resolved) CPABORT("tblite: no support for orbital resolved charge")
     338          152 :       IF (info%dipole > atom_resolved) CPABORT("tblite: no support for shell resolved dipole moment")
     339          152 :       IF (info%quadrupole > atom_resolved) &
     340            0 :          CPABORT("tblite: no support shell resolved quadrupole moment")
     341              : 
     342          152 :       CALL new_wavefunction(tb%wfn, tb%mol%nat, tb%calc%bas%nsh, tb%calc%bas%nao, nSpin, 0.0_dp)
     343          152 :       CALL get_occupation(tb%mol, tb%calc%bas, tb%calc%h0, tb%wfn%nocc, tb%wfn%n0at, tb%wfn%n0sh)
     344          152 :       CALL tb_reset_mixer(tb)
     345              : 
     346          152 :       CALL new_potential(tb%pot, tb%mol, tb%calc%bas, tb%wfn%nspin)
     347              : 
     348              :       !allocate quantities later required
     349         1064 :       ALLOCATE (tb%e_hal(tb%mol%nat), tb%e_rep(tb%mol%nat), tb%e_disp(tb%mol%nat))
     350         1064 :       ALLOCATE (tb%e_scd(tb%mol%nat), tb%e_es(tb%mol%nat), tb%e_int(tb%mol%nat))
     351          456 :       ALLOCATE (tb%selfenergy(tb%calc%bas%nsh))
     352          456 :       IF (ALLOCATED(tb%calc%ncoord)) ALLOCATE (tb%cn(tb%mol%nat))
     353              : 
     354              : #else
     355              :       MARK_USED(tb)
     356              :       MARK_USED(dft_control)
     357              :       CPABORT("Built without TBLITE")
     358              : #endif
     359              : 
     360          152 :    END SUBROUTINE tb_init_wf
     361              : 
     362              : #if defined(__TBLITE)
     363              : ! **************************************************************************************************
     364              : !> \brief Add tblite's on-site spin-polarization interaction.
     365              : !> \param tb ...
     366              : ! **************************************************************************************************
     367           28 :    SUBROUTINE tb_add_spin_polarization(tb)
     368              : 
     369              :       TYPE(tblite_type), POINTER                         :: tb
     370              : 
     371           28 :       CLASS(container_type), ALLOCATABLE                 :: cont
     372           28 :       TYPE(spin_polarization), ALLOCATABLE               :: spin
     373           28 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: wll
     374              : 
     375           28 :       ALLOCATE (spin)
     376           28 :       CALL tb_get_spin_constants(tb, wll)
     377           28 :       CALL new_spin_polarization(spin, tb%mol, wll, tb%calc%bas%nsh_id)
     378           28 :       CALL MOVE_ALLOC(spin, cont)
     379           28 :       CALL tb%calc%push_back(cont)
     380              : 
     381           28 :    END SUBROUTINE tb_add_spin_polarization
     382              : 
     383              : ! **************************************************************************************************
     384              : !> \brief Build tblite spin constants for the current basis.
     385              : !> \param tb ...
     386              : !> \param wll ...
     387              : ! **************************************************************************************************
     388           28 :    SUBROUTINE tb_get_spin_constants(tb, wll)
     389              : 
     390              :       TYPE(tblite_type), POINTER                         :: tb
     391              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     392              :          INTENT(OUT)                                     :: wll
     393              : 
     394              :       INTEGER                                            :: il, ish, izp, jl, jsh
     395              : 
     396          140 :       ALLOCATE (wll(tb%calc%bas%nsh, tb%calc%bas%nsh, tb%mol%nid))
     397           28 :       wll = 0.0_dp
     398           64 :       DO izp = 1, tb%mol%nid
     399          136 :          DO ish = 1, tb%calc%bas%nsh_id(izp)
     400           72 :             il = tb%calc%bas%cgto(ish, izp)%ang
     401          256 :             DO jsh = 1, tb%calc%bas%nsh_id(izp)
     402          148 :                jl = tb%calc%bas%cgto(jsh, izp)%ang
     403          220 :                wll(jsh, ish, izp) = get_spin_constant(jl, il, tb%mol%num(izp))
     404              :             END DO
     405              :          END DO
     406              :       END DO
     407              : 
     408           28 :    END SUBROUTINE tb_get_spin_constants
     409              : #endif
     410              : 
     411              : ! **************************************************************************************************
     412              : !> \brief Reset tblite's internal SCC mixer for a new CP2K SCF cycle.
     413              : !> \param tb ...
     414              : ! **************************************************************************************************
     415         2332 :    SUBROUTINE tb_reset_mixer(tb)
     416              : 
     417              :       TYPE(tblite_type), POINTER                         :: tb
     418              : 
     419              : #if defined(__TBLITE)
     420              : 
     421              :       TYPE(scf_info)                                     :: info
     422              : 
     423         2332 :       info = tb%calc%variable_info()
     424         4512 :       IF (ALLOCATED(tb%mixer)) DEALLOCATE (tb%mixer)
     425              :       CALL new_cp2k_tblite_mixer(tb%mixer, tb%mixer_memory, &
     426              :                                  tb%wfn%nspin*get_mixer_dimension(tb%mol, tb%calc%bas, info), &
     427              :                                  tb%mixer_damping, tb%mixer_omega0, tb%mixer_min_weight, &
     428         2332 :                                  tb%mixer_max_weight, tb%mixer_weight_factor)
     429              : 
     430              : #else
     431              :       MARK_USED(tb)
     432              :       CPABORT("Built without TBLITE")
     433              : #endif
     434              : 
     435         2332 :    END SUBROUTINE tb_reset_mixer
     436              : 
     437              : ! **************************************************************************************************
     438              : !> \brief Configure tblite's internal SCC mixer from CP2K input.
     439              : !> \param tb ...
     440              : !> \param iterations ...
     441              : !> \param memory ...
     442              : !> \param damping ...
     443              : !> \param omega0 ...
     444              : !> \param min_weight ...
     445              : !> \param max_weight ...
     446              : !> \param weight_factor ...
     447              : !> \param solver ...
     448              : ! **************************************************************************************************
     449         2180 :    SUBROUTINE tb_configure_mixer(tb, iterations, memory, damping, omega0, min_weight, max_weight, &
     450              :                                  weight_factor, solver)
     451              : 
     452              :       TYPE(tblite_type), POINTER                         :: tb
     453              :       INTEGER, INTENT(IN)                                :: iterations, memory, solver
     454              :       REAL(KIND=dp), INTENT(IN)                          :: damping, max_weight, min_weight, omega0, &
     455              :                                                             weight_factor
     456              : 
     457              : #if defined(__TBLITE)
     458              : 
     459         2180 :       IF (iterations < 1) CPABORT("tblite SCC mixer ITERATIONS must be positive")
     460         2180 :       IF (memory < 1) CPABORT("tblite SCC mixer MEMORY must be positive")
     461         2180 :       IF (damping <= 0.0_dp) CPABORT("tblite SCC mixer damping must be positive")
     462         2180 :       IF (omega0 <= 0.0_dp) CPABORT("tblite SCC mixer OMEGA0 must be positive")
     463         2180 :       IF (min_weight <= 0.0_dp) CPABORT("tblite SCC mixer MIN_WEIGHT must be positive")
     464         2180 :       IF (max_weight <= 0.0_dp) CPABORT("tblite SCC mixer MAX_WEIGHT must be positive")
     465         2180 :       IF (max_weight < min_weight) &
     466            0 :          CPABORT("tblite SCC mixer MAX_WEIGHT must not be smaller than MIN_WEIGHT")
     467         2180 :       IF (weight_factor <= 0.0_dp) CPABORT("tblite SCC mixer WEIGHT_FACTOR must be positive")
     468         2180 :       SELECT CASE (solver)
     469              :       CASE (tblite_solver_gvd, tblite_solver_gvr)
     470              :       CASE DEFAULT
     471         2180 :          CPABORT("Unknown tblite SCC mixer SOLVER")
     472              :       END SELECT
     473              : 
     474         2180 :       tb%calc%max_iter = iterations
     475         2180 :       tb%mixer_memory = memory
     476         2180 :       tb%mixer_solver = solver
     477         2180 :       tb%mixer_damping = damping
     478         2180 :       tb%calc%mixer_damping = damping
     479         2180 :       tb%mixer_omega0 = omega0
     480         2180 :       tb%mixer_min_weight = min_weight
     481         2180 :       tb%mixer_max_weight = max_weight
     482         2180 :       tb%mixer_weight_factor = weight_factor
     483              : 
     484              : #else
     485              :       MARK_USED(tb)
     486              :       MARK_USED(iterations)
     487              :       MARK_USED(memory)
     488              :       MARK_USED(damping)
     489              :       MARK_USED(omega0)
     490              :       MARK_USED(min_weight)
     491              :       MARK_USED(max_weight)
     492              :       MARK_USED(weight_factor)
     493              :       MARK_USED(solver)
     494              :       CPABORT("Built without TBLITE")
     495              : #endif
     496              : 
     497         2180 :    END SUBROUTINE tb_configure_mixer
     498              : 
     499              : ! **************************************************************************************************
     500              : !> \brief Return whether the tblite native SCC mixer is active for this run.
     501              : !> \param dft_control ...
     502              : !> \return ...
     503              : ! **************************************************************************************************
     504        91612 :    FUNCTION tb_native_scc_mixer_active(dft_control) RESULT(use_native_mixer)
     505              : 
     506              :       TYPE(dft_control_type), POINTER                    :: dft_control
     507              :       LOGICAL                                            :: use_native_mixer
     508              : 
     509        91612 :       use_native_mixer = .FALSE.
     510        91612 :       IF (.NOT. ASSOCIATED(dft_control)) RETURN
     511        91612 :       IF (dft_control%qs_control%do_ls_scf) RETURN
     512              : 
     513        91612 :       SELECT CASE (dft_control%qs_control%xtb_control%tblite_scc_mixer)
     514              :       CASE (tblite_scc_mixer_auto)
     515              :          use_native_mixer = .TRUE.
     516              :       CASE (tblite_scc_mixer_tblite)
     517         3354 :          use_native_mixer = .TRUE.
     518              :       CASE (tblite_scc_mixer_cp2k, tblite_scc_mixer_none)
     519         3354 :          use_native_mixer = .FALSE.
     520              :       CASE DEFAULT
     521        91612 :          CPABORT("Unknown tblite SCC mixer")
     522              :       END SELECT
     523              : 
     524              :    END FUNCTION tb_native_scc_mixer_active
     525              : 
     526              : ! **************************************************************************************************
     527              : !> \brief Return the native tblite SCC mixer residual on the CP2K iter_delta scale.
     528              : !> \param dft_control ...
     529              : !> \param tb ...
     530              : !> \param eps_scf CP2K reporting scale for the native residual.
     531              : !> \return ...
     532              : ! **************************************************************************************************
     533        23376 :    FUNCTION tb_scf_mixer_error(dft_control, tb, eps_scf) RESULT(mixer_error)
     534              : 
     535              :       TYPE(dft_control_type), POINTER                    :: dft_control
     536              :       TYPE(tblite_type), POINTER                         :: tb
     537              :       REAL(KIND=dp), INTENT(IN)                          :: eps_scf
     538              :       REAL(KIND=dp)                                      :: mixer_error
     539              : 
     540              : #if defined(__TBLITE)
     541              :       REAL(KIND=dp)                                      :: raw_error
     542              : #endif
     543              : 
     544        23376 :       mixer_error = 0.0_dp
     545              : 
     546              : #if defined(__TBLITE)
     547        23376 :       IF (.NOT. ASSOCIATED(tb)) RETURN
     548        23376 :       IF (.NOT. tb_native_scc_mixer_active(dft_control)) RETURN
     549        21752 :       IF (ALLOCATED(tb%mixer)) THEN
     550        21752 :          raw_error = REAL(tb%mixer%get_error(), KIND=dp)
     551        21752 :          IF (eps_scf > 0.0_dp) THEN
     552              :             mixer_error = eps_scf*raw_error/ &
     553        21752 :                           (tblite_scc_pconv*dft_control%qs_control%xtb_control%tblite_accuracy)
     554              :          ELSE
     555              :             mixer_error = raw_error
     556              :          END IF
     557              :       END IF
     558              : #else
     559              :       MARK_USED(dft_control)
     560              :       MARK_USED(tb)
     561              :       MARK_USED(eps_scf)
     562              : #endif
     563              : 
     564              :    END FUNCTION tb_scf_mixer_error
     565              : 
     566              : ! **************************************************************************************************
     567              : !> \brief ...
     568              : !> \param tb ...
     569              : !> \param typ ...
     570              : !> \param accuracy ...
     571              : !> \param param_file ...
     572              : ! **************************************************************************************************
     573          152 :    SUBROUTINE tb_set_calculator(tb, typ, accuracy, param_file)
     574              : 
     575              :       TYPE(tblite_type), POINTER                         :: tb
     576              :       INTEGER                                            :: typ
     577              :       REAL(KIND=dp), INTENT(IN)                          :: accuracy
     578              :       CHARACTER(LEN=*), INTENT(IN)                       :: param_file
     579              : 
     580              : #if defined(__TBLITE)
     581              : 
     582          152 :       TYPE(error_type), ALLOCATABLE                      :: error
     583              : 
     584          152 :       IF (ALLOCATED(tb%param)) DEALLOCATE (tb%param)
     585          152 :       IF (LEN_TRIM(param_file) > 0) THEN
     586            0 :          ALLOCATE (tb%param)
     587            0 :          CALL tb%param%load(TRIM(param_file), error)
     588            0 :          IF (ALLOCATED(error)) CPABORT("Could not load tblite PARAM file: "//TRIM(param_file))
     589            0 :          CALL new_xtb_calculator(tb%calc, tb%mol, tb%param, error)
     590              :       ELSE
     591          152 :          SELECT CASE (typ)
     592              :          CASE default
     593            0 :             CPABORT("Unknown xtb type")
     594              :          CASE (gfn1xtb)
     595           54 :             CALL new_gfn1_calculator(tb%calc, tb%mol, error)
     596              :          CASE (gfn2xtb)
     597           82 :             CALL new_gfn2_calculator(tb%calc, tb%mol, error)
     598              :          CASE (ipea1xtb)
     599          152 :             CALL new_ipea1_calculator(tb%calc, tb%mol, error)
     600              :          END SELECT
     601              :       END IF
     602          152 :       IF (ALLOCATED(error)) CPABORT("tblite calculator setup failed")
     603              : 
     604          152 :       tb%accuracy = accuracy
     605              : 
     606              : #else
     607              :       MARK_USED(tb)
     608              :       MARK_USED(typ)
     609              :       MARK_USED(accuracy)
     610              :       MARK_USED(param_file)
     611              :       CPABORT("Built without TBLITE")
     612              : #endif
     613              : 
     614          152 :    END SUBROUTINE tb_set_calculator
     615              : 
     616              : ! **************************************************************************************************
     617              : !> \brief ...
     618              : !> \param qs_env ...
     619              : !> \param tb ...
     620              : !> \param para_env ...
     621              : ! **************************************************************************************************
     622         2396 :    SUBROUTINE tb_init_ham(qs_env, tb, para_env)
     623              : 
     624              :       TYPE(qs_environment_type)                          :: qs_env
     625              :       TYPE(tblite_type)                                  :: tb
     626              :       TYPE(mp_para_env_type)                             :: para_env
     627              : 
     628              : #if defined(__TBLITE)
     629              : 
     630         2396 :       TYPE(container_cache)                              :: hcache, rcache
     631              : 
     632        12920 :       tb%e_hal = 0.0_dp
     633        12920 :       tb%e_rep = 0.0_dp
     634        12920 :       tb%e_disp = 0.0_dp
     635        12920 :       tb%e_int = 0.0_dp
     636         2396 :       IF (ALLOCATED(tb%grad)) THEN
     637         1946 :          tb%grad = 0.0_dp
     638          114 :          CALL tb_zero_force(qs_env)
     639              :       END IF
     640        31148 :       tb%sigma = 0.0_dp
     641              : 
     642         2396 :       IF (ALLOCATED(tb%calc%halogen)) THEN
     643         1172 :          CALL tb%calc%halogen%update(tb%mol, hcache)
     644         1172 :          IF (ALLOCATED(tb%grad)) THEN
     645          884 :             tb%grad = 0.0_dp
     646              :             CALL tb%calc%halogen%get_engrad(tb%mol, hcache, tb%e_hal, &
     647           52 :             & tb%grad, tb%sigma)
     648              :             CALL tb_dump_sigma_component("after_halogen", tb%sigma, para_env)
     649           52 :             CALL tb_grad2force(qs_env, tb, para_env, 0)
     650              :          ELSE
     651         1120 :             CALL tb%calc%halogen%get_engrad(tb%mol, hcache, tb%e_hal)
     652              :          END IF
     653              :       END IF
     654              : 
     655         2396 :       IF (ALLOCATED(tb%calc%repulsion)) THEN
     656         2396 :          CALL tb%calc%repulsion%update(tb%mol, rcache)
     657         2396 :          IF (ALLOCATED(tb%grad)) THEN
     658         1946 :             tb%grad = 0.0_dp
     659              :             CALL tb%calc%repulsion%get_engrad(tb%mol, rcache, tb%e_rep, &
     660          114 :             & tb%grad, tb%sigma)
     661              :             CALL tb_dump_sigma_component("after_repulsion", tb%sigma, para_env)
     662          114 :             CALL tb_grad2force(qs_env, tb, para_env, 1)
     663              :          ELSE
     664         2282 :             CALL tb%calc%repulsion%get_engrad(tb%mol, rcache, tb%e_rep)
     665              :          END IF
     666              :       END IF
     667              : 
     668         2396 :       IF (ALLOCATED(tb%calc%dispersion)) THEN
     669         2396 :          CALL tb%calc%dispersion%update(tb%mol, tb%dcache)
     670         2396 :          IF (ALLOCATED(tb%grad)) THEN
     671         1946 :             tb%grad = 0.0_dp
     672              :             CALL tb%calc%dispersion%get_engrad(tb%mol, tb%dcache, tb%e_disp, &
     673          114 :             & tb%grad, tb%sigma)
     674              :             CALL tb_dump_sigma_component("after_dispersion_static", tb%sigma, para_env)
     675          114 :             CALL tb_grad2force(qs_env, tb, para_env, 2)
     676              :          ELSE
     677         2282 :             CALL tb%calc%dispersion%get_engrad(tb%mol, tb%dcache, tb%e_disp)
     678              :          END IF
     679              :       END IF
     680              : 
     681         2396 :       IF (ALLOCATED(tb%calc%interactions)) THEN
     682          286 :          CALL tb%calc%interactions%update(tb%mol, tb%icache)
     683              :       END IF
     684              : 
     685         2396 :       CALL new_potential(tb%pot, tb%mol, tb%calc%bas, tb%wfn%nspin)
     686         2396 :       IF (ALLOCATED(tb%calc%coulomb)) THEN
     687         2396 :          CALL tb%calc%coulomb%update(tb%mol, tb%cache)
     688              :       END IF
     689              : 
     690         2396 :       IF (ALLOCATED(tb%grad)) THEN
     691          114 :          IF (ALLOCATED(tb%calc%ncoord)) THEN
     692          114 :             CALL tb%calc%ncoord%get_cn(tb%mol, tb%cn, tb%dcndr, tb%dcndL)
     693              :          END IF
     694              :          CALL get_selfenergy(tb%calc%h0, tb%mol%id, tb%calc%bas%ish_at, &
     695          114 :          &  tb%calc%bas%nsh_id, cn=tb%cn, selfenergy=tb%selfenergy, dsedcn=tb%dsedcn)
     696              :       ELSE
     697         2282 :          IF (ALLOCATED(tb%calc%ncoord)) THEN
     698         2282 :             CALL tb%calc%ncoord%get_cn(tb%mol, tb%cn)
     699              :          END IF
     700              :          CALL get_selfenergy(tb%calc%h0, tb%mol%id, tb%calc%bas%ish_at, &
     701         2282 :          &  tb%calc%bas%nsh_id, cn=tb%cn, selfenergy=tb%selfenergy, dsedcn=tb%dsedcn)
     702              :       END IF
     703              : 
     704              : #else
     705              :       MARK_USED(qs_env)
     706              :       MARK_USED(tb)
     707              :       MARK_USED(para_env)
     708              :       CPABORT("Built without TBLITE")
     709              : #endif
     710              : 
     711         2396 :    END SUBROUTINE tb_init_ham
     712              : 
     713              : ! **************************************************************************************************
     714              : !> \brief ...
     715              : !> \param qs_env ...
     716              : !> \param tb ...
     717              : !> \param energy ...
     718              : ! **************************************************************************************************
     719        23488 :    SUBROUTINE tb_get_energy(qs_env, tb, energy)
     720              : 
     721              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     722              :       TYPE(tblite_type), POINTER                         :: tb
     723              :       TYPE(qs_energy_type), POINTER                      :: energy
     724              : 
     725              : #if defined(__TBLITE)
     726              : 
     727              :       INTEGER                                            :: iounit
     728              :       TYPE(cp_logger_type), POINTER                      :: logger
     729              :       TYPE(section_vals_type), POINTER                   :: scf_section
     730              : 
     731        23488 :       NULLIFY (scf_section, logger)
     732              : 
     733        23488 :       logger => cp_get_default_logger()
     734        23488 :       iounit = cp_logger_get_default_io_unit(logger)
     735        23488 :       scf_section => section_vals_get_subs_vals(qs_env%input, "DFT%SCF")
     736              : 
     737       143954 :       energy%repulsive = SUM(tb%e_rep)
     738       143954 :       energy%el_stat = SUM(tb%e_es)
     739       143954 :       energy%dispersion = SUM(tb%e_disp)
     740       143954 :       energy%dispersion_sc = SUM(tb%e_scd)
     741       143954 :       energy%xtb_xb_inter = SUM(tb%e_hal)
     742       143954 :       energy%xtb_xb_inter = energy%xtb_xb_inter + SUM(tb%e_int)
     743              : 
     744              :       energy%total = energy%core + energy%repulsive + energy%el_stat + energy%dispersion &
     745              :                      + energy%dispersion_sc + energy%xtb_xb_inter + energy%kTS &
     746        23488 :                      + energy%efield + energy%qmmm_el
     747              : 
     748              :       iounit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DETAILED_ENERGY", &
     749        23488 :                                     extension=".scfLog")
     750        23488 :       IF (iounit > 0) THEN
     751              :          WRITE (UNIT=iounit, FMT="(/,(T9,A,T60,F20.10))") &
     752          153 :             "Repulsive pair potential energy:               ", energy%repulsive, &
     753          153 :             "Zeroth order Hamiltonian energy:               ", energy%core, &
     754          153 :             "Electrostatic energy:                          ", energy%el_stat, &
     755          153 :             "Self-consistent dispersion energy:             ", energy%dispersion_sc, &
     756          306 :             "Non-self consistent dispersion energy:         ", energy%dispersion
     757              :          WRITE (UNIT=iounit, FMT="(T9,A,T60,F20.10)") &
     758          153 :             "Correction for halogen bonding:                ", energy%xtb_xb_inter
     759          153 :          IF (ABS(energy%efield) > 1.e-12_dp) THEN
     760              :             WRITE (UNIT=iounit, FMT="(T9,A,T60,F20.10)") &
     761            0 :                "Electric field interaction energy:             ", energy%efield
     762              :          END IF
     763          153 :          IF (qs_env%qmmm) THEN
     764              :             WRITE (UNIT=iounit, FMT="(T9,A,T60,F20.10)") &
     765            0 :                "QM/MM Electrostatic energy:                    ", energy%qmmm_el
     766              :          END IF
     767              :       END IF
     768              :       CALL cp_print_key_finished_output(iounit, logger, scf_section, &
     769        23488 :                                         "PRINT%DETAILED_ENERGY")
     770              : 
     771              : #else
     772              :       MARK_USED(qs_env)
     773              :       MARK_USED(tb)
     774              :       MARK_USED(energy)
     775              :       CPABORT("Built without TBLITE")
     776              : #endif
     777              : 
     778        23488 :    END SUBROUTINE tb_get_energy
     779              : 
     780              : ! **************************************************************************************************
     781              : !> \brief ...
     782              : !> \param tb ...
     783              : !> \param gto_basis_set ...
     784              : !> \param element_symbol ...
     785              : !> \param param ...
     786              : !> \param occ ...
     787              : ! **************************************************************************************************
     788          264 :    SUBROUTINE tb_get_basis(tb, gto_basis_set, element_symbol, param, occ)
     789              : 
     790              :       TYPE(tblite_type), POINTER                         :: tb
     791              :       TYPE(gto_basis_set_type), POINTER                  :: gto_basis_set
     792              :       CHARACTER(len=2), INTENT(IN)                       :: element_symbol
     793              :       TYPE(xtb_atom_type), POINTER                       :: param
     794              :       INTEGER, DIMENSION(5), INTENT(out)                 :: occ
     795              : 
     796              : #if defined(__TBLITE)
     797              : 
     798              :       REAL(KIND=dp)                                      :: docc
     799              :       CHARACTER(LEN=default_string_length)               :: sng
     800              :       INTEGER                                            :: ang, i_type, id_atom, ind_ao, ipgf, iSH, &
     801              :                                                             ishell, ityp, maxl, mprim, natorb, &
     802              :                                                             nset, nshell
     803              :       LOGICAL                                            :: do_ortho
     804              : 
     805          264 :       CALL allocate_gto_basis_set(gto_basis_set)
     806              : 
     807              :       !identifying element in the bas data
     808          264 :       CALL symbol_to_number(i_type, element_symbol)
     809          462 :       DO id_atom = 1, tb%mol%nat
     810          462 :          IF (i_type == tb%el_num(id_atom)) EXIT
     811              :       END DO
     812          264 :       param%z = i_type
     813          264 :       param%symbol = element_symbol
     814          264 :       param%defined = .TRUE.
     815          264 :       ityp = tb%mol%id(id_atom)
     816              : 
     817              :       !getting size information
     818          264 :       nset = tb%calc%bas%nsh_id(ityp)
     819          264 :       nshell = 1
     820          264 :       mprim = 0
     821          870 :       DO ishell = 1, nset
     822          870 :          mprim = MAX(mprim, tb%calc%bas%cgto(ishell, ityp)%nprim)
     823              :       END DO
     824          264 :       param%nshell = nset
     825          264 :       natorb = 0
     826              : 
     827              :       !write basis set information
     828          264 :       CALL integer_to_string(mprim, sng)
     829          264 :       gto_basis_set%name = element_symbol//"_STO-"//TRIM(sng)//"G"
     830          264 :       gto_basis_set%nset = nset
     831          264 :       CALL reallocate(gto_basis_set%lmax, 1, nset)
     832          264 :       CALL reallocate(gto_basis_set%lmin, 1, nset)
     833          264 :       CALL reallocate(gto_basis_set%npgf, 1, nset)
     834          264 :       CALL reallocate(gto_basis_set%nshell, 1, nset)
     835          264 :       CALL reallocate(gto_basis_set%n, 1, 1, 1, nset)
     836          264 :       CALL reallocate(gto_basis_set%l, 1, 1, 1, nset)
     837          264 :       CALL reallocate(gto_basis_set%zet, 1, mprim, 1, nset)
     838          264 :       CALL reallocate(gto_basis_set%gcc, 1, mprim, 1, 1, 1, nset)
     839              : 
     840          264 :       ind_ao = 0
     841          264 :       maxl = 0
     842          870 :       DO ishell = 1, nset
     843          606 :          ang = tb%calc%bas%cgto(ishell, ityp)%ang
     844          606 :          natorb = natorb + (2*ang + 1)
     845          606 :          param%lval(ishell) = ang
     846          606 :          maxl = MAX(ang, maxl)
     847          606 :          gto_basis_set%lmax(ishell) = ang
     848          606 :          gto_basis_set%lmin(ishell) = ang
     849          606 :          gto_basis_set%npgf(ishell) = tb%calc%bas%cgto(ishell, ityp)%nprim
     850          606 :          gto_basis_set%nshell(ishell) = nshell
     851          606 :          gto_basis_set%n(1, ishell) = ang + 1
     852          606 :          gto_basis_set%l(1, ishell) = ang
     853         3632 :          DO ipgf = 1, gto_basis_set%npgf(ishell)
     854         3026 :             gto_basis_set%gcc(ipgf, 1, ishell) = tb%calc%bas%cgto(ishell, ityp)%coeff(ipgf)
     855         3632 :             gto_basis_set%zet(ipgf, ishell) = tb%calc%bas%cgto(ishell, ityp)%alpha(ipgf)
     856              :          END DO
     857         2224 :          DO ipgf = 1, (2*ang + 1)
     858         1354 :             ind_ao = ind_ao + 1
     859         1354 :             param%lao(ind_ao) = ang
     860         1960 :             param%nao(ind_ao) = ishell
     861              :          END DO
     862              :       END DO
     863              : 
     864          264 :       do_ortho = .FALSE.
     865          264 :       CALL process_gto_basis(gto_basis_set, do_ortho, nset, maxl)
     866              : 
     867              :       !setting additional values in parameter
     868          264 :       param%rcut = get_cutoff(tb%calc%bas, tb%accuracy)
     869          264 :       param%natorb = natorb
     870          264 :       param%lmax = maxl !max angular momentum
     871              : 
     872              :       !getting occupation
     873          264 :       occ = 0
     874          264 :       docc = 0.0_dp
     875          264 :       IF (tb%calc%bas%nsh_at(id_atom) > 5) CPABORT("too many shells in tblite")
     876          870 :       DO iSh = 1, tb%calc%bas%nsh_at(id_atom)
     877          606 :          occ(iSh) = NINT(tb%calc%h0%refocc(iSh, ityp) + docc)
     878          606 :          docc = docc + tb%calc%h0%refocc(iSh, ityp) - REAL(occ(iSh))
     879          870 :          param%occupation(iSh) = occ(iSh)
     880              :       END DO
     881          264 :       IF (ABS(docc) > 0.1_dp) CPABORT("Getting occupation numbers from tblite fails")
     882         1584 :       param%zeff = SUM(occ) !effective core charge
     883              : 
     884              :       !set normalization process
     885          264 :       gto_basis_set%norm_type = 3
     886              : 
     887              : #else
     888              :       occ = 0
     889              :       MARK_USED(tb)
     890              :       MARK_USED(gto_basis_set)
     891              :       MARK_USED(element_symbol)
     892              :       MARK_USED(param)
     893              :       CPABORT("Built without TBLITE")
     894              : #endif
     895              : 
     896          264 :    END SUBROUTINE tb_get_basis
     897              : 
     898              : ! **************************************************************************************************
     899              : !> \brief ...
     900              : !> \param qs_env ...
     901              : !> \param calculate_forces ...
     902              : ! **************************************************************************************************
     903         2396 :    SUBROUTINE build_tblite_matrices(qs_env, calculate_forces)
     904              : 
     905              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     906              :       LOGICAL, INTENT(IN)                                :: calculate_forces
     907              : 
     908              : #if defined(__TBLITE)
     909              : 
     910              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_tblite_matrices'
     911              : 
     912              :       INTEGER                                            :: handle, maxder, nderivatives, nimg, img, nkind, i, &
     913              :                                                             ic, iw, iatom, jatom, ikind, jkind, iset, jset, n1, n2, icol, &
     914              :                                                             irow, ia, ib, sgfa, sgfb, ldsab, nseta, nsetb, &
     915              :                                                             natorb_a, natorb_b, sgfa0, slot
     916              :       LOGICAL                                            :: found, norml1, norml2, use_arnoldi
     917              :       REAL(KIND=dp)                                      :: dr, rr
     918              :       INTEGER, DIMENSION(3)                              :: cell
     919              :       REAL(KIND=dp)                                      :: hij, shpoly
     920              :       REAL(KIND=dp), DIMENSION(2)                        :: condnum
     921              :       REAL(KIND=dp), DIMENSION(3)                        :: rij
     922              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
     923              :       INTEGER                                            :: debug_status
     924              :       CHARACTER(LEN=32)                                  :: debug_value
     925              : #endif
     926         2396 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind
     927         2396 :       INTEGER, DIMENSION(:, :, :), POINTER                :: cell_to_index
     928         2396 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: owork
     929         2396 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: oint, sint, hint
     930         2396 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min
     931         2396 :       INTEGER, DIMENSION(:), POINTER                     :: npgfa, npgfb, nsgfa, nsgfb
     932         2396 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
     933         2396 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
     934         2396 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: rpgfa, rpgfb, zeta, zetb, scon_a, scon_b
     935         2396 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: sblock, fblock
     936              : !$    INTEGER                                            :: hash, hash1, lock_num
     937              : !$    INTEGER(KIND=int_8)                                :: iatom8
     938         2396 : !$    INTEGER(kind=omp_lock_kind), ALLOCATABLE, DIMENSION(:) :: locks
     939              :       INTEGER, PARAMETER                                :: nlock = 501
     940              : 
     941         2396 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER         :: atomic_kind_set
     942              :       TYPE(atprop_type), POINTER                            :: atprop
     943              :       TYPE(cp_blacs_env_type), POINTER                      :: blacs_env
     944              :       TYPE(cp_logger_type), POINTER                         :: logger
     945         2396 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER          :: matrix_h, matrix_s, matrix_p, matrix_w
     946              :       TYPE(dft_control_type), POINTER                       :: dft_control
     947         2396 :       TYPE(qs_force_type), DIMENSION(:), POINTER            :: force
     948              :       TYPE(gto_basis_set_type), POINTER                     :: basis_set_a, basis_set_b
     949         2396 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER     :: basis_set_list
     950              :       TYPE(kpoint_type), POINTER                            :: kpoints
     951         2396 :       TYPE(neighbor_list_set_p_type), DIMENSION(:), POINTER :: sab_orb
     952         2396 :       TYPE(neighbor_list_set_p_type), DIMENSION(:), POINTER :: sab_kp
     953              :       TYPE(mp_para_env_type), POINTER                       :: para_env
     954              :       TYPE(qs_energy_type), POINTER                         :: energy
     955              :       TYPE(qs_ks_env_type), POINTER                         :: ks_env
     956         2396 :       TYPE(qs_kind_type), DIMENSION(:), POINTER             :: qs_kind_set
     957              :       TYPE(qs_rho_type), POINTER                            :: rho
     958              :       TYPE(tblite_type), POINTER                            :: tb
     959              :       TYPE(tb_hamiltonian), POINTER                         :: h0
     960              :       TYPE(virial_type), POINTER                            :: virial
     961              : 
     962         2396 :       CALL timeset(routineN, handle)
     963              : 
     964         2396 :       NULLIFY (ks_env, energy, atomic_kind_set, qs_kind_set)
     965         2396 :       NULLIFY (matrix_h, matrix_s, atprop, dft_control)
     966         2396 :       NULLIFY (sab_orb, sab_kp, rho, tb, kpoints, cell_to_index)
     967              : 
     968              :       CALL get_qs_env(qs_env=qs_env, &
     969              :                       ks_env=ks_env, para_env=para_env, &
     970              :                       energy=energy, &
     971              :                       atomic_kind_set=atomic_kind_set, &
     972              :                       qs_kind_set=qs_kind_set, &
     973              :                       matrix_h_kp=matrix_h, &
     974              :                       matrix_s_kp=matrix_s, &
     975              :                       atprop=atprop, &
     976              :                       dft_control=dft_control, &
     977              :                       sab_orb=sab_orb, &
     978              :                       sab_kp=sab_kp, &
     979         2396 :                       rho=rho, tb_tblite=tb)
     980         2396 :       h0 => tb%calc%h0
     981              : 
     982              :       !update geometry (required for debug / geometry optimization)
     983         2396 :       CALL tb_update_geometry(qs_env, tb)
     984              : 
     985         2396 :       nkind = SIZE(atomic_kind_set)
     986         2396 :       nderivatives = 0
     987         2396 :       IF (calculate_forces) THEN
     988          114 :          nderivatives = 1
     989          114 :          IF (ALLOCATED(tb%grad)) DEALLOCATE (tb%grad)
     990          342 :          ALLOCATE (tb%grad(3, tb%mol%nat))
     991          114 :          IF (ALLOCATED(tb%dsedcn)) DEALLOCATE (tb%dsedcn)
     992          342 :          ALLOCATE (tb%dsedcn(tb%calc%bas%nsh))
     993          114 :          IF (ALLOCATED(tb%calc%ncoord)) THEN
     994          114 :             IF (ALLOCATED(tb%dcndr)) DEALLOCATE (tb%dcndr)
     995          456 :             ALLOCATE (tb%dcndr(3, tb%mol%nat, tb%mol%nat))
     996          114 :             IF (ALLOCATED(tb%dcndL)) DEALLOCATE (tb%dcndL)
     997          342 :             ALLOCATE (tb%dcndL(3, 3, tb%mol%nat))
     998              :          END IF
     999              :       ELSE
    1000         2282 :          IF (ALLOCATED(tb%grad)) DEALLOCATE (tb%grad)
    1001         2282 :          IF (ALLOCATED(tb%dcndr)) DEALLOCATE (tb%dcndr)
    1002         2282 :          IF (ALLOCATED(tb%dcndL)) DEALLOCATE (tb%dcndL)
    1003              :       END IF
    1004         2396 :       maxder = ncoset(nderivatives)
    1005         2396 :       nimg = dft_control%nimages
    1006         2396 :       IF (nimg > 1) THEN
    1007         1046 :          IF (.NOT. ASSOCIATED(sab_kp)) CPABORT("Missing k-point neighbor list for tblite")
    1008         1046 :          sab_orb => sab_kp
    1009         1046 :          CALL get_ks_env(ks_env=ks_env, kpoints=kpoints)
    1010         1046 :          CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
    1011              :       END IF
    1012              : 
    1013              :       !intialise hamiltonian
    1014         2396 :       CALL tb_init_ham(qs_env, tb, para_env)
    1015              : 
    1016              :       ! get density matrtix
    1017         2396 :       CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
    1018              : 
    1019              :       ! set up matrices for force calculations
    1020         2396 :       IF (calculate_forces) THEN
    1021          114 :          NULLIFY (force, matrix_w, virial)
    1022              :          CALL get_qs_env(qs_env=qs_env, &
    1023              :                          matrix_w_kp=matrix_w, &
    1024          114 :                          virial=virial, force=force)
    1025              : 
    1026          114 :          IF (SIZE(matrix_p, 1) == 2) THEN
    1027           36 :             DO img = 1, nimg
    1028              :                CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, &
    1029           18 :                               alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
    1030              :                CALL dbcsr_add(matrix_w(1, img)%matrix, matrix_w(2, img)%matrix, &
    1031           36 :                               alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
    1032              :             END DO
    1033              :          END IF
    1034          176 :          tb%use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
    1035              :       END IF
    1036              : 
    1037         2396 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
    1038              : 
    1039              :       ! set up basis set lists
    1040        11036 :       ALLOCATE (basis_set_list(nkind))
    1041         2396 :       CALL basis_set_list_setup(basis_set_list, "ORB", qs_kind_set)
    1042              : 
    1043              :       ! allocate overlap matrix
    1044         2396 :       CALL dbcsr_allocate_matrix_set(matrix_s, maxder, nimg)
    1045              :       CALL create_sab_matrix(ks_env, matrix_s, "OVERLAP MATRIX", basis_set_list, basis_set_list, &
    1046         2396 :                              sab_orb, .TRUE.)
    1047         2396 :       CALL set_ks_env(ks_env, matrix_s_kp=matrix_s)
    1048              : 
    1049              :       ! initialize H matrix
    1050         2396 :       CALL dbcsr_allocate_matrix_set(matrix_h, 1, nimg)
    1051        49394 :       DO img = 1, nimg
    1052        46998 :          ALLOCATE (matrix_h(1, img)%matrix)
    1053              :          CALL dbcsr_create(matrix_h(1, img)%matrix, template=matrix_s(1, img)%matrix, &
    1054        46998 :                            name="HAMILTONIAN MATRIX")
    1055        49394 :          CALL cp_dbcsr_alloc_block_from_nbl(matrix_h(1, img)%matrix, sab_orb)
    1056              :       END DO
    1057         2396 :       CALL set_ks_env(ks_env, matrix_h_kp=matrix_h)
    1058         2396 :       ldsab = get_memory_usage(qs_kind_set, "ORB", "ORB")
    1059              : 
    1060              :       ! loop over all atom pairs with a non-zero overlap (sab_orb)
    1061              : !$OMP PARALLEL DEFAULT(NONE) &
    1062              : !$OMP SHARED (calculate_forces, basis_set_list, sab_orb, matrix_s, matrix_h, &
    1063              : !$OMP        cell_to_index, nimg, atom_of_kind, qs_kind_set, tb, h0, ldsab, maxder, locks, &
    1064              : !$OMP        ncoset) &
    1065              : !$OMP PRIVATE (slot, hash, hash1, iatom8, lock_num, ikind, jkind, iatom, jatom, cell, rij, ic, irow, &
    1066              : !$OMP        icol, dr, n1, n2, ia, ib, i, iset, jset, sgfa, sgfb, nseta, nsetb, natorb_a, &
    1067              : !$OMP        natorb_b, sgfa0, found, zeta, first_sgfa, la_max, la_min, npgfa, nsgfa, rpgfa, set_radius_a, &
    1068              : !$OMP        scon_a, first_sgfb, lb_max, lb_min, npgfb, nsgfb, rpgfb, set_radius_b, scon_b, zetb, rr, hij, shpoly, &
    1069         2396 : !$OMP        owork, oint, sint, hint, basis_set_a, basis_set_b, sblock, fblock)
    1070              : 
    1071              : !$OMP SINGLE
    1072              : !$    ALLOCATE (locks(nlock))
    1073              : !$OMP END SINGLE
    1074              : !$OMP DO
    1075              : !$    DO lock_num = 1, nlock
    1076              : !$       CALL omp_init_lock(locks(lock_num))
    1077              : !$    END DO
    1078              : !$OMP END DO
    1079              : 
    1080              :       ALLOCATE (oint(ldsab, ldsab, maxder), owork(ldsab, ldsab))
    1081              : 
    1082              : !$OMP DO SCHEDULE(GUIDED)
    1083              :       DO slot = 1, sab_orb(1)%nl_size
    1084              : 
    1085              :          ikind = sab_orb(1)%nlist_task(slot)%ikind
    1086              :          jkind = sab_orb(1)%nlist_task(slot)%jkind
    1087              :          iatom = sab_orb(1)%nlist_task(slot)%iatom
    1088              :          jatom = sab_orb(1)%nlist_task(slot)%jatom
    1089              :          cell(:) = sab_orb(1)%nlist_task(slot)%cell(:)
    1090              :          rij(1:3) = sab_orb(1)%nlist_task(slot)%r(1:3)
    1091              : 
    1092              :          ! canonicalize pair ordering as in current serial flow
    1093              :          icol = MAX(iatom, jatom)
    1094              :          irow = MIN(iatom, jatom)
    1095              :          IF (iatom < jatom) THEN
    1096              :             rij = -rij
    1097              :             i = ikind
    1098              :             ikind = jkind
    1099              :             jkind = i
    1100              :          END IF
    1101              : 
    1102              :          dr = NORM2(rij(:))
    1103              : 
    1104              :          IF (nimg == 1) THEN
    1105              :             ic = 1
    1106              :          ELSE
    1107              :             ic = cell_to_index(cell(1), cell(2), cell(3))
    1108              :             CPASSERT(ic > 0)
    1109              :          END IF
    1110              : 
    1111              :          NULLIFY (sblock)
    1112              :          CALL dbcsr_get_block_p(matrix=matrix_s(1, ic)%matrix, &
    1113              :                                 row=irow, col=icol, BLOCK=sblock, found=found)
    1114              :          CPASSERT(found)
    1115              :          NULLIFY (fblock)
    1116              :          CALL dbcsr_get_block_p(matrix=matrix_h(1, ic)%matrix, &
    1117              :                                 row=irow, col=icol, BLOCK=fblock, found=found)
    1118              :          CPASSERT(found)
    1119              : 
    1120              :          ! --------- Overlap
    1121              :          !get basis information
    1122              :          basis_set_a => basis_set_list(ikind)%gto_basis_set
    1123              :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
    1124              :          basis_set_b => basis_set_list(jkind)%gto_basis_set
    1125              :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
    1126              :          ! basis a
    1127              :          first_sgfa => basis_set_a%first_sgf
    1128              :          la_max => basis_set_a%lmax
    1129              :          la_min => basis_set_a%lmin
    1130              :          npgfa => basis_set_a%npgf
    1131              :          nseta = basis_set_a%nset
    1132              :          nsgfa => basis_set_a%nsgf_set
    1133              :          rpgfa => basis_set_a%pgf_radius
    1134              :          set_radius_a => basis_set_a%set_radius
    1135              :          scon_a => basis_set_a%scon
    1136              :          zeta => basis_set_a%zet
    1137              :          ! basis b
    1138              :          first_sgfb => basis_set_b%first_sgf
    1139              :          lb_max => basis_set_b%lmax
    1140              :          lb_min => basis_set_b%lmin
    1141              :          npgfb => basis_set_b%npgf
    1142              :          nsetb = basis_set_b%nset
    1143              :          nsgfb => basis_set_b%nsgf_set
    1144              :          rpgfb => basis_set_b%pgf_radius
    1145              :          set_radius_b => basis_set_b%set_radius
    1146              :          scon_b => basis_set_b%scon
    1147              :          zetb => basis_set_b%zet
    1148              : 
    1149              :          natorb_a = 0
    1150              :          DO iset = 1, nseta
    1151              :             natorb_a = natorb_a + (2*basis_set_a%l(1, iset) + 1)
    1152              :          END DO
    1153              :          natorb_b = 0
    1154              :          DO iset = 1, nsetb
    1155              :             natorb_b = natorb_b + (2*basis_set_b%l(1, iset) + 1)
    1156              :          END DO
    1157              :          ALLOCATE (sint(natorb_a, natorb_b, maxder))
    1158              :          sint = 0.0_dp
    1159              :          ALLOCATE (hint(natorb_a, natorb_b, maxder))
    1160              :          hint = 0.0_dp
    1161              : 
    1162              :          !----------------- overlap integrals
    1163              :          DO iset = 1, nseta
    1164              :             n1 = npgfa(iset)*(ncoset(la_max(iset)) - ncoset(la_min(iset) - 1))
    1165              :             sgfa = first_sgfa(1, iset)
    1166              :             DO jset = 1, nsetb
    1167              :                IF (set_radius_a(iset) + set_radius_b(jset) < dr) CYCLE
    1168              :                n2 = npgfb(jset)*(ncoset(lb_max(jset)) - ncoset(lb_min(jset) - 1))
    1169              :                sgfb = first_sgfb(1, jset)
    1170              :                IF (calculate_forces) THEN
    1171              :                   CALL overlap_ab(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
    1172              :                                   lb_max(jset), lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
    1173              :                                   rij, sab=oint(:, :, 1), dab=oint(:, :, 2:4))
    1174              :                ELSE
    1175              :                   CALL overlap_ab(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
    1176              :                                   lb_max(jset), lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
    1177              :                                   rij, sab=oint(:, :, 1))
    1178              :                END IF
    1179              :                ! Contraction
    1180              :                CALL contraction(oint(:, :, 1), owork, ca=scon_a(:, sgfa:), na=n1, ma=nsgfa(iset), &
    1181              :                                 cb=scon_b(:, sgfb:), nb=n2, mb=nsgfb(jset), fscale=1.0_dp, trans=.FALSE.)
    1182              :                CALL block_add("IN", owork, nsgfa(iset), nsgfb(jset), sint(:, :, 1), sgfa, sgfb, trans=.FALSE.)
    1183              :                IF (calculate_forces) THEN
    1184              :                   DO i = 2, 4
    1185              :                      CALL contraction(oint(:, :, i), owork, ca=scon_a(:, sgfa:), na=n1, ma=nsgfa(iset), &
    1186              :                                       cb=scon_b(:, sgfb:), nb=n2, mb=nsgfb(jset), fscale=1.0_dp, trans=.FALSE.)
    1187              :                      CALL block_add("IN", owork, nsgfa(iset), nsgfb(jset), sint(:, :, i), sgfa, sgfb, trans=.FALSE.)
    1188              :                   END DO
    1189              :                END IF
    1190              :             END DO
    1191              :          END DO
    1192              : 
    1193              : !$       iatom8 = INT(iatom - 1, int_8)*INT(SIZE(atom_of_kind), int_8) + INT(jatom, int_8)
    1194              : !$       hash1 = INT(MOD(iatom8, INT(nlock, int_8)) + 1)
    1195              :          ! update S matrix
    1196              : !$       hash = hash1
    1197              : !$       CALL omp_set_lock(locks(hash))
    1198              :          IF (icol <= irow) THEN
    1199              :             sblock(:, :) = sblock(:, :) + sint(:, :, 1)
    1200              :          ELSE
    1201              :             sblock(:, :) = sblock(:, :) + TRANSPOSE(sint(:, :, 1))
    1202              :          END IF
    1203              : !$       CALL omp_unset_lock(locks(hash))
    1204              : 
    1205              :          ! --------- Hamiltonian
    1206              :          IF (icol == irow .AND. dr < same_atom) THEN
    1207              :             !get diagonal F matrix from selfenergy
    1208              :             n1 = tb%calc%bas%ish_at(icol)
    1209              :             DO iset = 1, nseta
    1210              :                sgfa = first_sgfa(1, iset)
    1211              :                hij = tb%selfenergy(n1 + iset)
    1212              :                DO ia = sgfa, sgfa + nsgfa(iset) - 1
    1213              :                   hint(ia, ia, 1) = hij
    1214              :                END DO
    1215              :             END DO
    1216              :          ELSE
    1217              :             !get off-diagonal F matrix
    1218              :             rr = SQRT(dr/(h0%rad(jkind) + h0%rad(ikind)))
    1219              :             n1 = tb%calc%bas%ish_at(icol)
    1220              :             sgfa0 = 1
    1221              :             DO iset = 1, nseta
    1222              :                sgfa = first_sgfa(1, iset)
    1223              :                sgfa0 = sgfa0 + tb%calc%bas%cgto(iset, tb%mol%id(icol))%nprim
    1224              :                n2 = tb%calc%bas%ish_at(irow)
    1225              :                DO jset = 1, nsetb
    1226              :                   sgfb = first_sgfb(1, jset)
    1227              :                   shpoly = (1.0_dp + h0%shpoly(iset, ikind)*rr) &
    1228              :                            *(1.0_dp + h0%shpoly(jset, jkind)*rr)
    1229              :                   hij = 0.5_dp*(tb%selfenergy(n1 + iset) + tb%selfenergy(n2 + jset)) &
    1230              :                         *h0%hscale(iset, jset, ikind, jkind)*shpoly
    1231              :                   DO ia = sgfa, sgfa + nsgfa(iset) - 1
    1232              :                      DO ib = sgfb, sgfb + nsgfb(jset) - 1
    1233              :                         hint(ia, ib, 1) = hij*sint(ia, ib, 1)
    1234              :                      END DO
    1235              :                   END DO
    1236              :                END DO
    1237              :             END DO
    1238              :          END IF
    1239              : 
    1240              :          ! update F matrix
    1241              : !$       CALL omp_set_lock(locks(hash))
    1242              :          IF (icol <= irow) THEN
    1243              :             fblock(:, :) = fblock(:, :) + hint(:, :, 1)
    1244              :          ELSE
    1245              :             fblock(:, :) = fblock(:, :) + TRANSPOSE(hint(:, :, 1))
    1246              :          END IF
    1247              : !$       CALL omp_unset_lock(locks(hash))
    1248              : 
    1249              :          DEALLOCATE (sint, hint)
    1250              : 
    1251              :       END DO
    1252              : !$OMP END DO
    1253              :       DEALLOCATE (oint, owork)
    1254              : !$OMP DO
    1255              : !$    DO lock_num = 1, nlock
    1256              : !$       CALL omp_destroy_lock(locks(lock_num))
    1257              : !$    END DO
    1258              : !$OMP END DO
    1259              : !$OMP SINGLE
    1260              : !$    DEALLOCATE (locks)
    1261              : !$OMP END SINGLE NOWAIT
    1262              : !$OMP END PARALLEL
    1263              : 
    1264        49394 :       DO img = 1, nimg
    1265       100968 :          DO i = 1, SIZE(matrix_s, 1)
    1266       100968 :             CALL dbcsr_finalize(matrix_s(i, img)%matrix)
    1267              :          END DO
    1268        96392 :          DO i = 1, SIZE(matrix_h, 1)
    1269        93996 :             CALL dbcsr_finalize(matrix_h(i, img)%matrix)
    1270              :          END DO
    1271              :       END DO
    1272              : 
    1273              :       !compute multipole moments for gfn2
    1274         2396 :       IF (dft_control%qs_control%xtb_control%tblite_method == gfn2xtb) &
    1275         1224 :          CALL tb_get_multipole(qs_env, tb)
    1276              : 
    1277              :       ! output overlap information
    1278         2396 :       NULLIFY (logger)
    1279         2396 :       logger => cp_get_default_logger()
    1280         2396 :       IF (.NOT. calculate_forces) THEN
    1281         2282 :          IF (cp_print_key_should_output(logger%iter_info, qs_env%input, &
    1282              :                                         "DFT%PRINT%OVERLAP_CONDITION") /= 0) THEN
    1283              :             iw = cp_print_key_unit_nr(logger, qs_env%input, "DFT%PRINT%OVERLAP_CONDITION", &
    1284            2 :                                       extension=".Log")
    1285            2 :             CALL section_vals_val_get(qs_env%input, "DFT%PRINT%OVERLAP_CONDITION%1-NORM", l_val=norml1)
    1286            2 :             CALL section_vals_val_get(qs_env%input, "DFT%PRINT%OVERLAP_CONDITION%DIAGONALIZATION", l_val=norml2)
    1287            2 :             CALL section_vals_val_get(qs_env%input, "DFT%PRINT%OVERLAP_CONDITION%ARNOLDI", l_val=use_arnoldi)
    1288            2 :             CALL get_qs_env(qs_env=qs_env, blacs_env=blacs_env)
    1289            2 :             CALL overlap_condnum(matrix_s, condnum, iw, norml1, norml2, use_arnoldi, blacs_env)
    1290              :          END IF
    1291              :       END IF
    1292              : 
    1293         2396 :       DEALLOCATE (basis_set_list)
    1294              : 
    1295         2396 :       CALL timestop(handle)
    1296              : 
    1297              : #else
    1298              :       MARK_USED(qs_env)
    1299              :       MARK_USED(calculate_forces)
    1300              :       CPABORT("Built without TBLITE")
    1301              : #endif
    1302              : 
    1303         4792 :    END SUBROUTINE build_tblite_matrices
    1304              : 
    1305              : ! **************************************************************************************************
    1306              : !> \brief ...
    1307              : !> \param qs_env ...
    1308              : !> \param dft_control ...
    1309              : !> \param tb ...
    1310              : !> \param calculate_forces ...
    1311              : !> \param use_rho ...
    1312              : ! **************************************************************************************************
    1313        49086 :    SUBROUTINE tb_update_charges(qs_env, dft_control, tb, calculate_forces, use_rho)
    1314              : 
    1315              :       TYPE(qs_environment_type), POINTER                                 :: qs_env
    1316              :       TYPE(dft_control_type), POINTER                                    :: dft_control
    1317              :       TYPE(tblite_type), POINTER                                         :: tb
    1318              :       LOGICAL, INTENT(IN)                                                :: calculate_forces
    1319              :       LOGICAL, INTENT(IN)                                                :: use_rho
    1320              : 
    1321              : #if defined(__TBLITE)
    1322              : 
    1323              :       INTEGER                                            :: iatom, ikind, is, ns, atom_a, ii, im
    1324              :       INTEGER                                            :: ispin, nspin
    1325              :       INTEGER                                            :: nimg, nkind, nsgf, natorb, na, n_mix_cols, mix_offset
    1326              :       INTEGER                                            :: n_atom, max_orb, max_shell
    1327              :       INTEGER                                            :: raw_state_status, raw_state_unit
    1328              :       LOGICAL                                            :: discard_mixed_output, do_combined_mixing, do_dipole, do_quadrupole, &
    1329              :                                                             native_sign_mixing, skip_charge_mixing, &
    1330              :                                                             reuse_native_input, skip_scf_dispersion, skip_scf_dispersion_energy, &
    1331              :                                                             seed_native_from_rho, &
    1332              :                                                             skip_scf_dispersion_gradient, skip_scf_dispersion_potential, &
    1333              :                                                             use_native_mixer, use_no_mixer
    1334              :       REAL(KIND=dp)                                      :: native_seed_charge, norm, moment_alpha, &
    1335              :                                                             new_charge, pao
    1336              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    1337              :       INTEGER                                            :: debug_status
    1338              :       CHARACTER(LEN=32)                                  :: debug_value
    1339              : #endif
    1340              :       CHARACTER(LEN=default_path_length)                 :: raw_state_file
    1341              :       INTEGER, DIMENSION(5)                              :: occ
    1342              :       INTEGER, DIMENSION(25)                             :: lao
    1343              :       INTEGER, DIMENSION(25)                             :: nao
    1344        49086 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: ch_atom, ch_shell, ch_ref, ch_orb, mix_vars
    1345        49086 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: aocg, ao_dip, ao_quad
    1346        49086 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: aocg_spin, ao_dip_spin, ao_quad_spin, &
    1347        49086 :                                                             ch_orb_spin, ch_shell_spin
    1348              : 
    1349        49086 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1350        49086 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_s, matrix_p
    1351        49086 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: p_matrix
    1352              :       TYPE(dbcsr_type), POINTER                          :: s_matrix
    1353        49086 :       TYPE(error_type), ALLOCATABLE                      :: error
    1354              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1355        49086 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1356        49086 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1357              :       TYPE(qs_rho_type), POINTER                         :: rho
    1358              :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
    1359              :       TYPE(scf_control_type), POINTER                    :: scf_control
    1360              :       TYPE(xtb_atom_type), POINTER                       :: xtb_kind
    1361              : 
    1362              :       ! compute mulliken charges required for charge update
    1363        49086 :       NULLIFY (particle_set, qs_kind_set, atomic_kind_set, scf_control)
    1364              :       CALL get_qs_env(qs_env=qs_env, scf_env=scf_env, particle_set=particle_set, qs_kind_set=qs_kind_set, &
    1365              :                       atomic_kind_set=atomic_kind_set, matrix_s_kp=matrix_s, rho=rho, para_env=para_env, &
    1366        49086 :                       scf_control=scf_control)
    1367              : 
    1368              :       ! also compute multipoles needed by GFN2
    1369        49086 :       do_dipole = .FALSE.
    1370        49086 :       do_quadrupole = .FALSE.
    1371        49086 :       skip_scf_dispersion = .FALSE.
    1372              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    1373              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DEBUG_SKIP_SCF_DISPERSION", debug_value, STATUS=debug_status)
    1374              :       IF (debug_status == 0) READ (debug_value, *, IOSTAT=debug_status) skip_scf_dispersion
    1375              : #endif
    1376        49086 :       skip_scf_dispersion_energy = skip_scf_dispersion
    1377        49086 :       skip_scf_dispersion_gradient = skip_scf_dispersion
    1378        49086 :       skip_scf_dispersion_potential = skip_scf_dispersion
    1379              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    1380              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DEBUG_SKIP_SCF_DISPERSION_ENERGY", debug_value, STATUS=debug_status)
    1381              :       IF (debug_status == 0) READ (debug_value, *, IOSTAT=debug_status) skip_scf_dispersion_energy
    1382              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DEBUG_SKIP_SCF_DISPERSION_GRADIENT", debug_value, STATUS=debug_status)
    1383              :       IF (debug_status == 0) READ (debug_value, *, IOSTAT=debug_status) skip_scf_dispersion_gradient
    1384              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DEBUG_SKIP_SCF_DISPERSION_POTENTIAL", debug_value, STATUS=debug_status)
    1385              :       IF (debug_status == 0) READ (debug_value, *, IOSTAT=debug_status) skip_scf_dispersion_potential
    1386              : #endif
    1387        49086 :       IF (dft_control%qs_control%do_ls_scf .OR. scf_control%use_ot) THEN
    1388              :          use_native_mixer = .FALSE.
    1389              :          use_no_mixer = .TRUE.
    1390              :       ELSE
    1391        91276 :          SELECT CASE (dft_control%qs_control%xtb_control%tblite_scc_mixer)
    1392              :          CASE (tblite_scc_mixer_auto)
    1393        42590 :             use_native_mixer = tb_native_scc_mixer_active(dft_control)
    1394        42590 :             use_no_mixer = .FALSE.
    1395              :          CASE (tblite_scc_mixer_tblite)
    1396              :             use_native_mixer = .TRUE.
    1397              :             use_no_mixer = .FALSE.
    1398              :          CASE (tblite_scc_mixer_cp2k)
    1399              :             use_native_mixer = .FALSE.
    1400              :             use_no_mixer = .FALSE.
    1401              :          CASE (tblite_scc_mixer_none)
    1402              :             use_native_mixer = .FALSE.
    1403            0 :             use_no_mixer = .TRUE.
    1404              :          CASE DEFAULT
    1405        48686 :             CPABORT("Unknown tblite SCC mixer")
    1406              :          END SELECT
    1407              :       END IF
    1408        45334 :       IF (use_native_mixer .AND. use_rho .AND. (.NOT. calculate_forces) .AND. &
    1409              :           scf_env%iter_count > dft_control%qs_control%xtb_control%tblite_mixer_iterations) THEN
    1410            0 :          CPABORT("tblite SCC mixer exceeded TBLITE_MIXER/ITERATIONS")
    1411              :       END IF
    1412        45622 :       IF (use_native_mixer .AND. use_rho .AND. (.NOT. calculate_forces) .AND. &
    1413              :           scf_env%iter_count == 1) THEN
    1414              :          CALL tb_configure_mixer(tb, dft_control%qs_control%xtb_control%tblite_mixer_iterations, &
    1415              :                                  dft_control%qs_control%xtb_control%tblite_mixer_memory, &
    1416              :                                  dft_control%qs_control%xtb_control%tblite_mixer_damping, &
    1417              :                                  dft_control%qs_control%xtb_control%tblite_mixer_omega0, &
    1418              :                                  dft_control%qs_control%xtb_control%tblite_mixer_min_weight, &
    1419              :                                  dft_control%qs_control%xtb_control%tblite_mixer_max_weight, &
    1420              :                                  dft_control%qs_control%xtb_control%tblite_mixer_weight_factor, &
    1421         2180 :                                  dft_control%qs_control%xtb_control%tblite_mixer_solver)
    1422         2180 :          CALL tb_reset_mixer(tb)
    1423              :       END IF
    1424        49086 :       nspin = dft_control%nspins
    1425        49086 :       IF (nspin /= tb%wfn%nspin) CPABORT("CP2K/tblite spin channel mismatch")
    1426              : 
    1427        49086 :       NULLIFY (matrix_p)
    1428        49086 :       IF (use_rho) THEN
    1429        25836 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
    1430        23250 :       ELSEIF (calculate_forces .AND. nspin > 1) THEN
    1431           18 :          IF (.NOT. ASSOCIATED(tb%rho_ao_kp_ref)) &
    1432            0 :             CPABORT("Missing converged tblite density for UKS/LSD forces")
    1433           18 :          matrix_p => tb%rho_ao_kp_ref
    1434              :       ELSE
    1435        23232 :          matrix_p => scf_env%p_mix_new
    1436              :       END IF
    1437        49086 :       IF (nspin > 1 .AND. (.NOT. calculate_forces)) CALL tb_store_density_ref(tb, matrix_p)
    1438        49086 :       IF (ASSOCIATED(tb%dipbra)) do_dipole = .TRUE.
    1439        49086 :       IF (ASSOCIATED(tb%quadbra)) do_quadrupole = .TRUE.
    1440        49086 :       reuse_native_input = .FALSE.
    1441        49086 :       IF (use_native_mixer .AND. scf_env%iter_count == 1) THEN
    1442         7284 :          reuse_native_input = ANY(ABS(tb%wfn%qsh) > 1.0E-14_dp)
    1443         4344 :          IF (do_dipole) reuse_native_input = reuse_native_input .OR. &
    1444         4442 :                                              ANY(ABS(tb%wfn%dpat) > 1.0E-14_dp)
    1445         4344 :          IF (do_quadrupole) reuse_native_input = reuse_native_input .OR. &
    1446         6148 :                                                  ANY(ABS(tb%wfn%qpat) > 1.0E-14_dp)
    1447              :       END IF
    1448        49086 :       n_atom = SIZE(particle_set)
    1449        49086 :       nkind = SIZE(atomic_kind_set)
    1450        49086 :       nimg = dft_control%nimages
    1451        49086 :       CALL get_qs_kind_set(qs_kind_set, maxsgf=nsgf)
    1452       196344 :       ALLOCATE (aocg(nsgf, n_atom))
    1453       245430 :       ALLOCATE (aocg_spin(nsgf, n_atom, nspin))
    1454        49086 :       aocg = 0.0_dp
    1455        49086 :       aocg_spin = 0.0_dp
    1456        49086 :       IF (do_dipole) THEN
    1457       110370 :          ALLOCATE (ao_dip(n_atom, dip_n))
    1458       147160 :          ALLOCATE (ao_dip_spin(n_atom, dip_n, nspin))
    1459        36790 :          ao_dip_spin = 0.0_dp
    1460              :       END IF
    1461        49086 :       IF (do_quadrupole) THEN
    1462       110370 :          ALLOCATE (ao_quad(n_atom, quad_n))
    1463       147160 :          ALLOCATE (ao_quad_spin(n_atom, quad_n, nspin))
    1464        36790 :          ao_quad_spin = 0.0_dp
    1465              :       END IF
    1466        49086 :       max_orb = 0
    1467        49086 :       max_shell = 0
    1468       120080 :       DO ikind = 1, nkind
    1469        70994 :          CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_kind)
    1470        70994 :          CALL get_xtb_atom_param(xtb_kind, natorb=natorb)
    1471       120080 :          max_orb = MAX(max_orb, natorb)
    1472              :       END DO
    1473       299552 :       DO is = 1, n_atom
    1474       299552 :          max_shell = MAX(max_shell, tb%calc%bas%nsh_at(is))
    1475              :       END DO
    1476       343602 :       ALLOCATE (ch_atom(n_atom, nspin), ch_shell(n_atom, max_shell))
    1477       294516 :       ALLOCATE (ch_orb(max_orb, n_atom), ch_ref(max_orb, n_atom))
    1478       441774 :       ALLOCATE (ch_orb_spin(max_orb, n_atom, nspin), ch_shell_spin(n_atom, max_shell, nspin))
    1479        49086 :       ch_atom = 0.0_dp
    1480        49086 :       ch_shell = 0.0_dp
    1481        49086 :       ch_orb = 0.0_dp
    1482        49086 :       ch_orb_spin = 0.0_dp
    1483        49086 :       ch_shell_spin = 0.0_dp
    1484        49086 :       ch_ref = 0.0_dp
    1485        49086 :       IF (nimg > 1) THEN
    1486        37240 :          DO ispin = 1, nspin
    1487        18620 :             CALL tb_ao_charges_kp_spin(matrix_p, matrix_s, aocg_spin(:, :, ispin), ispin, para_env)
    1488        18620 :             IF (do_dipole) THEN
    1489        57824 :                DO im = 1, dip_n
    1490              :                   CALL tb_contract_dens_kp_spin(matrix_p, tb%dipbra, tb%dipket, im, dip_n, &
    1491        57824 :                                                 ao_dip_spin(:, im, ispin), ispin, para_env)
    1492              :                END DO
    1493              :             END IF
    1494        37240 :             IF (do_quadrupole) THEN
    1495       101192 :                DO im = 1, quad_n
    1496              :                   CALL tb_contract_dens_kp_spin(matrix_p, tb%quadbra, tb%quadket, im, quad_n, &
    1497       101192 :                                                 ao_quad_spin(:, im, ispin), ispin, para_env)
    1498              :                END DO
    1499              :             END IF
    1500              :          END DO
    1501              :       ELSE
    1502              :          NULLIFY (p_matrix, s_matrix)
    1503        30466 :          p_matrix => matrix_p(:, 1)
    1504        30466 :          s_matrix => matrix_s(1, 1)%matrix
    1505        65820 :          DO ispin = 1, nspin
    1506        35354 :             CALL tb_ao_charges_matrix(matrix_p(ispin, 1)%matrix, s_matrix, aocg_spin(:, :, ispin), para_env)
    1507        35354 :             IF (do_dipole) THEN
    1508       104768 :                DO im = 1, dip_n
    1509              :                   CALL tb_contract_dens_matrix(matrix_p(ispin, 1)%matrix, tb%dipbra(im)%matrix, &
    1510       104768 :                                                tb%dipket(im)%matrix, ao_dip_spin(:, im, ispin), para_env)
    1511              :                END DO
    1512              :             END IF
    1513        65820 :             IF (do_quadrupole) THEN
    1514       183344 :                DO im = 1, quad_n
    1515              :                   CALL tb_contract_dens_matrix(matrix_p(ispin, 1)%matrix, tb%quadbra(im)%matrix, &
    1516       183344 :                                                tb%quadket(im)%matrix, ao_quad_spin(:, im, ispin), para_env)
    1517              :                END DO
    1518              :             END IF
    1519              :          END DO
    1520              :       END IF
    1521        49086 :       IF (nspin == 1) THEN
    1522      2290856 :          aocg(:, :) = aocg_spin(:, :, 1)
    1523       688280 :          IF (do_dipole) ao_dip(:, :) = ao_dip_spin(:, :, 1)
    1524      1332362 :          IF (do_quadrupole) ao_quad(:, :) = ao_quad_spin(:, :, 1)
    1525              :       ELSE
    1526        70188 :          aocg(:, :) = aocg_spin(:, :, 1) + aocg_spin(:, :, 2)
    1527         4888 :          IF (do_dipole) THEN
    1528        15432 :             DO im = 1, dip_n
    1529        44304 :                DO iatom = 1, n_atom
    1530        28872 :                   pao = ao_dip_spin(iatom, im, 1)
    1531        28872 :                   ao_dip_spin(iatom, im, 1) = pao + ao_dip_spin(iatom, im, 2)
    1532        40446 :                   ao_dip_spin(iatom, im, 2) = pao - ao_dip_spin(iatom, im, 2)
    1533              :                END DO
    1534              :             END DO
    1535        44304 :             ao_dip(:, :) = ao_dip_spin(:, :, 1)
    1536              :          END IF
    1537         4888 :          IF (do_quadrupole) THEN
    1538        27006 :             DO im = 1, quad_n
    1539        84750 :                DO iatom = 1, n_atom
    1540        57744 :                   pao = ao_quad_spin(iatom, im, 1)
    1541        57744 :                   ao_quad_spin(iatom, im, 1) = pao + ao_quad_spin(iatom, im, 2)
    1542        80892 :                   ao_quad_spin(iatom, im, 2) = pao - ao_quad_spin(iatom, im, 2)
    1543              :                END DO
    1544              :             END DO
    1545        84750 :             ao_quad(:, :) = ao_quad_spin(:, :, 1)
    1546              :          END IF
    1547              :       END IF
    1548        49086 :       NULLIFY (xtb_kind)
    1549       120080 :       DO ikind = 1, nkind
    1550        70994 :          CALL get_atomic_kind(atomic_kind_set(ikind), natom=na)
    1551        70994 :          CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_kind)
    1552        70994 :          CALL get_xtb_atom_param(xtb_kind, natorb=natorb, lao=lao, nao=nao, occupation=occ)
    1553       441540 :          DO iatom = 1, na
    1554       250466 :             atom_a = atomic_kind_set(ikind)%atom_list(iatom)
    1555      2210332 :             DO is = 1, natorb
    1556      1959866 :                ns = lao(is) + 1
    1557      1959866 :                norm = 2*lao(is) + 1
    1558      1959866 :                ch_ref(is, atom_a) = tb%calc%h0%refocc(nao(is), ikind)/norm
    1559      1959866 :                ch_orb(is, atom_a) = aocg(is, atom_a) - ch_ref(is, atom_a)
    1560      1959866 :                ch_orb_spin(is, atom_a, 1) = ch_orb(is, atom_a)
    1561      1959866 :                IF (nspin == 2) ch_orb_spin(is, atom_a, 2) = &
    1562        43992 :                   aocg_spin(is, atom_a, 1) - aocg_spin(is, atom_a, 2)
    1563      1959866 :                ch_shell(atom_a, ns) = ch_orb(is, atom_a) + ch_shell(atom_a, ns)
    1564      4214190 :                DO ispin = 1, nspin
    1565              :                   ch_shell_spin(atom_a, ns, ispin) = ch_orb_spin(is, atom_a, ispin) + &
    1566      3963724 :                                                      ch_shell_spin(atom_a, ns, ispin)
    1567              :                END DO
    1568              :             END DO
    1569       584910 :             DO ispin = 1, nspin
    1570      2627724 :                ch_atom(atom_a, ispin) = SUM(ch_orb_spin(:, atom_a, ispin))
    1571              :             END DO
    1572              :          END DO
    1573              :       END DO
    1574       299552 :       native_seed_charge = -SUM(ch_atom(:, 1))
    1575              :       seed_native_from_rho = SUM(ABS(aocg_spin)) > 1.0E-10_dp .AND. &
    1576      2480318 :                              ABS(native_seed_charge - REAL(dft_control%charge, dp)) < 1.0E-5_dp
    1577        49086 :       DEALLOCATE (aocg, aocg_spin)
    1578              : 
    1579        49086 :       raw_state_status = 1
    1580              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    1581              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_RAW_STATE_DUMP", raw_state_file, STATUS=raw_state_status)
    1582              : #endif
    1583              :       IF (raw_state_status == 0) THEN
    1584              :          OPEN (NEWUNIT=raw_state_unit, FILE=TRIM(raw_state_file), STATUS="REPLACE", ACTION="WRITE")
    1585              :          WRITE (raw_state_unit, *) "qat"
    1586              :          DO iatom = 1, n_atom
    1587              :             WRITE (raw_state_unit, "(I0,1X,ES24.16)") iatom, -ch_atom(iatom, 1)
    1588              :          END DO
    1589              :          WRITE (raw_state_unit, *) "qsh"
    1590              :          DO iatom = 1, n_atom
    1591              :             DO is = 1, tb%calc%bas%nsh_at(iatom)
    1592              :                WRITE (raw_state_unit, "(I0,1X,ES24.16)") tb%calc%bas%ish_at(iatom) + is, -ch_shell(iatom, is)
    1593              :             END DO
    1594              :          END DO
    1595              :          IF (do_dipole) THEN
    1596              :             WRITE (raw_state_unit, *) "dpat"
    1597              :             DO iatom = 1, n_atom
    1598              :                WRITE (raw_state_unit, "(I0,3(1X,ES24.16))") iatom, -ao_dip(iatom, :)
    1599              :             END DO
    1600              :          END IF
    1601              :          IF (do_quadrupole) THEN
    1602              :             WRITE (raw_state_unit, *) "qpat"
    1603              :             DO iatom = 1, n_atom
    1604              :                WRITE (raw_state_unit, "(I0,6(1X,ES24.16))") iatom, -ao_quad(iatom, :)
    1605              :             END DO
    1606              :          END IF
    1607              :          CLOSE (raw_state_unit)
    1608              :       END IF
    1609              : 
    1610        49086 :       IF (use_native_mixer) THEN
    1611        45334 :          IF (.NOT. ALLOCATED(tb%mixer)) CPABORT("tblite mixer not initialized")
    1612        45334 :          IF (use_rho .AND. (.NOT. calculate_forces) .AND. scf_env%iter_count > 1) THEN
    1613        21440 :             CALL tb%mixer%next(error)
    1614        21440 :             IF (ALLOCATED(error)) CPABORT("tblite native mixer failed")
    1615        21440 :             CALL tb%mixer%get(tb%wfn%qsh)
    1616       162654 :             tb%wfn%qat(:, :) = 0.0_dp
    1617       136004 :             DO iatom = 1, n_atom
    1618       114564 :                ii = tb%calc%bas%ish_at(iatom)
    1619       254540 :                DO ispin = 1, nspin
    1620              :                   tb%wfn%qat(iatom, ispin) = &
    1621       564030 :                      SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), ispin))
    1622              :                END DO
    1623              :             END DO
    1624        21440 :             IF (do_dipole) THEN
    1625        15926 :                CALL tb%mixer%get(tb%wfn%dpat)
    1626        15926 :                DEALLOCATE (ao_dip)
    1627              :             END IF
    1628        21440 :             IF (do_quadrupole) THEN
    1629        15926 :                CALL tb%mixer%get(tb%wfn%qpat)
    1630        15926 :                DEALLOCATE (ao_quad)
    1631              :             END IF
    1632              :          ELSE
    1633        23894 :             IF (use_rho .AND. (.NOT. calculate_forces)) THEN
    1634         2180 :                IF (.NOT. reuse_native_input) THEN
    1635          130 :                   IF (seed_native_from_rho) THEN
    1636              :                      ! Seed the native tblite mixer from CP2K's current density so SCF_GUESS/RESTART
    1637              :                      ! controls the initial SCC state.
    1638          610 :                      DO iatom = 1, n_atom
    1639          508 :                         ii = tb%calc%bas%ish_at(iatom)
    1640         1118 :                         DO ispin = 1, nspin
    1641         1844 :                            DO is = 1, tb%calc%bas%nsh_at(iatom)
    1642         1844 :                               tb%wfn%qsh(ii + is, ispin) = -ch_shell_spin(iatom, is, ispin)
    1643              :                            END DO
    1644              :                            tb%wfn%qat(iatom, ispin) = &
    1645         2352 :                               SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), ispin))
    1646              :                         END DO
    1647              :                      END DO
    1648          102 :                      IF (do_dipole) THEN
    1649          300 :                         DO iatom = 1, n_atom
    1650          548 :                            DO ispin = 1, nspin
    1651         1240 :                               tb%wfn%dpat(:, iatom, ispin) = -ao_dip_spin(iatom, :, ispin)
    1652              :                            END DO
    1653              :                         END DO
    1654              :                      END IF
    1655          102 :                      IF (do_quadrupole) THEN
    1656          300 :                         DO iatom = 1, n_atom
    1657          548 :                            DO ispin = 1, nspin
    1658         1984 :                               tb%wfn%qpat(:, iatom, ispin) = -ao_quad_spin(iatom, :, ispin)
    1659              :                            END DO
    1660              :                         END DO
    1661              :                      END IF
    1662              :                   ELSE
    1663          364 :                      tb%wfn%qsh(:, :) = 0.0_dp
    1664          200 :                      tb%wfn%qat(:, :) = 0.0_dp
    1665          204 :                      IF (do_dipole) tb%wfn%dpat(:, :, :) = 0.0_dp
    1666          324 :                      IF (do_quadrupole) tb%wfn%qpat(:, :, :) = 0.0_dp
    1667              :                   END IF
    1668              :                END IF
    1669         2180 :                IF (do_dipole) DEALLOCATE (ao_dip)
    1670         2180 :                IF (do_quadrupole) DEALLOCATE (ao_quad)
    1671              :             ELSE
    1672        21714 :                IF ((.NOT. use_rho) .AND. (.NOT. calculate_forces)) THEN
    1673        21608 :                   CALL tb%mixer%set(tb%wfn%qsh)
    1674        21608 :                   IF (do_dipole) CALL tb%mixer%set(tb%wfn%dpat)
    1675        21608 :                   IF (do_quadrupole) CALL tb%mixer%set(tb%wfn%qpat)
    1676              :                END IF
    1677       137454 :                DO iatom = 1, n_atom
    1678       115740 :                   ii = tb%calc%bas%ish_at(iatom)
    1679       257234 :                   DO ispin = 1, nspin
    1680       453926 :                      DO is = 1, tb%calc%bas%nsh_at(iatom)
    1681       453926 :                         tb%wfn%qsh(ii + is, ispin) = -ch_shell_spin(iatom, is, ispin)
    1682              :                      END DO
    1683              :                      tb%wfn%qat(iatom, ispin) = &
    1684       569666 :                         SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), ispin))
    1685              :                   END DO
    1686              :                END DO
    1687        21714 :                IF (do_dipole) THEN
    1688       104480 :                   DO iatom = 1, n_atom
    1689       195396 :                      DO ispin = 1, nspin
    1690       452084 :                         tb%wfn%dpat(:, iatom, ispin) = -ao_dip_spin(iatom, :, ispin)
    1691              :                      END DO
    1692              :                   END DO
    1693        16060 :                   DEALLOCATE (ao_dip)
    1694              :                END IF
    1695        21714 :                IF (do_quadrupole) THEN
    1696       104480 :                   DO iatom = 1, n_atom
    1697       195396 :                      DO ispin = 1, nspin
    1698       724832 :                         tb%wfn%qpat(:, iatom, ispin) = -ao_quad_spin(iatom, :, ispin)
    1699              :                      END DO
    1700              :                   END DO
    1701        16060 :                   DEALLOCATE (ao_quad)
    1702              :                END IF
    1703        21714 :                IF ((.NOT. use_rho) .AND. (.NOT. calculate_forces)) THEN
    1704        21608 :                   CALL tb%mixer%diff(tb%wfn%qsh)
    1705        21608 :                   IF (do_dipole) CALL tb%mixer%diff(tb%wfn%dpat)
    1706        21608 :                   IF (do_quadrupole) CALL tb%mixer%diff(tb%wfn%qpat)
    1707              :                END IF
    1708              :             END IF
    1709              :          END IF
    1710              :       ELSE
    1711              :          ! charge mixing
    1712         3752 :          native_sign_mixing = .FALSE.
    1713         3752 :          IF (dft_control%qs_control%do_ls_scf .OR. scf_control%use_ot) THEN
    1714              :             ! LS_SCF and OT optimize the electronic variables directly. Use the
    1715              :             ! current shell/multipole response from that density without an
    1716              :             ! extra SCC variable mixing step.
    1717         3352 :          ELSEIF (nspin > 1) THEN
    1718         1938 :             n_mix_cols = nspin*max_shell
    1719         1938 :             IF (do_dipole) n_mix_cols = n_mix_cols + nspin*dip_n
    1720         1938 :             IF (do_quadrupole) n_mix_cols = n_mix_cols + nspin*quad_n
    1721         7752 :             ALLOCATE (mix_vars(n_atom, n_mix_cols))
    1722         1938 :             mix_vars = 0.0_dp
    1723              : 
    1724         1938 :             mix_offset = 0
    1725         5814 :             DO ispin = 1, nspin
    1726              :                mix_vars(:, mix_offset + 1:mix_offset + max_shell) = &
    1727        27132 :                   -ch_shell_spin(:, 1:max_shell, ispin)
    1728         5814 :                mix_offset = mix_offset + max_shell
    1729              :             END DO
    1730         1938 :             IF (do_dipole) THEN
    1731         5814 :                DO ispin = 1, nspin
    1732              :                   mix_vars(:, mix_offset + 1:mix_offset + dip_n) = &
    1733        38760 :                      -ao_dip_spin(:, 1:dip_n, ispin)
    1734         5814 :                   mix_offset = mix_offset + dip_n
    1735              :                END DO
    1736              :             END IF
    1737         1938 :             IF (do_quadrupole) THEN
    1738         5814 :                DO ispin = 1, nspin
    1739              :                   mix_vars(:, mix_offset + 1:mix_offset + quad_n) = &
    1740        73644 :                      -ao_quad_spin(:, 1:quad_n, ispin)
    1741         5814 :                   mix_offset = mix_offset + quad_n
    1742              :                END DO
    1743              :             END IF
    1744              : 
    1745         1938 :             IF (.NOT. use_no_mixer) THEN
    1746              :                CALL charge_mixing(scf_env%mixing_method, scf_env%mixing_store, &
    1747         1938 :                                   mix_vars, para_env, scf_env%iter_count)
    1748              :             END IF
    1749              : 
    1750         1938 :             mix_offset = 0
    1751         5814 :             DO ispin = 1, nspin
    1752              :                ch_shell_spin(:, 1:max_shell, ispin) = &
    1753        27132 :                   -mix_vars(:, mix_offset + 1:mix_offset + max_shell)
    1754         5814 :                mix_offset = mix_offset + max_shell
    1755              :             END DO
    1756        13566 :             ch_shell(:, 1:max_shell) = ch_shell_spin(:, 1:max_shell, 1)
    1757         1938 :             IF (do_dipole) THEN
    1758         5814 :                DO ispin = 1, nspin
    1759              :                   ao_dip_spin(:, 1:dip_n, ispin) = &
    1760        38760 :                      -mix_vars(:, mix_offset + 1:mix_offset + dip_n)
    1761         5814 :                   mix_offset = mix_offset + dip_n
    1762              :                END DO
    1763        19380 :                ao_dip(:, 1:dip_n) = ao_dip_spin(:, 1:dip_n, 1)
    1764              :             END IF
    1765         1938 :             IF (do_quadrupole) THEN
    1766         5814 :                DO ispin = 1, nspin
    1767              :                   ao_quad_spin(:, 1:quad_n, ispin) = &
    1768        73644 :                      -mix_vars(:, mix_offset + 1:mix_offset + quad_n)
    1769         5814 :                   mix_offset = mix_offset + quad_n
    1770              :                END DO
    1771        36822 :                ao_quad(:, 1:quad_n) = ao_quad_spin(:, 1:quad_n, 1)
    1772              :             END IF
    1773         1938 :             DEALLOCATE (mix_vars)
    1774              :          ELSE
    1775         1414 :             do_combined_mixing = do_dipole .OR. do_quadrupole
    1776         1414 :             native_sign_mixing = do_dipole .OR. do_quadrupole
    1777         1414 :             discard_mixed_output = .FALSE.
    1778         1414 :             skip_charge_mixing = use_no_mixer
    1779         1414 :             IF (skip_charge_mixing) THEN
    1780              :                !
    1781         1414 :             ELSEIF (do_combined_mixing) THEN
    1782         1414 :                n_mix_cols = max_shell
    1783         1414 :                IF (do_dipole) n_mix_cols = n_mix_cols + dip_n
    1784         1414 :                IF (do_quadrupole) n_mix_cols = n_mix_cols + quad_n
    1785         5656 :                ALLOCATE (mix_vars(n_atom, n_mix_cols))
    1786              :                IF (native_sign_mixing) THEN
    1787        15554 :                   mix_vars(:, 1:max_shell) = -ch_shell(:, 1:max_shell)
    1788              :                ELSE
    1789              :                   mix_vars(:, 1:max_shell) = ch_shell(:, 1:max_shell)
    1790              :                END IF
    1791         1414 :                mix_offset = max_shell
    1792         1414 :                IF (do_dipole) THEN
    1793              :                   IF (native_sign_mixing) THEN
    1794        22624 :                      mix_vars(:, mix_offset + 1:mix_offset + dip_n) = -ao_dip(:, 1:dip_n)
    1795              :                   ELSE
    1796              :                      mix_vars(:, mix_offset + 1:mix_offset + dip_n) = ao_dip(:, 1:dip_n)
    1797              :                   END IF
    1798              :                   mix_offset = mix_offset + dip_n
    1799              :                END IF
    1800         1414 :                IF (do_quadrupole) THEN
    1801              :                   IF (native_sign_mixing) THEN
    1802        43834 :                      mix_vars(:, mix_offset + 1:mix_offset + quad_n) = -ao_quad(:, 1:quad_n)
    1803              :                   ELSE
    1804              :                      mix_vars(:, mix_offset + 1:mix_offset + quad_n) = ao_quad(:, 1:quad_n)
    1805              :                   END IF
    1806              :                END IF
    1807              :                CALL charge_mixing(scf_env%mixing_method, scf_env%mixing_store, &
    1808         1414 :                                   mix_vars, para_env, scf_env%iter_count)
    1809              :                IF (.NOT. discard_mixed_output) THEN
    1810              :                   IF (native_sign_mixing) THEN
    1811        15554 :                      ch_shell(:, 1:max_shell) = -mix_vars(:, 1:max_shell)
    1812              :                   ELSE
    1813              :                      ch_shell(:, 1:max_shell) = mix_vars(:, 1:max_shell)
    1814              :                   END IF
    1815         1414 :                   mix_offset = max_shell
    1816         1414 :                   IF (do_dipole) THEN
    1817              :                      IF (native_sign_mixing) THEN
    1818        22624 :                         ao_dip(:, 1:dip_n) = -mix_vars(:, mix_offset + 1:mix_offset + dip_n)
    1819              :                      ELSE
    1820              :                         ao_dip(:, 1:dip_n) = mix_vars(:, mix_offset + 1:mix_offset + dip_n)
    1821              :                      END IF
    1822              :                      mix_offset = mix_offset + dip_n
    1823              :                   END IF
    1824         1414 :                   IF (do_quadrupole) THEN
    1825              :                      IF (native_sign_mixing) THEN
    1826        43834 :                         ao_quad(:, 1:quad_n) = -mix_vars(:, mix_offset + 1:mix_offset + quad_n)
    1827              :                      ELSE
    1828              :                         ao_quad(:, 1:quad_n) = mix_vars(:, mix_offset + 1:mix_offset + quad_n)
    1829              :                      END IF
    1830              :                   END IF
    1831              :                END IF
    1832         1414 :                DEALLOCATE (mix_vars)
    1833              :             ELSE
    1834              :                CALL charge_mixing(scf_env%mixing_method, scf_env%mixing_store, &
    1835            0 :                                   ch_shell, para_env, scf_env%iter_count)
    1836              :             END IF
    1837              :          END IF
    1838              : 
    1839              :          !setting new wave function
    1840         3752 :          CALL tb%pot%reset
    1841        14124 :          tb%e_es = 0.0_dp
    1842        14124 :          tb%e_scd = 0.0_dp
    1843         3752 :          moment_alpha = scf_env%p_mix_alpha
    1844         3752 :          IF (nspin > 1) THEN
    1845         6540 :             DO iatom = 1, n_atom
    1846         4360 :                ii = tb%calc%bas%ish_at(iatom)
    1847        15260 :                DO ispin = 1, nspin
    1848        26160 :                   DO is = 1, tb%calc%bas%nsh_at(iatom)
    1849        26160 :                      tb%wfn%qsh(ii + is, ispin) = -ch_shell_spin(iatom, is, ispin)
    1850              :                   END DO
    1851              :                   tb%wfn%qat(iatom, ispin) = &
    1852        30520 :                      SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), ispin))
    1853              :                END DO
    1854              :             END DO
    1855         2180 :             IF (do_dipole) THEN
    1856         6540 :                DO iatom = 1, n_atom
    1857        15260 :                   DO ispin = 1, nspin
    1858        39240 :                      tb%wfn%dpat(:, iatom, ispin) = -ao_dip_spin(iatom, :, ispin)
    1859              :                   END DO
    1860              :                END DO
    1861         2180 :                DEALLOCATE (ao_dip)
    1862              :             END IF
    1863         2180 :             IF (do_quadrupole) THEN
    1864         6540 :                DO iatom = 1, n_atom
    1865        15260 :                   DO ispin = 1, nspin
    1866        65400 :                      tb%wfn%qpat(:, iatom, ispin) = -ao_quad_spin(iatom, :, ispin)
    1867              :                   END DO
    1868              :                END DO
    1869         2180 :                DEALLOCATE (ao_quad)
    1870              :             END IF
    1871              :          ELSE
    1872         7584 :             DO iatom = 1, n_atom
    1873         6012 :                ii = tb%calc%bas%ish_at(iatom)
    1874        15288 :                DO is = 1, tb%calc%bas%nsh_at(iatom)
    1875         9276 :                   new_charge = -ch_shell(iatom, is)
    1876        15288 :                   tb%wfn%qsh(ii + is, 1) = new_charge
    1877              :                END DO
    1878         7584 :                IF (native_sign_mixing) THEN
    1879        14140 :                   tb%wfn%qat(iatom, 1) = SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), 1))
    1880              :                ELSE
    1881          356 :                   tb%wfn%qat(iatom, 1) = -ch_atom(iatom, 1)
    1882              :                END IF
    1883              :             END DO
    1884              : 
    1885         1572 :             IF (do_dipole) THEN
    1886         7584 :                DO iatom = 1, n_atom
    1887        25620 :                   DO im = 1, dip_n
    1888        24048 :                      tb%wfn%dpat(im, iatom, 1) = -ao_dip(iatom, im)
    1889              :                   END DO
    1890              :                END DO
    1891         1572 :                DEALLOCATE (ao_dip)
    1892              :             END IF
    1893         1572 :             IF (do_quadrupole) THEN
    1894         7584 :                DO iatom = 1, n_atom
    1895        43656 :                   DO im = 1, quad_n
    1896        42084 :                      tb%wfn%qpat(im, iatom, 1) = -ao_quad(iatom, im)
    1897              :                   END DO
    1898              :                END DO
    1899         1572 :                DEALLOCATE (ao_quad)
    1900              :             END IF
    1901              :          END IF
    1902              :       END IF
    1903              : 
    1904        49086 :       CALL tb%pot%reset
    1905       299552 :       tb%e_es = 0.0_dp
    1906       299552 :       tb%e_scd = 0.0_dp
    1907       299552 :       tb%e_int = 0.0_dp
    1908        49086 :       IF (ALLOCATED(tb%calc%coulomb)) THEN
    1909        49086 :          CALL tb%calc%coulomb%get_potential(tb%mol, tb%cache, tb%wfn, tb%pot)
    1910        49086 :          CALL tb%calc%coulomb%get_energy(tb%mol, tb%cache, tb%wfn, tb%e_es)
    1911              :       END IF
    1912        49086 :       IF (ALLOCATED(tb%calc%dispersion)) THEN
    1913              :          IF (.NOT. skip_scf_dispersion_potential) &
    1914        49086 :             CALL tb%calc%dispersion%get_potential(tb%mol, tb%dcache, tb%wfn, tb%pot)
    1915              :          IF (.NOT. skip_scf_dispersion_energy) &
    1916        49086 :             CALL tb%calc%dispersion%get_energy(tb%mol, tb%dcache, tb%wfn, tb%e_scd)
    1917              :       END IF
    1918        49086 :       IF (ALLOCATED(tb%calc%interactions)) THEN
    1919         4888 :          CALL tb%calc%interactions%get_potential(tb%mol, tb%icache, tb%wfn, tb%pot)
    1920         4888 :          CALL tb%calc%interactions%get_energy(tb%mol, tb%icache, tb%wfn, tb%e_int)
    1921              :       END IF
    1922              : 
    1923        49086 :       IF (calculate_forces) THEN
    1924          114 :          IF (ALLOCATED(tb%calc%coulomb)) THEN
    1925         1946 :             tb%grad = 0.0_dp
    1926          114 :             CALL tb%calc%coulomb%get_gradient(tb%mol, tb%cache, tb%wfn, tb%grad, tb%sigma)
    1927          114 :             CALL tb_dump_sigma_component("after_coulomb", tb%sigma, para_env)
    1928          114 :             CALL tb_grad2force(qs_env, tb, para_env, 3)
    1929              :          END IF
    1930              : 
    1931          114 :          IF (ALLOCATED(tb%calc%dispersion) .AND. .NOT. skip_scf_dispersion_gradient) THEN
    1932         1946 :             tb%grad = 0.0_dp
    1933          114 :             CALL tb%calc%dispersion%get_gradient(tb%mol, tb%dcache, tb%wfn, tb%grad, tb%sigma)
    1934          114 :             CALL tb_dump_sigma_component("after_dispersion_scf", tb%sigma, para_env)
    1935          114 :             CALL tb_grad2force(qs_env, tb, para_env, 2)
    1936              :          END IF
    1937              : 
    1938          114 :          IF (ALLOCATED(tb%calc%interactions)) THEN
    1939          194 :             tb%grad = 0.0_dp
    1940           18 :             CALL tb%calc%interactions%get_gradient(tb%mol, tb%icache, tb%wfn, tb%grad, tb%sigma)
    1941           18 :             CALL tb_dump_sigma_component("after_interactions_scf", tb%sigma, para_env)
    1942           18 :             CALL tb_grad2force(qs_env, tb, para_env, 3)
    1943              :          END IF
    1944              :       END IF
    1945              : 
    1946        49086 :       IF (ALLOCATED(ao_dip_spin)) DEALLOCATE (ao_dip_spin)
    1947        49086 :       IF (ALLOCATED(ao_quad_spin)) DEALLOCATE (ao_quad_spin)
    1948        49086 :       DEALLOCATE (ch_atom, ch_shell, ch_orb, ch_ref, ch_orb_spin, ch_shell_spin)
    1949              : 
    1950              : #else
    1951              :       MARK_USED(qs_env)
    1952              :       MARK_USED(tb)
    1953              :       MARK_USED(dft_control)
    1954              :       MARK_USED(calculate_forces)
    1955              :       MARK_USED(use_rho)
    1956              :       CPABORT("Built without TBLITE")
    1957              : #endif
    1958              : 
    1959       147258 :    END SUBROUTINE tb_update_charges
    1960              : 
    1961              : ! **************************************************************************************************
    1962              : !> \brief ...
    1963              : !> \param qs_env ...
    1964              : !> \param tb ...
    1965              : !> \param dft_control ...
    1966              : ! **************************************************************************************************
    1967        25710 :    SUBROUTINE tb_ham_add_coulomb(qs_env, tb, dft_control)
    1968              : 
    1969              :       TYPE(qs_environment_type), POINTER                       :: qs_env
    1970              :       TYPE(tblite_type), POINTER                               :: tb
    1971              :       TYPE(dft_control_type), POINTER                          :: dft_control
    1972              : 
    1973              : #if defined(__TBLITE)
    1974              : 
    1975              :       INTEGER                                            :: ikind, jkind, iatom, jatom, icol, irow
    1976              :       INTEGER                                            :: ic, id1, id2, id3, iq1, iq2, iq3, iq4, iq5, iq6, &
    1977              :                                                             is, nimg, ni, nj, i, j, nspin
    1978              :       INTEGER                                            :: la, lb, za, zb
    1979              :       LOGICAL                                            :: found
    1980              :       INTEGER, DIMENSION(3)                              :: cellind
    1981              :       INTEGER, DIMENSION(25)                             :: naoa, naob
    1982              :       REAL(KIND=dp), DIMENSION(3)                        :: rij
    1983              :       REAL(KIND=dp)                                      :: mpfac
    1984              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    1985              :       INTEGER                                            :: debug_status
    1986              :       CHARACTER(LEN=32)                                  :: debug_value
    1987              : #endif
    1988        25710 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: kind_of, sum_shell
    1989        25710 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: ashift, bshift
    1990        25710 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: ksblock, sblock
    1991        25710 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
    1992        25710 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: dip_ket1, dip_ket2, dip_ket3, &
    1993        25710 :                                                             dip_bra1, dip_bra2, dip_bra3
    1994        25710 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: quad_ket1, quad_ket2, quad_ket3, &
    1995        25710 :                                                             quad_ket4, quad_ket5, quad_ket6, &
    1996        25710 :                                                             quad_bra1, quad_bra2, quad_bra3, &
    1997        25710 :                                                             quad_bra4, quad_bra5, quad_bra6
    1998              : 
    1999        25710 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2000              :       TYPE(dbcsr_iterator_type)                          :: iter
    2001        25710 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_s
    2002        25710 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: ks_matrix
    2003              :       TYPE(kpoint_type), POINTER                         :: kpoints
    2004              :       TYPE(neighbor_list_iterator_p_type), &
    2005        25710 :          DIMENSION(:), POINTER                           :: nl_iterator
    2006              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    2007        25710 :          POINTER                                         :: n_list
    2008              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    2009        25710 :          POINTER                                         :: kp_list
    2010        25710 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    2011              :       TYPE(xtb_atom_type), POINTER                       :: xtb_atom_a, xtb_atom_b
    2012              : 
    2013        25710 :       nimg = dft_control%nimages
    2014        25710 :       mpfac = -0.5_dp
    2015              : 
    2016        25710 :       NULLIFY (matrix_s, ks_matrix, n_list, kp_list, qs_kind_set)
    2017              :       CALL get_qs_env(qs_env=qs_env, sab_orb=n_list, sab_kp=kp_list, &
    2018        25710 :                       matrix_s_kp=matrix_s, matrix_ks_kp=ks_matrix, qs_kind_set=qs_kind_set)
    2019        25710 :       IF (nimg > 1) THEN
    2020         9798 :          IF (.NOT. ASSOCIATED(kp_list)) CPABORT("Missing k-point neighbor list for tblite Hamiltonian")
    2021         9798 :          n_list => kp_list
    2022              :       END IF
    2023        25710 :       nspin = SIZE(ks_matrix, 1)
    2024              : 
    2025              :       !creating sum of shell lists
    2026        77130 :       ALLOCATE (sum_shell(tb%mol%nat))
    2027       155974 :       i = 0
    2028       155974 :       DO j = 1, tb%mol%nat
    2029       130264 :          sum_shell(j) = i
    2030       155974 :          i = i + tb%calc%bas%nsh_at(j)
    2031              :       END DO
    2032              : 
    2033        25710 :       IF (nimg == 1) THEN
    2034              :          ! no k-points; all matrices have been transformed to periodic bsf
    2035        15912 :          CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
    2036              :          CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
    2037        15912 :                                   kind_of=kind_of)
    2038        15912 :          CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
    2039       188401 :          DO WHILE (dbcsr_iterator_blocks_left(iter))
    2040       172489 :             CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
    2041              : 
    2042       172489 :             ikind = kind_of(irow)
    2043       172489 :             jkind = kind_of(icol)
    2044              : 
    2045              :             ! atomic parameters
    2046       172489 :             CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_atom_a)
    2047       172489 :             CALL get_qs_kind(qs_kind_set(jkind), xtb_parameter=xtb_atom_b)
    2048       172489 :             CALL get_xtb_atom_param(xtb_atom_a, z=za, nao=naoa)
    2049       172489 :             CALL get_xtb_atom_param(xtb_atom_b, z=zb, nao=naob)
    2050              : 
    2051       172489 :             ni = SIZE(sblock, 1)
    2052       689956 :             ALLOCATE (ashift(ni, ni))
    2053              : 
    2054       172489 :             nj = SIZE(sblock, 2)
    2055       689956 :             ALLOCATE (bshift(nj, nj))
    2056              : 
    2057       351872 :             DO is = 1, nspin
    2058       179383 :                ashift = 0.0_dp
    2059      1569844 :                DO i = 1, ni
    2060      1390461 :                   la = naoa(i) + sum_shell(irow)
    2061      1569844 :                   ashift(i, i) = tb_spin_project(tb%pot%vsh(la, :), is)
    2062              :                END DO
    2063       179383 :                bshift = 0.0_dp
    2064      1533056 :                DO j = 1, nj
    2065      1353673 :                   lb = naob(j) + sum_shell(icol)
    2066      1533056 :                   bshift(j, j) = tb_spin_project(tb%pot%vsh(lb, :), is)
    2067              :                END DO
    2068       179383 :                NULLIFY (ksblock)
    2069              :                CALL dbcsr_get_block_p(matrix=ks_matrix(is, 1)%matrix, &
    2070       179383 :                                       row=irow, col=icol, block=ksblock, found=found)
    2071       179383 :                CPASSERT(found)
    2072       717532 :                ksblock = ksblock - 0.5_dp*(MATMUL(ashift, sblock) &
    2073    444226831 :                                            + MATMUL(sblock, bshift))
    2074              :                ksblock = ksblock - 0.5_dp*(tb_spin_project(tb%pot%vat(irow, :), is) &
    2075     26302671 :                                            + tb_spin_project(tb%pot%vat(icol, :), is))*sblock
    2076              :             END DO
    2077       533379 :             DEALLOCATE (ashift, bshift)
    2078              :          END DO
    2079        15912 :          CALL dbcsr_iterator_stop(iter)
    2080              : 
    2081        15912 :          IF (ASSOCIATED(tb%dipbra)) THEN
    2082        11530 :             CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
    2083       144249 :             DO WHILE (dbcsr_iterator_blocks_left(iter))
    2084       132719 :                CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
    2085              : 
    2086       132719 :                NULLIFY (dip_bra1, dip_bra2, dip_bra3)
    2087              :                CALL dbcsr_get_block_p(matrix=tb%dipbra(1)%matrix, &
    2088       132719 :                                       row=irow, col=icol, BLOCK=dip_bra1, found=found)
    2089       132719 :                CPASSERT(found)
    2090              :                CALL dbcsr_get_block_p(matrix=tb%dipbra(2)%matrix, &
    2091       132719 :                                       row=irow, col=icol, BLOCK=dip_bra2, found=found)
    2092       132719 :                CPASSERT(found)
    2093              :                CALL dbcsr_get_block_p(matrix=tb%dipbra(3)%matrix, &
    2094       132719 :                                       row=irow, col=icol, BLOCK=dip_bra3, found=found)
    2095       132719 :                CPASSERT(found)
    2096       132719 :                NULLIFY (dip_ket1, dip_ket2, dip_ket3)
    2097              :                CALL dbcsr_get_block_p(matrix=tb%dipket(1)%matrix, &
    2098       132719 :                                       row=irow, col=icol, BLOCK=dip_ket1, found=found)
    2099       132719 :                CPASSERT(found)
    2100              :                CALL dbcsr_get_block_p(matrix=tb%dipket(2)%matrix, &
    2101       132719 :                                       row=irow, col=icol, BLOCK=dip_ket2, found=found)
    2102       132719 :                CPASSERT(found)
    2103              :                CALL dbcsr_get_block_p(matrix=tb%dipket(3)%matrix, &
    2104       132719 :                                       row=irow, col=icol, BLOCK=dip_ket3, found=found)
    2105       132719 :                CPASSERT(found)
    2106              : 
    2107       281788 :                DO is = 1, nspin
    2108       137539 :                   NULLIFY (ksblock)
    2109              :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, 1)%matrix, &
    2110       137539 :                                          row=irow, col=icol, block=ksblock, found=found)
    2111       137539 :                   CPASSERT(found)
    2112              :                   ksblock = ksblock + mpfac*(dip_ket1*tb_spin_project(tb%pot%vdp(1, irow, :), is) &
    2113              :                                              + dip_ket2*tb_spin_project(tb%pot%vdp(2, irow, :), is) &
    2114              :                                              + dip_ket3*tb_spin_project(tb%pot%vdp(3, irow, :), is) &
    2115              :                                              + dip_bra1*tb_spin_project(tb%pot%vdp(1, icol, :), is) &
    2116              :                                              + dip_bra2*tb_spin_project(tb%pot%vdp(2, icol, :), is) &
    2117     21994497 :                                              + dip_bra3*tb_spin_project(tb%pot%vdp(3, icol, :), is))
    2118              :                END DO
    2119              :             END DO
    2120        11530 :             CALL dbcsr_iterator_stop(iter)
    2121              :          END IF
    2122              : 
    2123        15912 :          IF (ASSOCIATED(tb%quadbra)) THEN
    2124        11530 :             CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
    2125       144249 :             DO WHILE (dbcsr_iterator_blocks_left(iter))
    2126       132719 :                CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
    2127              : 
    2128       132719 :                NULLIFY (quad_bra1, quad_bra2, quad_bra3, quad_bra4, quad_bra5, quad_bra6)
    2129              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(1)%matrix, &
    2130       132719 :                                       row=irow, col=icol, BLOCK=quad_bra1, found=found)
    2131       132719 :                CPASSERT(found)
    2132              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(2)%matrix, &
    2133       132719 :                                       row=irow, col=icol, BLOCK=quad_bra2, found=found)
    2134       132719 :                CPASSERT(found)
    2135              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(3)%matrix, &
    2136       132719 :                                       row=irow, col=icol, BLOCK=quad_bra3, found=found)
    2137       132719 :                CPASSERT(found)
    2138              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(4)%matrix, &
    2139       132719 :                                       row=irow, col=icol, BLOCK=quad_bra4, found=found)
    2140       132719 :                CPASSERT(found)
    2141              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(5)%matrix, &
    2142       132719 :                                       row=irow, col=icol, BLOCK=quad_bra5, found=found)
    2143       132719 :                CPASSERT(found)
    2144              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(6)%matrix, &
    2145       132719 :                                       row=irow, col=icol, BLOCK=quad_bra6, found=found)
    2146       132719 :                CPASSERT(found)
    2147              : 
    2148       132719 :                NULLIFY (quad_ket1, quad_ket2, quad_ket3, quad_ket4, quad_ket5, quad_ket6)
    2149              :                CALL dbcsr_get_block_p(matrix=tb%quadket(1)%matrix, &
    2150       132719 :                                       row=irow, col=icol, BLOCK=quad_ket1, found=found)
    2151       132719 :                CPASSERT(found)
    2152              :                CALL dbcsr_get_block_p(matrix=tb%quadket(2)%matrix, &
    2153       132719 :                                       row=irow, col=icol, BLOCK=quad_ket2, found=found)
    2154       132719 :                CPASSERT(found)
    2155              :                CALL dbcsr_get_block_p(matrix=tb%quadket(3)%matrix, &
    2156       132719 :                                       row=irow, col=icol, BLOCK=quad_ket3, found=found)
    2157       132719 :                CPASSERT(found)
    2158              :                CALL dbcsr_get_block_p(matrix=tb%quadket(4)%matrix, &
    2159       132719 :                                       row=irow, col=icol, BLOCK=quad_ket4, found=found)
    2160       132719 :                CPASSERT(found)
    2161              :                CALL dbcsr_get_block_p(matrix=tb%quadket(5)%matrix, &
    2162       132719 :                                       row=irow, col=icol, BLOCK=quad_ket5, found=found)
    2163       132719 :                CPASSERT(found)
    2164              :                CALL dbcsr_get_block_p(matrix=tb%quadket(6)%matrix, &
    2165       132719 :                                       row=irow, col=icol, BLOCK=quad_ket6, found=found)
    2166       132719 :                CPASSERT(found)
    2167              : 
    2168       281788 :                DO is = 1, nspin
    2169       137539 :                   NULLIFY (ksblock)
    2170              :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, 1)%matrix, &
    2171       137539 :                                          row=irow, col=icol, block=ksblock, found=found)
    2172       137539 :                   CPASSERT(found)
    2173              : 
    2174              :                   ksblock = ksblock + mpfac*(quad_ket1*tb_spin_project(tb%pot%vqp(1, irow, :), is) &
    2175              :                                              + quad_ket2*tb_spin_project(tb%pot%vqp(2, irow, :), is) &
    2176              :                                              + quad_ket3*tb_spin_project(tb%pot%vqp(3, irow, :), is) &
    2177              :                                              + quad_ket4*tb_spin_project(tb%pot%vqp(4, irow, :), is) &
    2178              :                                              + quad_ket5*tb_spin_project(tb%pot%vqp(5, irow, :), is) &
    2179              :                                              + quad_ket6*tb_spin_project(tb%pot%vqp(6, irow, :), is) &
    2180              :                                              + quad_bra1*tb_spin_project(tb%pot%vqp(1, icol, :), is) &
    2181              :                                              + quad_bra2*tb_spin_project(tb%pot%vqp(2, icol, :), is) &
    2182              :                                              + quad_bra3*tb_spin_project(tb%pot%vqp(3, icol, :), is) &
    2183              :                                              + quad_bra4*tb_spin_project(tb%pot%vqp(4, icol, :), is) &
    2184              :                                              + quad_bra5*tb_spin_project(tb%pot%vqp(5, icol, :), is) &
    2185     21994497 :                                              + quad_bra6*tb_spin_project(tb%pot%vqp(6, icol, :), is))
    2186              :                END DO
    2187              :             END DO
    2188        11530 :             CALL dbcsr_iterator_stop(iter)
    2189              :          END IF
    2190              : 
    2191              :       ELSE
    2192         9798 :          NULLIFY (kpoints)
    2193         9798 :          CALL get_qs_env(qs_env=qs_env, kpoints=kpoints)
    2194         9798 :          NULLIFY (cell_to_index)
    2195         9798 :          CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
    2196              : 
    2197         9798 :          NULLIFY (nl_iterator)
    2198         9798 :          CALL neighbor_list_iterator_create(nl_iterator, n_list)
    2199      1310935 :          DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
    2200              :             CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
    2201      1301137 :                                    iatom=iatom, jatom=jatom, r=rij, cell=cellind)
    2202              : 
    2203      1301137 :             icol = MAX(iatom, jatom)
    2204      1301137 :             irow = MIN(iatom, jatom)
    2205              : 
    2206      1301137 :             IF (iatom > jatom) THEN
    2207       554345 :                i = ikind
    2208       554345 :                ikind = jkind
    2209       554345 :                jkind = i
    2210              :             END IF
    2211              : 
    2212      1301137 :             ic = cell_to_index(cellind(1), cellind(2), cellind(3))
    2213      1301137 :             CPASSERT(ic > 0)
    2214              : 
    2215      1301137 :             NULLIFY (sblock)
    2216              :             CALL dbcsr_get_block_p(matrix=matrix_s(1, ic)%matrix, &
    2217      1301137 :                                    row=irow, col=icol, block=sblock, found=found)
    2218      1301137 :             CPASSERT(found)
    2219              : 
    2220              :             ! atomic parameters
    2221      1301137 :             CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_atom_a)
    2222      1301137 :             CALL get_qs_kind(qs_kind_set(jkind), xtb_parameter=xtb_atom_b)
    2223      1301137 :             CALL get_xtb_atom_param(xtb_atom_a, z=za, nao=naoa)
    2224      1301137 :             CALL get_xtb_atom_param(xtb_atom_b, z=zb, nao=naob)
    2225              : 
    2226      1301137 :             ni = SIZE(sblock, 1)
    2227      5204548 :             ALLOCATE (ashift(ni, ni))
    2228              : 
    2229      1301137 :             nj = SIZE(sblock, 2)
    2230      5204548 :             ALLOCATE (bshift(nj, nj))
    2231              : 
    2232      2602274 :             DO is = 1, nspin
    2233      1301137 :                ashift = 0.0_dp
    2234     12968215 :                DO i = 1, ni
    2235     11667078 :                   la = naoa(i) + sum_shell(irow)
    2236     12968215 :                   ashift(i, i) = tb_spin_project(tb%pot%vsh(la, :), is)
    2237              :                END DO
    2238      1301137 :                bshift = 0.0_dp
    2239     12968215 :                DO j = 1, nj
    2240     11667078 :                   lb = naob(j) + sum_shell(icol)
    2241     12968215 :                   bshift(j, j) = tb_spin_project(tb%pot%vsh(lb, :), is)
    2242              :                END DO
    2243      1301137 :                NULLIFY (ksblock)
    2244              :                CALL dbcsr_get_block_p(matrix=ks_matrix(is, ic)%matrix, &
    2245      1301137 :                                       row=irow, col=icol, block=ksblock, found=found)
    2246      1301137 :                CPASSERT(found)
    2247      5204548 :                ksblock = ksblock - 0.5_dp*(MATMUL(ashift, sblock) &
    2248   4127157197 :                                            + MATMUL(sblock, bshift))
    2249              :                ksblock = ksblock - 0.5_dp*(tb_spin_project(tb%pot%vat(irow, :), is) &
    2250    236899731 :                                            + tb_spin_project(tb%pot%vat(icol, :), is))*sblock
    2251              :             END DO
    2252      3913209 :             DEALLOCATE (ashift, bshift)
    2253              :          END DO
    2254         9798 :          CALL neighbor_list_iterator_release(nl_iterator)
    2255              : 
    2256         9798 :          IF (ASSOCIATED(tb%dipbra)) THEN
    2257         7486 :             NULLIFY (nl_iterator)
    2258         7486 :             CALL neighbor_list_iterator_create(nl_iterator, n_list)
    2259       842837 :             DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
    2260              :                CALL get_iterator_info(nl_iterator, &
    2261       835351 :                                       iatom=iatom, jatom=jatom, cell=cellind)
    2262       835351 :                icol = MAX(iatom, jatom)
    2263       835351 :                irow = MIN(iatom, jatom)
    2264       835351 :                ic = cell_to_index(cellind(1), cellind(2), cellind(3))
    2265       835351 :                CPASSERT(ic > 0)
    2266       835351 :                id1 = 1 + dip_n*(ic - 1)
    2267       835351 :                id2 = 2 + dip_n*(ic - 1)
    2268       835351 :                id3 = 3 + dip_n*(ic - 1)
    2269              : 
    2270       835351 :                NULLIFY (dip_bra1, dip_bra2, dip_bra3)
    2271              :                CALL dbcsr_get_block_p(matrix=tb%dipbra(id1)%matrix, &
    2272       835351 :                                       row=irow, col=icol, BLOCK=dip_bra1, found=found)
    2273       835351 :                CPASSERT(found)
    2274              :                CALL dbcsr_get_block_p(matrix=tb%dipbra(id2)%matrix, &
    2275       835351 :                                       row=irow, col=icol, BLOCK=dip_bra2, found=found)
    2276       835351 :                CPASSERT(found)
    2277              :                CALL dbcsr_get_block_p(matrix=tb%dipbra(id3)%matrix, &
    2278       835351 :                                       row=irow, col=icol, BLOCK=dip_bra3, found=found)
    2279       835351 :                CPASSERT(found)
    2280       835351 :                NULLIFY (dip_ket1, dip_ket2, dip_ket3)
    2281              :                CALL dbcsr_get_block_p(matrix=tb%dipket(id1)%matrix, &
    2282       835351 :                                       row=irow, col=icol, BLOCK=dip_ket1, found=found)
    2283       835351 :                CPASSERT(found)
    2284              :                CALL dbcsr_get_block_p(matrix=tb%dipket(id2)%matrix, &
    2285       835351 :                                       row=irow, col=icol, BLOCK=dip_ket2, found=found)
    2286       835351 :                CPASSERT(found)
    2287              :                CALL dbcsr_get_block_p(matrix=tb%dipket(id3)%matrix, &
    2288       835351 :                                       row=irow, col=icol, BLOCK=dip_ket3, found=found)
    2289       835351 :                CPASSERT(found)
    2290              : 
    2291      1678188 :                DO is = 1, nspin
    2292       835351 :                   NULLIFY (ksblock)
    2293              :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, ic)%matrix, &
    2294       835351 :                                          row=irow, col=icol, block=ksblock, found=found)
    2295       835351 :                   CPASSERT(found)
    2296              :                   ksblock = ksblock + mpfac*(dip_ket1*tb_spin_project(tb%pot%vdp(1, irow, :), is) &
    2297              :                                              + dip_ket2*tb_spin_project(tb%pot%vdp(2, irow, :), is) &
    2298              :                                              + dip_ket3*tb_spin_project(tb%pot%vdp(3, irow, :), is) &
    2299              :                                              + dip_bra1*tb_spin_project(tb%pot%vdp(1, icol, :), is) &
    2300              :                                              + dip_bra2*tb_spin_project(tb%pot%vdp(2, icol, :), is) &
    2301    151660893 :                                              + dip_bra3*tb_spin_project(tb%pot%vdp(3, icol, :), is))
    2302              :                END DO
    2303              :             END DO
    2304         7486 :             CALL neighbor_list_iterator_release(nl_iterator)
    2305              :          END IF
    2306              : 
    2307         9798 :          IF (ASSOCIATED(tb%quadbra)) THEN
    2308         7486 :             NULLIFY (nl_iterator)
    2309         7486 :             CALL neighbor_list_iterator_create(nl_iterator, n_list)
    2310       842837 :             DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
    2311              :                CALL get_iterator_info(nl_iterator, &
    2312       835351 :                                       iatom=iatom, jatom=jatom, cell=cellind)
    2313       835351 :                icol = MAX(iatom, jatom)
    2314       835351 :                irow = MIN(iatom, jatom)
    2315       835351 :                ic = cell_to_index(cellind(1), cellind(2), cellind(3))
    2316       835351 :                CPASSERT(ic > 0)
    2317       835351 :                iq1 = 1 + quad_n*(ic - 1)
    2318       835351 :                iq2 = 2 + quad_n*(ic - 1)
    2319       835351 :                iq3 = 3 + quad_n*(ic - 1)
    2320       835351 :                iq4 = 4 + quad_n*(ic - 1)
    2321       835351 :                iq5 = 5 + quad_n*(ic - 1)
    2322       835351 :                iq6 = 6 + quad_n*(ic - 1)
    2323              : 
    2324       835351 :                NULLIFY (quad_bra1, quad_bra2, quad_bra3, quad_bra4, quad_bra5, quad_bra6)
    2325              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(iq1)%matrix, &
    2326       835351 :                                       row=irow, col=icol, BLOCK=quad_bra1, found=found)
    2327       835351 :                CPASSERT(found)
    2328              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(iq2)%matrix, &
    2329       835351 :                                       row=irow, col=icol, BLOCK=quad_bra2, found=found)
    2330       835351 :                CPASSERT(found)
    2331              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(iq3)%matrix, &
    2332       835351 :                                       row=irow, col=icol, BLOCK=quad_bra3, found=found)
    2333       835351 :                CPASSERT(found)
    2334              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(iq4)%matrix, &
    2335       835351 :                                       row=irow, col=icol, BLOCK=quad_bra4, found=found)
    2336       835351 :                CPASSERT(found)
    2337              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(iq5)%matrix, &
    2338       835351 :                                       row=irow, col=icol, BLOCK=quad_bra5, found=found)
    2339       835351 :                CPASSERT(found)
    2340              :                CALL dbcsr_get_block_p(matrix=tb%quadbra(iq6)%matrix, &
    2341       835351 :                                       row=irow, col=icol, BLOCK=quad_bra6, found=found)
    2342       835351 :                CPASSERT(found)
    2343              : 
    2344       835351 :                NULLIFY (quad_ket1, quad_ket2, quad_ket3, quad_ket4, quad_ket5, quad_ket6)
    2345              :                CALL dbcsr_get_block_p(matrix=tb%quadket(iq1)%matrix, &
    2346       835351 :                                       row=irow, col=icol, BLOCK=quad_ket1, found=found)
    2347       835351 :                CPASSERT(found)
    2348              :                CALL dbcsr_get_block_p(matrix=tb%quadket(iq2)%matrix, &
    2349       835351 :                                       row=irow, col=icol, BLOCK=quad_ket2, found=found)
    2350       835351 :                CPASSERT(found)
    2351              :                CALL dbcsr_get_block_p(matrix=tb%quadket(iq3)%matrix, &
    2352       835351 :                                       row=irow, col=icol, BLOCK=quad_ket3, found=found)
    2353       835351 :                CPASSERT(found)
    2354              :                CALL dbcsr_get_block_p(matrix=tb%quadket(iq4)%matrix, &
    2355       835351 :                                       row=irow, col=icol, BLOCK=quad_ket4, found=found)
    2356       835351 :                CPASSERT(found)
    2357              :                CALL dbcsr_get_block_p(matrix=tb%quadket(iq5)%matrix, &
    2358       835351 :                                       row=irow, col=icol, BLOCK=quad_ket5, found=found)
    2359       835351 :                CPASSERT(found)
    2360              :                CALL dbcsr_get_block_p(matrix=tb%quadket(iq6)%matrix, &
    2361       835351 :                                       row=irow, col=icol, BLOCK=quad_ket6, found=found)
    2362       835351 :                CPASSERT(found)
    2363              : 
    2364      1678188 :                DO is = 1, nspin
    2365       835351 :                   NULLIFY (ksblock)
    2366              :                   CALL dbcsr_get_block_p(matrix=ks_matrix(is, ic)%matrix, &
    2367       835351 :                                          row=irow, col=icol, block=ksblock, found=found)
    2368       835351 :                   CPASSERT(found)
    2369              : 
    2370              :                   ksblock = ksblock + mpfac*(quad_ket1*tb_spin_project(tb%pot%vqp(1, irow, :), is) &
    2371              :                                              + quad_ket2*tb_spin_project(tb%pot%vqp(2, irow, :), is) &
    2372              :                                              + quad_ket3*tb_spin_project(tb%pot%vqp(3, irow, :), is) &
    2373              :                                              + quad_ket4*tb_spin_project(tb%pot%vqp(4, irow, :), is) &
    2374              :                                              + quad_ket5*tb_spin_project(tb%pot%vqp(5, irow, :), is) &
    2375              :                                              + quad_ket6*tb_spin_project(tb%pot%vqp(6, irow, :), is) &
    2376              :                                              + quad_bra1*tb_spin_project(tb%pot%vqp(1, icol, :), is) &
    2377              :                                              + quad_bra2*tb_spin_project(tb%pot%vqp(2, icol, :), is) &
    2378              :                                              + quad_bra3*tb_spin_project(tb%pot%vqp(3, icol, :), is) &
    2379              :                                              + quad_bra4*tb_spin_project(tb%pot%vqp(4, icol, :), is) &
    2380              :                                              + quad_bra5*tb_spin_project(tb%pot%vqp(5, icol, :), is) &
    2381    151660893 :                                              + quad_bra6*tb_spin_project(tb%pot%vqp(6, icol, :), is))
    2382              :                END DO
    2383              :             END DO
    2384         7486 :             CALL neighbor_list_iterator_release(nl_iterator)
    2385              :          END IF
    2386              : 
    2387              :       END IF
    2388              : 
    2389              : #else
    2390              :       MARK_USED(qs_env)
    2391              :       MARK_USED(tb)
    2392              :       MARK_USED(dft_control)
    2393              :       CPABORT("Built without TBLITE")
    2394              : #endif
    2395              : 
    2396        51420 :    END SUBROUTINE tb_ham_add_coulomb
    2397              : 
    2398              : ! **************************************************************************************************
    2399              : !> \brief ...
    2400              : !> \param qs_env ...
    2401              : !> \param tb ...
    2402              : ! **************************************************************************************************
    2403         1224 :    SUBROUTINE tb_get_multipole(qs_env, tb)
    2404              : 
    2405              :       TYPE(qs_environment_type), POINTER                       :: qs_env
    2406              :       TYPE(tblite_type), POINTER                               :: tb
    2407              : 
    2408              : #if defined(__TBLITE)
    2409              : 
    2410              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tb_get_multipole'
    2411              : 
    2412              :       INTEGER                                     :: ikind, jkind, iatom, jatom, icol, irow, iset, jset, ityp, jtyp
    2413              :       INTEGER                                     :: ic, idx, id1, id2, id3, img, iq1, iq2, iq3, iq4, iq5, iq6
    2414              :       INTEGER                                     :: nkind, natom, handle, nimg, i, inda, indb
    2415              :       INTEGER                                     :: atom_a, atom_b, nseta, nsetb, ia, ib, ij
    2416              :       LOGICAL                                     :: found
    2417              :       REAL(KIND=dp)                               :: r2
    2418              :       INTEGER, DIMENSION(3)                       :: cell
    2419         1224 :       INTEGER, DIMENSION(:, :, :), POINTER        :: cell_to_index
    2420              :       REAL(KIND=dp), DIMENSION(3)                 :: rij
    2421         1224 :       INTEGER, DIMENSION(:), POINTER              :: la_max, lb_max
    2422         1224 :       INTEGER, DIMENSION(:), POINTER              :: nsgfa, nsgfb
    2423         1224 :       INTEGER, DIMENSION(:, :), POINTER           :: first_sgfa, first_sgfb
    2424         1224 :       INTEGER, ALLOCATABLE                        :: atom_of_kind(:)
    2425         1224 :       REAL(KIND=dp), ALLOCATABLE                  :: stmp(:)
    2426         1224 :       REAL(KIND=dp), ALLOCATABLE                  :: dtmp(:, :), qtmp(:, :), dtmpj(:, :), qtmpj(:, :)
    2427         1224 :       REAL(KIND=dp), DIMENSION(:, :), POINTER     :: dip_ket1, dip_ket2, dip_ket3, &
    2428         1224 :                                                      dip_bra1, dip_bra2, dip_bra3
    2429         1224 :       REAL(KIND=dp), DIMENSION(:, :), POINTER     :: quad_ket1, quad_ket2, quad_ket3, &
    2430         1224 :                                                      quad_ket4, quad_ket5, quad_ket6, &
    2431         1224 :                                                      quad_bra1, quad_bra2, quad_bra3, &
    2432         1224 :                                                      quad_bra4, quad_bra5, quad_bra6
    2433              : 
    2434         1224 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER         :: atomic_kind_set
    2435         1224 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER          :: matrix_s
    2436              :       TYPE(dft_control_type), POINTER                       :: dft_control
    2437              :       TYPE(gto_basis_set_type), POINTER                     :: basis_set_a, basis_set_b
    2438         1224 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER     :: basis_set_list
    2439              :       TYPE(kpoint_type), POINTER                            :: kpoints
    2440         1224 :       TYPE(neighbor_list_set_p_type), DIMENSION(:), POINTER :: sab_orb
    2441         1224 :       TYPE(neighbor_list_set_p_type), DIMENSION(:), POINTER :: sab_kp
    2442              :       TYPE(neighbor_list_iterator_p_type), &
    2443         1224 :          DIMENSION(:), POINTER                              :: nl_iterator
    2444         1224 :       TYPE(particle_type), DIMENSION(:), POINTER            :: particle_set
    2445         1224 :       TYPE(qs_kind_type), DIMENSION(:), POINTER             :: qs_kind_set
    2446              : 
    2447         1224 :       CALL timeset(routineN, handle)
    2448              : 
    2449              :       !get info from environment vaiarable
    2450         1224 :       NULLIFY (atomic_kind_set, qs_kind_set, sab_orb, sab_kp, particle_set)
    2451         1224 :       NULLIFY (dft_control, matrix_s, kpoints, cell_to_index)
    2452              :       CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, &
    2453              :                       qs_kind_set=qs_kind_set, &
    2454              :                       sab_orb=sab_orb, &
    2455              :                       sab_kp=sab_kp, &
    2456              :                       particle_set=particle_set, &
    2457              :                       dft_control=dft_control, &
    2458              :                       kpoints=kpoints, &
    2459         1224 :                       matrix_s_kp=matrix_s)
    2460         1224 :       natom = SIZE(particle_set)
    2461         1224 :       nkind = SIZE(atomic_kind_set)
    2462         1224 :       nimg = dft_control%nimages
    2463         1224 :       IF (nimg > 1) THEN
    2464          552 :          IF (.NOT. ASSOCIATED(sab_kp)) CPABORT("Missing k-point neighbor list for tblite multipoles")
    2465          552 :          sab_orb => sab_kp
    2466          552 :          CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
    2467              :       END IF
    2468              : 
    2469         1224 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
    2470              : 
    2471              :       !set up basis set lists
    2472         5446 :       ALLOCATE (basis_set_list(nkind))
    2473         1224 :       CALL basis_set_list_setup(basis_set_list, "ORB", qs_kind_set)
    2474              : 
    2475         3672 :       ALLOCATE (stmp(msao(tb%calc%bas%maxl)**2))
    2476         3672 :       ALLOCATE (dtmp(dip_n, msao(tb%calc%bas%maxl)**2))
    2477         3672 :       ALLOCATE (qtmp(quad_n, msao(tb%calc%bas%maxl)**2))
    2478         2448 :       ALLOCATE (dtmpj(dip_n, msao(tb%calc%bas%maxl)**2))
    2479         2448 :       ALLOCATE (qtmpj(quad_n, msao(tb%calc%bas%maxl)**2))
    2480              : 
    2481              :       ! allocate dipole/quadrupole moment matrix elemnts
    2482         1224 :       CALL dbcsr_allocate_matrix_set(tb%dipbra, dip_n*nimg)
    2483         1224 :       CALL dbcsr_allocate_matrix_set(tb%dipket, dip_n*nimg)
    2484         1224 :       CALL dbcsr_allocate_matrix_set(tb%quadbra, quad_n*nimg)
    2485         1224 :       CALL dbcsr_allocate_matrix_set(tb%quadket, quad_n*nimg)
    2486        21988 :       DO img = 1, nimg
    2487        83056 :          DO i = 1, dip_n
    2488        62292 :             idx = i + dip_n*(img - 1)
    2489        62292 :             ALLOCATE (tb%dipbra(idx)%matrix)
    2490        62292 :             ALLOCATE (tb%dipket(idx)%matrix)
    2491              :             CALL dbcsr_create(tb%dipbra(idx)%matrix, template=matrix_s(1, img)%matrix, &
    2492        62292 :                               name="DIPOLE BRAMATRIX")
    2493              :             CALL dbcsr_create(tb%dipket(idx)%matrix, template=matrix_s(1, img)%matrix, &
    2494        62292 :                               name="DIPOLE KETMATRIX")
    2495        62292 :             CALL cp_dbcsr_alloc_block_from_nbl(tb%dipbra(idx)%matrix, sab_orb)
    2496        83056 :             CALL cp_dbcsr_alloc_block_from_nbl(tb%dipket(idx)%matrix, sab_orb)
    2497              :          END DO
    2498       146572 :          DO i = 1, quad_n
    2499       124584 :             idx = i + quad_n*(img - 1)
    2500       124584 :             ALLOCATE (tb%quadbra(idx)%matrix)
    2501       124584 :             ALLOCATE (tb%quadket(idx)%matrix)
    2502              :             CALL dbcsr_create(tb%quadbra(idx)%matrix, template=matrix_s(1, img)%matrix, &
    2503       124584 :                               name="QUADRUPOLE BRAMATRIX")
    2504              :             CALL dbcsr_create(tb%quadket(idx)%matrix, template=matrix_s(1, img)%matrix, &
    2505       124584 :                               name="QUADRUPOLE KETMATRIX")
    2506       124584 :             CALL cp_dbcsr_alloc_block_from_nbl(tb%quadbra(idx)%matrix, sab_orb)
    2507       145348 :             CALL cp_dbcsr_alloc_block_from_nbl(tb%quadket(idx)%matrix, sab_orb)
    2508              :          END DO
    2509              :       END DO
    2510              : 
    2511              :       !loop over all atom pairs with a non-zero overlap (sab_orb)
    2512         1224 :       NULLIFY (nl_iterator)
    2513         1224 :       CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
    2514       254049 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
    2515              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
    2516       252825 :                                 iatom=iatom, jatom=jatom, r=rij, cell=cell)
    2517              : 
    2518      1011300 :          r2 = NORM2(rij(:))**2
    2519              : 
    2520       252825 :          icol = MAX(iatom, jatom)
    2521       252825 :          irow = MIN(iatom, jatom)
    2522              : 
    2523       252825 :          IF (iatom < jatom) THEN
    2524       311704 :             rij = -rij
    2525        77926 :             i = ikind
    2526        77926 :             ikind = jkind
    2527        77926 :             jkind = i
    2528              :          END IF
    2529              : 
    2530       252825 :          IF (nimg == 1) THEN
    2531              :             ic = 1
    2532              :          ELSE
    2533        60641 :             ic = cell_to_index(cell(1), cell(2), cell(3))
    2534        60641 :             CPASSERT(ic > 0)
    2535              :          END IF
    2536       252825 :          id1 = 1 + dip_n*(ic - 1)
    2537       252825 :          id2 = 2 + dip_n*(ic - 1)
    2538       252825 :          id3 = 3 + dip_n*(ic - 1)
    2539       252825 :          iq1 = 1 + quad_n*(ic - 1)
    2540       252825 :          iq2 = 2 + quad_n*(ic - 1)
    2541       252825 :          iq3 = 3 + quad_n*(ic - 1)
    2542       252825 :          iq4 = 4 + quad_n*(ic - 1)
    2543       252825 :          iq5 = 5 + quad_n*(ic - 1)
    2544       252825 :          iq6 = 6 + quad_n*(ic - 1)
    2545              : 
    2546       252825 :          ityp = tb%mol%id(icol)
    2547       252825 :          jtyp = tb%mol%id(irow)
    2548              : 
    2549       252825 :          NULLIFY (dip_bra1, dip_bra2, dip_bra3)
    2550              :          CALL dbcsr_get_block_p(matrix=tb%dipbra(id1)%matrix, &
    2551       252825 :                                 row=irow, col=icol, BLOCK=dip_bra1, found=found)
    2552       252825 :          CPASSERT(found)
    2553              :          CALL dbcsr_get_block_p(matrix=tb%dipbra(id2)%matrix, &
    2554       252825 :                                 row=irow, col=icol, BLOCK=dip_bra2, found=found)
    2555       252825 :          CPASSERT(found)
    2556              :          CALL dbcsr_get_block_p(matrix=tb%dipbra(id3)%matrix, &
    2557       252825 :                                 row=irow, col=icol, BLOCK=dip_bra3, found=found)
    2558       252825 :          CPASSERT(found)
    2559              : 
    2560       252825 :          NULLIFY (dip_ket1, dip_ket2, dip_ket3)
    2561              :          CALL dbcsr_get_block_p(matrix=tb%dipket(id1)%matrix, &
    2562       252825 :                                 row=irow, col=icol, BLOCK=dip_ket1, found=found)
    2563       252825 :          CPASSERT(found)
    2564              :          CALL dbcsr_get_block_p(matrix=tb%dipket(id2)%matrix, &
    2565       252825 :                                 row=irow, col=icol, BLOCK=dip_ket2, found=found)
    2566       252825 :          CPASSERT(found)
    2567              :          CALL dbcsr_get_block_p(matrix=tb%dipket(id3)%matrix, &
    2568       252825 :                                 row=irow, col=icol, BLOCK=dip_ket3, found=found)
    2569       252825 :          CPASSERT(found)
    2570              : 
    2571       252825 :          NULLIFY (quad_bra1, quad_bra2, quad_bra3, quad_bra4, quad_bra5, quad_bra6)
    2572              :          CALL dbcsr_get_block_p(matrix=tb%quadbra(iq1)%matrix, &
    2573       252825 :                                 row=irow, col=icol, BLOCK=quad_bra1, found=found)
    2574       252825 :          CPASSERT(found)
    2575              :          CALL dbcsr_get_block_p(matrix=tb%quadbra(iq2)%matrix, &
    2576       252825 :                                 row=irow, col=icol, BLOCK=quad_bra2, found=found)
    2577       252825 :          CPASSERT(found)
    2578              :          CALL dbcsr_get_block_p(matrix=tb%quadbra(iq3)%matrix, &
    2579       252825 :                                 row=irow, col=icol, BLOCK=quad_bra3, found=found)
    2580       252825 :          CPASSERT(found)
    2581              :          CALL dbcsr_get_block_p(matrix=tb%quadbra(iq4)%matrix, &
    2582       252825 :                                 row=irow, col=icol, BLOCK=quad_bra4, found=found)
    2583       252825 :          CPASSERT(found)
    2584              :          CALL dbcsr_get_block_p(matrix=tb%quadbra(iq5)%matrix, &
    2585       252825 :                                 row=irow, col=icol, BLOCK=quad_bra5, found=found)
    2586       252825 :          CPASSERT(found)
    2587              :          CALL dbcsr_get_block_p(matrix=tb%quadbra(iq6)%matrix, &
    2588       252825 :                                 row=irow, col=icol, BLOCK=quad_bra6, found=found)
    2589       252825 :          CPASSERT(found)
    2590              : 
    2591       252825 :          NULLIFY (quad_ket1, quad_ket2, quad_ket3, quad_ket4, quad_ket5, quad_ket6)
    2592              :          CALL dbcsr_get_block_p(matrix=tb%quadket(iq1)%matrix, &
    2593       252825 :                                 row=irow, col=icol, BLOCK=quad_ket1, found=found)
    2594       252825 :          CPASSERT(found)
    2595              :          CALL dbcsr_get_block_p(matrix=tb%quadket(iq2)%matrix, &
    2596       252825 :                                 row=irow, col=icol, BLOCK=quad_ket2, found=found)
    2597       252825 :          CPASSERT(found)
    2598              :          CALL dbcsr_get_block_p(matrix=tb%quadket(iq3)%matrix, &
    2599       252825 :                                 row=irow, col=icol, BLOCK=quad_ket3, found=found)
    2600       252825 :          CPASSERT(found)
    2601              :          CALL dbcsr_get_block_p(matrix=tb%quadket(iq4)%matrix, &
    2602       252825 :                                 row=irow, col=icol, BLOCK=quad_ket4, found=found)
    2603       252825 :          CPASSERT(found)
    2604              :          CALL dbcsr_get_block_p(matrix=tb%quadket(iq5)%matrix, &
    2605       252825 :                                 row=irow, col=icol, BLOCK=quad_ket5, found=found)
    2606       252825 :          CPASSERT(found)
    2607              :          CALL dbcsr_get_block_p(matrix=tb%quadket(iq6)%matrix, &
    2608       252825 :                                 row=irow, col=icol, BLOCK=quad_ket6, found=found)
    2609       252825 :          CPASSERT(found)
    2610              : 
    2611              :          !get basis information
    2612       252825 :          basis_set_a => basis_set_list(ikind)%gto_basis_set
    2613       252825 :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
    2614       252825 :          basis_set_b => basis_set_list(jkind)%gto_basis_set
    2615       252825 :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
    2616       252825 :          atom_a = atom_of_kind(icol)
    2617       252825 :          atom_b = atom_of_kind(irow)
    2618              :          ! basis a
    2619       252825 :          first_sgfa => basis_set_a%first_sgf
    2620       252825 :          la_max => basis_set_a%lmax
    2621       252825 :          nseta = basis_set_a%nset
    2622       252825 :          nsgfa => basis_set_a%nsgf_set
    2623              :          ! basis b
    2624       252825 :          first_sgfb => basis_set_b%first_sgf
    2625       252825 :          lb_max => basis_set_b%lmax
    2626       252825 :          nsetb = basis_set_b%nset
    2627       252825 :          nsgfb => basis_set_b%nsgf_set
    2628              : 
    2629              :          ! --------- Hamiltonian
    2630              :          ! Periodic self-images are off-diagonal lattice contributions, not the on-site block.
    2631       254049 :          IF (icol == irow .AND. r2 < same_atom**2) THEN
    2632         9729 :             DO iset = 1, nseta
    2633        29631 :                DO jset = 1, nsetb
    2634              :                   CALL multipole_cgto(tb%calc%bas%cgto(jset, ityp), tb%calc%bas%cgto(iset, ityp), &
    2635        79608 :                        & r2, -rij, tb%calc%bas%intcut, stmp, dtmp, qtmp)
    2636              : 
    2637        84440 :                   DO inda = 1, nsgfa(iset)
    2638        57460 :                      ia = first_sgfa(1, iset) - first_sgfa(1, 1) + inda
    2639       245668 :                      DO indb = 1, nsgfb(jset)
    2640       168306 :                         ib = first_sgfb(1, jset) - first_sgfb(1, 1) + indb
    2641       168306 :                         ij = indb + nsgfb(jset)*(inda - 1)
    2642              : 
    2643       168306 :                         dip_ket1(ib, ia) = dip_ket1(ib, ia) + dtmp(1, ij)
    2644       168306 :                         dip_ket2(ib, ia) = dip_ket2(ib, ia) + dtmp(2, ij)
    2645       168306 :                         dip_ket3(ib, ia) = dip_ket3(ib, ia) + dtmp(3, ij)
    2646              : 
    2647       168306 :                         quad_ket1(ib, ia) = quad_ket1(ib, ia) + qtmp(1, ij)
    2648       168306 :                         quad_ket2(ib, ia) = quad_ket2(ib, ia) + qtmp(2, ij)
    2649       168306 :                         quad_ket3(ib, ia) = quad_ket3(ib, ia) + qtmp(3, ij)
    2650       168306 :                         quad_ket4(ib, ia) = quad_ket4(ib, ia) + qtmp(4, ij)
    2651       168306 :                         quad_ket5(ib, ia) = quad_ket5(ib, ia) + qtmp(5, ij)
    2652       168306 :                         quad_ket6(ib, ia) = quad_ket6(ib, ia) + qtmp(6, ij)
    2653              : 
    2654       168306 :                         dip_bra1(ib, ia) = dip_bra1(ib, ia) + dtmp(1, ij)
    2655       168306 :                         dip_bra2(ib, ia) = dip_bra2(ib, ia) + dtmp(2, ij)
    2656       168306 :                         dip_bra3(ib, ia) = dip_bra3(ib, ia) + dtmp(3, ij)
    2657              : 
    2658       168306 :                         quad_bra1(ib, ia) = quad_bra1(ib, ia) + qtmp(1, ij)
    2659       168306 :                         quad_bra2(ib, ia) = quad_bra2(ib, ia) + qtmp(2, ij)
    2660       168306 :                         quad_bra3(ib, ia) = quad_bra3(ib, ia) + qtmp(3, ij)
    2661       168306 :                         quad_bra4(ib, ia) = quad_bra4(ib, ia) + qtmp(4, ij)
    2662       168306 :                         quad_bra5(ib, ia) = quad_bra5(ib, ia) + qtmp(5, ij)
    2663       225766 :                         quad_bra6(ib, ia) = quad_bra6(ib, ia) + qtmp(6, ij)
    2664              :                      END DO
    2665              :                   END DO
    2666              :                END DO
    2667              :             END DO
    2668              :          ELSE
    2669       998420 :             DO iset = 1, nseta
    2670      3239764 :                DO jset = 1, nsetb
    2671              :                   CALL multipole_cgto(tb%calc%bas%cgto(jset, jtyp), tb%calc%bas%cgto(iset, ityp), &
    2672      8965376 :                       & r2, -rij, tb%calc%bas%intcut, stmp, dtmp, qtmp)
    2673              : 
    2674      9706820 :                   DO inda = 1, nsgfa(iset)
    2675      6717230 :                      ia = first_sgfa(1, iset) - first_sgfa(1, 1) + inda
    2676     29097556 :                      DO indb = 1, nsgfb(jset)
    2677     20138982 :                         ib = first_sgfb(1, jset) - first_sgfb(1, 1) + indb
    2678              : 
    2679     20138982 :                         ij = indb + nsgfb(jset)*(inda - 1)
    2680              :                         CALL tb_shift_multipole(-rij, stmp(ij), dtmp(:, ij), qtmp(:, ij), &
    2681     80555928 :                                                 dtmpj(:, ij), qtmpj(:, ij))
    2682              : 
    2683     20138982 :                         dip_bra1(ib, ia) = dip_bra1(ib, ia) + dtmp(1, ij)
    2684     20138982 :                         dip_bra2(ib, ia) = dip_bra2(ib, ia) + dtmp(2, ij)
    2685     20138982 :                         dip_bra3(ib, ia) = dip_bra3(ib, ia) + dtmp(3, ij)
    2686              : 
    2687     20138982 :                         quad_bra1(ib, ia) = quad_bra1(ib, ia) + qtmp(1, ij)
    2688     20138982 :                         quad_bra2(ib, ia) = quad_bra2(ib, ia) + qtmp(2, ij)
    2689     20138982 :                         quad_bra3(ib, ia) = quad_bra3(ib, ia) + qtmp(3, ij)
    2690     20138982 :                         quad_bra4(ib, ia) = quad_bra4(ib, ia) + qtmp(4, ij)
    2691     20138982 :                         quad_bra5(ib, ia) = quad_bra5(ib, ia) + qtmp(5, ij)
    2692     20138982 :                         quad_bra6(ib, ia) = quad_bra6(ib, ia) + qtmp(6, ij)
    2693              : 
    2694     20138982 :                         dip_ket1(ib, ia) = dip_ket1(ib, ia) + dtmpj(1, ij)
    2695     20138982 :                         dip_ket2(ib, ia) = dip_ket2(ib, ia) + dtmpj(2, ij)
    2696     20138982 :                         dip_ket3(ib, ia) = dip_ket3(ib, ia) + dtmpj(3, ij)
    2697              : 
    2698     20138982 :                         quad_ket1(ib, ia) = quad_ket1(ib, ia) + qtmpj(1, ij)
    2699     20138982 :                         quad_ket2(ib, ia) = quad_ket2(ib, ia) + qtmpj(2, ij)
    2700     20138982 :                         quad_ket3(ib, ia) = quad_ket3(ib, ia) + qtmpj(3, ij)
    2701     20138982 :                         quad_ket4(ib, ia) = quad_ket4(ib, ia) + qtmpj(4, ij)
    2702     20138982 :                         quad_ket5(ib, ia) = quad_ket5(ib, ia) + qtmpj(5, ij)
    2703     26856212 :                         quad_ket6(ib, ia) = quad_ket6(ib, ia) + qtmpj(6, ij)
    2704              :                      END DO
    2705              :                   END DO
    2706              :                END DO
    2707              :             END DO
    2708              :          END IF
    2709              :       END DO
    2710         1224 :       CALL neighbor_list_iterator_release(nl_iterator)
    2711              : 
    2712        63516 :       DO i = 1, SIZE(tb%dipbra)
    2713        62292 :          CALL dbcsr_finalize(tb%dipbra(i)%matrix)
    2714        63516 :          CALL dbcsr_finalize(tb%dipket(i)%matrix)
    2715              :       END DO
    2716       125808 :       DO i = 1, SIZE(tb%quadbra)
    2717       124584 :          CALL dbcsr_finalize(tb%quadbra(i)%matrix)
    2718       125808 :          CALL dbcsr_finalize(tb%quadket(i)%matrix)
    2719              :       END DO
    2720              : 
    2721         1224 :       DEALLOCATE (basis_set_list)
    2722              : 
    2723         1224 :       CALL timestop(handle)
    2724              : 
    2725              : #else
    2726              :       MARK_USED(qs_env)
    2727              :       MARK_USED(tb)
    2728              :       CPABORT("Built without TBLITE")
    2729              : #endif
    2730              : 
    2731         2448 :    END SUBROUTINE tb_get_multipole
    2732              : 
    2733              : ! **************************************************************************************************
    2734              : !> \brief Shift a multipole operator from one center to the other.
    2735              : !> \param vec displacement vector between the two centers
    2736              : !> \param s overlap integral
    2737              : !> \param di dipole integral on the original center
    2738              : !> \param qi quadrupole integral on the original center
    2739              : !> \param dj dipole integral on the shifted center
    2740              : !> \param qj quadrupole integral on the shifted center
    2741              : ! **************************************************************************************************
    2742     20138982 :    PURE SUBROUTINE tb_shift_multipole(vec, s, di, qi, dj, qj)
    2743              : 
    2744              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: vec
    2745              :       REAL(KIND=dp), INTENT(IN)                          :: s
    2746              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: di, qi
    2747              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: dj, qj
    2748              : 
    2749              :       REAL(KIND=dp)                                      :: tr
    2750              : 
    2751     20138982 :       dj(1) = di(1) + vec(1)*s
    2752     20138982 :       dj(2) = di(2) + vec(2)*s
    2753     20138982 :       dj(3) = di(3) + vec(3)*s
    2754              : 
    2755     20138982 :       qj(1) = 2*vec(1)*di(1) + vec(1)**2*s
    2756     20138982 :       qj(3) = 2*vec(2)*di(2) + vec(2)**2*s
    2757     20138982 :       qj(6) = 2*vec(3)*di(3) + vec(3)**2*s
    2758     20138982 :       qj(2) = vec(1)*di(2) + vec(2)*di(1) + vec(1)*vec(2)*s
    2759     20138982 :       qj(4) = vec(1)*di(3) + vec(3)*di(1) + vec(1)*vec(3)*s
    2760     20138982 :       qj(5) = vec(2)*di(3) + vec(3)*di(2) + vec(2)*vec(3)*s
    2761     20138982 :       tr = 0.5_dp*(qj(1) + qj(3) + qj(6))
    2762              : 
    2763     20138982 :       qj(1) = qi(1) + 1.5_dp*qj(1) - tr
    2764     20138982 :       qj(2) = qi(2) + 1.5_dp*qj(2)
    2765     20138982 :       qj(3) = qi(3) + 1.5_dp*qj(3) - tr
    2766     20138982 :       qj(4) = qi(4) + 1.5_dp*qj(4)
    2767     20138982 :       qj(5) = qi(5) + 1.5_dp*qj(5)
    2768     20138982 :       qj(6) = qi(6) + 1.5_dp*qj(6) - tr
    2769              : 
    2770     20138982 :    END SUBROUTINE tb_shift_multipole
    2771              : 
    2772              : ! **************************************************************************************************
    2773              : !> \brief compute the mulliken properties (AO resolved)
    2774              : !> \param p_mat ...
    2775              : !> \param s_matrix ...
    2776              : !> \param charges ...
    2777              : !> \param para_env ...
    2778              : ! **************************************************************************************************
    2779       751246 :    SUBROUTINE tb_ao_charges_matrix(p_mat, s_matrix, charges, para_env)
    2780              :       TYPE(dbcsr_type), POINTER                          :: p_mat, s_matrix
    2781              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: charges
    2782              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2783              : 
    2784              :       INTEGER                                            :: i, iblock_col, iblock_row, j
    2785              :       LOGICAL                                            :: found
    2786       751246 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: p_block, s_block
    2787              :       TYPE(dbcsr_iterator_type)                          :: iter
    2788              : 
    2789     36445824 :       charges = 0.0_dp
    2790       751246 :       CALL dbcsr_iterator_start(iter, s_matrix)
    2791      6709689 :       DO WHILE (dbcsr_iterator_blocks_left(iter))
    2792      5958443 :          NULLIFY (s_block, p_block)
    2793      5958443 :          CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, s_block)
    2794      5958443 :          CALL dbcsr_get_block_p(matrix=p_mat, row=iblock_row, col=iblock_col, BLOCK=p_block, found=found)
    2795      5958443 :          IF (.NOT. found) CYCLE
    2796      5958443 :          IF (.NOT. (ASSOCIATED(s_block) .AND. ASSOCIATED(p_block))) CYCLE
    2797              : 
    2798     59006235 :          DO j = 1, SIZE(p_block, 2)
    2799    534867799 :             DO i = 1, SIZE(p_block, 1)
    2800    528909356 :                charges(i, iblock_row) = charges(i, iblock_row) + p_block(i, j)*s_block(i, j)
    2801              :             END DO
    2802              :          END DO
    2803      6709689 :          IF (iblock_col /= iblock_row) THEN
    2804     41213921 :             DO j = 1, SIZE(p_block, 2)
    2805    374104760 :                DO i = 1, SIZE(p_block, 1)
    2806    369952530 :                   charges(j, iblock_col) = charges(j, iblock_col) + p_block(i, j)*s_block(i, j)
    2807              :                END DO
    2808              :             END DO
    2809              :          END IF
    2810              :       END DO
    2811       751246 :       CALL dbcsr_iterator_stop(iter)
    2812     72140402 :       CALL para_env%sum(charges)
    2813              : 
    2814       751246 :    END SUBROUTINE tb_ao_charges_matrix
    2815              : 
    2816              : ! **************************************************************************************************
    2817              : !> \brief compute the AO-resolved Mulliken charges for one k-point spin channel.
    2818              : !> \param p_matrix_kp ...
    2819              : !> \param s_matrix_kp ...
    2820              : !> \param charges ...
    2821              : !> \param ispin ...
    2822              : !> \param para_env ...
    2823              : ! **************************************************************************************************
    2824        18620 :    SUBROUTINE tb_ao_charges_kp_spin(p_matrix_kp, s_matrix_kp, charges, ispin, para_env)
    2825              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: p_matrix_kp, s_matrix_kp
    2826              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: charges
    2827              :       INTEGER, INTENT(IN)                                :: ispin
    2828              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2829              : 
    2830              :       INTEGER                                            :: ic
    2831              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: image_charges
    2832              :       TYPE(dbcsr_type), POINTER                          :: p_mat, s_mat
    2833              : 
    2834       781680 :       charges = 0.0_dp
    2835        74480 :       ALLOCATE (image_charges(SIZE(charges, 1), SIZE(charges, 2)))
    2836       734512 :       DO ic = 1, SIZE(s_matrix_kp, 2)
    2837              :          NULLIFY (p_mat, s_mat)
    2838       715892 :          p_mat => p_matrix_kp(ispin, ic)%matrix
    2839       715892 :          s_mat => s_matrix_kp(1, ic)%matrix
    2840       734512 :          IF (ASSOCIATED(p_mat) .AND. ASSOCIATED(s_mat)) THEN
    2841       715892 :             image_charges = 0.0_dp
    2842       715892 :             CALL tb_ao_charges_matrix(p_mat, s_mat, image_charges, para_env)
    2843     34796272 :             charges(:, :) = charges(:, :) + image_charges(:, :)
    2844              :          END IF
    2845              :       END DO
    2846        18620 :       DEALLOCATE (image_charges)
    2847              : 
    2848        18620 :    END SUBROUTINE tb_ao_charges_kp_spin
    2849              : 
    2850              : ! **************************************************************************************************
    2851              : !> \brief compute the mulliken properties (AO resolved)
    2852              : !> \param p_mat ...
    2853              : !> \param bra_mat ...
    2854              : !> \param ket_mat ...
    2855              : !> \param output ...
    2856              : !> \param para_env ...
    2857              : ! **************************************************************************************************
    2858      4645152 :    SUBROUTINE tb_contract_dens_matrix(p_mat, bra_mat, ket_mat, output, para_env)
    2859              :       TYPE(dbcsr_type), POINTER                          :: p_mat, bra_mat, ket_mat
    2860              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: output
    2861              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2862              : 
    2863              :       INTEGER                                            :: i, iblock_col, iblock_row, j
    2864              :       LOGICAL                                            :: found
    2865      4645152 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: bra, ket, p_block
    2866              :       TYPE(dbcsr_iterator_type)                          :: iter
    2867              : 
    2868     26433090 :       output = 0.0_dp
    2869      4645152 :       CALL dbcsr_iterator_start(iter, bra_mat)
    2870     40250043 :       DO WHILE (dbcsr_iterator_blocks_left(iter))
    2871     35604891 :          NULLIFY (p_block, bra, ket)
    2872     35604891 :          CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, bra)
    2873     35604891 :          CALL dbcsr_get_block_p(matrix=p_mat, row=iblock_row, col=iblock_col, BLOCK=p_block, found=found)
    2874     35604891 :          IF (.NOT. found) CYCLE
    2875     35604891 :          CALL dbcsr_get_block_p(matrix=ket_mat, row=iblock_row, col=iblock_col, BLOCK=ket, found=found)
    2876     35604891 :          IF (.NOT. found) CPABORT("missing block")
    2877              : 
    2878     35604891 :          IF (.NOT. (ASSOCIATED(bra) .AND. ASSOCIATED(p_block))) CYCLE
    2879     40250043 :          IF (iblock_col == iblock_row) THEN
    2880    107220069 :             DO j = 1, SIZE(p_block, 1)
    2881    968330133 :                DO i = 1, SIZE(p_block, 2)
    2882    957436164 :                   output(iblock_row) = output(iblock_row) + p_block(j, i)*bra(j, i)
    2883              :                END DO
    2884              :             END DO
    2885              :          ELSE
    2886    246069432 :             DO j = 1, SIZE(p_block, 1)
    2887   2233890450 :                DO i = 1, SIZE(p_block, 2)
    2888   2209179528 :                   output(iblock_row) = output(iblock_row) + p_block(j, i)*ket(j, i)
    2889              :                END DO
    2890              :             END DO
    2891    246069432 :             DO j = 1, SIZE(p_block, 1)
    2892   2233890450 :                DO i = 1, SIZE(p_block, 2)
    2893   2209179528 :                   output(iblock_col) = output(iblock_col) + p_block(j, i)*bra(j, i)
    2894              :                END DO
    2895              :             END DO
    2896              :          END IF
    2897              :       END DO
    2898      4645152 :       CALL dbcsr_iterator_stop(iter)
    2899     48221028 :       CALL para_env%sum(output)
    2900              : 
    2901      4645152 :    END SUBROUTINE tb_contract_dens_matrix
    2902              : 
    2903              : ! **************************************************************************************************
    2904              : !> \brief compute the AO-resolved density contraction for one k-point spin channel.
    2905              : !> \param p_matrix ...
    2906              : !> \param bra_mat ...
    2907              : !> \param ket_mat ...
    2908              : !> \param iop ...
    2909              : !> \param nops ...
    2910              : !> \param output ...
    2911              : !> \param ispin ...
    2912              : !> \param para_env ...
    2913              : ! **************************************************************************************************
    2914       130104 :    SUBROUTINE tb_contract_dens_kp_spin(p_matrix, bra_mat, ket_mat, iop, nops, output, ispin, para_env)
    2915              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: p_matrix
    2916              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: bra_mat, ket_mat
    2917              :       INTEGER, INTENT(IN)                                :: iop, nops
    2918              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: output
    2919              :       INTEGER, INTENT(IN)                                :: ispin
    2920              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2921              : 
    2922              :       INTEGER                                            :: ic, idx, nimg
    2923              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: image_output
    2924              :       TYPE(dbcsr_type), POINTER                          :: p_mat
    2925              : 
    2926       130104 :       nimg = SIZE(p_matrix, 2)
    2927       665460 :       output = 0.0_dp
    2928       390312 :       ALLOCATE (image_output(SIZE(output)))
    2929      4539528 :       DO ic = 1, nimg
    2930      4409424 :          idx = iop + nops*(ic - 1)
    2931      4409424 :          CPASSERT(idx <= SIZE(bra_mat))
    2932      4409424 :          CPASSERT(idx <= SIZE(ket_mat))
    2933              :          NULLIFY (p_mat)
    2934      4409424 :          p_mat => p_matrix(ispin, ic)%matrix
    2935      4409424 :          image_output = 0.0_dp
    2936      4409424 :          CALL tb_contract_dens_matrix(p_mat, bra_mat(idx)%matrix, ket_mat(idx)%matrix, image_output, para_env)
    2937     25053732 :          output = output + image_output
    2938              :       END DO
    2939       130104 :       DEALLOCATE (image_output)
    2940              : 
    2941       130104 :    END SUBROUTINE tb_contract_dens_kp_spin
    2942              : 
    2943              : ! **************************************************************************************************
    2944              : !> \brief compute the mulliken properties (AO resolved)
    2945              : !> \param p_matrix ...
    2946              : !> \param bra_mat ...
    2947              : !> \param ket_mat ...
    2948              : !> \param output ...
    2949              : !> \param para_env ...
    2950              : !> \par History
    2951              : !>      adapted from ao_charges_2
    2952              : !> \note
    2953              : ! **************************************************************************************************
    2954            0 :    SUBROUTINE contract_dens(p_matrix, bra_mat, ket_mat, output, para_env)
    2955              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: p_matrix
    2956              :       TYPE(dbcsr_type), POINTER                          :: bra_mat, ket_mat
    2957              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: output
    2958              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2959              : 
    2960              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'contract_dens'
    2961              : 
    2962              :       INTEGER                                            :: handle, i, iblock_col, iblock_row, &
    2963              :                                                             ispin, j, nspin
    2964              :       LOGICAL                                            :: found
    2965            0 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: bra, ket, p_block
    2966              :       TYPE(dbcsr_iterator_type)                          :: iter
    2967              : 
    2968            0 :       CALL timeset(routineN, handle)
    2969              : 
    2970            0 :       nspin = SIZE(p_matrix)
    2971            0 :       output = 0.0_dp
    2972            0 :       DO ispin = 1, nspin
    2973            0 :          CALL dbcsr_iterator_start(iter, bra_mat)
    2974            0 :          DO WHILE (dbcsr_iterator_blocks_left(iter))
    2975            0 :             NULLIFY (p_block, bra, ket)
    2976              : 
    2977            0 :             CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, bra)
    2978              :             CALL dbcsr_get_block_p(matrix=p_matrix(ispin)%matrix, &
    2979            0 :                                    row=iblock_row, col=iblock_col, BLOCK=p_block, found=found)
    2980            0 :             IF (.NOT. found) CYCLE
    2981              :             CALL dbcsr_get_block_p(matrix=ket_mat, &
    2982            0 :                                    row=iblock_row, col=iblock_col, BLOCK=ket, found=found)
    2983            0 :             IF (.NOT. found) CPABORT("missing block")
    2984              : 
    2985            0 :             IF (.NOT. (ASSOCIATED(bra) .AND. ASSOCIATED(p_block))) CYCLE
    2986            0 :             IF (iblock_col == iblock_row) THEN
    2987            0 :                DO j = 1, SIZE(p_block, 1)
    2988            0 :                   DO i = 1, SIZE(p_block, 2)
    2989            0 :                      output(iblock_row) = output(iblock_row) + p_block(j, i)*bra(j, i)
    2990              :                   END DO
    2991              :                END DO
    2992              :             ELSE
    2993            0 :                DO j = 1, SIZE(p_block, 1)
    2994            0 :                   DO i = 1, SIZE(p_block, 2)
    2995            0 :                      output(iblock_row) = output(iblock_row) + p_block(j, i)*ket(j, i)
    2996              :                   END DO
    2997              :                END DO
    2998            0 :                DO j = 1, SIZE(p_block, 1)
    2999            0 :                   DO i = 1, SIZE(p_block, 2)
    3000            0 :                      output(iblock_col) = output(iblock_col) + p_block(j, i)*bra(j, i)
    3001              :                   END DO
    3002              :                END DO
    3003              :             END IF
    3004              :          END DO
    3005            0 :          CALL dbcsr_iterator_stop(iter)
    3006              :       END DO
    3007              : 
    3008            0 :       CALL para_env%sum(output)
    3009            0 :       CALL timestop(handle)
    3010              : 
    3011            0 :    END SUBROUTINE contract_dens
    3012              : 
    3013              : ! **************************************************************************************************
    3014              : !> \brief compute the AO-resolved density contraction for real-space k-point image matrices
    3015              : !> \param p_matrix ...
    3016              : !> \param bra_mat ...
    3017              : !> \param ket_mat ...
    3018              : !> \param iop ...
    3019              : !> \param nops ...
    3020              : !> \param output ...
    3021              : !> \param para_env ...
    3022              : ! **************************************************************************************************
    3023            0 :    SUBROUTINE contract_dens_kp(p_matrix, bra_mat, ket_mat, iop, nops, output, para_env)
    3024              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: p_matrix
    3025              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: bra_mat, ket_mat
    3026              :       INTEGER, INTENT(IN)                                :: iop, nops
    3027              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: output
    3028              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3029              : 
    3030              :       INTEGER                                            :: ic, idx, nimg
    3031              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: image_output
    3032            0 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: p_image
    3033              : 
    3034            0 :       nimg = SIZE(p_matrix, 2)
    3035            0 :       output = 0.0_dp
    3036            0 :       ALLOCATE (image_output(SIZE(output)))
    3037            0 :       DO ic = 1, nimg
    3038            0 :          idx = iop + nops*(ic - 1)
    3039            0 :          CPASSERT(idx <= SIZE(bra_mat))
    3040            0 :          CPASSERT(idx <= SIZE(ket_mat))
    3041              :          NULLIFY (p_image)
    3042            0 :          p_image => p_matrix(:, ic)
    3043            0 :          image_output = 0.0_dp
    3044            0 :          CALL contract_dens(p_image, bra_mat(idx)%matrix, ket_mat(idx)%matrix, image_output, para_env)
    3045            0 :          output = output + image_output
    3046              :       END DO
    3047            0 :       DEALLOCATE (image_output)
    3048              : 
    3049            0 :    END SUBROUTINE contract_dens_kp
    3050              : 
    3051              : ! **************************************************************************************************
    3052              : !> \brief save gradient to force
    3053              : !> \param qs_env ...
    3054              : !> \param tb ...
    3055              : !> \param para_env ...
    3056              : !> \param ityp ...
    3057              : !> \note
    3058              : ! **************************************************************************************************
    3059          754 :    SUBROUTINE tb_grad2force(qs_env, tb, para_env, ityp)
    3060              : 
    3061              :       TYPE(qs_environment_type)                          :: qs_env
    3062              :       TYPE(tblite_type)                                  :: tb
    3063              :       TYPE(mp_para_env_type)                             :: para_env
    3064              :       INTEGER                                            :: ityp
    3065              : 
    3066              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'tb_grad2force'
    3067              : 
    3068              :       CHARACTER(LEN=default_path_length)                 :: dump_file
    3069              :       INTEGER                                            :: atoma, dump_status, dump_unit, handle, &
    3070              :                                                             iatom, ikind, natom
    3071          754 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind, kind_of
    3072          754 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3073          754 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    3074          754 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    3075              : 
    3076          754 :       CALL timeset(routineN, handle)
    3077              : 
    3078          754 :       NULLIFY (force, atomic_kind_set)
    3079              :       CALL get_qs_env(qs_env=qs_env, force=force, particle_set=particle_set, &
    3080          754 :                       atomic_kind_set=atomic_kind_set)
    3081              :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
    3082          754 :                                atom_of_kind=atom_of_kind, kind_of=kind_of)
    3083              : 
    3084          754 :       natom = SIZE(particle_set)
    3085              : 
    3086          754 :       dump_status = 1
    3087              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    3088              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_FORCE_DUMP", dump_file, STATUS=dump_status)
    3089              : #endif
    3090              :       IF (dump_status == 0) THEN
    3091              :          OPEN (NEWUNIT=dump_unit, FILE=TRIM(dump_file), STATUS="UNKNOWN", &
    3092              :                POSITION="APPEND", ACTION="WRITE")
    3093              :          WRITE (dump_unit, "(A,1X,I0)") "component", ityp
    3094              :          DO iatom = 1, natom
    3095              :             WRITE (dump_unit, "(I0,3(1X,ES24.16))") iatom, tb%grad(:, iatom)/para_env%num_pe
    3096              :          END DO
    3097              :          CLOSE (dump_unit)
    3098              :       END IF
    3099              : 
    3100          754 :       SELECT CASE (ityp)
    3101              :       CASE DEFAULT
    3102            0 :          CPABORT("unknown force type")
    3103              :       CASE (0)
    3104          260 :          DO iatom = 1, natom
    3105          208 :             ikind = kind_of(iatom)
    3106          208 :             atoma = atom_of_kind(iatom)
    3107              :             force(ikind)%all_potential(:, atoma) = &
    3108          884 :                force(ikind)%all_potential(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
    3109              :          END DO
    3110              :       CASE (1)
    3111          572 :          DO iatom = 1, natom
    3112          458 :             ikind = kind_of(iatom)
    3113          458 :             atoma = atom_of_kind(iatom)
    3114              :             force(ikind)%repulsive(:, atoma) = &
    3115         1946 :                force(ikind)%repulsive(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
    3116              :          END DO
    3117              :       CASE (2)
    3118         1144 :          DO iatom = 1, natom
    3119          916 :             ikind = kind_of(iatom)
    3120          916 :             atoma = atom_of_kind(iatom)
    3121              :             force(ikind)%dispersion(:, atoma) = &
    3122         3892 :                force(ikind)%dispersion(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
    3123              :          END DO
    3124              :       CASE (3)
    3125          634 :          DO iatom = 1, natom
    3126          502 :             ikind = kind_of(iatom)
    3127          502 :             atoma = atom_of_kind(iatom)
    3128              :             force(ikind)%rho_elec(:, atoma) = &
    3129         2140 :                force(ikind)%rho_elec(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
    3130              :          END DO
    3131              :       CASE (4)
    3132         1144 :          DO iatom = 1, natom
    3133          916 :             ikind = kind_of(iatom)
    3134          916 :             atoma = atom_of_kind(iatom)
    3135              :             force(ikind)%overlap(:, atoma) = &
    3136         3892 :                force(ikind)%overlap(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
    3137              :          END DO
    3138              :       CASE (5)
    3139          754 :          DO iatom = 1, natom
    3140            0 :             ikind = kind_of(iatom)
    3141            0 :             atoma = atom_of_kind(iatom)
    3142              :             force(ikind)%efield(:, atoma) = &
    3143            0 :                force(ikind)%efield(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
    3144              :          END DO
    3145              :       END SELECT
    3146              : 
    3147          754 :       CALL timestop(handle)
    3148              : 
    3149         1508 :    END SUBROUTINE tb_grad2force
    3150              : 
    3151              : ! **************************************************************************************************
    3152              : !> \brief set gradient to zero
    3153              : !> \param qs_env ...
    3154              : !> \note
    3155              : ! **************************************************************************************************
    3156          114 :    SUBROUTINE tb_zero_force(qs_env)
    3157              : 
    3158              :       TYPE(qs_environment_type)                          :: qs_env
    3159              : 
    3160              :       INTEGER                                            :: iatom, ikind, natom
    3161          114 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: kind_of
    3162          114 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3163          114 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    3164          114 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    3165              : 
    3166          114 :       NULLIFY (force, atomic_kind_set)
    3167              :       CALL get_qs_env(qs_env=qs_env, force=force, particle_set=particle_set, &
    3168          114 :                       atomic_kind_set=atomic_kind_set)
    3169              :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
    3170          114 :                                kind_of=kind_of)
    3171              : 
    3172          114 :       natom = SIZE(particle_set)
    3173              : 
    3174          572 :       DO iatom = 1, natom
    3175          458 :          ikind = kind_of(iatom)
    3176         8162 :          force(ikind)%all_potential = 0.0_dp
    3177         8162 :          force(ikind)%repulsive = 0.0_dp
    3178         8162 :          force(ikind)%dispersion = 0.0_dp
    3179         8162 :          force(ikind)%rho_elec = 0.0_dp
    3180         8162 :          force(ikind)%overlap = 0.0_dp
    3181         8276 :          force(ikind)%efield = 0.0_dp
    3182              :       END DO
    3183              : 
    3184          228 :    END SUBROUTINE tb_zero_force
    3185              : 
    3186              : ! **************************************************************************************************
    3187              : !> \brief compute the derivative of the energy
    3188              : !> \param qs_env ...
    3189              : !> \param use_rho ...
    3190              : !> \param nimg ...
    3191              : ! **************************************************************************************************
    3192          114 :    SUBROUTINE tb_derive_dH_diag(qs_env, use_rho, nimg)
    3193              : 
    3194              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3195              :       LOGICAL, INTENT(IN)                                :: use_rho
    3196              :       INTEGER, INTENT(IN)                                :: nimg
    3197              : 
    3198              : #if defined(__TBLITE)
    3199              :       INTEGER                                            :: i, iatom, ic, ikind, ind, is, ish, ispin, &
    3200              :                                                             jatom, jkind
    3201              :       INTEGER, DIMENSION(3)                              :: cellind
    3202          114 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
    3203              :       LOGICAL                                            :: found
    3204              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: dE
    3205          114 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pblock
    3206          114 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p
    3207              :       TYPE(kpoint_type), POINTER                         :: kpoints
    3208              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3209              :       TYPE(neighbor_list_iterator_p_type), &
    3210          114 :          DIMENSION(:), POINTER                           :: nl_iterator
    3211              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    3212          114 :          POINTER                                         :: sab_orb
    3213              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    3214          114 :          POINTER                                         :: sab_kp
    3215              :       TYPE(qs_rho_type), POINTER                         :: rho
    3216              :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
    3217              :       TYPE(tblite_type), POINTER                         :: tb
    3218              : 
    3219              :       ! compute mulliken charges required for charge update
    3220          114 :       NULLIFY (scf_env, rho, tb, sab_orb, sab_kp, para_env, kpoints)
    3221              :       CALL get_qs_env(qs_env=qs_env, scf_env=scf_env, rho=rho, tb_tblite=tb, &
    3222          114 :                       sab_orb=sab_orb, sab_kp=sab_kp, para_env=para_env, kpoints=kpoints)
    3223              : 
    3224          114 :       NULLIFY (cell_to_index)
    3225          114 :       IF (nimg > 1) THEN
    3226           56 :          IF (.NOT. ASSOCIATED(sab_kp)) CPABORT("Missing tblite k-point neighbor list")
    3227           56 :          sab_orb => sab_kp
    3228           56 :          CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
    3229              :       END IF
    3230              : 
    3231          114 :       NULLIFY (matrix_p)
    3232          114 :       IF (use_rho) THEN
    3233           96 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
    3234           18 :       ELSEIF (ASSOCIATED(tb%rho_ao_kp_ref)) THEN
    3235           18 :          matrix_p => tb%rho_ao_kp_ref
    3236              :       ELSE
    3237            0 :          matrix_p => scf_env%p_mix_new
    3238              :       END IF
    3239              : 
    3240          342 :       ALLOCATE (dE(tb%mol%nat))
    3241              : 
    3242          114 :       dE = 0.0_dp
    3243              :       ! loop over all atom pairs with a non-zero overlap (sab_orb)
    3244          114 :       NULLIFY (nl_iterator)
    3245          114 :       CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
    3246        22021 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
    3247              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
    3248        21907 :                                 iatom=iatom, jatom=jatom, cell=cellind)
    3249              : 
    3250        21907 :          IF (iatom /= jatom) CYCLE
    3251              : 
    3252         5807 :          IF (ikind /= jkind) CPABORT("Type wrong")
    3253              : 
    3254         5807 :          is = tb%calc%bas%ish_at(iatom)
    3255              : 
    3256         5807 :          IF (nimg == 1) THEN
    3257              :             ic = 1
    3258              :          ELSE
    3259         2468 :             ic = cell_to_index(cellind(1), cellind(2), cellind(3))
    3260         2468 :             CPASSERT(ic > 0)
    3261              :          END IF
    3262              : 
    3263         5807 :          IF (cellind(1) /= 0) CYCLE
    3264         2017 :          IF (cellind(2) /= 0) CYCLE
    3265          651 :          IF (cellind(3) /= 0) CYCLE
    3266              : 
    3267          594 :          DO ispin = 1, SIZE(matrix_p, 1)
    3268              :             CALL dbcsr_get_block_p(matrix=matrix_p(ispin, ic)%matrix, &
    3269          251 :                                    row=iatom, col=jatom, BLOCK=pblock, found=found)
    3270              : 
    3271          251 :             IF (.NOT. found) CPABORT("block not found")
    3272              : 
    3273          251 :             ind = 0
    3274        23064 :             DO ish = 1, tb%calc%bas%nsh_id(ikind)
    3275         2643 :                DO i = 1, msao(tb%calc%bas%cgto(ish, ikind)%ang)
    3276         1737 :                   ind = ind + 1
    3277         2392 :                   dE(iatom) = dE(iatom) + tb%dsedcn(is + ish)*pblock(ind, ind)
    3278              :                END DO
    3279              :             END DO
    3280              :          END DO
    3281              :       END DO
    3282          114 :       CALL neighbor_list_iterator_release(nl_iterator)
    3283          114 :       CALL para_env%sum(dE)
    3284              : 
    3285         1946 :       tb%grad = 0.0_dp
    3286          114 :       CALL tb_add_grad(tb%grad, tb%dcndr, dE, tb%mol%nat)
    3287          114 :       IF (tb%use_virial) CALL tb_add_sig(tb%sigma, tb%dcndL, dE, tb%mol%nat)
    3288          114 :       CALL tb_grad2force(qs_env, tb, para_env, 4)
    3289          114 :       DEALLOCATE (dE)
    3290              : 
    3291              : #else
    3292              :       MARK_USED(qs_env)
    3293              :       MARK_USED(use_rho)
    3294              :       MARK_USED(nimg)
    3295              :       CPABORT("Built without TBLITE")
    3296              : #endif
    3297              : 
    3298          114 :    END SUBROUTINE tb_derive_dH_diag
    3299              : 
    3300              : ! **************************************************************************************************
    3301              : !> \brief compute the derivative of the energy
    3302              : !> \param qs_env ...
    3303              : !> \param use_rho ...
    3304              : !> \param nimg ...
    3305              : ! **************************************************************************************************
    3306          114 :    SUBROUTINE tb_derive_dH_off(qs_env, use_rho, nimg)
    3307              : 
    3308              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3309              :       LOGICAL, INTENT(IN)                                :: use_rho
    3310              :       INTEGER, INTENT(IN)                                :: nimg
    3311              : 
    3312              : #if defined(__TBLITE)
    3313              :       INTEGER                                            :: i, ij, iatom, ic, icol, ikind, ni, nj, nkind, nel, &
    3314              :                                                             sgfi, sgfj, ityp, jatom, jkind, jrow, jtyp, iset, jset, &
    3315              :                                                             nseti, nsetj, ia, ib, inda, indb, fold_index, &
    3316              :                                                             has_nyquist_image, n_cn_norm_images, n_periodic, &
    3317              :                                                             n_non_nyquist_images, &
    3318              :                                                             n_sampled_kpoints, sampled_axes, sampled_even_axes, &
    3319              :                                                             sampled_non_nyquist_axes, sampled_odd_axes, nspin
    3320              :       INTEGER, DIMENSION(3)                              :: cellind, fold_shape, nkp_cellind, nkp_grid
    3321          114 :       INTEGER, DIMENSION(:), POINTER                     :: nsgfa, nsgfb
    3322          114 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
    3323          114 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
    3324              :       LOGICAL                                            :: found, has_multipole_response, image_pair, kpoint_image_pair, &
    3325              :                                                             sampled_image_pair
    3326              :       REAL(KIND=dp)                                      :: r2, dr, itemp, jtemp, rr, hij, shpoly, dshpoly, idHdc, jdHdc, &
    3327              :                                                             scal, hp, i_a_shift, j_a_shift, i_a_shift_mag, j_a_shift_mag, &
    3328              :                                                             ishift, jshift, ishift_mag, jshift_mag, pij_charge, &
    3329              :                                                             pij_magnet, wij_charge, &
    3330              :                                                             dip_deriv_fac, quad_deriv_fac, dip_deriv_fac_pair, &
    3331              :                                                             quad_deriv_fac_pair, overlap_deriv_fac, pot_deriv_scale, &
    3332              :                                                             w_deriv_scale, h0_deriv_scale, mp_deriv_scale, &
    3333              :                                                             pot_image_deriv_scale, w_image_deriv_scale, &
    3334              :                                                             h0_image_deriv_scale, mp_image_deriv_scale, &
    3335              :                                                             pot_pair_scale, w_pair_scale, h0_pair_scale, mp_pair_scale, &
    3336              :                                                             pot_self_image_deriv_scale, w_self_image_deriv_scale, &
    3337              :                                                             h0_self_image_deriv_scale, mp_self_image_deriv_scale, &
    3338              :                                                             cn_image_scale, cn_deriv_scale, &
    3339              :                                                             nyquist_self_image_deriv_scale
    3340              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    3341              :       INTEGER                                            :: debug_status
    3342              :       CHARACTER(LEN=32)                                  :: scale_value
    3343              : #endif
    3344              :       REAL(KIND=dp), DIMENSION(3)                        :: rij, dgrad
    3345              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hsigma
    3346          114 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: dE, t_ov, idip, jdip, idip_mag, jdip_mag, &
    3347          114 :                                                             iquad, jquad, iquad_mag, jquad_mag
    3348          114 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: non_nyquist_folded_seen
    3349          114 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: t_dip, t_quad, t_d_ov
    3350          114 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: t_i_dip, t_i_quad, t_j_dip, t_j_quad
    3351          114 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pblock, pblock_beta, wblock, wblock_beta
    3352              : 
    3353          114 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3354          114 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_w
    3355          114 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
    3356              :       TYPE(gto_basis_set_type), POINTER            :: basis_set_a, basis_set_b
    3357              :       TYPE(kpoint_type), POINTER                         :: kpoints
    3358              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3359              :       TYPE(neighbor_list_iterator_p_type), &
    3360          114 :          DIMENSION(:), POINTER                           :: nl_iterator
    3361              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    3362          114 :          POINTER                                         :: sab_orb
    3363              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    3364          114 :          POINTER                                         :: sab_kp
    3365          114 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    3366              :       TYPE(qs_rho_type), POINTER                         :: rho
    3367              :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
    3368              :       TYPE(tb_hamiltonian), POINTER                      :: h0
    3369              :       TYPE(tblite_type), POINTER                         :: tb
    3370              : 
    3371              :       ! compute mulliken charges required for charge update
    3372          114 :       NULLIFY (scf_env, rho, tb, sab_orb, sab_kp, para_env, kpoints, matrix_w)
    3373              :       CALL get_qs_env(qs_env=qs_env, &
    3374              :                       atomic_kind_set=atomic_kind_set, &
    3375              :                       scf_env=scf_env, &
    3376              :                       rho=rho, &
    3377              :                       tb_tblite=tb, &
    3378              :                       sab_orb=sab_orb, &
    3379              :                       sab_kp=sab_kp, &
    3380              :                       para_env=para_env, &
    3381              :                       qs_kind_set=qs_kind_set, &
    3382              :                       kpoints=kpoints, &
    3383          114 :                       matrix_w_kp=matrix_w)
    3384              : 
    3385          114 :       NULLIFY (cell_to_index)
    3386          114 :       IF (nimg > 1) THEN
    3387           56 :          IF (.NOT. ASSOCIATED(sab_kp)) CPABORT("Missing tblite k-point neighbor list")
    3388           56 :          sab_orb => sab_kp
    3389           56 :          CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index, nkp_grid=nkp_grid)
    3390              :       ELSE
    3391          232 :          nkp_grid = 1
    3392              :       END IF
    3393          114 :       sampled_odd_axes = 0
    3394          114 :       IF (nkp_grid(1) > 1 .AND. MODULO(nkp_grid(1), 2) == 1) sampled_odd_axes = sampled_odd_axes + 1
    3395          114 :       IF (nkp_grid(2) > 1 .AND. MODULO(nkp_grid(2), 2) == 1) sampled_odd_axes = sampled_odd_axes + 1
    3396          114 :       IF (nkp_grid(3) > 1 .AND. MODULO(nkp_grid(3), 2) == 1) sampled_odd_axes = sampled_odd_axes + 1
    3397          456 :       n_periodic = COUNT(tb%mol%periodic)
    3398              :       n_sampled_kpoints = 1
    3399          456 :       DO i = 1, 3
    3400          456 :          IF (tb%mol%periodic(i)) n_sampled_kpoints = n_sampled_kpoints*nkp_grid(i)
    3401              :       END DO
    3402              : 
    3403          114 :       h0 => tb%calc%h0
    3404          114 :       has_multipole_response = ASSOCIATED(tb%dipbra) .OR. ASSOCIATED(tb%quadbra)
    3405          114 :       dip_deriv_fac = -1.0_dp
    3406          114 :       quad_deriv_fac = -1.0_dp
    3407          114 :       pot_deriv_scale = 1.0_dp
    3408          114 :       w_deriv_scale = 1.0_dp
    3409          114 :       h0_deriv_scale = 1.0_dp
    3410          114 :       mp_deriv_scale = 1.0_dp
    3411              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    3412              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_POT_SCALE", scale_value, STATUS=debug_status)
    3413              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) pot_deriv_scale
    3414              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_W_SCALE", scale_value, STATUS=debug_status)
    3415              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) w_deriv_scale
    3416              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_H0_SCALE", scale_value, STATUS=debug_status)
    3417              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) h0_deriv_scale
    3418              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_MP_SCALE", scale_value, STATUS=debug_status)
    3419              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) mp_deriv_scale
    3420              : #endif
    3421          114 :       pot_image_deriv_scale = pot_deriv_scale
    3422          114 :       w_image_deriv_scale = w_deriv_scale
    3423          114 :       h0_image_deriv_scale = h0_deriv_scale
    3424          114 :       mp_image_deriv_scale = mp_deriv_scale
    3425              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    3426              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_POT_IMAGE_SCALE", scale_value, STATUS=debug_status)
    3427              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) pot_image_deriv_scale
    3428              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_W_IMAGE_SCALE", scale_value, STATUS=debug_status)
    3429              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) w_image_deriv_scale
    3430              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_H0_IMAGE_SCALE", scale_value, STATUS=debug_status)
    3431              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) h0_image_deriv_scale
    3432              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_MP_IMAGE_SCALE", scale_value, STATUS=debug_status)
    3433              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) mp_image_deriv_scale
    3434              : #endif
    3435          114 :       pot_self_image_deriv_scale = pot_image_deriv_scale
    3436          114 :       w_self_image_deriv_scale = w_image_deriv_scale
    3437          114 :       h0_self_image_deriv_scale = h0_image_deriv_scale
    3438          114 :       mp_self_image_deriv_scale = mp_image_deriv_scale
    3439              :       ! K-point self-images are stored in CP2K's sorted on-site image block.
    3440              :       ! Keep the sampled-image H0 response on the real-space normalization. The
    3441              :       ! corresponding Pulay/W contribution is normalized below from the
    3442              :       ! Nyquist multiplicity of the sampled k-point image. Multipole models use
    3443              :       ! the sampled matrix block orientation for their self-image derivatives.
    3444          304 :       IF (nimg > 1 .AND. ANY(nkp_grid > 1) .AND. has_multipole_response) &
    3445           30 :          mp_self_image_deriv_scale = -mp_image_deriv_scale
    3446              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    3447              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_POT_SELF_IMAGE_SCALE", scale_value, STATUS=debug_status)
    3448              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) pot_self_image_deriv_scale
    3449              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_W_SELF_IMAGE_SCALE", scale_value, STATUS=debug_status)
    3450              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) w_self_image_deriv_scale
    3451              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_H0_SELF_IMAGE_SCALE", scale_value, STATUS=debug_status)
    3452              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) h0_self_image_deriv_scale
    3453              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_MP_SELF_IMAGE_SCALE", scale_value, STATUS=debug_status)
    3454              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) mp_self_image_deriv_scale
    3455              : #endif
    3456          114 :       cn_image_scale = 1.0_dp
    3457          256 :       IF (nimg > 1 .AND. ANY(tb%mol%periodic)) cn_image_scale = -0.25_dp
    3458          114 :       cn_deriv_scale = 1.0_dp
    3459              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    3460              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DH_CN_IMAGE_SCALE", scale_value, STATUS=debug_status)
    3461              :       IF (debug_status == 0) READ (scale_value, *, IOSTAT=debug_status) cn_image_scale
    3462              : #endif
    3463              : 
    3464          114 :       NULLIFY (matrix_p)
    3465          114 :       IF (use_rho) THEN
    3466           96 :          CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
    3467           18 :       ELSEIF (ASSOCIATED(tb%rho_ao_kp_ref)) THEN
    3468           18 :          matrix_p => tb%rho_ao_kp_ref
    3469              :       ELSE
    3470            0 :          matrix_p => scf_env%p_mix_new
    3471              :       END IF
    3472          114 :       nspin = SIZE(matrix_p, 1)
    3473              : 
    3474              :       ! set up basis set lists
    3475          114 :       nkind = SIZE(atomic_kind_set)
    3476          516 :       ALLOCATE (basis_set_list(nkind))
    3477          114 :       CALL basis_set_list_setup(basis_set_list, "ORB", qs_kind_set)
    3478              : 
    3479          342 :       ALLOCATE (dE(tb%mol%nat))
    3480              : 
    3481          114 :       nel = msao(tb%calc%bas%maxl)**2
    3482          342 :       ALLOCATE (t_ov(nel))
    3483          342 :       ALLOCATE (t_d_ov(3, nel))
    3484          228 :       ALLOCATE (t_dip(dip_n, nel))
    3485          456 :       ALLOCATE (t_i_dip(3, dip_n, nel), t_j_dip(3, dip_n, nel))
    3486          342 :       ALLOCATE (t_quad(quad_n, nel))
    3487          456 :       ALLOCATE (t_i_quad(3, quad_n, nel), t_j_quad(3, quad_n, nel))
    3488              : 
    3489          114 :       ALLOCATE (idip(dip_n), jdip(dip_n), idip_mag(dip_n), jdip_mag(dip_n))
    3490          114 :       ALLOCATE (iquad(quad_n), jquad(quad_n), iquad_mag(quad_n), jquad_mag(quad_n))
    3491              : 
    3492          114 :       dE = 0.0_dp
    3493         1946 :       tb%grad = 0.0_dp
    3494          114 :       hsigma = 0.0_dp
    3495          456 :       fold_shape = 2*nkp_grid + 1
    3496          684 :       ALLOCATE (non_nyquist_folded_seen(PRODUCT(fold_shape)))
    3497          114 :       non_nyquist_folded_seen = 0
    3498          114 :       has_nyquist_image = 0
    3499              :       ! loop over all atom pairs with a non-zero overlap (sab_orb)
    3500          114 :       NULLIFY (nl_iterator)
    3501          114 :       CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
    3502        22021 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
    3503              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
    3504        21907 :                                 iatom=iatom, jatom=jatom, r=rij, cell=cellind)
    3505              : 
    3506        21907 :          icol = MAX(iatom, jatom)
    3507        21907 :          jrow = MIN(iatom, jatom)
    3508              : 
    3509        21907 :          IF (iatom < jatom) THEN
    3510        26676 :             rij = -rij
    3511         6669 :             i = ikind
    3512         6669 :             ikind = jkind
    3513         6669 :             jkind = i
    3514              :          END IF
    3515              : 
    3516        21907 :          ityp = tb%mol%id(icol)
    3517        21907 :          jtyp = tb%mol%id(jrow)
    3518              : 
    3519        87628 :          r2 = DOT_PRODUCT(rij, rij)
    3520        21907 :          dr = SQRT(r2)
    3521        21907 :          IF (icol == jrow .AND. dr < same_atom) CYCLE
    3522        21678 :          rr = SQRT(dr/(h0%rad(ikind) + h0%rad(jkind)))
    3523              : 
    3524              :          !get basis information
    3525        21678 :          basis_set_a => basis_set_list(ikind)%gto_basis_set
    3526        21678 :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
    3527        21678 :          first_sgfa => basis_set_a%first_sgf
    3528        21678 :          nsgfa => basis_set_a%nsgf_set
    3529        21678 :          nseti = basis_set_a%nset
    3530        21678 :          basis_set_b => basis_set_list(jkind)%gto_basis_set
    3531        21678 :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
    3532        21678 :          first_sgfb => basis_set_b%first_sgf
    3533        21678 :          nsgfb => basis_set_b%nsgf_set
    3534        21678 :          nsetj = basis_set_b%nset
    3535              : 
    3536        21678 :          IF (nimg == 1) THEN
    3537              :             ic = 1
    3538              :          ELSE
    3539         8854 :             ic = cell_to_index(cellind(1), cellind(2), cellind(3))
    3540         8854 :             CPASSERT(ic > 0)
    3541              :          END IF
    3542        21678 :          image_pair = (cellind(1) /= 0 .OR. cellind(2) /= 0 .OR. cellind(3) /= 0)
    3543        21678 :          nkp_cellind = 0
    3544        86712 :          DO i = 1, 3
    3545        86712 :             IF (nkp_grid(i) > 1) THEN
    3546        25902 :                nkp_cellind(i) = MODULO(cellind(i), nkp_grid(i))
    3547        25902 :                IF (2*nkp_cellind(i) > nkp_grid(i)) nkp_cellind(i) = nkp_cellind(i) - nkp_grid(i)
    3548              :             END IF
    3549              :          END DO
    3550        21678 :          sampled_axes = 0
    3551        21678 :          IF (nkp_cellind(1) /= 0) sampled_axes = sampled_axes + 1
    3552        21678 :          IF (nkp_cellind(2) /= 0) sampled_axes = sampled_axes + 1
    3553        21678 :          IF (nkp_cellind(3) /= 0) sampled_axes = sampled_axes + 1
    3554        21678 :          kpoint_image_pair = image_pair .AND. sampled_axes > 0
    3555        21678 :          sampled_even_axes = 0
    3556        21678 :          IF (nkp_grid(1) > 1 .AND. MODULO(nkp_grid(1), 2) == 0 .AND. &
    3557         3669 :              ABS(2*nkp_cellind(1)) == nkp_grid(1)) sampled_even_axes = sampled_even_axes + 1
    3558        21678 :          IF (nkp_grid(2) > 1 .AND. MODULO(nkp_grid(2), 2) == 0 .AND. &
    3559         3830 :              ABS(2*nkp_cellind(2)) == nkp_grid(2)) sampled_even_axes = sampled_even_axes + 1
    3560        21678 :          IF (nkp_grid(3) > 1 .AND. MODULO(nkp_grid(3), 2) == 0 .AND. &
    3561         3889 :              ABS(2*nkp_cellind(3)) == nkp_grid(3)) sampled_even_axes = sampled_even_axes + 1
    3562        21678 :          sampled_non_nyquist_axes = MAX(0, sampled_axes - sampled_even_axes)
    3563        21678 :          IF (kpoint_image_pair .AND. sampled_even_axes > 0) has_nyquist_image = 1
    3564        21678 :          IF (kpoint_image_pair .AND. sampled_non_nyquist_axes > 0 .AND. sampled_even_axes == 0) THEN
    3565              :             fold_index = 1 + (nkp_cellind(1) + nkp_grid(1)) &
    3566              :                          + fold_shape(1)*(nkp_cellind(2) + nkp_grid(2)) &
    3567         1406 :                          + fold_shape(1)*fold_shape(2)*(nkp_cellind(3) + nkp_grid(3))
    3568         1406 :             non_nyquist_folded_seen(fold_index) = 1
    3569              :          END IF
    3570        21678 :          sampled_image_pair = kpoint_image_pair .AND. sampled_even_axes > 0
    3571              :          pot_pair_scale = MERGE(pot_image_deriv_scale, pot_deriv_scale, image_pair)
    3572              :          w_pair_scale = MERGE(w_image_deriv_scale, w_deriv_scale, image_pair)
    3573              :          h0_pair_scale = MERGE(h0_image_deriv_scale, h0_deriv_scale, image_pair)
    3574              :          mp_pair_scale = MERGE(mp_image_deriv_scale, mp_deriv_scale, image_pair)
    3575        21678 :          IF (icol == jrow .AND. sampled_image_pair) THEN
    3576         2008 :             pot_pair_scale = pot_self_image_deriv_scale
    3577         2008 :             w_pair_scale = w_self_image_deriv_scale
    3578              :             ! sampled_even_axes identifies a Nyquist self-image. The sorted
    3579              :             ! self-image block needs one normalization; the multiplicity follows
    3580              :             ! from the sampled mesh, periodicity, and active response channels.
    3581         2008 :             nyquist_self_image_deriv_scale = 1.0_dp
    3582         2008 :             IF (has_multipole_response) THEN
    3583          712 :                IF (n_periodic > 1) &
    3584              :                   nyquist_self_image_deriv_scale = 1.0_dp + REAL(n_periodic, dp)/ &
    3585          696 :                                                    REAL(n_sampled_kpoints*(1 + dip_n + quad_n), dp)
    3586         1296 :             ELSEIF (n_periodic == 3) THEN
    3587         1216 :                nyquist_self_image_deriv_scale = 1.0_dp + 1.0_dp/REAL(n_sampled_kpoints*n_periodic, dp)
    3588              :             END IF
    3589         2008 :             w_pair_scale = w_pair_scale*nyquist_self_image_deriv_scale
    3590              :             ! Odd Monkhorst-Pack meshes do not contain a Nyquist image along the
    3591              :             ! sampled axis. Match the self-image W derivative to the reduced
    3592              :             ! real-space representation used by the k-point density transform.
    3593         2008 :             w_pair_scale = w_pair_scale*(1.0_dp - 0.125_dp*REAL(sampled_odd_axes, dp))
    3594         2008 :             h0_pair_scale = h0_self_image_deriv_scale
    3595         2008 :             mp_pair_scale = mp_self_image_deriv_scale
    3596              :          END IF
    3597              : 
    3598        21678 :          NULLIFY (pblock, pblock_beta)
    3599              :          CALL dbcsr_get_block_p(matrix=matrix_p(1, ic)%matrix, &
    3600        21678 :                                 row=jrow, col=icol, BLOCK=pblock, found=found)
    3601        21678 :          IF (.NOT. found) CPABORT("pblock not found")
    3602        21678 :          IF (nspin > 1) THEN
    3603              :             CALL dbcsr_get_block_p(matrix=matrix_p(2, ic)%matrix, &
    3604           19 :                                    row=jrow, col=icol, BLOCK=pblock_beta, found=found)
    3605           19 :             IF (.NOT. found) CPABORT("pblock beta not found")
    3606              :          END IF
    3607              : 
    3608        21678 :          NULLIFY (wblock, wblock_beta)
    3609              :          CALL dbcsr_get_block_p(matrix=matrix_w(1, ic)%matrix, &
    3610        21678 :                                 row=jrow, col=icol, block=wblock, found=found)
    3611        21678 :          CPASSERT(found)
    3612        21678 :          IF (nspin > 1) THEN
    3613              :             CALL dbcsr_get_block_p(matrix=matrix_w(2, ic)%matrix, &
    3614           19 :                                    row=jrow, col=icol, block=wblock_beta, found=found)
    3615           19 :             CPASSERT(found)
    3616              :          END IF
    3617              : 
    3618        21678 :          i_a_shift = tb%pot%vat(icol, 1)
    3619        21678 :          j_a_shift = tb%pot%vat(jrow, 1)
    3620        21678 :          i_a_shift_mag = 0.0_dp
    3621        21678 :          j_a_shift_mag = 0.0_dp
    3622        21678 :          IF (SIZE(tb%pot%vat, 2) > 1) THEN
    3623           19 :             i_a_shift_mag = tb%pot%vat(icol, 2)
    3624           19 :             j_a_shift_mag = tb%pot%vat(jrow, 2)
    3625              :          END IF
    3626        86712 :          idip(:) = tb%pot%vdp(:, icol, 1)
    3627        86712 :          jdip(:) = tb%pot%vdp(:, jrow, 1)
    3628        21678 :          idip_mag(:) = 0.0_dp
    3629        21678 :          jdip_mag(:) = 0.0_dp
    3630        21678 :          IF (SIZE(tb%pot%vdp, 3) > 1) THEN
    3631           76 :             idip_mag(:) = tb%pot%vdp(:, icol, 2)
    3632           76 :             jdip_mag(:) = tb%pot%vdp(:, jrow, 2)
    3633              :          END IF
    3634       151746 :          iquad(:) = tb%pot%vqp(:, icol, 1)
    3635       151746 :          jquad(:) = tb%pot%vqp(:, jrow, 1)
    3636        21678 :          iquad_mag(:) = 0.0_dp
    3637        21678 :          jquad_mag(:) = 0.0_dp
    3638        21678 :          IF (SIZE(tb%pot%vqp, 3) > 1) THEN
    3639          133 :             iquad_mag(:) = tb%pot%vqp(:, icol, 2)
    3640          133 :             jquad_mag(:) = tb%pot%vqp(:, jrow, 2)
    3641              :          END IF
    3642        21678 :          dip_deriv_fac_pair = dip_deriv_fac
    3643        21678 :          quad_deriv_fac_pair = quad_deriv_fac
    3644        21678 :          overlap_deriv_fac = 1.0_dp
    3645              : 
    3646        21678 :          ni = tb%calc%bas%ish_at(icol)
    3647        86060 :          DO iset = 1, nseti
    3648        64268 :             sgfi = first_sgfa(1, iset)
    3649        64268 :             ishift = i_a_shift + tb%pot%vsh(ni + iset, 1)
    3650        64268 :             ishift_mag = 0.0_dp
    3651        64268 :             IF (SIZE(tb%pot%vsh, 2) > 1) ishift_mag = i_a_shift_mag + tb%pot%vsh(ni + iset, 2)
    3652        64268 :             nj = tb%calc%bas%ish_at(jrow)
    3653       277517 :             DO jset = 1, nsetj
    3654       191342 :                sgfj = first_sgfb(1, jset)
    3655       191342 :                jshift = j_a_shift + tb%pot%vsh(nj + jset, 1)
    3656       191342 :                jshift_mag = 0.0_dp
    3657       191342 :                IF (SIZE(tb%pot%vsh, 2) > 1) jshift_mag = j_a_shift_mag + tb%pot%vsh(nj + jset, 2)
    3658              : 
    3659              :                !get integrals and derivatives
    3660              :                CALL multipole_grad_cgto(tb%calc%bas%cgto(iset, ityp), tb%calc%bas%cgto(jset, jtyp), &
    3661              :                   & r2, rij, tb%calc%bas%intcut, t_ov, t_dip, t_quad, t_d_ov, t_i_dip, t_i_quad, &
    3662       191342 :                   & t_j_dip, t_j_quad)
    3663              : 
    3664              :                shpoly = (1.0_dp + h0%shpoly(iset, ikind)*rr) &
    3665       191342 :                         *(1.0_dp + h0%shpoly(jset, jkind)*rr)
    3666              :                dshpoly = ((1.0_dp + h0%shpoly(iset, ikind)*rr)*h0%shpoly(jset, jkind)*rr &
    3667              :                           + (1.0_dp + h0%shpoly(jset, jkind)*rr)*h0%shpoly(iset, ikind)*rr) &
    3668       191342 :                          *0.5_dp/r2
    3669       191342 :                scal = h0%hscale(iset, jset, ikind, jkind)
    3670       191342 :                hij = 0.5_dp*(tb%selfenergy(ni + iset) + tb%selfenergy(nj + jset))*scal
    3671              : 
    3672       191342 :                idHdc = tb%dsedcn(ni + iset)*shpoly*scal
    3673       191342 :                jdHdc = tb%dsedcn(nj + jset)*shpoly*scal
    3674              : 
    3675       191342 :                itemp = 0.0_dp
    3676       191342 :                jtemp = 0.0_dp
    3677       191342 :                dgrad = 0.0_dp
    3678       761422 :                DO inda = 1, nsgfa(iset)
    3679       570080 :                   ia = first_sgfa(1, iset) - first_sgfa(1, 1) + inda
    3680      2466192 :                   DO indb = 1, nsgfb(jset)
    3681      1704770 :                      ib = first_sgfb(1, jset) - first_sgfb(1, 1) + indb
    3682              : 
    3683      1704770 :                      ij = inda + nsgfa(iset)*(indb - 1)
    3684              : 
    3685      1704770 :                      pij_charge = pblock(ib, ia)
    3686      1704770 :                      pij_magnet = 0.0_dp
    3687      1704770 :                      wij_charge = wblock(ib, ia)
    3688      1704770 :                      IF (nspin > 1) THEN
    3689          206 :                         pij_charge = pij_charge + pblock_beta(ib, ia)
    3690          206 :                         pij_magnet = pblock(ib, ia) - pblock_beta(ib, ia)
    3691              :                         ! CP2K's core Hamiltonian force setup leaves matrix_w(1)
    3692              :                         ! as the already combined alpha+beta channel for LSD.
    3693              :                      END IF
    3694              : 
    3695      1704770 :                      itemp = itemp + overlap_deriv_fac*idHdc*pij_charge*t_ov(ij)
    3696      1704770 :                      jtemp = jtemp + overlap_deriv_fac*jdHdc*pij_charge*t_ov(ij)
    3697              : 
    3698      1704770 :                      hp = 2*hij*pij_charge
    3699              :                      dgrad(:) = dgrad(:) &
    3700              :                                 + overlap_deriv_fac*(-pot_pair_scale*((ishift + jshift)*pij_charge &
    3701              :                                                                       + (ishift_mag + jshift_mag)*pij_magnet)*t_d_ov(:, ij) &
    3702              :                                                      - 2*w_pair_scale*wij_charge*t_d_ov(:, ij) &
    3703              :                                                      + h0_pair_scale*(hp*shpoly*t_d_ov(:, ij) &
    3704              :                                                                       + hp*dshpoly*t_ov(ij)*rij)) &
    3705              :                                 + mp_pair_scale*(pij_charge*( &
    3706      1704770 :                                                  dip_deriv_fac_pair*(MATMUL(t_i_dip(:, :, ij), idip) &
    3707      1704770 :                                                                      + MATMUL(t_j_dip(:, :, ij), jdip)) &
    3708      1704770 :                                                  + quad_deriv_fac_pair*(MATMUL(t_i_quad(:, :, ij), iquad) &
    3709      1704770 :                                                                         + MATMUL(t_j_quad(:, :, ij), jquad))) &
    3710              :                                                  + pij_magnet*( &
    3711      1704770 :                                                  dip_deriv_fac_pair*(MATMUL(t_i_dip(:, :, ij), idip_mag) &
    3712      1704770 :                                                                      + MATMUL(t_j_dip(:, :, ij), jdip_mag)) &
    3713      1704770 :                                                  + quad_deriv_fac_pair*(MATMUL(t_i_quad(:, :, ij), iquad_mag) &
    3714    264809430 :                                                                         + MATMUL(t_j_quad(:, :, ij), jquad_mag))))
    3715              : 
    3716              :                   END DO
    3717              :                END DO
    3718              :                ! Periodic self-image pairs share one atom in the sorted CP2K block representation.
    3719       191342 :                IF (icol == jrow) THEN
    3720        48552 :                   IF (sampled_image_pair) THEN
    3721        18072 :                      dE(icol) = dE(icol) + cn_image_scale*0.5_dp*(itemp + jtemp)
    3722              :                   ELSE
    3723        30480 :                      dE(icol) = dE(icol) + 0.5_dp*(itemp + jtemp)
    3724              :                   END IF
    3725              :                ELSE
    3726       142790 :                   dE(icol) = dE(icol) + itemp
    3727       142790 :                   dE(jrow) = dE(jrow) + jtemp
    3728              :                END IF
    3729       765368 :                tb%grad(:, icol) = tb%grad(:, icol) - dgrad
    3730       765368 :                tb%grad(:, jrow) = tb%grad(:, jrow) + dgrad
    3731       255610 :                IF (tb%use_virial) THEN
    3732       177679 :                   IF (icol == jrow) THEN
    3733       173760 :                      DO ia = 1, 3
    3734       564720 :                         DO ib = 1, 3
    3735       521280 :                            IF (sampled_image_pair) THEN
    3736       116640 :                               hsigma(ia, ib) = hsigma(ia, ib) - 0.25_dp*(rij(ia)*dgrad(ib) + rij(ib)*dgrad(ia))
    3737              :                            ELSE
    3738       274320 :                               hsigma(ia, ib) = hsigma(ia, ib) + 0.25_dp*(rij(ia)*dgrad(ib) + rij(ib)*dgrad(ia))
    3739              :                            END IF
    3740              :                         END DO
    3741              :                      END DO
    3742              :                   ELSE
    3743       536956 :                      DO ia = 1, 3
    3744      1745107 :                         DO ib = 1, 3
    3745      1610868 :                            hsigma(ia, ib) = hsigma(ia, ib) + 0.50_dp*(rij(ia)*dgrad(ib) + rij(ib)*dgrad(ia))
    3746              :                         END DO
    3747              :                      END DO
    3748              :                   END IF
    3749              :                END IF
    3750              :             END DO
    3751              :          END DO
    3752              :       END DO
    3753          114 :       CALL neighbor_list_iterator_release(nl_iterator)
    3754              : 
    3755          114 :       CALL para_env%sum(hsigma)
    3756          114 :       CALL para_env%sum(dE)
    3757          114 :       CALL para_env%max(non_nyquist_folded_seen)
    3758          114 :       CALL para_env%max(has_nyquist_image)
    3759         7236 :       n_non_nyquist_images = COUNT(non_nyquist_folded_seen > 0)
    3760          114 :       n_cn_norm_images = 1 + n_non_nyquist_images + has_nyquist_image
    3761              :       ! GFN2-like multipole Hamiltonians fold the scalar CN response over
    3762              :       ! k-point image classes. Non-Nyquist classes need the central class plus
    3763              :       ! the sampled folded images, with one aggregate Nyquist class if present.
    3764          114 :       IF (has_multipole_response .AND. n_periodic == 3 .AND. n_non_nyquist_images > 0) &
    3765            2 :          cn_deriv_scale = 1.0_dp - 0.5_dp/REAL(n_cn_norm_images, dp)
    3766          572 :       dE = cn_deriv_scale*dE
    3767          114 :       CALL para_env%sum(tb%grad)
    3768              : 
    3769          114 :       CALL tb_add_grad(tb%grad, tb%dcndr, dE, tb%mol%nat)
    3770          114 :       CALL tb_grad2force(qs_env, tb, para_env, 4)
    3771              : 
    3772          114 :       CALL tb_dump_sigma_component("before_h0_off", tb%sigma, para_env)
    3773         1482 :       tb%sigma = tb%sigma + hsigma
    3774              :       CALL tb_dump_sigma_component("after_h0_off_direct", tb%sigma, para_env)
    3775          114 :       IF (tb%use_virial) THEN
    3776           52 :          CALL tb_add_sig(tb%sigma, tb%dcndL, dE, tb%mol%nat)
    3777              :          CALL tb_dump_sigma_component("after_h0_off_cn", tb%sigma, para_env)
    3778              :       END IF
    3779              : 
    3780          114 :       DEALLOCATE (dE)
    3781          114 :       DEALLOCATE (non_nyquist_folded_seen)
    3782          114 :       DEALLOCATE (basis_set_list)
    3783          114 :       DEALLOCATE (t_ov, t_d_ov)
    3784          114 :       DEALLOCATE (t_dip, t_i_dip, t_j_dip)
    3785          114 :       DEALLOCATE (t_quad, t_i_quad, t_j_quad)
    3786          114 :       DEALLOCATE (idip, jdip, idip_mag, jdip_mag, iquad, jquad, iquad_mag, jquad_mag)
    3787              : 
    3788          114 :       IF (tb%use_virial) CALL tb_add_stress(qs_env, tb, para_env)
    3789              : 
    3790              : #else
    3791              :       MARK_USED(qs_env)
    3792              :       MARK_USED(use_rho)
    3793              :       MARK_USED(nimg)
    3794              :       CPABORT("Built without TBLITE")
    3795              : #endif
    3796              : 
    3797          114 :    END SUBROUTINE tb_derive_dH_off
    3798              : 
    3799              : ! **************************************************************************************************
    3800              : !> \brief Run native tblite CLI and compare against CP2K/tblite.
    3801              : !> \param qs_env ...
    3802              : ! **************************************************************************************************
    3803          114 :    SUBROUTINE tb_reference_cli_compare(qs_env)
    3804              : 
    3805              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    3806              : 
    3807              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'tb_reference_cli_compare'
    3808              : 
    3809              :       CHARACTER(LEN=16)                                  :: solvation_model_name
    3810              :       CHARACTER(LEN=32) :: acc_str, charge_str, efield_x_str, efield_y_str, efield_z_str, &
    3811              :          etemp_guess_val_str, etemp_str, iter_str, spin_str, spinpol_str
    3812              :       CHARACTER(LEN=4*default_path_length+16) :: efield_str, etemp_guess_str, param_str, &
    3813              :          post_processing_output_str, post_processing_str, restart_str, solvation_str, verbosity_str
    3814              :       CHARACTER(LEN=8)                                   :: guess, method, solver
    3815              :       CHARACTER(LEN=8*default_path_length)               :: command
    3816              :       CHARACTER(LEN=default_path_length)                 :: file_base, gen_file, grad_file, &
    3817              :                                                             json_file, log_file, &
    3818              :                                                             post_processing_output_file
    3819              :       INTEGER                                            :: cmdstat, exitstat, handle, iounit, &
    3820              :                                                             n_periodic, natom, nkp, &
    3821              :                                                             reference_iterations, spin
    3822              :       INTEGER, DIMENSION(3)                              :: periodic
    3823              :       LOGICAL                                            :: do_kpoints, have_energy, have_gradient, &
    3824              :                                                             have_virial, too_large, &
    3825              :                                                             unsupported_kpoints
    3826              :       REAL(KIND=dp)                                      :: cli_energy, cp_energy, ediff, etemp, &
    3827              :                                                             etemp_guess, fmax, fsum, vmax, vsum
    3828          114 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: cli_gradient, cli_virial, cp_gradient
    3829          114 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: xkp
    3830          114 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    3831              :       TYPE(cell_type), POINTER                           :: cell
    3832              :       TYPE(cp_logger_type), POINTER                      :: logger
    3833              :       TYPE(dft_control_type), POINTER                    :: dft_control
    3834              :       TYPE(kpoint_type), POINTER                         :: kpoints
    3835              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    3836          114 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    3837              :       TYPE(qs_energy_type), POINTER                      :: energy
    3838          114 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
    3839              :       TYPE(scf_control_type), POINTER                    :: scf_control
    3840              :       TYPE(virial_type), POINTER                         :: virial
    3841              :       TYPE(xtb_reference_cli_type)                       :: ref
    3842              : 
    3843          114 :       CALL timeset(routineN, handle)
    3844              : 
    3845          114 :       NULLIFY (atomic_kind_set, cell, dft_control, energy, force, kpoints, logger, para_env, particle_set, &
    3846          114 :                scf_control, virial, xkp)
    3847              :       CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, cell=cell, &
    3848              :                       dft_control=dft_control, energy=energy, force=force, &
    3849              :                       para_env=para_env, particle_set=particle_set, scf_control=scf_control, &
    3850          114 :                       virial=virial, do_kpoints=do_kpoints, kpoints=kpoints)
    3851              : 
    3852          114 :       ref = dft_control%qs_control%xtb_control%reference_cli
    3853          114 :       IF (.NOT. ref%enabled) THEN
    3854          112 :          CALL timestop(handle)
    3855          112 :          RETURN
    3856              :       END IF
    3857            2 :       IF (.NOT. para_env%is_source()) THEN
    3858            1 :          CALL timestop(handle)
    3859            1 :          RETURN
    3860              :       END IF
    3861              : 
    3862            1 :       logger => cp_get_default_logger()
    3863            1 :       iounit = cp_logger_get_default_io_unit(logger)
    3864            1 :       verbosity_str = ""
    3865            1 :       IF (logger%iter_info%print_level == silent_print_level) THEN
    3866            0 :          verbosity_str = " --silent"
    3867            1 :       ELSE IF (logger%iter_info%print_level == high_print_level .OR. &
    3868              :                logger%iter_info%print_level == debug_print_level) THEN
    3869            0 :          verbosity_str = " --verbose"
    3870              :       END IF
    3871            1 :       IF (ref%solvation_active) THEN
    3872            1 :          periodic = 0
    3873            1 :          IF (ASSOCIATED(cell)) CALL get_cell(cell=cell, periodic=periodic)
    3874            4 :          n_periodic = COUNT(periodic == 1)
    3875            1 :          IF (n_periodic == 3) THEN
    3876              :             WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    3877            0 :                "tblite reference CLI implicit solvation is not supported for PERIODIC XYZ."
    3878              :             WRITE (UNIT=iounit, FMT="(T2,A)") &
    3879            0 :                "Use PERIODIC NONE for molecular solvation diagnostics, or remove IMPLICIT_SOLVATION."
    3880            0 :             CPABORT("REFERENCE_CLI implicit solvation is incompatible with PERIODIC XYZ")
    3881            1 :          ELSE IF (n_periodic > 0) THEN
    3882              :             WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    3883            0 :                "WARNING: tblite reference CLI implicit solvation with finite periodicity is diagnostic only."
    3884              :             WRITE (UNIT=iounit, FMT="(T2,A,I0,A)") &
    3885            0 :                "The generated native tblite reference geometry has ", n_periodic, &
    3886            0 :                " periodic direction(s); continuum-solvation conventions are primarily molecular."
    3887              :          END IF
    3888              :       END IF
    3889            1 :       unsupported_kpoints = .FALSE.
    3890            1 :       IF (do_kpoints .AND. ASSOCIATED(kpoints)) THEN
    3891            0 :          nkp = 0
    3892            0 :          CALL get_kpoint_info(kpoint=kpoints, nkp=nkp, xkp=xkp)
    3893            0 :          unsupported_kpoints = nkp > 1
    3894            0 :          IF (nkp == 1 .AND. ASSOCIATED(xkp)) unsupported_kpoints = ANY(ABS(xkp(:, 1)) > 1.0E-12_dp)
    3895              :       END IF
    3896            0 :       IF (unsupported_kpoints) THEN
    3897              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    3898            0 :             "tblite reference CLI check skipped: CP2K KPOINTS are active."
    3899              :          WRITE (UNIT=iounit, FMT="(T2,A)") &
    3900            0 :             "The native tblite CLI reference path does not reproduce CP2K multi-k-point sampling."
    3901            0 :          IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot check CP2K k-point calculations")
    3902            0 :          CALL timestop(handle)
    3903            0 :          RETURN
    3904              :       END IF
    3905            1 :       IF (dft_control%qs_control%xtb_control%tblite_scc_mixer == tblite_scc_mixer_cp2k) THEN
    3906              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    3907            0 :             "WARNING: tblite reference CLI cannot reproduce XTB/SCC_MIXER CP2K."
    3908              :          WRITE (UNIT=iounit, FMT="(T2,A)") &
    3909            0 :             "The external native tblite run uses tblite's own SCC mixer; only the converged result is compared."
    3910            0 :          IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot reproduce SCC_MIXER CP2K")
    3911              :       END IF
    3912            1 :       natom = SIZE(particle_set)
    3913            1 :       method = tb_reference_method_name(dft_control%qs_control%xtb_control%tblite_method)
    3914            1 :       guess = tb_reference_guess_name(ref%guess)
    3915            1 :       solver = tb_reference_solver_name(dft_control%qs_control%xtb_control%tblite_mixer_solver)
    3916            1 :       file_base = tb_join_path(ref%work_directory, ref%prefix)
    3917            1 :       gen_file = TRIM(file_base)//".gen"
    3918            1 :       grad_file = TRIM(file_base)//".grad"
    3919            1 :       json_file = TRIM(file_base)//".json"
    3920            1 :       log_file = TRIM(file_base)//".log"
    3921            1 :       post_processing_output_file = ""
    3922            1 :       IF (LEN_TRIM(ref%grad_file) > 0) grad_file = ref%grad_file
    3923            1 :       IF (LEN_TRIM(ref%json_file) > 0) json_file = ref%json_file
    3924            1 :       IF (LEN_TRIM(ref%post_processing_output_file) > 0) &
    3925            1 :          post_processing_output_file = ref%post_processing_output_file
    3926              : 
    3927            1 :       WRITE (charge_str, "(I0)") dft_control%charge
    3928            1 :       spin = MAX(0, dft_control%multiplicity - 1)
    3929            1 :       WRITE (spin_str, "(I0)") spin
    3930            1 :       WRITE (acc_str, "(ES16.8)") dft_control%qs_control%xtb_control%tblite_accuracy
    3931            1 :       reference_iterations = dft_control%qs_control%xtb_control%tblite_mixer_iterations
    3932            1 :       WRITE (iter_str, "(I0)") reference_iterations
    3933            1 :       efield_str = ""
    3934            1 :       IF (ref%efield_active) THEN
    3935            1 :          WRITE (efield_x_str, "(ES16.8)") ref%efield(1)
    3936            1 :          WRITE (efield_y_str, "(ES16.8)") ref%efield(2)
    3937            1 :          WRITE (efield_z_str, "(ES16.8)") ref%efield(3)
    3938              :          efield_str = " --efield "//TRIM(ADJUSTL(efield_x_str))//","// &
    3939            1 :                       TRIM(ADJUSTL(efield_y_str))//","//TRIM(ADJUSTL(efield_z_str))
    3940              :       END IF
    3941            1 :       solvation_str = ""
    3942            1 :       solvation_model_name = ""
    3943            1 :       IF (ref%solvation_active) THEN
    3944            2 :          SELECT CASE (ref%solvation_model)
    3945              :          CASE (tblite_cli_solvation_alpb)
    3946            1 :             solvation_model_name = "ALPB"
    3947            1 :             solvation_str = " --alpb "
    3948              :          CASE (tblite_cli_solvation_gbsa)
    3949            0 :             solvation_model_name = "GBSA"
    3950            0 :             solvation_str = " --gbsa "
    3951              :          CASE (tblite_cli_solvation_gbe)
    3952            0 :             solvation_model_name = "GBE"
    3953            0 :             solvation_str = " --gbe "
    3954              :          CASE (tblite_cli_solvation_gb)
    3955            0 :             solvation_model_name = "GB"
    3956            0 :             solvation_str = " --gb "
    3957              :          CASE (tblite_cli_solvation_cpcm)
    3958            0 :             solvation_model_name = "CPCM"
    3959            0 :             solvation_str = " --cpcm "
    3960              :          CASE DEFAULT
    3961            1 :             CPABORT("Unknown tblite reference CLI implicit-solvation model")
    3962              :          END SELECT
    3963            1 :          solvation_str = TRIM(solvation_str)//" "//TRIM(tb_shell_quote(ref%solvation_solvent))
    3964            2 :          SELECT CASE (ref%solvation_born_kernel)
    3965              :          CASE (tblite_cli_born_kernel_auto)
    3966              :          CASE (tblite_cli_born_kernel_p16)
    3967            1 :             solvation_str = TRIM(solvation_str)//" --born-kernel p16"
    3968              :          CASE (tblite_cli_born_kernel_still)
    3969            0 :             solvation_str = TRIM(solvation_str)//" --born-kernel still"
    3970              :          CASE DEFAULT
    3971            1 :             CPABORT("Unknown tblite reference CLI Born kernel")
    3972              :          END SELECT
    3973            2 :          SELECT CASE (ref%solvation_state)
    3974              :          CASE (tblite_cli_solution_state_gsolv)
    3975              :          CASE (tblite_cli_solution_state_bar1mol)
    3976            1 :             solvation_str = TRIM(solvation_str)//" --solv-state bar1mol"
    3977              :          CASE (tblite_cli_solution_state_reference)
    3978            0 :             solvation_str = TRIM(solvation_str)//" --solv-state reference"
    3979              :          CASE DEFAULT
    3980            1 :             CPABORT("Unknown tblite reference CLI solution state")
    3981              :          END SELECT
    3982              :       END IF
    3983            1 :       IF (dft_control%qs_control%xtb_control%tblite_mixer_memory /= reference_iterations) THEN
    3984              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    3985            0 :             "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/MEMORY."
    3986              :          WRITE (UNIT=iounit, FMT="(T2,A,I0,A,I0,A)") &
    3987            0 :             "The native reference run uses tblite's internal mixer memory tied to --iterations (", &
    3988            0 :             reference_iterations, "), while CP2K uses MEMORY ", &
    3989            0 :             dft_control%qs_control%xtb_control%tblite_mixer_memory, "."
    3990            0 :          IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/MEMORY")
    3991              :       END IF
    3992            1 :       IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_damping - &
    3993              :               tblite_mixer_damping_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
    3994              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    3995            0 :             "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/DAMPING."
    3996              :          WRITE (UNIT=iounit, FMT="(T2,A,F8.4,A,F8.4,A)") &
    3997            0 :             "The native reference run uses tblite's library default ", tblite_mixer_damping_default, &
    3998            0 :             ", while CP2K uses DAMPING ", dft_control%qs_control%xtb_control%tblite_mixer_damping, "."
    3999            0 :          IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/DAMPING")
    4000              :       END IF
    4001            1 :       IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_omega0 - &
    4002              :               tblite_mixer_omega0_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
    4003              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    4004            0 :             "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/OMEGA0."
    4005              :          WRITE (UNIT=iounit, FMT="(T2,A,ES12.4,A,ES12.4,A)") &
    4006            0 :             "The native reference run uses tblite's library default ", tblite_mixer_omega0_default, &
    4007            0 :             ", while CP2K uses OMEGA0 ", dft_control%qs_control%xtb_control%tblite_mixer_omega0, "."
    4008            0 :          IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/OMEGA0")
    4009              :       END IF
    4010            1 :       IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_min_weight - &
    4011              :               tblite_mixer_min_weight_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
    4012              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    4013            0 :             "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/MIN_WEIGHT."
    4014              :          WRITE (UNIT=iounit, FMT="(T2,A,ES12.4,A,ES12.4,A)") &
    4015            0 :             "The native reference run uses tblite's library default ", tblite_mixer_min_weight_default, &
    4016            0 :             ", while CP2K uses MIN_WEIGHT ", dft_control%qs_control%xtb_control%tblite_mixer_min_weight, "."
    4017            0 :          IF (ref%stop_on_error) &
    4018            0 :             CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/MIN_WEIGHT")
    4019              :       END IF
    4020            1 :       IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_max_weight - &
    4021              :               tblite_mixer_max_weight_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
    4022              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    4023            0 :             "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/MAX_WEIGHT."
    4024              :          WRITE (UNIT=iounit, FMT="(T2,A,ES12.4,A,ES12.4,A)") &
    4025            0 :             "The native reference run uses tblite's library default ", tblite_mixer_max_weight_default, &
    4026            0 :             ", while CP2K uses MAX_WEIGHT ", dft_control%qs_control%xtb_control%tblite_mixer_max_weight, "."
    4027            0 :          IF (ref%stop_on_error) &
    4028            0 :             CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/MAX_WEIGHT")
    4029              :       END IF
    4030            1 :       IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_weight_factor - &
    4031              :               tblite_mixer_weight_factor_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
    4032              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    4033            0 :             "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/WEIGHT_FACTOR."
    4034              :          WRITE (UNIT=iounit, FMT="(T2,A,ES12.4,A,ES12.4,A)") &
    4035            0 :             "The native reference run uses tblite's library default ", tblite_mixer_weight_factor_default, &
    4036            0 :             ", while CP2K uses WEIGHT_FACTOR ", &
    4037            0 :             dft_control%qs_control%xtb_control%tblite_mixer_weight_factor, "."
    4038            0 :          IF (ref%stop_on_error) &
    4039            0 :             CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/WEIGHT_FACTOR")
    4040              :       END IF
    4041            1 :       etemp = 300.0_dp
    4042            1 :       IF (ASSOCIATED(scf_control) .AND. ASSOCIATED(scf_control%smear)) THEN
    4043            1 :          IF (scf_control%smear%do_smear) THEN
    4044            1 :             etemp = cp_unit_from_cp2k(scf_control%smear%electronic_temperature, "K")
    4045            1 :             IF (scf_control%smear%method /= smear_fermi_dirac) THEN
    4046              :                WRITE (UNIT=iounit, FMT="(/,T2,A,A,A)") &
    4047            0 :                   "WARNING: tblite reference CLI cannot reproduce CP2K smearing method ", &
    4048            0 :                   TRIM(tb_reference_smear_method_name(scf_control%smear%method)), "."
    4049              :                WRITE (UNIT=iounit, FMT="(T2,A,F12.3,A)") &
    4050            0 :                   "The native reference run uses Fermi-Dirac electronic temperature ", etemp, " K instead."
    4051              :             END IF
    4052              :          END IF
    4053              :       END IF
    4054            1 :       WRITE (etemp_str, "(ES16.8)") etemp
    4055            1 :       etemp_guess = 0.0_dp
    4056            1 :       etemp_guess_str = ""
    4057            1 :       IF (ref%electronic_temperature_guess > 0.0_dp) THEN
    4058            0 :          etemp_guess = cp_unit_from_cp2k(ref%electronic_temperature_guess, "K")
    4059            0 :          WRITE (etemp_guess_val_str, "(ES16.8)") etemp_guess
    4060            0 :          etemp_guess_str = " --etemp-guess "//TRIM(ADJUSTL(etemp_guess_val_str))
    4061              :       END IF
    4062            1 :       param_str = ""
    4063            1 :       IF (LEN_TRIM(dft_control%qs_control%xtb_control%tblite_param_file) > 0) &
    4064            0 :          param_str = " --param "//TRIM(tb_shell_quote(dft_control%qs_control%xtb_control%tblite_param_file))
    4065            1 :       spinpol_str = ""
    4066            1 :       IF (dft_control%lsd) spinpol_str = " --spin-polarized"
    4067            1 :       post_processing_str = ""
    4068            1 :       IF (LEN_TRIM(ref%post_processing) > 0) &
    4069            1 :          post_processing_str = " --post-processing "//TRIM(tb_shell_quote(ref%post_processing))
    4070            1 :       post_processing_output_str = ""
    4071            1 :       IF (LEN_TRIM(post_processing_output_file) > 0) THEN
    4072              :          WRITE (UNIT=iounit, FMT="(/,T2,A)") &
    4073            1 :             "WARNING: tblite reference CLI POST_PROCESSING_OUTPUT was requested explicitly."
    4074              :          WRITE (UNIT=iounit, FMT="(T2,A)") &
    4075            1 :             "Some tblite 0.5.0 command-line builds document --post-processing-output but do not parse it."
    4076              :          post_processing_output_str = " --post-processing-output "// &
    4077            1 :                                       TRIM(tb_shell_quote(post_processing_output_file))
    4078              :       END IF
    4079            1 :       restart_str = " --no-restart"
    4080            1 :       IF (LEN_TRIM(ref%restart_file) > 0) &
    4081            0 :          restart_str = " --restart "//TRIM(tb_shell_quote(ref%restart_file))
    4082              : 
    4083            1 :       CALL tb_write_reference_gen(qs_env, TRIM(gen_file))
    4084              : 
    4085              :       command = TRIM(tb_shell_quote(ref%program_name))//" run --method "//TRIM(method)// &
    4086              :                 TRIM(param_str)// &
    4087              :                 TRIM(spinpol_str)// &
    4088              :                 " --charge "//TRIM(ADJUSTL(charge_str))// &
    4089              :                 " --spin "//TRIM(ADJUSTL(spin_str))// &
    4090              :                 " --acc "//TRIM(ADJUSTL(acc_str))// &
    4091              :                 " --guess "//TRIM(guess)// &
    4092              :                 " --solver "//TRIM(solver)// &
    4093              :                 " --iterations "//TRIM(ADJUSTL(iter_str))// &
    4094              :                 " --etemp "//TRIM(ADJUSTL(etemp_str))// &
    4095              :                 TRIM(etemp_guess_str)// &
    4096              :                 TRIM(efield_str)// &
    4097              :                 TRIM(solvation_str)// &
    4098              :                 TRIM(post_processing_str)// &
    4099              :                 TRIM(post_processing_output_str)// &
    4100              :                 TRIM(restart_str)// &
    4101              :                 TRIM(verbosity_str)//" --input "//TRIM(tb_shell_quote(ref%input_format))// &
    4102              :                 " --grad "//TRIM(tb_shell_quote(grad_file))// &
    4103              :                 " --json "//TRIM(tb_shell_quote(json_file))//" "//TRIM(tb_shell_quote(gen_file))// &
    4104            1 :                 " > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
    4105              : 
    4106            1 :       cmdstat = 0
    4107            1 :       exitstat = 0
    4108            1 :       CALL execute_command_line(TRIM(command), exitstat=exitstat, cmdstat=cmdstat)
    4109            1 :       IF (cmdstat /= 0 .OR. exitstat /= 0) THEN
    4110            1 :          WRITE (UNIT=iounit, FMT="(/,T2,A)") "tblite reference CLI check failed to run."
    4111            1 :          WRITE (UNIT=iounit, FMT="(T2,A,A)") "Command: ", TRIM(command)
    4112            1 :          WRITE (UNIT=iounit, FMT="(T2,A,I0,T32,A,I0)") "cmdstat:", cmdstat, "exitstat:", exitstat
    4113            1 :          IF (ref%stop_on_error) CPABORT("tblite reference CLI command failed")
    4114            1 :          CALL tb_reference_cleanup(ref, gen_file, grad_file, json_file, log_file, post_processing_output_file)
    4115            1 :          CALL timestop(handle)
    4116            1 :          RETURN
    4117              :       END IF
    4118              : 
    4119            0 :       ALLOCATE (cli_gradient(3, natom), cli_virial(3, 3))
    4120              :       CALL tb_read_reference_grad(TRIM(grad_file), natom, cli_energy, cli_gradient, cli_virial, &
    4121            0 :                                   have_energy, have_gradient, have_virial)
    4122              : 
    4123            0 :       WRITE (UNIT=iounit, FMT="(/,T2,A)") "tblite reference CLI check"
    4124            0 :       WRITE (UNIT=iounit, FMT="(T2,A,A)") "Executable: ", TRIM(ref%program_name)
    4125            0 :       WRITE (UNIT=iounit, FMT="(T2,A,A)") "Method:     ", TRIM(method)
    4126            0 :       WRITE (UNIT=iounit, FMT="(T2,A,A)") "Guess:      ", TRIM(guess)
    4127            0 :       WRITE (UNIT=iounit, FMT="(T2,A,A)") "Solver:     ", TRIM(solver)
    4128            0 :       WRITE (UNIT=iounit, FMT="(T2,A,L1)") "Spin-pol.:  ", dft_control%lsd
    4129            0 :       IF (ref%efield_active) &
    4130            0 :          WRITE (UNIT=iounit, FMT="(T2,A,3ES16.8,A)") "Efield:     ", ref%efield, " V/Angstrom"
    4131            0 :       IF (ref%solvation_active) &
    4132            0 :          WRITE (UNIT=iounit, FMT="(T2,A,A,1X,A)") "Solvation:  ", TRIM(solvation_model_name), &
    4133            0 :          TRIM(ref%solvation_solvent)
    4134            0 :       IF (LEN_TRIM(ref%post_processing) > 0) &
    4135            0 :          WRITE (UNIT=iounit, FMT="(T2,A,A)") "Post proc.: ", TRIM(ref%post_processing)
    4136            0 :       IF (LEN_TRIM(post_processing_output_file) > 0) &
    4137            0 :          WRITE (UNIT=iounit, FMT="(T2,A,A)") "PP output:  ", TRIM(post_processing_output_file)
    4138            0 :       IF (ref%electronic_temperature_guess > 0.0_dp) &
    4139            0 :          WRITE (UNIT=iounit, FMT="(T2,A,F12.3,A)") "Guess etemp:", etemp_guess, " K"
    4140            0 :       WRITE (UNIT=iounit, FMT="(T2,A,A)") "Grad file:  ", TRIM(grad_file)
    4141            0 :       WRITE (UNIT=iounit, FMT="(T2,A,A)") "JSON file:  ", TRIM(json_file)
    4142            0 :       WRITE (UNIT=iounit, FMT="(T2,A,A)") "Log file:   ", TRIM(log_file)
    4143              : 
    4144            0 :       too_large = .FALSE.
    4145            0 :       IF (ref%check_energy) THEN
    4146            0 :          IF (have_energy) THEN
    4147            0 :             cp_energy = energy%total
    4148            0 :             ediff = ABS(cp_energy - cli_energy)
    4149              :             WRITE (UNIT=iounit, FMT="(T2,A,3ES22.12)") &
    4150            0 :                "Energy CP2K/CLI/absdiff:", cp_energy, cli_energy, ediff
    4151            0 :             too_large = too_large .OR. ediff > ref%error_limit
    4152              :          ELSE
    4153            0 :             WRITE (UNIT=iounit, FMT="(T2,A)") "Energy check skipped: no CLI energy found."
    4154              :          END IF
    4155              :       END IF
    4156              : 
    4157            0 :       IF (ref%check_forces) THEN
    4158            0 :          IF (have_gradient .AND. ASSOCIATED(force)) THEN
    4159            0 :             ALLOCATE (cp_gradient(3, natom))
    4160            0 :             CALL total_qs_force(cp_gradient, force, atomic_kind_set)
    4161            0 :             fsum = SUM(ABS(cp_gradient - cli_gradient))
    4162            0 :             fmax = MAXVAL(ABS(cp_gradient - cli_gradient))
    4163            0 :             WRITE (UNIT=iounit, FMT="(T2,A,2ES22.12)") "Gradient diff sum/max:", fsum, fmax
    4164            0 :             too_large = too_large .OR. fmax > ref%error_limit
    4165            0 :             DEALLOCATE (cp_gradient)
    4166              :          ELSE
    4167            0 :             WRITE (UNIT=iounit, FMT="(T2,A)") "Gradient check skipped: no CLI gradient or CP2K force found."
    4168              :          END IF
    4169              :       END IF
    4170              : 
    4171            0 :       IF (ref%check_virial) THEN
    4172            0 :          IF (have_virial .AND. ASSOCIATED(virial)) THEN
    4173              :             ! Native tblite prints the positive cell derivative; CP2K stores the PV virial
    4174              :             ! with the opposite sign.
    4175            0 :             vsum = SUM(ABS(-virial%pv_virial - cli_virial))
    4176            0 :             vmax = MAXVAL(ABS(-virial%pv_virial - cli_virial))
    4177            0 :             WRITE (UNIT=iounit, FMT="(T2,A,2ES22.12)") "Virial diff sum/max:", vsum, vmax
    4178            0 :             too_large = too_large .OR. vmax > ref%error_limit
    4179              :          ELSE
    4180            0 :             WRITE (UNIT=iounit, FMT="(T2,A)") "Virial check skipped: no CLI virial or CP2K virial found."
    4181              :          END IF
    4182              :       END IF
    4183              : 
    4184            0 :       IF (too_large) THEN
    4185              :          WRITE (UNIT=iounit, FMT="(T2,A,ES12.4)") &
    4186            0 :             "tblite reference CLI deviation exceeded ERROR_LIMIT = ", ref%error_limit
    4187            0 :          IF (ref%stop_on_error) CPABORT("tblite reference CLI deviation exceeded ERROR_LIMIT")
    4188              :       END IF
    4189              : 
    4190            0 :       CALL tb_reference_cli_aux_commands(ref, dft_control, gen_file, file_base, verbosity_str, iounit)
    4191              : 
    4192            0 :       CALL tb_reference_cleanup(ref, gen_file, grad_file, json_file, log_file, post_processing_output_file)
    4193            0 :       DEALLOCATE (cli_gradient, cli_virial)
    4194              : 
    4195            0 :       CALL timestop(handle)
    4196              : 
    4197          912 :    END SUBROUTINE tb_reference_cli_compare
    4198              : 
    4199              : ! **************************************************************************************************
    4200              : !> \brief Map CP2K tblite method id to native tblite CLI method name.
    4201              : !> \param method_id ...
    4202              : !> \return ...
    4203              : ! **************************************************************************************************
    4204            1 :    FUNCTION tb_reference_method_name(method_id) RESULT(method)
    4205              :       INTEGER, INTENT(IN)                                :: method_id
    4206              :       CHARACTER(LEN=8)                                   :: method
    4207              : 
    4208            1 :       SELECT CASE (method_id)
    4209              :       CASE (gfn1xtb)
    4210            0 :          method = "gfn1"
    4211              :       CASE (gfn2xtb)
    4212            1 :          method = "gfn2"
    4213              :       CASE (ipea1xtb)
    4214            0 :          method = "ipea1"
    4215              :       CASE DEFAULT
    4216            1 :          CPABORT("Unknown tblite reference CLI method")
    4217              :       END SELECT
    4218              : 
    4219            1 :    END FUNCTION tb_reference_method_name
    4220              : 
    4221              : ! **************************************************************************************************
    4222              : !> \brief Map CP2K tblite reference CLI guess id to native tblite CLI guess name.
    4223              : !> \param guess_id ...
    4224              : !> \return ...
    4225              : ! **************************************************************************************************
    4226            1 :    FUNCTION tb_reference_guess_name(guess_id) RESULT(guess)
    4227              :       INTEGER, INTENT(IN)                                :: guess_id
    4228              :       CHARACTER(LEN=8)                                   :: guess
    4229              : 
    4230            2 :       SELECT CASE (guess_id)
    4231              :       CASE (tblite_guess_sad)
    4232            1 :          guess = "sad"
    4233              :       CASE (tblite_guess_eeq)
    4234            0 :          guess = "eeq"
    4235              :       CASE (tblite_guess_ceh)
    4236            0 :          guess = "ceh"
    4237              :       CASE DEFAULT
    4238            1 :          CPABORT("Unknown tblite reference CLI guess")
    4239              :       END SELECT
    4240              : 
    4241            1 :    END FUNCTION tb_reference_guess_name
    4242              : 
    4243              : ! **************************************************************************************************
    4244              : !> \brief Map CP2K tblite solver id to native tblite CLI solver name.
    4245              : !> \param solver_id ...
    4246              : !> \return ...
    4247              : ! **************************************************************************************************
    4248            1 :    FUNCTION tb_reference_solver_name(solver_id) RESULT(solver)
    4249              :       INTEGER, INTENT(IN)                                :: solver_id
    4250              :       CHARACTER(LEN=8)                                   :: solver
    4251              : 
    4252            2 :       SELECT CASE (solver_id)
    4253              :       CASE (tblite_solver_gvd)
    4254            1 :          solver = "gvd"
    4255              :       CASE (tblite_solver_gvr)
    4256            0 :          solver = "gvr"
    4257              :       CASE DEFAULT
    4258            1 :          CPABORT("Unknown tblite reference CLI solver")
    4259              :       END SELECT
    4260              : 
    4261            1 :    END FUNCTION tb_reference_solver_name
    4262              : 
    4263              : ! **************************************************************************************************
    4264              : !> \brief Map CP2K smearing method id to a diagnostic label.
    4265              : !> \param method_id ...
    4266              : !> \return ...
    4267              : ! **************************************************************************************************
    4268            0 :    FUNCTION tb_reference_smear_method_name(method_id) RESULT(method)
    4269              :       INTEGER, INTENT(IN)                                :: method_id
    4270              :       CHARACTER(LEN=24)                                  :: method
    4271              : 
    4272            0 :       SELECT CASE (method_id)
    4273              :       CASE (smear_fermi_dirac)
    4274            0 :          method = "FERMI_DIRAC"
    4275              :       CASE (smear_energy_window)
    4276            0 :          method = "ENERGY_WINDOW"
    4277              :       CASE (smear_list)
    4278            0 :          method = "LIST"
    4279              :       CASE (smear_gaussian)
    4280            0 :          method = "GAUSSIAN"
    4281              :       CASE (smear_mp)
    4282            0 :          method = "METHFESSEL_PAXTON"
    4283              :       CASE (smear_mv)
    4284            0 :          method = "MARZARI_VANDERBILT"
    4285              :       CASE DEFAULT
    4286            0 :          method = "UNKNOWN"
    4287              :       END SELECT
    4288              : 
    4289            0 :    END FUNCTION tb_reference_smear_method_name
    4290              : 
    4291              : ! **************************************************************************************************
    4292              : !> \brief Run optional native tblite auxiliary subcommands.
    4293              : !> \param ref ...
    4294              : !> \param dft_control ...
    4295              : !> \param gen_file ...
    4296              : !> \param file_base ...
    4297              : !> \param verbosity_str ...
    4298              : !> \param iounit ...
    4299              : ! **************************************************************************************************
    4300            0 :    SUBROUTINE tb_reference_cli_aux_commands(ref, dft_control, gen_file, file_base, verbosity_str, iounit)
    4301              : 
    4302              :       TYPE(xtb_reference_cli_type), INTENT(IN)           :: ref
    4303              :       TYPE(dft_control_type), INTENT(IN)                 :: dft_control
    4304              :       CHARACTER(LEN=*), INTENT(IN)                       :: gen_file, file_base, verbosity_str
    4305              :       INTEGER, INTENT(IN)                                :: iounit
    4306              : 
    4307              :       CHARACTER(LEN=32)                                  :: charge_str, efield_x_str, efield_y_str, &
    4308              :                                                             efield_z_str, etemp_guess_val_str, &
    4309              :                                                             spin_str
    4310              :       CHARACTER(LEN=4*default_path_length+16)            :: copy_str, dry_run_str, efield_str, &
    4311              :                                                             etemp_guess_str, grad_str, json_str, &
    4312              :                                                             method_str, output_str
    4313              :       CHARACTER(LEN=8*default_path_length)               :: command
    4314              :       CHARACTER(LEN=default_path_length)                 :: guess_input, log_file
    4315              :       INTEGER                                            :: spin
    4316              :       REAL(KIND=dp)                                      :: etemp_guess
    4317              : 
    4318            0 :       WRITE (charge_str, "(I0)") dft_control%charge
    4319            0 :       spin = MAX(0, dft_control%multiplicity - 1)
    4320            0 :       WRITE (spin_str, "(I0)") spin
    4321              : 
    4322            0 :       IF (ref%guess_cli%enabled) THEN
    4323            0 :          guess_input = ref%guess_cli%input_file
    4324            0 :          IF (LEN_TRIM(guess_input) == 0) guess_input = gen_file
    4325            0 :          etemp_guess_str = ""
    4326            0 :          IF (ref%guess_cli%electronic_temperature_guess > 0.0_dp) THEN
    4327            0 :             etemp_guess = cp_unit_from_cp2k(ref%guess_cli%electronic_temperature_guess, "K")
    4328            0 :             WRITE (etemp_guess_val_str, "(ES16.8)") etemp_guess
    4329            0 :             etemp_guess_str = " --etemp-guess "//TRIM(ADJUSTL(etemp_guess_val_str))
    4330              :          END IF
    4331            0 :          efield_str = ""
    4332            0 :          IF (ref%guess_cli%efield_active) THEN
    4333            0 :             WRITE (efield_x_str, "(ES16.8)") ref%guess_cli%efield(1)
    4334            0 :             WRITE (efield_y_str, "(ES16.8)") ref%guess_cli%efield(2)
    4335            0 :             WRITE (efield_z_str, "(ES16.8)") ref%guess_cli%efield(3)
    4336              :             efield_str = " --efield "//TRIM(ADJUSTL(efield_x_str))//","// &
    4337            0 :                          TRIM(ADJUSTL(efield_y_str))//","//TRIM(ADJUSTL(efield_z_str))
    4338              :          END IF
    4339            0 :          grad_str = ""
    4340            0 :          IF (ref%guess_cli%grad) grad_str = " --grad"
    4341            0 :          json_str = ""
    4342            0 :          IF (LEN_TRIM(ref%guess_cli%json_file) > 0) &
    4343            0 :             json_str = " --json "//TRIM(tb_shell_quote(ref%guess_cli%json_file))
    4344            0 :          log_file = TRIM(file_base)//".guess.log"
    4345              :          command = TRIM(tb_shell_quote(ref%program_name))// &
    4346              :                    " guess --charge "//TRIM(ADJUSTL(charge_str))// &
    4347              :                    " --spin "//TRIM(ADJUSTL(spin_str))// &
    4348              :                    " --method "//TRIM(tb_reference_guess_name(ref%guess_cli%method))// &
    4349              :                    " --solver "//TRIM(tb_reference_solver_name(ref%guess_cli%solver))// &
    4350              :                    TRIM(etemp_guess_str)// &
    4351              :                    TRIM(efield_str)// &
    4352              :                    TRIM(grad_str)// &
    4353              :                    TRIM(json_str)// &
    4354              :                    TRIM(verbosity_str)//" --input "//TRIM(tb_shell_quote(ref%guess_cli%input_format))// &
    4355              :                    " "//TRIM(tb_shell_quote(guess_input))// &
    4356            0 :                    " > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
    4357            0 :          CALL tb_reference_cli_execute(ref, "guess", command, log_file, iounit)
    4358            0 :          IF (.NOT. ref%keep_files .AND. LEN_TRIM(ref%guess_cli%json_file) > 0) &
    4359            0 :             CALL tb_delete_file(ref%guess_cli%json_file)
    4360              :       END IF
    4361              : 
    4362            0 :       IF (ref%param_cli%enabled) THEN
    4363            0 :          method_str = ""
    4364            0 :          IF (ref%param_cli%method_explicit .OR. LEN_TRIM(ref%param_cli%input_file) == 0) &
    4365              :             method_str = " --method "// &
    4366              :                          TRIM(tb_reference_method_name(MERGE(ref%param_cli%method, &
    4367              :                                                              dft_control%qs_control%xtb_control%tblite_method, &
    4368            0 :                                                              ref%param_cli%method_explicit)))
    4369            0 :          output_str = ""
    4370            0 :          IF (LEN_TRIM(ref%param_cli%output_file) > 0) &
    4371            0 :             output_str = " --output "//TRIM(tb_shell_quote(ref%param_cli%output_file))
    4372            0 :          log_file = TRIM(file_base)//".param.log"
    4373              :          command = TRIM(tb_shell_quote(ref%program_name))//" param"// &
    4374              :                    TRIM(method_str)// &
    4375            0 :                    TRIM(output_str)
    4376            0 :          IF (LEN_TRIM(ref%param_cli%input_file) > 0) &
    4377            0 :             command = TRIM(command)//" "//TRIM(tb_shell_quote(ref%param_cli%input_file))
    4378            0 :          command = TRIM(command)//" > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
    4379            0 :          CALL tb_reference_cli_execute(ref, "param", command, log_file, iounit)
    4380            0 :          IF (.NOT. ref%keep_files .AND. LEN_TRIM(ref%param_cli%output_file) > 0) &
    4381            0 :             CALL tb_delete_file(ref%param_cli%output_file)
    4382              :       END IF
    4383              : 
    4384            0 :       IF (ref%fit_cli%enabled) THEN
    4385            0 :          dry_run_str = ""
    4386            0 :          IF (ref%fit_cli%dry_run) dry_run_str = " --dry-run"
    4387            0 :          copy_str = ""
    4388            0 :          IF (LEN_TRIM(ref%fit_cli%copy_file) > 0) &
    4389            0 :             copy_str = " --copy "//TRIM(tb_shell_quote(ref%fit_cli%copy_file))
    4390            0 :          log_file = TRIM(file_base)//".fit.log"
    4391              :          command = TRIM(tb_shell_quote(ref%program_name))//" fit"// &
    4392              :                    TRIM(dry_run_str)// &
    4393              :                    TRIM(copy_str)// &
    4394              :                    TRIM(verbosity_str)//" "//TRIM(tb_shell_quote(ref%fit_cli%param_file))// &
    4395              :                    " "//TRIM(tb_shell_quote(ref%fit_cli%input_file))// &
    4396            0 :                    " > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
    4397            0 :          CALL tb_reference_cli_execute(ref, "fit", command, log_file, iounit)
    4398            0 :          IF (.NOT. ref%keep_files .AND. LEN_TRIM(ref%fit_cli%copy_file) > 0) &
    4399            0 :             CALL tb_delete_file(ref%fit_cli%copy_file)
    4400              :       END IF
    4401              : 
    4402            0 :       IF (ref%tagdiff_cli%enabled) THEN
    4403            0 :          method_str = ""
    4404            0 :          IF (ref%tagdiff_cli%fit) method_str = " --fit"
    4405            0 :          log_file = TRIM(file_base)//".tagdiff.log"
    4406              :          command = TRIM(tb_shell_quote(ref%program_name))//" tagdiff"// &
    4407              :                    TRIM(method_str)//" "//TRIM(tb_shell_quote(ref%tagdiff_cli%actual_file))// &
    4408              :                    " "//TRIM(tb_shell_quote(ref%tagdiff_cli%reference_file))// &
    4409            0 :                    " > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
    4410            0 :          CALL tb_reference_cli_execute(ref, "tagdiff", command, log_file, iounit)
    4411              :       END IF
    4412              : 
    4413            0 :    END SUBROUTINE tb_reference_cli_aux_commands
    4414              : 
    4415              : ! **************************************************************************************************
    4416              : !> \brief Execute one native tblite REFERENCE_CLI auxiliary command.
    4417              : !> \param ref ...
    4418              : !> \param label ...
    4419              : !> \param command ...
    4420              : !> \param log_file ...
    4421              : !> \param iounit ...
    4422              : ! **************************************************************************************************
    4423            0 :    SUBROUTINE tb_reference_cli_execute(ref, label, command, log_file, iounit)
    4424              : 
    4425              :       TYPE(xtb_reference_cli_type), INTENT(IN)           :: ref
    4426              :       CHARACTER(LEN=*), INTENT(IN)                       :: label, command, log_file
    4427              :       INTEGER, INTENT(IN)                                :: iounit
    4428              : 
    4429              :       INTEGER                                            :: cmdstat, exitstat
    4430              : 
    4431            0 :       cmdstat = 0
    4432            0 :       exitstat = 0
    4433            0 :       CALL execute_command_line(TRIM(command), exitstat=exitstat, cmdstat=cmdstat)
    4434            0 :       IF (cmdstat /= 0 .OR. exitstat /= 0) THEN
    4435            0 :          WRITE (UNIT=iounit, FMT="(/,T2,A,A)") "tblite reference CLI auxiliary command failed: ", &
    4436            0 :             TRIM(label)
    4437            0 :          WRITE (UNIT=iounit, FMT="(T2,A,A)") "Command: ", TRIM(command)
    4438            0 :          WRITE (UNIT=iounit, FMT="(T2,A,I0,T32,A,I0)") "cmdstat:", cmdstat, "exitstat:", exitstat
    4439            0 :          IF (ref%stop_on_error) CPABORT("tblite reference CLI auxiliary command failed")
    4440              :       ELSE
    4441            0 :          WRITE (UNIT=iounit, FMT="(/,T2,A,A)") "tblite reference CLI auxiliary command completed: ", &
    4442            0 :             TRIM(label)
    4443            0 :          WRITE (UNIT=iounit, FMT="(T2,A,A)") "Log file: ", TRIM(log_file)
    4444              :       END IF
    4445            0 :       IF (.NOT. ref%keep_files) CALL tb_delete_file(log_file)
    4446              : 
    4447            0 :    END SUBROUTINE tb_reference_cli_execute
    4448              : 
    4449              : ! **************************************************************************************************
    4450              : !> \brief Join directory and filename.
    4451              : !> \param directory ...
    4452              : !> \param filename ...
    4453              : !> \return ...
    4454              : ! **************************************************************************************************
    4455            1 :    FUNCTION tb_join_path(directory, filename) RESULT(path)
    4456              :       CHARACTER(LEN=*), INTENT(IN)                       :: directory, filename
    4457              :       CHARACTER(LEN=default_path_length)                 :: path
    4458              : 
    4459            1 :       IF (LEN_TRIM(directory) == 0 .OR. TRIM(directory) == ".") THEN
    4460            1 :          path = TRIM(filename)
    4461            0 :       ELSE IF (directory(LEN_TRIM(directory):LEN_TRIM(directory)) == "/") THEN
    4462            0 :          path = TRIM(directory)//TRIM(filename)
    4463              :       ELSE
    4464            0 :          path = TRIM(directory)//"/"//TRIM(filename)
    4465              :       END IF
    4466              : 
    4467            1 :    END FUNCTION tb_join_path
    4468              : 
    4469              : ! **************************************************************************************************
    4470              : !> \brief Shell-quote a filename or executable path.
    4471              : !> \param text ...
    4472              : !> \return ...
    4473              : ! **************************************************************************************************
    4474            9 :    FUNCTION tb_shell_quote(text) RESULT(quoted)
    4475              :       CHARACTER(LEN=*), INTENT(IN)                       :: text
    4476              :       CHARACTER(LEN=4*default_path_length)               :: quoted
    4477              : 
    4478              :       INTEGER                                            :: i
    4479              : 
    4480            9 :       quoted = "'"
    4481          150 :       DO i = 1, LEN_TRIM(text)
    4482          150 :          IF (text(i:i) == "'") THEN
    4483            0 :             quoted = TRIM(quoted)//"'\\''"
    4484              :          ELSE
    4485          141 :             quoted = TRIM(quoted)//text(i:i)
    4486              :          END IF
    4487              :       END DO
    4488            9 :       quoted = TRIM(quoted)//"'"
    4489              : 
    4490            9 :    END FUNCTION tb_shell_quote
    4491              : 
    4492              : ! **************************************************************************************************
    4493              : !> \brief Write current CP2K geometry as DFTB+ gen format for native tblite.
    4494              : !> \param qs_env ...
    4495              : !> \param filename ...
    4496              : ! **************************************************************************************************
    4497            1 :    SUBROUTINE tb_write_reference_gen(qs_env, filename)
    4498              : 
    4499              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    4500              :       CHARACTER(LEN=*), INTENT(IN)                       :: filename
    4501              : 
    4502            1 :       CHARACTER(LEN=2), ALLOCATABLE, DIMENSION(:)        :: symbols, unique_symbols
    4503              :       INTEGER                                            :: iatom, ikind, ios, natom, nuniq, unit_nr
    4504            1 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: species
    4505              :       INTEGER, DIMENSION(3)                              :: periodic
    4506              :       LOGICAL                                            :: found
    4507              :       REAL(KIND=dp)                                      :: to_angstrom
    4508              :       TYPE(cell_type), POINTER                           :: cell
    4509            1 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    4510              : 
    4511            1 :       NULLIFY (cell, particle_set)
    4512            1 :       CALL get_qs_env(qs_env=qs_env, cell=cell, particle_set=particle_set)
    4513              : 
    4514            1 :       natom = SIZE(particle_set)
    4515            1 :       to_angstrom = cp_unit_from_cp2k(1.0_dp, "angstrom")
    4516            5 :       ALLOCATE (symbols(natom), unique_symbols(natom), species(natom))
    4517            1 :       nuniq = 0
    4518            5 :       DO iatom = 1, natom
    4519            4 :          CALL get_atomic_kind(particle_set(iatom)%atomic_kind, element_symbol=symbols(iatom))
    4520            4 :          found = .FALSE.
    4521            9 :          DO ikind = 1, nuniq
    4522            9 :             IF (TRIM(unique_symbols(ikind)) == TRIM(symbols(iatom))) THEN
    4523              :                found = .TRUE.
    4524              :                EXIT
    4525              :             END IF
    4526              :          END DO
    4527            4 :          IF (.NOT. found) THEN
    4528            3 :             nuniq = nuniq + 1
    4529            3 :             unique_symbols(nuniq) = symbols(iatom)
    4530            3 :             ikind = nuniq
    4531              :          END IF
    4532            5 :          species(iatom) = ikind
    4533              :       END DO
    4534              : 
    4535              :       OPEN (NEWUNIT=unit_nr, FILE=TRIM(filename), STATUS="REPLACE", ACTION="WRITE", &
    4536            1 :             FORM="FORMATTED", IOSTAT=ios)
    4537            1 :       IF (ios /= 0) CPABORT("Could not open tblite reference CLI geometry file")
    4538              : 
    4539            1 :       CALL get_cell(cell=cell, periodic=periodic)
    4540            4 :       IF (ANY(periodic == 1)) THEN
    4541            0 :          WRITE (UNIT=unit_nr, FMT="(I0,1X,A)") natom, "S"
    4542              :       ELSE
    4543            1 :          WRITE (UNIT=unit_nr, FMT="(I0,1X,A)") natom, "C"
    4544              :       END IF
    4545            4 :       WRITE (UNIT=unit_nr, FMT="(*(A,1X))") (TRIM(unique_symbols(ikind)), ikind=1, nuniq)
    4546            5 :       DO iatom = 1, natom
    4547              :          WRITE (UNIT=unit_nr, FMT="(I0,1X,I0,3(1X,ES24.16))") &
    4548           17 :             iatom, species(iatom), particle_set(iatom)%r(:)*to_angstrom
    4549              :       END DO
    4550            4 :       IF (ANY(periodic == 1)) THEN
    4551            0 :          WRITE (UNIT=unit_nr, FMT="(3(1X,ES24.16))") 0.0_dp, 0.0_dp, 0.0_dp
    4552            0 :          DO ikind = 1, 3
    4553            0 :             WRITE (UNIT=unit_nr, FMT="(3(1X,ES24.16))") cell%hmat(:, ikind)*to_angstrom
    4554              :          END DO
    4555              :       END IF
    4556            1 :       CLOSE (unit_nr)
    4557              : 
    4558            1 :       DEALLOCATE (symbols, unique_symbols, species)
    4559              : 
    4560            1 :    END SUBROUTINE tb_write_reference_gen
    4561              : 
    4562              : ! **************************************************************************************************
    4563              : !> \brief Read native tblite gradient file.
    4564              : !> \param filename ...
    4565              : !> \param natom ...
    4566              : !> \param energy ...
    4567              : !> \param gradient ...
    4568              : !> \param virial ...
    4569              : !> \param have_energy ...
    4570              : !> \param have_gradient ...
    4571              : !> \param have_virial ...
    4572              : ! **************************************************************************************************
    4573            0 :    SUBROUTINE tb_read_reference_grad(filename, natom, energy, gradient, virial, &
    4574              :                                      have_energy, have_gradient, have_virial)
    4575              : 
    4576              :       CHARACTER(LEN=*), INTENT(IN)                       :: filename
    4577              :       INTEGER, INTENT(IN)                                :: natom
    4578              :       REAL(KIND=dp), INTENT(OUT)                         :: energy
    4579              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT)        :: gradient, virial
    4580              :       LOGICAL, INTENT(OUT)                               :: have_energy, have_gradient, have_virial
    4581              : 
    4582              :       CHARACTER(LEN=1024)                                :: line
    4583              :       INTEGER                                            :: ios, nread, unit_nr
    4584              :       LOGICAL                                            :: exists
    4585            0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: values
    4586              : 
    4587            0 :       have_energy = .FALSE.
    4588            0 :       have_gradient = .FALSE.
    4589            0 :       have_virial = .FALSE.
    4590            0 :       energy = 0.0_dp
    4591            0 :       gradient = 0.0_dp
    4592            0 :       virial = 0.0_dp
    4593              : 
    4594            0 :       INQUIRE (FILE=TRIM(filename), EXIST=exists)
    4595            0 :       IF (.NOT. exists) RETURN
    4596              : 
    4597              :       OPEN (NEWUNIT=unit_nr, FILE=TRIM(filename), STATUS="OLD", ACTION="READ", &
    4598            0 :             FORM="FORMATTED", IOSTAT=ios)
    4599            0 :       IF (ios /= 0) RETURN
    4600              : 
    4601              :       DO
    4602            0 :          READ (UNIT=unit_nr, FMT="(A)", IOSTAT=ios) line
    4603            0 :          IF (ios /= 0) EXIT
    4604            0 :          IF (INDEX(line, "energy             :real:0:") > 0) THEN
    4605            0 :             READ (UNIT=unit_nr, FMT="(A)", IOSTAT=ios) line
    4606            0 :             IF (ios == 0) THEN
    4607            0 :                READ (line, *, IOSTAT=ios) energy
    4608            0 :                have_energy = ios == 0
    4609              :             END IF
    4610            0 :          ELSE IF (INDEX(line, "gradient           :real:2:3,") > 0) THEN
    4611            0 :             ALLOCATE (values(3*natom))
    4612            0 :             CALL tb_read_real_values(unit_nr, values, nread)
    4613            0 :             IF (nread == 3*natom) THEN
    4614            0 :                CALL tb_values_to_matrix(values, gradient)
    4615            0 :                have_gradient = .TRUE.
    4616              :             END IF
    4617            0 :             DEALLOCATE (values)
    4618            0 :          ELSE IF (INDEX(line, "virial             :real:2:3,3") > 0) THEN
    4619            0 :             ALLOCATE (values(9))
    4620            0 :             CALL tb_read_real_values(unit_nr, values, nread)
    4621            0 :             IF (nread == 9) THEN
    4622            0 :                CALL tb_values_to_matrix(values, virial)
    4623            0 :                have_virial = .TRUE.
    4624              :             END IF
    4625            0 :             DEALLOCATE (values)
    4626              :          END IF
    4627              :       END DO
    4628            0 :       CLOSE (unit_nr)
    4629              : 
    4630            0 :    END SUBROUTINE tb_read_reference_grad
    4631              : 
    4632              : ! **************************************************************************************************
    4633              : !> \brief Read a fixed number of real values from following lines.
    4634              : !> \param unit_nr ...
    4635              : !> \param values ...
    4636              : !> \param nread ...
    4637              : ! **************************************************************************************************
    4638            0 :    SUBROUTINE tb_read_real_values(unit_nr, values, nread)
    4639              : 
    4640              :       INTEGER, INTENT(IN)                                :: unit_nr
    4641              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: values
    4642              :       INTEGER, INTENT(OUT)                               :: nread
    4643              : 
    4644              :       CHARACTER(LEN=1024)                                :: line
    4645              :       INTEGER                                            :: ios
    4646              : 
    4647            0 :       nread = 0
    4648            0 :       DO WHILE (nread < SIZE(values))
    4649            0 :          READ (UNIT=unit_nr, FMT="(A)", IOSTAT=ios) line
    4650            0 :          IF (ios /= 0) EXIT
    4651            0 :          CALL tb_parse_real_line(line, values, nread)
    4652              :       END DO
    4653              : 
    4654            0 :    END SUBROUTINE tb_read_real_values
    4655              : 
    4656              : ! **************************************************************************************************
    4657              : !> \brief Parse real values from one text line.
    4658              : !> \param line ...
    4659              : !> \param values ...
    4660              : !> \param nread ...
    4661              : ! **************************************************************************************************
    4662            0 :    SUBROUTINE tb_parse_real_line(line, values, nread)
    4663              : 
    4664              :       CHARACTER(LEN=*), INTENT(IN)                       :: line
    4665              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: values
    4666              :       INTEGER, INTENT(INOUT)                             :: nread
    4667              : 
    4668              :       CHARACTER(LEN=128)                                 :: token
    4669              :       INTEGER                                            :: first, ios, last, pos
    4670              : 
    4671            0 :       pos = 1
    4672            0 :       DO WHILE (pos <= LEN_TRIM(line) .AND. nread < SIZE(values))
    4673            0 :          DO WHILE (pos <= LEN_TRIM(line) .AND. INDEX(" ,[]", line(pos:pos)) > 0)
    4674            0 :             pos = pos + 1
    4675              :          END DO
    4676            0 :          IF (pos > LEN_TRIM(line)) EXIT
    4677              :          first = pos
    4678            0 :          DO WHILE (pos <= LEN_TRIM(line) .AND. INDEX(" ,[]", line(pos:pos)) == 0)
    4679            0 :             pos = pos + 1
    4680              :          END DO
    4681            0 :          last = pos - 1
    4682            0 :          token = line(first:last)
    4683            0 :          READ (token, *, IOSTAT=ios) values(nread + 1)
    4684            0 :          IF (ios == 0) nread = nread + 1
    4685              :       END DO
    4686              : 
    4687            0 :    END SUBROUTINE tb_parse_real_line
    4688              : 
    4689              : ! **************************************************************************************************
    4690              : !> \brief Convert flat native tblite values to CP2K atom-major matrix layout.
    4691              : !> \param values ...
    4692              : !> \param matrix ...
    4693              : ! **************************************************************************************************
    4694            0 :    SUBROUTINE tb_values_to_matrix(values, matrix)
    4695              : 
    4696              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: values
    4697              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT)        :: matrix
    4698              : 
    4699              :       INTEGER                                            :: i, j, n
    4700              : 
    4701            0 :       n = 0
    4702            0 :       DO j = 1, SIZE(matrix, 2)
    4703            0 :          DO i = 1, SIZE(matrix, 1)
    4704            0 :             n = n + 1
    4705            0 :             matrix(i, j) = values(n)
    4706              :          END DO
    4707              :       END DO
    4708              : 
    4709            0 :    END SUBROUTINE tb_values_to_matrix
    4710              : 
    4711              : ! **************************************************************************************************
    4712              : !> \brief Delete temporary files unless requested otherwise.
    4713              : !> \param ref ...
    4714              : !> \param gen_file ...
    4715              : !> \param grad_file ...
    4716              : !> \param json_file ...
    4717              : !> \param log_file ...
    4718              : !> \param post_processing_output_file ...
    4719              : ! **************************************************************************************************
    4720            1 :    SUBROUTINE tb_reference_cleanup(ref, gen_file, grad_file, json_file, log_file, post_processing_output_file)
    4721              : 
    4722              :       TYPE(xtb_reference_cli_type), INTENT(IN)           :: ref
    4723              :       CHARACTER(LEN=*), INTENT(IN)                       :: gen_file, grad_file, json_file, &
    4724              :                                                             log_file, post_processing_output_file
    4725              : 
    4726            1 :       IF (ref%keep_files) RETURN
    4727            1 :       CALL tb_delete_file(gen_file)
    4728            1 :       CALL tb_delete_file(grad_file)
    4729            1 :       CALL tb_delete_file(json_file)
    4730            1 :       CALL tb_delete_file(log_file)
    4731            1 :       IF (LEN_TRIM(post_processing_output_file) > 0) &
    4732            1 :          CALL tb_delete_file(post_processing_output_file)
    4733              : 
    4734              :    END SUBROUTINE tb_reference_cleanup
    4735              : 
    4736              : ! **************************************************************************************************
    4737              : !> \brief Delete a file if it exists.
    4738              : !> \param filename ...
    4739              : ! **************************************************************************************************
    4740            5 :    SUBROUTINE tb_delete_file(filename)
    4741              : 
    4742              :       CHARACTER(LEN=*), INTENT(IN)                       :: filename
    4743              : 
    4744              :       INTEGER                                            :: ios, unit_nr
    4745              :       LOGICAL                                            :: exists
    4746              : 
    4747            5 :       INQUIRE (FILE=TRIM(filename), EXIST=exists)
    4748            5 :       IF (.NOT. exists) RETURN
    4749            2 :       OPEN (NEWUNIT=unit_nr, FILE=TRIM(filename), STATUS="OLD", IOSTAT=ios)
    4750            2 :       IF (ios == 0) CLOSE (unit_nr, STATUS="DELETE")
    4751              : 
    4752              :    END SUBROUTINE tb_delete_file
    4753              : 
    4754              : ! **************************************************************************************************
    4755              : !> \brief Dump cumulative tblite virial pieces for local debugging.
    4756              : !> \param label ...
    4757              : !> \param sigma ...
    4758              : !> \param para_env ...
    4759              : ! **************************************************************************************************
    4760            0 :    SUBROUTINE tb_dump_sigma_component(label, sigma, para_env)
    4761              : 
    4762              :       CHARACTER(LEN=*), INTENT(IN)                       :: label
    4763              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: sigma
    4764              :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env
    4765              : 
    4766              :       CHARACTER(LEN=default_path_length)                 :: dump_file
    4767              :       INTEGER                                            :: dump_status, dump_unit, i
    4768              : 
    4769            0 :       dump_status = 1
    4770              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    4771              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_SIGMA_COMPONENT_DUMP", dump_file, STATUS=dump_status)
    4772              : #endif
    4773              :       IF (dump_status /= 0) RETURN
    4774              : 
    4775              :       OPEN (NEWUNIT=dump_unit, FILE=TRIM(dump_file), STATUS="UNKNOWN", &
    4776              :             POSITION="APPEND", ACTION="WRITE")
    4777              :       WRITE (dump_unit, "(A)") TRIM(label)
    4778              :       DO i = 1, 3
    4779              :          WRITE (dump_unit, "(3(1X,ES24.16))") sigma(i, :)/para_env%num_pe
    4780              :       END DO
    4781              :       CLOSE (dump_unit)
    4782              : 
    4783              :    END SUBROUTINE tb_dump_sigma_component
    4784              : 
    4785              : ! **************************************************************************************************
    4786              : !> \brief save stress tensor
    4787              : !> \param qs_env ...
    4788              : !> \param tb ...
    4789              : !> \param para_env ...
    4790              : ! **************************************************************************************************
    4791           52 :    SUBROUTINE tb_add_stress(qs_env, tb, para_env)
    4792              : 
    4793              :       TYPE(qs_environment_type)                          :: qs_env
    4794              :       TYPE(tblite_type)                                  :: tb
    4795              :       TYPE(mp_para_env_type)                             :: para_env
    4796              : 
    4797              :       CHARACTER(LEN=default_path_length)                 :: dump_file
    4798              :       INTEGER                                            :: dump_status, dump_unit, i
    4799              :       INTEGER, DIMENSION(3)                              :: periodic
    4800              :       TYPE(cell_type), POINTER                           :: cell
    4801              :       TYPE(virial_type), POINTER                         :: virial
    4802              : 
    4803           52 :       NULLIFY (virial, cell)
    4804           52 :       CALL get_qs_env(qs_env=qs_env, virial=virial, cell=cell)
    4805           52 :       CALL get_cell(cell=cell, periodic=periodic)
    4806              : 
    4807           72 :       IF (ALL(periodic == 0)) THEN
    4808              :          CALL cp_warn(__LOCATION__, &
    4809              :                       "tblite stress tensor requested for an isolated system. "// &
    4810              :                       "The reported virial is useful for finite-difference checks, "// &
    4811            4 :                       "but it is not a physically meaningful bulk stress for an isolated molecule.")
    4812              :       END IF
    4813              : 
    4814           52 :       dump_status = 1
    4815              : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
    4816              :       CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_VIRIAL_DUMP", dump_file, STATUS=dump_status)
    4817              : #endif
    4818              :       IF (dump_status == 0) THEN
    4819              :          OPEN (NEWUNIT=dump_unit, FILE=TRIM(dump_file), STATUS="UNKNOWN", &
    4820              :                POSITION="APPEND", ACTION="WRITE")
    4821              :          WRITE (dump_unit, "(A)") "sigma"
    4822              :          DO i = 1, 3
    4823              :             WRITE (dump_unit, "(3(1X,ES24.16))") tb%sigma(i, :)/para_env%num_pe
    4824              :          END DO
    4825              :          CLOSE (dump_unit)
    4826              :       END IF
    4827              : 
    4828          676 :       virial%pv_virial = virial%pv_virial - tb%sigma/para_env%num_pe
    4829              : 
    4830           52 :    END SUBROUTINE tb_add_stress
    4831              : 
    4832              : ! **************************************************************************************************
    4833              : !> \brief add contrib. to gradient
    4834              : !> \param grad ...
    4835              : !> \param deriv ...
    4836              : !> \param dE ...
    4837              : !> \param natom ...
    4838              : ! **************************************************************************************************
    4839          228 :    SUBROUTINE tb_add_grad(grad, deriv, dE, natom)
    4840              : 
    4841              :       REAL(KIND=dp), DIMENSION(:, :)                     :: grad
    4842              :       REAL(KIND=dp), DIMENSION(:, :, :)                  :: deriv
    4843              :       REAL(KIND=dp), DIMENSION(:)                        :: dE
    4844              :       INTEGER                                            :: natom
    4845              : 
    4846              :       INTEGER                                            :: i, j
    4847              : 
    4848         1144 :       DO i = 1, natom
    4849         5628 :          DO j = 1, natom
    4850        18852 :             grad(:, i) = grad(:, i) + deriv(:, i, j)*dE(j)
    4851              :          END DO
    4852              :       END DO
    4853              : 
    4854          228 :    END SUBROUTINE tb_add_grad
    4855              : 
    4856              : ! **************************************************************************************************
    4857              : !> \brief add contrib. to sigma
    4858              : !> \param sig ...
    4859              : !> \param deriv ...
    4860              : !> \param dE ...
    4861              : !> \param natom ...
    4862              : ! **************************************************************************************************
    4863          104 :    SUBROUTINE tb_add_sig(sig, deriv, dE, natom)
    4864              : 
    4865              :       REAL(KIND=dp), DIMENSION(:, :)                     :: sig
    4866              :       REAL(KIND=dp), DIMENSION(:, :, :)                  :: deriv
    4867              :       REAL(KIND=dp), DIMENSION(:)                        :: dE
    4868              :       INTEGER                                            :: natom
    4869              : 
    4870              :       INTEGER                                            :: i, j
    4871              : 
    4872          416 :       DO i = 1, 3
    4873         1940 :          DO j = 1, natom
    4874         6408 :             sig(:, i) = sig(:, i) + deriv(:, i, j)*dE(j)
    4875              :          END DO
    4876              :       END DO
    4877              : 
    4878          104 :    END SUBROUTINE tb_add_sig
    4879              : 
    4880      3185290 : END MODULE tblite_interface
        

Generated by: LCOV version 2.0-1