LCOV - code coverage report
Current view: top level - src - dft_plus_u.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 81.6 % 1732 1413
Test Date: 2026-10-15 00:55:44 Functions: 94.1 % 17 16

            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              : !> \brief   Add the DFT+U contribution to the Hamiltonian matrix
       9              : !> \details The implemented methods refers to:\n
      10              : !>          S. L. Dudarev, D. Nguyen Manh, and A. P. Sutton,
      11              : !>          Philos. Mag. B \b 75, 613 (1997)\n
      12              : !>          S. L. Dudarev et al.,
      13              : !>          Phys. Rev. B \b 57, 1505 (1998)
      14              : !> \author  Matthias Krack (MK)
      15              : !> \date    14.01.2008
      16              : !> \version 1.0
      17              : ! **************************************************************************************************
      18              : MODULE dft_plus_u
      19              :    USE OMP_LIB,                         ONLY: omp_get_max_threads,&
      20              :                                               omp_get_thread_num
      21              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      22              :                                               get_atomic_kind,&
      23              :                                               get_atomic_kind_set
      24              :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      25              :                                               gto_basis_set_type
      26              :    USE bibliography,                    ONLY: Dudarev1997,&
      27              :                                               Dudarev1998,&
      28              :                                               cite_reference
      29              :    USE cp_cfm_basic_linalg,             ONLY: cp_cfm_column_scale,&
      30              :                                               cp_cfm_transpose
      31              :    USE cp_cfm_diag,                     ONLY: cp_cfm_heevd
      32              :    USE cp_cfm_types,                    ONLY: cp_cfm_create,&
      33              :                                               cp_cfm_get_info,&
      34              :                                               cp_cfm_release,&
      35              :                                               cp_cfm_to_cfm,&
      36              :                                               cp_cfm_type,&
      37              :                                               cp_fm_to_cfm
      38              :    USE cp_control_types,                ONLY: dft_control_type
      39              :    USE cp_dbcsr_api,                    ONLY: &
      40              :         dbcsr_copy, dbcsr_create, dbcsr_deallocate_matrix, dbcsr_desymmetrize, dbcsr_finalize, &
      41              :         dbcsr_get_block_p, dbcsr_init_p, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
      42              :         dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_multiply, &
      43              :         dbcsr_p_type, dbcsr_put_block, dbcsr_release, dbcsr_set, dbcsr_type
      44              :    USE cp_dbcsr_contrib,                ONLY: dbcsr_get_block_diag,&
      45              :                                               dbcsr_get_diag,&
      46              :                                               dbcsr_set_diag
      47              :    USE cp_dbcsr_operations,             ONLY: copy_dbcsr_to_fm,&
      48              :                                               copy_fm_to_dbcsr,&
      49              :                                               cp_dbcsr_plus_fm_fm_t,&
      50              :                                               cp_dbcsr_sm_fm_multiply
      51              :    USE cp_dbcsr_output,                 ONLY: cp_dbcsr_write_sparse_matrix,&
      52              :                                               write_fm_with_basis_info
      53              :    USE cp_fm_basic_linalg,              ONLY: cp_fm_scale_and_add,&
      54              :                                               cp_fm_schur_product,&
      55              :                                               cp_fm_transpose
      56              :    USE cp_fm_diag,                      ONLY: choose_eigv_solver
      57              :    USE cp_fm_struct,                    ONLY: cp_fm_struct_type
      58              :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      59              :                                               cp_fm_get_info,&
      60              :                                               cp_fm_release,&
      61              :                                               cp_fm_set_submatrix,&
      62              :                                               cp_fm_to_fm,&
      63              :                                               cp_fm_type
      64              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      65              :                                               cp_logger_type
      66              :    USE cp_output_handling,              ONLY: cp_p_file,&
      67              :                                               cp_print_key_finished_output,&
      68              :                                               cp_print_key_should_output,&
      69              :                                               cp_print_key_unit_nr,&
      70              :                                               low_print_level
      71              :    USE input_constants,                 ONLY: diag_update_method_adiis,&
      72              :                                               plus_u_lowdin,&
      73              :                                               plus_u_mulliken,&
      74              :                                               plus_u_mulliken_charges,&
      75              :                                               plus_u_tensorial
      76              :    USE input_section_types,             ONLY: section_vals_type
      77              :    USE kinds,                           ONLY: default_string_length,&
      78              :                                               dp
      79              :    USE kpoint_types,                    ONLY: kpoint_env_type,&
      80              :                                               kpoint_type
      81              :    USE local_gemm_api,                  ONLY: LOCAL_GEMM_PU_GPU,&
      82              :                                               local_gemm_ctxt_type
      83              :    USE mathconstants,                   ONLY: z_one,&
      84              :                                               z_zero
      85              :    USE mathlib,                         ONLY: invert_matrix,&
      86              :                                               jacobi
      87              :    USE message_passing,                 ONLY: mp_para_env_type
      88              :    USE orbital_symbols,                 ONLY: sgf_symbol
      89              :    USE parallel_gemm_api,               ONLY: parallel_gemm
      90              :    USE particle_methods,                ONLY: get_particle_set
      91              :    USE particle_types,                  ONLY: particle_type
      92              :    USE physcon,                         ONLY: evolt
      93              :    USE qs_energy_types,                 ONLY: qs_energy_type
      94              :    USE qs_environment_types,            ONLY: get_qs_env,&
      95              :                                               qs_environment_type
      96              :    USE qs_force_types,                  ONLY: qs_force_type
      97              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      98              :                                               get_qs_kind_set,&
      99              :                                               qs_kind_type,&
     100              :                                               set_qs_kind
     101              :    USE qs_kpoint_operators,             ONLY: kpoint_operator_context_create,&
     102              :                                               kpoint_operator_context_release,&
     103              :                                               kpoint_operator_context_type,&
     104              :                                               kpoint_operator_get
     105              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
     106              :                                               qs_rho_type
     107              :    USE qs_scf_types,                    ONLY: qs_scf_env_type
     108              : #include "./base/base_uses.f90"
     109              : 
     110              :    IMPLICIT NONE
     111              : 
     112              :    PRIVATE
     113              : 
     114              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'dft_plus_u'
     115              : 
     116              :    PUBLIC :: plus_u
     117              :    PUBLIC :: lowdin_kp_init, lowdin_kp_initial_density, lowdin_kp_population, lowdin_kp_apply
     118              :    PUBLIC :: lowdin_kp_forces
     119              :    PUBLIC :: lowdin_kp_apply_mo, lowdin_kp_kernel
     120              :    PUBLIC :: lowdin_kp_prepare
     121              : 
     122              : CONTAINS
     123              : ! **************************************************************************************************
     124              : !> \brief         Add the DFT+U contribution to the Hamiltonian matrix.\n
     125              : !>                Wrapper routine for all "+U" methods
     126              : !> \param[in]     qs_env Quickstep environment
     127              : !> \param[in,out] matrix_h Hamiltonian matrices for each spin
     128              : !> \param[in,out] matrix_w Energy weighted density matrices for each spin
     129              : !> \date          14.01.2008
     130              : !> \author        Matthias Krack (MK)
     131              : !> \version       1.0
     132              : ! **************************************************************************************************
     133         6386 :    SUBROUTINE plus_u(qs_env, matrix_h, matrix_w)
     134              : 
     135              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     136              :       TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
     137              :          POINTER                                         :: matrix_h, matrix_w
     138              : 
     139              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'plus_u'
     140              : 
     141              :       INTEGER                                            :: handle, output_unit, print_level
     142              :       LOGICAL                                            :: orthonormal_basis, should_output
     143              :       TYPE(cp_logger_type), POINTER                      :: logger
     144              :       TYPE(dft_control_type), POINTER                    :: dft_control
     145              :       TYPE(section_vals_type), POINTER                   :: input
     146              : 
     147         6386 :       CALL timeset(routineN, handle)
     148              : 
     149         6386 :       CPASSERT(ASSOCIATED(qs_env))
     150              : 
     151         6386 :       NULLIFY (input, dft_control)
     152              : 
     153         6386 :       logger => cp_get_default_logger()
     154              : 
     155              :       CALL get_qs_env(qs_env=qs_env, &
     156              :                       input=input, &
     157         6386 :                       dft_control=dft_control)
     158              : 
     159         6386 :       CALL cite_reference(Dudarev1997)
     160         6386 :       CALL cite_reference(Dudarev1998)
     161              : 
     162              :       ! Later we could save here some time, if the method in use has this property
     163              :       ! which then has to be figured out here
     164              : 
     165         6386 :       orthonormal_basis = .FALSE.
     166              : 
     167              :       ! Setup print control
     168              : 
     169         6386 :       print_level = logger%iter_info%print_level
     170              :       should_output = (BTEST(cp_print_key_should_output(logger%iter_info, input, &
     171              :                                                         "DFT%PRINT%PLUS_U"), cp_p_file) .AND. &
     172         6386 :                        (.NOT. PRESENT(matrix_w)))
     173              :       output_unit = cp_print_key_unit_nr(logger, input, "DFT%PRINT%PLUS_U", &
     174              :                                          extension=".plus_u", &
     175              :                                          ignore_should_output=should_output, &
     176         6386 :                                          log_filename=.FALSE.)
     177              : 
     178              :       ! Select DFT+U method
     179              : 
     180         6386 :       SELECT CASE (dft_control%plus_u_method_id)
     181              :       CASE (plus_u_lowdin)
     182              :          IF (orthonormal_basis) THEN
     183              :             ! For an orthonormal basis the Lowdin method and the Mulliken method
     184              :             ! are equivalent
     185              :             CALL mulliken(qs_env, orthonormal_basis, matrix_h, &
     186              :                           should_output, output_unit, print_level)
     187              :          ELSE
     188              :             CALL lowdin(qs_env, matrix_h, matrix_w, &
     189         2556 :                         should_output, output_unit, print_level)
     190              :          END IF
     191              :       CASE (plus_u_mulliken)
     192              :          CALL mulliken(qs_env, orthonormal_basis, matrix_h, &
     193         2096 :                        should_output, output_unit, print_level)
     194              :       CASE (plus_u_mulliken_charges)
     195              :          CALL mulliken_charges(qs_env, orthonormal_basis, matrix_h, matrix_w, &
     196          962 :                                should_output, output_unit, print_level)
     197              :       CASE (plus_u_tensorial)
     198              :          CALL tensorial(qs_env, matrix_h, matrix_w, &
     199          772 :                         should_output, output_unit, print_level)
     200              :       CASE DEFAULT
     201         6386 :          CPABORT("Invalid DFT+U method requested")
     202              :       END SELECT
     203              : 
     204              :       CALL cp_print_key_finished_output(output_unit, logger, input, "DFT%PRINT%PLUS_U", &
     205         6386 :                                         ignore_should_output=should_output)
     206              : 
     207         6386 :       CALL timestop(handle)
     208              : 
     209         6386 :    END SUBROUTINE plus_u
     210              : 
     211              : ! **************************************************************************************************
     212              : !> \brief         Add a DFT+U contribution to the Hamiltonian matrix\n
     213              : !>                using a method based on Lowdin charges
     214              : !>                \f[Q = S^{1/2} P S^{1/2}\f]
     215              : !>                where \b P and \b S are the density and the
     216              : !>                overlap matrix, respectively.
     217              : !> \param[in]     qs_env Quickstep environment
     218              : !> \param[in,out] matrix_h Hamiltonian matrices for each spin
     219              : !> \param[in,out] matrix_w Energy weighted density matrices for each spin
     220              : !> \param should_output ...
     221              : !> \param output_unit ...
     222              : !> \param print_level ...
     223              : !> \date          02.07.2008
     224              : !> \par
     225              : !>  \f{eqnarray*}{
     226              : !>   E^{\rm DFT+U} & = & E^{\rm DFT} +  E^{\rm U}
     227              : !>                 & = & E^{\rm DFT} +  \frac{1}{2}(U - J)\sum_\mu (q_\mu - q_\mu^2)\\[1ex]
     228              : !>   V_{\mu\nu}^{\rm DFT+U} & = & V_{\mu\nu}^{\rm DFT} + V_{\mu\nu}^{\rm U}\\\
     229              : !>                          & = & \frac{\partial E^{\rm DFT}}
     230              : !>                                     {\partial P_{\mu\nu}} +
     231              : !>                                \frac{\partial E^{\rm U}}
     232              : !>                                     {\partial P_{\mu\nu}}\\\
     233              : !>                          & = & H_{\mu\nu} +
     234              : !>                                \frac{\partial E^{\rm U}}{\partial q_\mu}
     235              : !>                                \frac{\partial q_\mu}{\partial P_{\mu\nu}}\\\
     236              : !>  \f}
     237              : !> \author        Matthias Krack (MK)
     238              : !> \version       1.0
     239              : ! **************************************************************************************************
     240         2556 :    SUBROUTINE lowdin(qs_env, matrix_h, matrix_w, should_output, output_unit, &
     241              :                      print_level)
     242              : 
     243              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     244              :       TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
     245              :          POINTER                                         :: matrix_h, matrix_w
     246              :       LOGICAL, INTENT(IN)                                :: should_output
     247              :       INTEGER, INTENT(IN)                                :: output_unit, print_level
     248              : 
     249              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'lowdin'
     250              : 
     251              :       CHARACTER(LEN=10)                                  :: spin_info
     252         2556 :       CHARACTER(LEN=6), ALLOCATABLE, DIMENSION(:)        :: symbol
     253              :       CHARACTER(LEN=default_string_length)               :: atomic_kind_name
     254              :       INTEGER :: atom_a, handle, i, i0, iatom, ikind, iorb, isb, iset, isgf, ishell, ispin, j, &
     255              :          jsb, jsgf, lu, m, max_scf, n, natom_of_kind, nkind, norb, nsb, nsbsize, nset, nsgf, &
     256              :          nsgf_kind, nspin
     257         2556 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: shell_sgf
     258              :       INTEGER, DIMENSION(1)                              :: iloc
     259         2556 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, nshell, orbitals
     260         2556 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgf, l, last_sgf
     261              :       LOGICAL                                            :: debug, dft_plus_u_atom, do_kpoints, &
     262              :                                                             found, if_plus_j, just_energy, smear
     263         2556 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: orb_occ
     264              :       REAL(KIND=dp) :: eps_scf, eps_u_ramping, fspin, hund_j, occ, perturbation_strength, sij, &
     265              :          trq, trq2, trqxq_hund_j, u_minus_j, u_minus_j_target, u_ramping
     266         2556 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: eigval, q_eigval
     267         2556 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: orbq, q_eigvec, q_matrix, q_opp_matrix, &
     268         2556 :                                                             q_work, slam
     269              :       REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :), &
     270         2556 :          POINTER                                         :: local_data
     271         2556 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: q_block, q_opp_block, v_block, vhxc_block
     272         2556 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     273              :       TYPE(cp_fm_struct_type), POINTER                   :: fmstruct
     274              :       TYPE(cp_fm_type)                                   :: fm_sev, fm_work1, fm_work2, slambda
     275              :       TYPE(cp_fm_type), POINTER                          :: fm_s_half
     276         2556 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_vhxc
     277         2556 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_s
     278              :       TYPE(dbcsr_type)                                   :: sm_q, sm_q_opp, sm_v
     279              :       TYPE(dbcsr_type), POINTER                          :: sm_h, sm_p, sm_p_opp, sm_s, sm_vhxc, sm_w
     280              :       TYPE(dft_control_type), POINTER                    :: dft_control
     281              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
     282              :       TYPE(kpoint_type), POINTER                         :: kpoints
     283              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     284              :       TYPE(qs_energy_type), POINTER                      :: energy
     285         2556 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     286              :       TYPE(qs_rho_type), POINTER                         :: rho
     287              :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     288              : 
     289         2556 :       CALL timeset(routineN, handle)
     290              : 
     291         2556 :       debug = .FALSE. ! Set to .TRUE. to print debug information
     292              : 
     293         2556 :       NULLIFY (sm_h, sm_p, sm_p_opp, sm_s, sm_w, vhxc_block, sm_vhxc, matrix_vhxc)
     294              : 
     295         2556 :       smear = .FALSE.
     296         2556 :       max_scf = -1
     297         2556 :       eps_scf = 1.0E30_dp
     298         2556 :       if_plus_j = .FALSE.
     299              : 
     300              :       CALL get_qs_env(qs_env=qs_env, &
     301              :                       atomic_kind_set=atomic_kind_set, &
     302              :                       qs_kind_set=qs_kind_set, &
     303              :                       dft_control=dft_control, &
     304              :                       do_kpoints=do_kpoints, &
     305              :                       kpoints=kpoints, &
     306              :                       energy=energy, &
     307              :                       matrix_s_kp=matrix_s, &
     308              :                       matrix_vhxc=matrix_vhxc, &
     309              :                       rho=rho, &
     310              :                       scf_env=scf_env, &
     311         2556 :                       para_env=para_env)
     312              : 
     313         2556 :       CALL qs_rho_get(rho, rho_ao_kp=matrix_p) ! Density matrices in sparse format
     314              : 
     315         2556 :       energy%dft_plus_u = 0.0_dp
     316              : 
     317         2556 :       nspin = dft_control%nspins
     318         2556 :       IF (dft_control%mtlr_dft_with_perturbation) THEN
     319         1448 :          IF (.NOT. ASSOCIATED(matrix_vhxc)) THEN
     320            0 :             CPABORT("MTLR requires the projected Hxc matrix for every spin channel.")
     321              :          END IF
     322         1448 :          IF (SIZE(matrix_vhxc) /= nspin) THEN
     323            0 :             CPABORT("The number of projected Hxc matrices does not match the spin channels.")
     324              :          END IF
     325              :       END IF
     326              : 
     327         2556 :       IF (nspin == 2) THEN
     328              :          fspin = 1.0_dp
     329              :       ELSE
     330          488 :          fspin = 0.5_dp
     331              :       END IF
     332              : 
     333              :       ! Get the number of basis functions and atomic kinds.
     334         2556 :       CALL get_qs_kind_set(qs_kind_set, nsgf=nsgf)
     335              : 
     336         2556 :       nkind = SIZE(atomic_kind_set)
     337              : 
     338         2556 :       IF (PRESENT(matrix_h) .OR. PRESENT(matrix_w)) THEN
     339              :          just_energy = .FALSE.
     340              :       ELSE
     341           34 :          just_energy = .TRUE.
     342              :       END IF
     343              : 
     344              :       ! Check if unlike spin +J correction is needed and reject an
     345              :       ! incompatible enforced occupation setup before any expensive work.
     346         6472 :       DO ikind = 1, nkind
     347         3916 :          NULLIFY (orbitals)
     348              :          CALL get_qs_kind(qs_kind_set(ikind), &
     349              :                           hund_j=hund_j, &
     350         3916 :                           orbitals=orbitals)
     351         6472 :          IF (hund_j /= 0.0_dp) THEN
     352         1774 :             if_plus_j = .TRUE.
     353         1774 :             IF (ASSOCIATED(orbitals)) THEN
     354              :                CALL cp_abort(__LOCATION__, "ENFORCE_OCCUPATION is incompatible with a nonzero Hund J "// &
     355            0 :                              "in the Lowdin DFT+U+J method.")
     356              :             END IF
     357              :          END IF
     358              :       END DO
     359              : 
     360         2556 :       NULLIFY (orbitals)
     361              : 
     362         2556 :       IF (.NOT. do_kpoints) THEN
     363              :          ! Retrieve S^(1/2) from the SCF environment
     364         1924 :          fm_s_half => scf_env%s_half
     365         1924 :          CPASSERT(ASSOCIATED(fm_s_half))
     366              :          ! work matrices
     367         1924 :          CALL cp_fm_get_info(fm_s_half, matrix_struct=fmstruct)
     368              :          CALL cp_fm_create(matrix=fm_work1, matrix_struct=fmstruct, &
     369         1924 :                            name="FULL WORK MATRIX 1")
     370              :          CALL cp_fm_create(matrix=fm_work2, matrix_struct=fmstruct, &
     371         1924 :                            name="FULL WORK MATRIX 2")
     372              :       END IF
     373              : 
     374              :       ! Calculate S eigenvectors and Lambda matrix for forces
     375              :       ! See sTDA forces (get_lowdin_mo_coefficients in qs_tddfpt2_stda_utils
     376              :       ! A. Hehn et al JCTC 2022, 18, 4186
     377         2556 :       IF (PRESENT(matrix_w) .AND. .NOT. do_kpoints) THEN
     378            2 :          CALL cp_fm_create(matrix=fm_sev, matrix_struct=fmstruct)
     379            2 :          CALL cp_fm_create(matrix=slambda, matrix_struct=fmstruct)
     380            8 :          ALLOCATE (eigval(nsgf), slam(nsgf, 1))
     381            2 :          sm_s => matrix_s(1, 1)%matrix
     382            2 :          CALL copy_dbcsr_to_fm(sm_s, fm_work1)
     383            2 :          CALL choose_eigv_solver(fm_work1, fm_sev, eigval)
     384              :          !
     385           48 :          DO i = 1, nsgf
     386           48 :             IF (eigval(i) > 0._dp) THEN
     387           46 :                slam(i, 1) = SQRT(eigval(i))
     388              :             ELSE
     389            0 :                CPABORT("S matrix not positive definit")
     390              :             END IF
     391              :          END DO
     392           48 :          DO i = 1, nsgf
     393           48 :             CALL cp_fm_set_submatrix(slambda, slam, 1, i, nsgf, 1, 1.0_dp, 0.0_dp)
     394              :          END DO
     395           48 :          DO i = 1, nsgf
     396           48 :             CALL cp_fm_set_submatrix(slambda, slam, i, 1, 1, nsgf, 1.0_dp, 1.0_dp, .TRUE.)
     397              :          END DO
     398            2 :          CALL cp_fm_get_info(slambda, local_data=local_data)
     399           48 :          DO i = 1, SIZE(local_data, 2)
     400          577 :             DO j = 1, SIZE(local_data, 1)
     401          529 :                sij = local_data(j, i)
     402          529 :                IF (sij > 0.0_dp) sij = 1.0_dp/sij
     403          575 :                local_data(j, i) = sij
     404              :             END DO
     405              :          END DO
     406            4 :          DEALLOCATE (eigval, slam)
     407              :       END IF
     408              : 
     409              :       ! Calculate S^(1/2)*P*S^(1/2)
     410         2556 :       IF (do_kpoints) THEN
     411              :          ! OT and ADIIS evaluate the current trial density, including energy-only line searches.
     412              :          ! Density mixing instead owns separate accepted coordinates.
     413              :          IF (qs_env%scf_control%use_ot .OR. &
     414          632 :              qs_env%scf_control%diagonalization%update_method == diag_update_method_adiis .OR. PRESENT(matrix_w)) THEN
     415          262 :             CALL lowdin_kp_population(kpoints, alpha=1.0_dp)
     416              :          END IF
     417         2528 :          ALLOCATE (orbq(nsgf, nspin))
     418          632 :          orbq = 0.0_dp
     419        10430 :          orbq(kpoints%lowdin_orbitals, :) = kpoints%lowdin_q
     420              :       END IF
     421              : 
     422              :       ! Create local block diagonal matrices
     423         2556 :       sm_s => matrix_s(1, 1)%matrix
     424         2556 :       CALL dbcsr_get_block_diag(sm_s, sm_q)
     425         2556 :       IF (if_plus_j .AND. nspin == 2) THEN
     426         1774 :          CALL dbcsr_get_block_diag(sm_s, sm_q_opp)
     427              :       END IF
     428         2556 :       CALL dbcsr_get_block_diag(sm_s, sm_v)
     429              : 
     430              :       ! Loop over all spins
     431         7180 :       DO ispin = 1, nspin
     432              : 
     433         4624 :          CALL dbcsr_set(sm_q, 0.0_dp)
     434         4624 :          IF (if_plus_j .AND. nspin == 2) THEN
     435         3548 :             CALL dbcsr_set(sm_q_opp, 0.0_dp)
     436              :          END IF
     437         4624 :          CALL dbcsr_set(sm_v, 0.0_dp)
     438              : 
     439         4624 :          IF (dft_control%mtlr_dft_with_perturbation) THEN
     440         2896 :             IF (ispin == 1) perturbation_strength = 0.9_dp*dft_control%perturbation_strength
     441         2896 :             IF (ispin == 2) perturbation_strength = 1.1_dp*dft_control%perturbation_strength
     442         2896 :             IF (.NOT. ASSOCIATED(matrix_vhxc(ispin)%matrix)) THEN
     443            0 :                CPABORT("MTLR projected Hxc matrix is not initialized.")
     444              :             END IF
     445         2896 :             sm_vhxc => matrix_vhxc(ispin)%matrix
     446              :          END IF
     447              : 
     448         4624 :          IF (do_kpoints) THEN
     449          858 :             CALL dbcsr_set_diag(sm_q, orbq(:, ispin))
     450          858 :             IF (if_plus_j .AND. nspin == 2) CALL dbcsr_set_diag(sm_q_opp, orbq(:, 3 - ispin))
     451              :          ELSE
     452              :             ! Calculate S^(1/2)*P*S^(1/2) as a full matrix (Lowdin)
     453         3766 :             sm_p => matrix_p(ispin, 1)%matrix
     454         3766 :             CALL cp_dbcsr_sm_fm_multiply(sm_p, fm_s_half, fm_work1, nsgf)
     455              :             CALL parallel_gemm(transa="N", &
     456              :                                transb="N", &
     457              :                                m=nsgf, &
     458              :                                n=nsgf, &
     459              :                                k=nsgf, &
     460              :                                alpha=1.0_dp, &
     461              :                                matrix_a=fm_s_half, &
     462              :                                matrix_b=fm_work1, &
     463              :                                beta=0.0_dp, &
     464         3766 :                                matrix_c=fm_work2)
     465              :             IF (debug) THEN
     466              :                CALL cp_dbcsr_write_sparse_matrix(sm_p, 4, 6, qs_env, para_env, &
     467              :                                                  output_unit=output_unit)
     468              :                CALL write_fm_with_basis_info(fm_s_half, 4, 6, qs_env, para_env, &
     469              :                                              output_unit=output_unit)
     470              :                CALL write_fm_with_basis_info(fm_work2, 4, 6, qs_env, para_env, &
     471              :                                              output_unit=output_unit)
     472              :             END IF ! debug
     473              :             ! Copy occupation matrix to sparse matrix format, finally we are only
     474              :             ! interested in the diagonal (atomic) blocks, i.e. the previous full
     475              :             ! matrix product is not the most efficient choice, anyway.
     476         3766 :             CALL copy_fm_to_dbcsr(fm_work2, sm_q, keep_sparsity=.TRUE.)
     477              : 
     478              :             ! If nspin == 1 and one would like to add "unlike" spin +J corrections,
     479              :             ! sm_p is already enough and sm_p_opp is not needed
     480         3766 :             IF (if_plus_j .AND. nspin == 2) THEN
     481              :                ! Calculate S^(1/2)*P*S^(1/2) for the other spin channel if
     482              :                ! unlike spin +J correction is activated.
     483         3548 :                sm_p_opp => matrix_p(3 - ispin, 1)%matrix
     484         3548 :                CALL cp_dbcsr_sm_fm_multiply(sm_p_opp, fm_s_half, fm_work1, nsgf)
     485              :                CALL parallel_gemm(transa="N", &
     486              :                                   transb="N", &
     487              :                                   m=nsgf, &
     488              :                                   n=nsgf, &
     489              :                                   k=nsgf, &
     490              :                                   alpha=1.0_dp, &
     491              :                                   matrix_a=fm_s_half, &
     492              :                                   matrix_b=fm_work1, &
     493              :                                   beta=0.0_dp, &
     494         3548 :                                   matrix_c=fm_work2)
     495         3548 :                CALL copy_fm_to_dbcsr(fm_work2, sm_q_opp, keep_sparsity=.TRUE.)
     496              :             END IF
     497              :          END IF
     498              : 
     499              :          ! E[DFT+U] = E[DFT] + E[U]
     500              :          !          = E[DFT] + (U - J)*(Tr(q) - Tr(q*q))/2
     501              : 
     502              :          ! V(i,j)[DFT+U] = V(i,j)[DFT] + V(i,j)[U]
     503              :          !               = dE[DFT]/dP(i,j) + dE[U]/dP(i,j)
     504              :          !               = dE[DFT]/dP(i,j) + (dE(U)/dq)*(dq/dP(i,j))
     505              : 
     506              :          ! Loop over all atomic kinds
     507        11480 :          DO ikind = 1, nkind
     508              : 
     509              :             ! Load the required atomic kind data
     510              :             CALL get_atomic_kind(atomic_kind_set(ikind), &
     511              :                                  atom_list=atom_list, &
     512              :                                  name=atomic_kind_name, &
     513         6856 :                                  natom=natom_of_kind)
     514              : 
     515              :             CALL get_qs_kind(qs_kind_set(ikind), &
     516              :                              dft_plus_u_atom=dft_plus_u_atom, &
     517              :                              l_of_dft_plus_u=lu, &
     518              :                              nsgf=nsgf_kind, &
     519              :                              basis_set=orb_basis_set, &
     520              :                              u_minus_j=u_minus_j, &
     521              :                              hund_j=hund_j, &
     522              :                              u_minus_j_target=u_minus_j_target, &
     523              :                              u_ramping=u_ramping, &
     524              :                              eps_u_ramping=eps_u_ramping, &
     525              :                              orbitals=orbitals, &
     526              :                              eps_scf=eps_scf, &
     527              :                              max_scf=max_scf, &
     528         6856 :                              smear=smear)
     529              : 
     530              :             ! Check, if the atoms of this atomic kind need a DFT+U correction
     531         6856 :             IF (.NOT. ASSOCIATED(orb_basis_set)) CYCLE
     532         6856 :             IF (.NOT. dft_plus_u_atom) CYCLE
     533         4624 :             IF (lu < 0) CYCLE
     534              : 
     535              :             ! Apply U ramping if requested
     536         4624 :             IF ((ispin == 1) .AND. (u_ramping > 0.0_dp) .AND. .NOT. do_kpoints) THEN
     537            0 :                IF (qs_env%scf_env%iter_delta <= eps_u_ramping) THEN
     538            0 :                   u_minus_j = MIN(u_minus_j + u_ramping, u_minus_j_target)
     539            0 :                   CALL set_qs_kind(qs_kind_set(ikind), u_minus_j=u_minus_j)
     540              :                END IF
     541            0 :                IF (should_output .AND. (output_unit > 0)) THEN
     542              :                   WRITE (UNIT=output_unit, FMT="(T3,A,3X,A,F0.3,A)") &
     543            0 :                      "Kind name: "//TRIM(ADJUSTL(atomic_kind_name)), &
     544            0 :                      "U(eff) = ", u_minus_j*evolt, " eV"
     545              :                END IF
     546              :             END IF
     547              : 
     548         4624 :             IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) CYCLE
     549              : 
     550              :             ! Load the required Gaussian basis set data
     551              :             CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
     552              :                                    first_sgf=first_sgf, &
     553              :                                    l=l, &
     554              :                                    last_sgf=last_sgf, &
     555              :                                    nset=nset, &
     556         4624 :                                    nshell=nshell)
     557              : 
     558              :             ! Select this kind's shell once; occupations and potentials use the same AO order.
     559        13872 :             ALLOCATE (shell_sgf(nsgf_kind))
     560         4624 :             n = 0
     561        10622 :             DO iset = 1, nset
     562        26566 :                DO ishell = 1, nshell(iset)
     563        15944 :                   IF (l(ishell, iset) /= lu) CYCLE
     564        33422 :                   DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
     565        18176 :                      n = n + 1
     566        34120 :                      shell_sgf(n) = isgf
     567              :                   END DO
     568              :                END DO
     569              :             END DO
     570         4624 :             nsbsize = 2*lu + 1
     571         4624 :             nsb = n/nsbsize
     572              : 
     573        18496 :             ALLOCATE (q_matrix(n, n))
     574         4624 :             q_matrix(:, :) = 0.0_dp
     575              : 
     576         4624 :             IF (hund_j /= 0.0_dp .AND. nspin == 2) THEN
     577        10644 :                ALLOCATE (q_opp_matrix(n, n))
     578         3548 :                q_opp_matrix(:, :) = 0.0_dp
     579              :             END IF
     580              : 
     581         4624 :             IF (dft_control%mtlr_dft_with_perturbation .AND. &
     582              :                 dft_control%mtlr_ikind == ikind) THEN
     583         2896 :                dft_control%vhxc(ispin) = 0.0_dp
     584         2896 :                dft_control%trq(ispin) = 0.0_dp
     585              :             END IF
     586              : 
     587              :             ! Print headline if requested
     588         4624 :             IF (should_output .AND. (print_level > low_print_level)) THEN
     589            0 :                IF (output_unit > 0) THEN
     590            0 :                   ALLOCATE (symbol(nsbsize))
     591            0 :                   DO m = -lu, lu
     592            0 :                      symbol(lu + m + 1) = sgf_symbol(0, lu, m)
     593              :                   END DO
     594            0 :                   IF (nspin > 1) THEN
     595            0 :                      WRITE (UNIT=spin_info, FMT="(A8,I2)") " of spin", ispin
     596              :                   ELSE
     597            0 :                      spin_info = ""
     598              :                   END IF
     599              :                   WRITE (UNIT=output_unit, FMT="(/,T3,A,I0,A,/,/,T5,A,10(2X,A6))") &
     600            0 :                      "DFT+U occupations"//TRIM(spin_info)//" for the atoms of atomic kind ", ikind, &
     601            0 :                      ": "//TRIM(atomic_kind_name), &
     602            0 :                      "Atom   Shell  ", (ADJUSTR(symbol(i)), i=1, nsbsize), " Trace"
     603            0 :                   DEALLOCATE (symbol)
     604              :                END IF
     605              :             END IF
     606              : 
     607              :             ! Loop over all atoms of the current atomic kind
     608        11640 :             DO iatom = 1, natom_of_kind
     609         7016 :                atom_a = atom_list(iatom)
     610         7016 :                q_matrix(:, :) = 0.0_dp
     611         7016 :                IF (ALLOCATED(q_opp_matrix)) THEN
     612         5940 :                   q_opp_matrix(:, :) = 0.0_dp
     613              :                END IF
     614              : 
     615              :                ! Get diagonal block
     616              :                CALL dbcsr_get_block_p(matrix=sm_q, &
     617              :                                       row=atom_a, &
     618              :                                       col=atom_a, &
     619              :                                       block=q_block, &
     620         7016 :                                       found=found)
     621         7016 :                IF (hund_j /= 0.0_dp .AND. nspin == 2) THEN
     622              :                   CALL dbcsr_get_block_p(matrix=sm_q_opp, &
     623              :                                          row=atom_a, &
     624              :                                          col=atom_a, &
     625              :                                          block=q_opp_block, &
     626         5940 :                                          found=found)
     627              :                END IF
     628              :                IF (dft_control%mtlr_dft_with_perturbation .AND. &
     629         7016 :                    dft_control%mtlr_ikind == ikind .AND. &
     630              :                    qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a) THEN
     631              :                   CALL dbcsr_get_block_p(matrix=sm_vhxc, &
     632              :                                          row=atom_a, &
     633              :                                          col=atom_a, &
     634              :                                          block=vhxc_block, &
     635         2896 :                                          found=found)
     636              :                END IF
     637              : 
     638         7016 :                IF (ASSOCIATED(q_block)) THEN
     639              :                   ! Calculate energy contribution to E(U)
     640        14988 :                   DO i = 1, n
     641        11480 :                      isgf = shell_sgf(i)
     642        11480 :                      q_matrix(i, i) = q_block(isgf, isgf)
     643        11480 :                      IF (hund_j /= 0.0_dp .AND. nspin == 2 .AND. ASSOCIATED(q_opp_block)) THEN
     644         8252 :                         q_opp_matrix(i, i) = q_opp_block(isgf, isgf)
     645              :                      END IF
     646              :                      IF (ASSOCIATED(vhxc_block) .AND. dft_control%mtlr_dft_with_perturbation .AND. &
     647        14988 :                          dft_control%mtlr_ikind == ikind .AND. qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a) THEN
     648         4792 :                         dft_control%vhxc(ispin) = dft_control%vhxc(ispin) + vhxc_block(isgf, isgf)
     649         4792 :                         dft_control%trq(ispin) = dft_control%trq(ispin) + q_block(isgf, isgf)
     650              :                      END IF
     651              :                   END DO
     652              : 
     653              :                   ! Perform the requested manipulations of the (initial) orbital occupations
     654         3508 :                   IF (ASSOCIATED(orbitals)) THEN
     655           68 :                      IF ((qs_env%scf_env%iter_delta >= eps_scf) .OR. &
     656              :                          ((qs_env%scf_env%outer_scf%iter_count == 0) .AND. &
     657              :                           (qs_env%scf_env%iter_count <= max_scf))) THEN
     658           66 :                         ALLOCATE (orb_occ(nsbsize))
     659           66 :                         ALLOCATE (q_eigval(n))
     660           22 :                         q_eigval(:) = 0.0_dp
     661           66 :                         ALLOCATE (q_eigvec(n, n))
     662           22 :                         q_eigvec(:, :) = 0.0_dp
     663           22 :                         norb = SIZE(orbitals)
     664           22 :                         CALL jacobi(q_matrix, q_eigval, q_eigvec)
     665           22 :                         q_matrix(:, :) = 0.0_dp
     666           66 :                         DO isb = 1, nsb
     667           44 :                            trq = 0.0_dp
     668          176 :                            DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
     669          176 :                               trq = trq + q_eigval(i)
     670              :                            END DO
     671           44 :                            IF (smear) THEN
     672           44 :                               occ = trq/REAL(norb, KIND=dp)
     673              :                            ELSE
     674            0 :                               occ = 1.0_dp/fspin
     675              :                            END IF
     676           44 :                            orb_occ(:) = .FALSE.
     677          352 :                            iloc = MAXLOC(q_eigvec(:, isb*nsbsize))
     678           44 :                            jsb = INT((iloc(1) - 1)/nsbsize) + 1
     679           44 :                            i = 0
     680           44 :                            i0 = (jsb - 1)*nsbsize + 1
     681           44 :                            iorb = -1000
     682          198 :                            DO j = i0, jsb*nsbsize
     683          132 :                               i = i + 1
     684          132 :                               IF (i > norb) THEN
     685            0 :                                  DO m = -lu, lu
     686            0 :                                     IF (.NOT. orb_occ(lu + m + 1)) THEN
     687            0 :                                        iorb = i0 + lu + m
     688            0 :                                        orb_occ(lu + m + 1) = .TRUE.
     689              :                                     END IF
     690              :                                  END DO
     691              :                               ELSE
     692          132 :                                  iorb = i0 + lu + orbitals(i)
     693          132 :                                  orb_occ(lu + orbitals(i) + 1) = .TRUE.
     694              :                               END IF
     695          132 :                               CPASSERT(iorb /= -1000)
     696         1056 :                               iloc = MAXLOC(q_eigvec(iorb, :))
     697          132 :                               q_eigval(iloc(1)) = MIN(occ, trq)
     698          924 :                               q_matrix(:, iloc(1)) = q_eigval(iloc(1))*q_eigvec(:, iloc(1)) ! backtransform left
     699          176 :                               trq = trq - q_eigval(iloc(1))
     700              :                            END DO
     701              :                         END DO
     702        30426 :                         q_matrix(:, :) = MATMUL(q_matrix, TRANSPOSE(q_eigvec)) ! backtransform right
     703           22 :                         DEALLOCATE (orb_occ)
     704           22 :                         DEALLOCATE (q_eigval)
     705           22 :                         DEALLOCATE (q_eigvec)
     706              :                      END IF
     707              :                   END IF ! orbitals associated
     708              : 
     709        26468 :                   trq = fspin*SUM([(q_matrix(i, i), i=1, n)])
     710        64732 :                   trq2 = fspin*fspin*SUM(q_matrix*TRANSPOSE(q_matrix))
     711         3508 :                   trqxq_hund_j = 0.0_dp
     712         3508 :                   IF (hund_j /= 0.0_dp) THEN
     713         2970 :                      IF (nspin == 2) THEN
     714        41598 :                         trqxq_hund_j = SUM(q_matrix*TRANSPOSE(q_opp_matrix))
     715              :                      ELSE
     716            0 :                         trqxq_hund_j = SUM(q_matrix*TRANSPOSE(q_matrix))
     717              :                      END IF
     718              :                   END IF
     719              : 
     720              :                   ! Calculate energy contribution to E(U)
     721         3508 :                   energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*u_minus_j*(trq - trq2)/fspin
     722         3508 :                   IF (hund_j /= 0.0_dp) THEN
     723         2970 :                      trqxq_hund_j = fspin*fspin*trqxq_hund_j
     724         2970 :                      energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*hund_j*trqxq_hund_j/fspin
     725              :                   END IF
     726              : 
     727              :                   ! Calculate potential V(U) = dE(U)/dq
     728         3508 :                   IF (.NOT. just_energy) THEN
     729              :                      CALL dbcsr_get_block_p(matrix=sm_v, &
     730              :                                             row=atom_a, &
     731              :                                             col=atom_a, &
     732              :                                             block=v_block, &
     733         3474 :                                             found=found)
     734         3474 :                      CPASSERT(ASSOCIATED(v_block))
     735              : 
     736        14750 :                      DO j = 1, n
     737        11276 :                         jsgf = shell_sgf(j)
     738        63270 :                         DO i = 1, n
     739        48520 :                            isgf = shell_sgf(i)
     740        48520 :                            IF (i == j) THEN
     741        11276 :                               v_block(isgf, isgf) = u_minus_j*(0.5_dp - fspin*q_matrix(i, i))
     742              :                               IF (dft_control%mtlr_dft_with_perturbation .AND. &
     743        11276 :                                   dft_control%mtlr_ikind == ikind .AND. &
     744              :                                   qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a) THEN
     745         4792 :                                  v_block(isgf, isgf) = v_block(isgf, isgf) + perturbation_strength
     746              :                               END IF
     747              :                            ELSE
     748        37244 :                               CPASSERT(ABS(q_matrix(j, i)) < 1.0E-14_dp)
     749        37244 :                               IF (hund_j /= 0.0_dp .AND. nspin == 2) THEN
     750        21704 :                                  CPASSERT(ABS(q_opp_matrix(j, i)) < 1.0E-14_dp)
     751              :                               END IF
     752        37244 :                               v_block(isgf, jsgf) = -u_minus_j*fspin*q_matrix(j, i)
     753              :                            END IF
     754        59796 :                            IF (hund_j /= 0.0_dp) THEN
     755        29872 :                               IF (nspin == 2) THEN
     756        29872 :                                  v_block(isgf, jsgf) = v_block(isgf, jsgf) + hund_j*fspin*q_opp_matrix(j, i)
     757              :                               ELSE
     758            0 :                                  v_block(isgf, jsgf) = v_block(isgf, jsgf) + hund_j*fspin*q_matrix(j, i)
     759              :                               END IF
     760              :                            END IF
     761              :                         END DO
     762              :                      END DO
     763              :                   END IF ! not just energy
     764              : 
     765              :                END IF ! q_block associated
     766              : 
     767              :                ! Consider print requests
     768        18656 :                IF (should_output .AND. (print_level > low_print_level)) THEN
     769            0 :                   CALL para_env%sum(q_matrix)
     770            0 :                   IF (output_unit > 0) THEN
     771            0 :                      ALLOCATE (q_work(nsb, nsbsize))
     772            0 :                      q_work(:, :) = 0.0_dp
     773            0 :                      DO isb = 1, nsb
     774            0 :                         j = 0
     775            0 :                         DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
     776            0 :                            j = j + 1
     777            0 :                            q_work(isb, j) = q_matrix(i, i)
     778              :                         END DO
     779              :                      END DO
     780            0 :                      DO isb = 1, nsb
     781              :                         WRITE (UNIT=output_unit, FMT="(T3,I6,2X,I6,2X,10F8.3)") &
     782            0 :                            atom_a, isb, q_work(isb, :), SUM(q_work(isb, :))
     783              :                      END DO
     784              :                      WRITE (UNIT=output_unit, FMT="(T12,A,2X,10F8.3)") &
     785            0 :                         "Total", (SUM(q_work(:, i)), i=1, nsbsize), SUM(q_work)
     786            0 :                      WRITE (UNIT=output_unit, FMT="(A)") ""
     787            0 :                      DEALLOCATE (q_work)
     788              :                      IF (debug) THEN
     789              :                         ! Print the DFT+U occupation matrix
     790              :                         WRITE (UNIT=output_unit, FMT="(T9,70I10)") (i, i=1, n)
     791              :                         DO i = 1, n
     792              :                            WRITE (UNIT=output_unit, FMT="(T3,I6,70F10.6)") i, q_matrix(i, :)
     793              :                         END DO
     794              :                         ! Print the eigenvalues and eigenvectors of the occupation matrix
     795              :                         ALLOCATE (q_eigval(n))
     796              :                         q_eigval(:) = 0.0_dp
     797              :                         ALLOCATE (q_eigvec(n, n))
     798              :                         q_eigvec(:, :) = 0.0_dp
     799              :                         CALL jacobi(q_matrix, q_eigval, q_eigvec)
     800              :                         WRITE (UNIT=output_unit, FMT="(/,T9,70I10)") (i, i=1, n)
     801              :                         WRITE (UNIT=output_unit, FMT="(T9,71F10.6)") (q_eigval(i), i=1, n), &
     802              :                            SUM(q_eigval(1:n))
     803              :                         DO i = 1, n
     804              :                            WRITE (UNIT=output_unit, FMT="(T3,I6,70F10.6)") i, q_eigvec(i, :)
     805              :                         END DO
     806              :                         DEALLOCATE (q_eigval)
     807              :                         DEALLOCATE (q_eigvec)
     808              :                      END IF ! debug
     809              :                   END IF
     810              :                   IF (debug) THEN
     811              :                      ! Print the full atomic occupation matrix block
     812              :                      ALLOCATE (q_work(nsgf_kind, nsgf_kind))
     813              :                      q_work(:, :) = 0.0_dp
     814              :                      IF (ASSOCIATED(q_block)) q_work(:, :) = q_block(:, :)
     815              :                      CALL para_env%sum(q_work)
     816              :                      IF (output_unit > 0) THEN
     817              :                         norb = SIZE(q_work, 1)
     818              :                         WRITE (UNIT=output_unit, FMT="(/,T9,200I10)") (i, i=1, norb)
     819              :                         DO i = 1, norb
     820              :                            WRITE (UNIT=output_unit, FMT="(T3,I6,200F10.6)") i, q_work(i, :)
     821              :                         END DO
     822              :                         ALLOCATE (q_eigval(norb))
     823              :                         q_eigval(:) = 0.0_dp
     824              :                         ALLOCATE (q_eigvec(norb, norb))
     825              :                         q_eigvec(:, :) = 0.0_dp
     826              :                         CALL jacobi(q_work, q_eigval, q_eigvec)
     827              :                         WRITE (UNIT=output_unit, FMT="(/,T9,200I10)") (i, i=1, norb)
     828              :                         WRITE (UNIT=output_unit, FMT="(T9,201F10.6)") (q_eigval(i), i=1, norb), &
     829              :                            SUM(q_eigval(1:norb))
     830              :                         DO i = 1, norb
     831              :                            WRITE (UNIT=output_unit, FMT="(T3,I6,200F10.6)") i, q_eigvec(i, :)
     832              :                         END DO
     833              :                         DEALLOCATE (q_eigval)
     834              :                         DEALLOCATE (q_eigvec)
     835              :                      END IF
     836              :                      DEALLOCATE (q_work)
     837              :                   END IF ! debug
     838              :                END IF ! should output
     839              : 
     840              :             END DO ! next atom "iatom" of atomic kind "ikind"
     841              : 
     842         4624 :             IF (dft_control%mtlr_dft_with_perturbation .AND. &
     843              :                 dft_control%mtlr_ikind == ikind) THEN
     844         2896 :                dft_control%vhxc(ispin) = dft_control%vhxc(ispin)/REAL(n, dp)
     845         2896 :                CALL para_env%sum(dft_control%vhxc(ispin))
     846         2896 :                CALL para_env%sum(dft_control%trq(ispin))
     847              :             END IF
     848              : 
     849         4624 :             DEALLOCATE (shell_sgf, q_matrix)
     850              : 
     851        20728 :             IF (ALLOCATED(q_opp_matrix)) THEN
     852         3548 :                DEALLOCATE (q_opp_matrix)
     853              :             END IF
     854              : 
     855              :          END DO ! next atomic kind "ikind"
     856              : 
     857              :          ! Add V(i,j)[U] to V(i,j)[DFT]
     858         4624 :          IF (PRESENT(matrix_h) .OR. (PRESENT(matrix_w) .AND. do_kpoints)) THEN
     859         4554 :             IF (do_kpoints) THEN
     860              :                BLOCK
     861         1716 :                   REAL(dp) :: diagonal(nsgf)
     862          858 :                   CALL dbcsr_get_diag(sm_v, diagonal)
     863          858 :                   CALL para_env%sum(diagonal)
     864        11154 :                   kpoints%lowdin_v(:, ispin) = diagonal(kpoints%lowdin_orbitals)
     865              :                END BLOCK
     866              :             ELSE
     867         3696 :                sm_h => matrix_h(ispin, 1)%matrix
     868         3696 :                CALL cp_dbcsr_sm_fm_multiply(sm_v, fm_s_half, fm_work1, nsgf)
     869         3696 :                CALL cp_fm_transpose(fm_work1, fm_work2)
     870         3696 :                CALL cp_dbcsr_plus_fm_fm_t(sm_h, fm_s_half, fm_work2, nsgf)
     871              :             END IF
     872              :          END IF ! An update of the Hamiltonian matrix is requested
     873              : 
     874              :          ! Calculate the contribution (non-Pulay part) to the derivatives
     875              :          ! w.r.t. the nuclear positions
     876         7112 :          IF (PRESENT(matrix_w) .AND. .NOT. do_kpoints) THEN
     877              : 
     878            2 :             sm_p => matrix_p(ispin, 1)%matrix
     879            2 :             sm_w => matrix_w(ispin, 1)%matrix
     880              : 
     881            2 :             CALL cp_dbcsr_sm_fm_multiply(sm_v, fm_s_half, fm_work1, nsgf)
     882            2 :             CALL cp_fm_transpose(fm_work1, fm_work2)
     883            2 :             CALL cp_dbcsr_sm_fm_multiply(sm_p, fm_work2, fm_work1, nsgf)
     884            2 :             CALL parallel_gemm('N', 'N', nsgf, nsgf, nsgf, 1.0_dp, fm_work1, fm_sev, 0.0_dp, fm_work2)
     885            2 :             CALL parallel_gemm('T', 'N', nsgf, nsgf, nsgf, 1.0_dp, fm_sev, fm_work2, 0.0_dp, fm_work1)
     886            2 :             CALL cp_fm_schur_product(fm_work1, slambda, fm_work2)
     887            2 :             CALL cp_fm_transpose(fm_work2, fm_work1)
     888              :             ! Symmetrize before projecting onto the stored triangular sparse blocks.
     889            2 :             CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_work2, matrix_b=fm_work1)
     890            2 :             CALL parallel_gemm('N', 'N', nsgf, nsgf, nsgf, -1.0_dp, fm_sev, fm_work2, 0.0_dp, fm_work1)
     891            2 :             CALL cp_dbcsr_plus_fm_fm_t(sm_w, fm_work1, fm_sev, nsgf)
     892              : 
     893              :          END IF ! W matrix update requested
     894              : 
     895              :       END DO ! next spin "ispin"
     896              : 
     897         2556 :       IF (PRESENT(matrix_w)) THEN
     898           10 :          IF (do_kpoints) CALL lowdin_kp_forces(kpoints)
     899           10 :          CALL cp_fm_release(matrix=fm_sev)
     900           10 :          CALL cp_fm_release(matrix=slambda)
     901              :       END IF
     902              : 
     903              :       ! Collect the energy contributions from all processes
     904              : 
     905         2556 :       CALL para_env%sum(energy%dft_plus_u)
     906              : 
     907         2556 :       IF (energy%dft_plus_u < 0.0_dp) THEN
     908              :          CALL cp_warn(__LOCATION__, &
     909              :                       "DFT+U energy contribution is negative possibly due "// &
     910            0 :                       "to unphysical Lowdin charges!")
     911              :       END IF
     912              : 
     913              :       ! Release (local) full matrices
     914         2556 :       NULLIFY (fm_s_half)
     915         2556 :       CALL cp_fm_release(matrix=fm_work1)
     916         2556 :       CALL cp_fm_release(matrix=fm_work2)
     917              : 
     918              :       ! Release (local) sparse matrices
     919         2556 :       CALL dbcsr_release(sm_q)
     920         2556 :       CALL dbcsr_release(sm_v)
     921              : 
     922         2556 :       IF (if_plus_j .AND. nspin == 2) THEN
     923         1774 :          CALL dbcsr_release(sm_q_opp)
     924              :       END IF
     925              : 
     926         2556 :       CALL timestop(handle)
     927              : 
     928         5112 :    END SUBROUTINE lowdin
     929              : 
     930              : ! **************************************************************************************************
     931              : !> \brief Select the AO columns used by the existing orbital-diagonal Lowdin functional.
     932              : !> \param qs_env Quickstep environment, after S(k)**(1/2) has been prepared.
     933              : ! **************************************************************************************************
     934          120 :    SUBROUTINE lowdin_kp_init(qs_env)
     935              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     936              : 
     937              :       INTEGER                                            :: i, ia, ik, ikind, iset, ish, lu, m, nao, &
     938              :                                                             nset, nspin
     939              :       INTEGER, ALLOCATABLE                               :: first_atom(:)
     940          120 :       INTEGER, POINTER                                   :: atoms(:), first(:, :), l(:, :), &
     941          120 :                                                             last(:, :), nshell(:), orbitals(:)
     942              :       LOGICAL                                            :: active
     943              :       LOGICAL, ALLOCATABLE                               :: selected(:)
     944              :       REAL(KIND=dp)                                      :: j, u
     945          120 :       TYPE(atomic_kind_type), POINTER                    :: kinds_set(:)
     946              :       TYPE(dft_control_type), POINTER                    :: dft_control
     947              :       TYPE(gto_basis_set_type), POINTER                  :: basis
     948              :       TYPE(kpoint_env_type), POINTER                     :: kp
     949              :       TYPE(kpoint_type), POINTER                         :: kpoints
     950          120 :       TYPE(particle_type), POINTER                       :: particles(:)
     951          120 :       TYPE(qs_kind_type), POINTER                        :: qs_kinds(:)
     952              : 
     953              :       CALL get_qs_env(qs_env, kpoints=kpoints, atomic_kind_set=kinds_set, qs_kind_set=qs_kinds, &
     954          120 :                       particle_set=particles, dft_control=dft_control)
     955          120 :       IF (dft_control%mtlr_dft_with_perturbation) THEN
     956            0 :          CPABORT("MTLR with Lowdin DFT+U and k-points is not implemented")
     957              :       END IF
     958          600 :       DO ik = 1, SIZE(kpoints%kp_sym)
     959          600 :          IF (kpoints%kp_sym(ik)%kpoint_sym%apply_symmetry) THEN
     960            0 :             CPABORT("Lowdin DFT+U requires a full k-point grid or time-reversal-only reduction")
     961              :          END IF
     962              :       END DO
     963          120 :       CALL get_qs_kind_set(qs_kinds, nsgf=nao)
     964          120 :       nspin = dft_control%nspins
     965          600 :       ALLOCATE (first_atom(SIZE(particles)), selected(nao))
     966          120 :       CALL get_particle_set(particles, qs_kinds, first_sgf=first_atom)
     967          120 :       selected = .FALSE.
     968          360 :       DO ikind = 1, SIZE(qs_kinds)
     969          240 :          NULLIFY (orbitals)
     970              :          CALL get_qs_kind(qs_kinds(ikind), dft_plus_u_atom=active, l_of_dft_plus_u=lu, &
     971          240 :                           basis_set=basis, u_minus_j_target=u, hund_j=j, orbitals=orbitals)
     972          240 :          IF (.NOT. active) CYCLE
     973          120 :          IF (ASSOCIATED(orbitals)) THEN
     974            0 :             CPABORT("Lowdin DFT+U with k-points does not support ENFORCE_OCCUPATION")
     975              :          END IF
     976          120 :          IF (u == 0.0_dp .AND. j == 0.0_dp) CYCLE
     977          120 :          CALL get_atomic_kind(kinds_set(ikind), atom_list=atoms)
     978          120 :          CALL get_gto_basis_set(basis, first_sgf=first, last_sgf=last, l=l, nset=nset, nshell=nshell)
     979          600 :          DO ia = 1, SIZE(atoms)
     980          480 :             DO iset = 1, nset
     981          840 :                DO ish = 1, nshell(iset)
     982          600 :                   IF (l(ish, iset) /= lu) CYCLE
     983              :                   selected(first_atom(atoms(ia)) + first(ish, iset) - 1: &
     984         1440 :                            first_atom(atoms(ia)) + last(ish, iset) - 1) = .TRUE.
     985              :                END DO
     986              :             END DO
     987              :          END DO
     988              :       END DO
     989          120 :       IF (ALLOCATED(kpoints%lowdin_orbitals)) THEN
     990          112 :          DEALLOCATE (kpoints%lowdin_orbitals, kpoints%lowdin_q, kpoints%lowdin_q_new, kpoints%lowdin_v)
     991              :       END IF
     992         2880 :       m = COUNT(selected)
     993          360 :       ALLOCATE (kpoints%lowdin_orbitals(m))
     994         6480 :       kpoints%lowdin_orbitals(:) = PACK([(i, i=1, nao)], selected)
     995          960 :       ALLOCATE (kpoints%lowdin_q(m, nspin), kpoints%lowdin_q_new(m, nspin), kpoints%lowdin_v(m, nspin))
     996         1268 :       kpoints%lowdin_q(:, :) = 0.0_dp
     997         1268 :       kpoints%lowdin_q_new(:, :) = 0.0_dp
     998         1268 :       kpoints%lowdin_v(:, :) = 0.0_dp
     999          120 :       kpoints%lowdin_density_ready = .FALSE.
    1000          120 :       kpoints%lowdin_population_ready = .FALSE.
    1001          360 :       DO ik = 1, SIZE(kpoints%kp_env)
    1002          240 :          kp => kpoints%kp_env(ik)%kpoint_env
    1003          360 :          CALL lowdin_kp_prepare(kp, kpoints%lowdin_orbitals, kpoints%use_real_wfn)
    1004              :       END DO
    1005          360 :    END SUBROUTINE lowdin_kp_init
    1006              : 
    1007              : ! **************************************************************************************************
    1008              : !> \brief Prepare selected Lowdin projectors and their reusable product workspace.
    1009              : !> \param kp One k point; SCF already provides its overlap square root.
    1010              : !> \param orbitals Selected global AO indices.
    1011              : !> \param use_real_wfn Whether to use the real overlap square root.
    1012              : !> \param smat Optional complex overlap for post-SCF reconstruction; remains unchanged.
    1013              : ! **************************************************************************************************
    1014          240 :    SUBROUTINE lowdin_kp_prepare(kp, orbitals, use_real_wfn, smat)
    1015              :       TYPE(kpoint_env_type), POINTER                     :: kp
    1016              :       INTEGER, INTENT(IN)                                :: orbitals(:)
    1017              :       LOGICAL, INTENT(IN)                                :: use_real_wfn
    1018              :       TYPE(cp_cfm_type), INTENT(IN), OPTIONAL            :: smat
    1019              : 
    1020              :       INTEGER                                            :: i, m, n
    1021          240 :       REAL(dp), ALLOCATABLE                              :: eigenvalues(:)
    1022              :       TYPE(cp_cfm_type)                                  :: evec, work
    1023              : 
    1024          240 :       CALL cp_fm_release(kp%lowdin_b)
    1025          240 :       CALL cp_fm_release(kp%lowdin_work)
    1026          240 :       CALL cp_cfm_release(kp%lowdin_cb)
    1027          240 :       CALL cp_cfm_release(kp%lowdin_cwork)
    1028          240 :       CALL kp%lowdin_gemm%destroy()
    1029          240 :       m = SIZE(orbitals)
    1030          240 :       IF (m == 0) RETURN
    1031          240 :       IF (PRESENT(smat)) THEN
    1032            0 :          CPASSERT(.NOT. use_real_wfn)
    1033            0 :          CALL cp_cfm_get_info(smat, nrow_global=n)
    1034            0 :          ALLOCATE (eigenvalues(n))
    1035            0 :          CALL cp_cfm_create(evec, smat%matrix_struct)
    1036            0 :          CALL cp_cfm_create(work, smat%matrix_struct)
    1037            0 :          CALL cp_cfm_release(kp%cshalf)
    1038            0 :          CALL cp_cfm_create(kp%cshalf, smat%matrix_struct)
    1039            0 :          CALL cp_cfm_to_cfm(smat, work)
    1040            0 :          CALL cp_cfm_heevd(work, evec, eigenvalues)
    1041            0 :          CPASSERT(ALL(eigenvalues >= 0.0_dp))
    1042            0 :          CALL cp_cfm_to_cfm(evec, work)
    1043            0 :          CALL cp_cfm_column_scale(work, CMPLX(SQRT(eigenvalues), 0.0_dp, dp))
    1044            0 :          CALL parallel_gemm('N', 'C', n, n, n, z_one, work, evec, z_zero, kp%cshalf)
    1045            0 :          CALL cp_cfm_release(evec)
    1046            0 :          CALL cp_cfm_release(work)
    1047              :       END IF
    1048          240 :       CALL kp%lowdin_gemm%create(LOCAL_GEMM_PU_GPU, timing=.FALSE.)
    1049          240 :       IF (use_real_wfn) THEN
    1050            0 :          CALL cp_fm_create(kp%lowdin_b, kp%shalf%matrix_struct, ncol=m)
    1051            0 :          CALL cp_fm_create(kp%lowdin_work, kp%lowdin_b%matrix_struct)
    1052            0 :          DO i = 1, m
    1053            0 :             CALL cp_fm_to_fm(kp%shalf, kp%lowdin_b, 1, orbitals(i), i)
    1054              :          END DO
    1055              :          ! The real driver also uses complex storage during its ADIIS/CDIIS handover.
    1056            0 :          CALL cp_cfm_create(kp%lowdin_cb, kp%lowdin_b%matrix_struct)
    1057            0 :          CALL cp_fm_to_cfm(kp%lowdin_b, mtarget=kp%lowdin_cb)
    1058              :       ELSE
    1059          240 :          CALL cp_cfm_create(kp%lowdin_cb, kp%cshalf%matrix_struct, ncol=m)
    1060         1680 :          DO i = 1, m
    1061         1680 :             CALL cp_cfm_to_cfm(kp%cshalf, kp%lowdin_cb, 1, orbitals(i), i)
    1062              :          END DO
    1063              :       END IF
    1064          240 :       CALL cp_cfm_create(kp%lowdin_cwork, kp%lowdin_cb%matrix_struct)
    1065          240 :       IF (PRESENT(smat)) CALL cp_cfm_release(kp%cshalf)
    1066          480 :    END SUBROUTINE lowdin_kp_prepare
    1067              : 
    1068              : ! **************************************************************************************************
    1069              : !> \brief Complete the initial density's Lowdin coordinates, including atomic and density restarts.
    1070              : !> \param qs_env Quickstep environment with an initialized real-space density.
    1071              : !> \param fmwork Global AO matrix workspace from the SCF environment being initialized.
    1072              : ! **************************************************************************************************
    1073          120 :    SUBROUTINE lowdin_kp_initial_density(qs_env, fmwork)
    1074              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1075              :       TYPE(cp_fm_type), INTENT(IN)                       :: fmwork
    1076              : 
    1077              :       INTEGER                                            :: ik, ispin, kplocal, kpmax
    1078              :       TYPE(cp_cfm_type)                                  :: cpmat
    1079              :       TYPE(cp_fm_type)                                   :: pmat
    1080          120 :       TYPE(dbcsr_p_type), POINTER                        :: density(:, :)
    1081              :       TYPE(kpoint_env_type), POINTER                     :: kp
    1082          120 :       TYPE(kpoint_operator_context_type)                 :: ctx
    1083              :       TYPE(kpoint_type), POINTER                         :: kpoints
    1084              :       TYPE(qs_rho_type), POINTER                         :: rho
    1085              : 
    1086          120 :       CALL get_qs_env(qs_env, kpoints=kpoints, rho=rho)
    1087          120 :       IF (.NOT. ALLOCATED(kpoints%lowdin_orbitals)) RETURN
    1088          120 :       IF (.NOT. kpoints%lowdin_density_ready .AND. SIZE(kpoints%lowdin_orbitals) > 0) THEN
    1089              :          ! The initial real-space guess defines a finite Fourier series. Subsequent
    1090              :          ! accepted densities use their full Bloch matrices, never this sparse reconstruction.
    1091            8 :          CALL qs_rho_get(rho, rho_ao_kp=density)
    1092            8 :          CALL kpoint_operator_context_create(ctx, kpoints, fmwork, SIZE(density, 1))
    1093            8 :          kp => kpoints%kp_env(1)%kpoint_env
    1094            8 :          IF (kpoints%use_real_wfn) THEN
    1095            0 :             CALL cp_fm_create(pmat, kp%shalf%matrix_struct)
    1096              :          ELSE
    1097            8 :             CALL cp_cfm_create(cpmat, kp%cshalf%matrix_struct)
    1098              :          END IF
    1099            8 :          kplocal = SIZE(kpoints%kp_env)
    1100           24 :          kpmax = MAXVAL(kpoints%kp_dist(2, :) - kpoints%kp_dist(1, :) + 1)
    1101           92 :          kpoints%lowdin_q_new(:, :) = 0.0_dp
    1102           24 :          DO ik = 1, kpmax
    1103           48 :             DO ispin = 1, SIZE(density, 1)
    1104           24 :                IF (kpoints%use_real_wfn) THEN
    1105            0 :                   CALL kpoint_operator_get(ctx, ik, ispin, density, fm_re=pmat, matrix_row=ispin)
    1106              :                ELSE
    1107           24 :                   CALL kpoint_operator_get(ctx, ik, ispin, density, cmat=cpmat, matrix_row=ispin)
    1108              :                END IF
    1109           24 :                IF (ik > kplocal) CYCLE
    1110           24 :                kp => kpoints%kp_env(ik)%kpoint_env
    1111           40 :                IF (kpoints%use_real_wfn) THEN
    1112            0 :                   CALL lowdin_kp_accumulate(kp, kpoints%lowdin_q_new(:, ispin), pmat=pmat)
    1113              :                ELSE
    1114           24 :                   CALL lowdin_kp_accumulate(kp, kpoints%lowdin_q_new(:, ispin), cpmat=cpmat)
    1115              :                END IF
    1116              :             END DO
    1117              :          END DO
    1118            8 :          CALL kpoints%para_env%sum(kpoints%lowdin_q_new)
    1119            8 :          CALL kpoint_operator_context_release(ctx)
    1120            8 :          CALL cp_fm_release(pmat)
    1121            8 :          CALL cp_cfm_release(cpmat)
    1122            8 :          kpoints%lowdin_population_ready = .TRUE.
    1123              :       END IF
    1124          120 :       CALL lowdin_kp_population(kpoints, alpha=1.0_dp)
    1125          240 :    END SUBROUTINE lowdin_kp_initial_density
    1126              : 
    1127              : ! **************************************************************************************************
    1128              : !> \brief Cache the current occupations, optionally measure their residual and accept or mix them.
    1129              : !> \param kpoints Optional k-point state; absent or inactive Lowdin state is a no-op.
    1130              : !> \param delta Include the unmixed occupation residual in this convergence measure.
    1131              : !> \param alpha Weight of the current occupations in the accepted state; absent leaves it unchanged.
    1132              : ! **************************************************************************************************
    1133       265240 :    SUBROUTINE lowdin_kp_population(kpoints, delta, alpha)
    1134              :       TYPE(kpoint_type), OPTIONAL, POINTER               :: kpoints
    1135              :       REAL(KIND=dp), INTENT(INOUT), OPTIONAL             :: delta
    1136              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: alpha
    1137              : 
    1138       265240 :       IF (.NOT. PRESENT(kpoints)) RETURN
    1139       265240 :       IF (.NOT. ASSOCIATED(kpoints)) RETURN
    1140       265240 :       IF (.NOT. ALLOCATED(kpoints%lowdin_q)) RETURN
    1141         1222 :       IF (.NOT. kpoints%lowdin_population_ready) THEN
    1142         1968 :          IF (SIZE(kpoints%lowdin_q) > 0) THEN
    1143          656 :             CPASSERT(kpoints%lowdin_density_ready)
    1144          656 :             CALL lowdin_kp_project(kpoints, kpoints%lowdin_q_new)
    1145              :          END IF
    1146          656 :          kpoints%lowdin_population_ready = .TRUE.
    1147              :       END IF
    1148         5954 :       IF (PRESENT(delta)) delta = MAX(delta, MAXVAL(ABS(kpoints%lowdin_q_new - kpoints%lowdin_q)))
    1149         1222 :       IF (PRESENT(alpha)) THEN
    1150         1222 :          IF (alpha == 1.0_dp) THEN
    1151         9664 :             kpoints%lowdin_q(:, :) = kpoints%lowdin_q_new
    1152          294 :          ELSE IF (alpha /= 0.0_dp) THEN
    1153            0 :             kpoints%lowdin_q(:, :) = (1.0_dp - alpha)*kpoints%lowdin_q + alpha*kpoints%lowdin_q_new
    1154              :          END IF
    1155              :       END IF
    1156              :    END SUBROUTINE lowdin_kp_population
    1157              : 
    1158              : ! **************************************************************************************************
    1159              : !> \brief Project and reduce a Bloch density with one accumulator and matrix workspace per worker.
    1160              : !> \param kpoints Selected overlap columns and parallel distribution.
    1161              : !> \param q Weighted occupations; does not change the ground-state occupation caches.
    1162              : !> \param density Optional split-complex response; absent uses the current Bloch density.
    1163              : ! **************************************************************************************************
    1164          656 :    SUBROUTINE lowdin_kp_project(kpoints, q, density)
    1165              :       TYPE(kpoint_type), POINTER                         :: kpoints
    1166              :       REAL(KIND=dp), CONTIGUOUS, INTENT(OUT)             :: q(:, :)
    1167              :       TYPE(cp_fm_type), INTENT(IN), OPTIONAL             :: density(:, :, :)
    1168              : 
    1169              :       INTEGER                                            :: handle, ik, ispin, kplocal, m, nspin, &
    1170              :                                                             nworkers, thread
    1171          656 :       TYPE(cp_cfm_type), ALLOCATABLE                     :: work(:)
    1172              :       TYPE(kpoint_env_type), POINTER                     :: kp
    1173              : 
    1174          656 :       m = SIZE(q, 1)
    1175          656 :       IF (m == 0) RETURN
    1176          656 :       CALL timeset("lowdin_kp_population", handle)
    1177          656 :       nspin = SIZE(q, 2)
    1178          656 :       kplocal = SIZE(kpoints%kp_env)
    1179          656 :       kp => kpoints%kp_env(1)%kpoint_env
    1180          656 :       nworkers = 1
    1181          656 : !$    IF (kpoints%para_env_kp%num_pe == 1) nworkers = MIN(omp_get_max_threads(), kplocal)
    1182         2624 :       ALLOCATE (work(nworkers))
    1183         6802 :       q(:, :) = 0.0_dp
    1184          656 :       IF (PRESENT(density) .OR. .NOT. kpoints%use_real_wfn) THEN
    1185         1312 :          DO thread = 1, nworkers
    1186         1312 :             CALL cp_cfm_create(work(thread), kp%pmat(1, 1)%matrix_struct)
    1187              :          END DO
    1188              :       END IF
    1189              : !$OMP PARALLEL DO DEFAULT(NONE) SCHEDULE(STATIC) NUM_THREADS(nworkers) IF(nworkers > 1) &
    1190          656 : !$OMP SHARED(kpoints,density,work,nspin,kplocal,nworkers) PRIVATE(ik,ispin,kp,thread) REDUCTION(+:q)
    1191              :       DO ik = 1, kplocal
    1192              :          thread = 1
    1193              : !$       thread = omp_get_thread_num() + 1
    1194              :          kp => kpoints%kp_env(ik)%kpoint_env
    1195              :          DO ispin = 1, nspin
    1196              :             IF (PRESENT(density)) THEN
    1197              :                CALL cp_fm_to_cfm(density(ik, 1, ispin), density(ik, 2, ispin), work(thread))
    1198              :                CALL lowdin_kp_accumulate(kp, q(:, ispin), cpmat=work(thread))
    1199              :             ELSE IF (kpoints%use_real_wfn) THEN
    1200              :                CALL lowdin_kp_accumulate(kp, q(:, ispin), pmat=kp%pmat(1, ispin))
    1201              :             ELSE
    1202              :                CALL cp_fm_to_cfm(kp%pmat(1, ispin), kp%pmat(2, ispin), work(thread))
    1203              :                CALL lowdin_kp_accumulate(kp, q(:, ispin), cpmat=work(thread))
    1204              :             END IF
    1205              :          END DO
    1206              :       END DO
    1207              : !$OMP END PARALLEL DO
    1208              :       ! Each entry is a local tile contraction: reduce once across groups AND group ranks.
    1209          656 :       CALL kpoints%para_env%sum(q)
    1210         1312 :       DO thread = 1, nworkers
    1211         1312 :          CALL cp_cfm_release(work(thread))
    1212              :       END DO
    1213          656 :       CALL timestop(handle)
    1214         1312 :    END SUBROUTINE lowdin_kp_project
    1215              : 
    1216              : ! **************************************************************************************************
    1217              : !> \brief Accumulate weighted local entries of diag(B**H P B), without a full transformed density.
    1218              : !> \param kp One k point, with a private reusable product workspace.
    1219              : !> \param q Accumulated local contributions; the caller zeroes and reduces the worker buffers.
    1220              : !> \param pmat Real Bloch density.
    1221              : !> \param cpmat Complex Bloch density (exclusive with pmat).
    1222              : ! **************************************************************************************************
    1223         1780 :    SUBROUTINE lowdin_kp_accumulate(kp, q, pmat, cpmat)
    1224              :       TYPE(kpoint_env_type), POINTER                     :: kp
    1225              :       REAL(KIND=dp), INTENT(INOUT)                       :: q(:)
    1226              :       TYPE(cp_fm_type), INTENT(IN), OPTIONAL             :: pmat
    1227              :       TYPE(cp_cfm_type), INTENT(IN), OPTIONAL            :: cpmat
    1228              : 
    1229              :       INTEGER                                            :: j, m, n, nc, nr
    1230         1780 :       INTEGER, POINTER                                   :: columns(:)
    1231              :       LOGICAL                                            :: local
    1232              : 
    1233         1780 :       m = SIZE(q)
    1234            0 :       CPASSERT(PRESENT(pmat) .NEQV. PRESENT(cpmat))
    1235         1780 :       IF (PRESENT(pmat)) THEN
    1236            0 :          CALL cp_fm_get_info(kp%lowdin_b, nrow_global=n, nrow_local=nr, ncol_local=nc, col_indices=columns)
    1237            0 :          local = PRODUCT(kp%lowdin_b%matrix_struct%context%num_pe) == 1
    1238            0 :          IF (local) THEN
    1239              :             CALL kp%lowdin_gemm%gemm('N', 'N', n, m, n, 1.0_dp, pmat%local_data, SIZE(pmat%local_data, 1), &
    1240              :                                      kp%lowdin_b%local_data, SIZE(kp%lowdin_b%local_data, 1), 0.0_dp, &
    1241            0 :                                      kp%lowdin_work%local_data, SIZE(kp%lowdin_work%local_data, 1))
    1242              :          ELSE
    1243            0 :             CALL parallel_gemm('N', 'N', n, m, n, 1.0_dp, pmat, kp%lowdin_b, 0.0_dp, kp%lowdin_work)
    1244              :          END IF
    1245            0 :          DO j = 1, nc
    1246              :             q(columns(j)) = q(columns(j)) + kp%wkp* &
    1247            0 :                             SUM(kp%lowdin_b%local_data(:nr, j)*kp%lowdin_work%local_data(:nr, j))
    1248              :          END DO
    1249              :       ELSE
    1250         1780 :          CALL cp_cfm_get_info(kp%lowdin_cb, nrow_global=n, nrow_local=nr, ncol_local=nc, col_indices=columns)
    1251         1780 :          CALL lowdin_kp_gemm('N', 'N', n, m, n, cpmat, kp%lowdin_cb, z_zero, kp%lowdin_cwork, kp%lowdin_gemm)
    1252        12460 :          DO j = 1, nc
    1253              :             q(columns(j)) = q(columns(j)) + kp%wkp*REAL(SUM(CONJG(kp%lowdin_cb%local_data(:nr, j))* &
    1254       258100 :                                                             kp%lowdin_cwork%local_data(:nr, j)), dp)
    1255              :          END DO
    1256              :       END IF
    1257         1780 :    END SUBROUTINE lowdin_kp_accumulate
    1258              : 
    1259              : ! **************************************************************************************************
    1260              : !> \brief Add B diag(v) B**H before any solver, DIIS residual, or history storage uses H(k).
    1261              : !> \param kp One k point, with its private workspace.
    1262              : !> \param v Selected orbital potentials for the same raw/mixed state as the supplied Hamiltonian.
    1263              : !> \param rmat Real Hamiltonian.
    1264              : !> \param cmat Complex Hamiltonian (exclusive with rmat).
    1265              : ! **************************************************************************************************
    1266          792 :    SUBROUTINE lowdin_kp_apply(kp, v, rmat, cmat)
    1267              :       TYPE(kpoint_env_type), POINTER                     :: kp
    1268              :       REAL(KIND=dp), INTENT(IN)                          :: v(:)
    1269              :       TYPE(cp_fm_type), INTENT(INOUT), OPTIONAL          :: rmat
    1270              :       TYPE(cp_cfm_type), INTENT(INOUT), OPTIONAL         :: cmat
    1271              : 
    1272              :       INTEGER                                            :: j, m, n, nc, nr
    1273          792 :       INTEGER, POINTER                                   :: columns(:)
    1274              :       LOGICAL                                            :: local
    1275              : 
    1276          792 :       m = SIZE(v)
    1277            0 :       IF (m == 0) RETURN
    1278          792 :       IF (ALL(v == 0.0_dp)) RETURN
    1279          792 :       CPASSERT(PRESENT(rmat) .NEQV. PRESENT(cmat))
    1280          792 :       IF (PRESENT(rmat)) THEN
    1281            0 :          CALL cp_fm_get_info(kp%lowdin_b, nrow_global=n, nrow_local=nr, ncol_local=nc, col_indices=columns)
    1282            0 :          DO j = 1, nc
    1283            0 :             kp%lowdin_work%local_data(:nr, j) = v(columns(j))*kp%lowdin_b%local_data(:nr, j)
    1284              :          END DO
    1285            0 :          local = PRODUCT(kp%lowdin_b%matrix_struct%context%num_pe) == 1
    1286            0 :          IF (local) THEN
    1287              :             CALL kp%lowdin_gemm%gemm('N', 'T', n, n, m, 1.0_dp, &
    1288              :                                      kp%lowdin_work%local_data, SIZE(kp%lowdin_work%local_data, 1), &
    1289              :                                      kp%lowdin_b%local_data, SIZE(kp%lowdin_b%local_data, 1), 1.0_dp, &
    1290            0 :                                      rmat%local_data, SIZE(rmat%local_data, 1))
    1291              :          ELSE
    1292            0 :             CALL parallel_gemm('N', 'T', n, n, m, 1.0_dp, kp%lowdin_work, kp%lowdin_b, 1.0_dp, rmat)
    1293              :          END IF
    1294              :       ELSE
    1295          792 :          CALL cp_cfm_get_info(kp%lowdin_cb, nrow_global=n, nrow_local=nr, ncol_local=nc, col_indices=columns)
    1296         5544 :          DO j = 1, nc
    1297       114840 :             kp%lowdin_cwork%local_data(:nr, j) = v(columns(j))*kp%lowdin_cb%local_data(:nr, j)
    1298              :          END DO
    1299          792 :          CALL lowdin_kp_gemm('N', 'C', n, n, m, kp%lowdin_cwork, kp%lowdin_cb, z_one, cmat, kp%lowdin_gemm)
    1300              :       END IF
    1301          792 :    END SUBROUTINE lowdin_kp_apply
    1302              : 
    1303              : ! **************************************************************************************************
    1304              : !> \brief Add B diag(v) B**H C to the complex orbital gradient, without forming an AO matrix.
    1305              : !> \param kp K point owning the selected overlap columns and a private GEMM context.
    1306              : !> \param v Orbital potential, without k weights or occupations (applied by the caller).
    1307              : !> \param coeff Active complex orbitals.
    1308              : !> \param hc H*C, updated in place.
    1309              : ! **************************************************************************************************
    1310          584 :    SUBROUTINE lowdin_kp_apply_mo(kp, v, coeff, hc)
    1311              :       TYPE(kpoint_env_type), POINTER                     :: kp
    1312              :       REAL(KIND=dp), INTENT(IN)                          :: v(:)
    1313              :       TYPE(cp_cfm_type), INTENT(IN)                      :: coeff
    1314              :       TYPE(cp_cfm_type), INTENT(INOUT)                   :: hc
    1315              : 
    1316              :       INTEGER                                            :: i, m, n, nc, nmo, nr
    1317          584 :       INTEGER, POINTER                                   :: rows(:)
    1318              :       TYPE(cp_cfm_type)                                  :: projected
    1319              : 
    1320          584 :       m = SIZE(v)
    1321          584 :       IF (m == 0 .OR. ALL(v == 0.0_dp)) RETURN
    1322          584 :       CALL cp_cfm_get_info(coeff, nrow_global=n, ncol_global=nmo)
    1323          584 :       CALL cp_cfm_create(projected, coeff%matrix_struct, nrow=m)
    1324          584 :       CALL lowdin_kp_gemm('C', 'N', m, nmo, n, kp%lowdin_cb, coeff, z_zero, projected, kp%lowdin_gemm)
    1325          584 :       CALL cp_cfm_get_info(projected, nrow_local=nr, ncol_local=nc, row_indices=rows)
    1326         4088 :       DO i = 1, nr
    1327        18104 :          projected%local_data(i, :nc) = v(rows(i))*projected%local_data(i, :nc)
    1328              :       END DO
    1329          584 :       CALL lowdin_kp_gemm('N', 'N', n, nmo, m, kp%lowdin_cb, projected, z_one, hc, kp%lowdin_gemm)
    1330          584 :       CALL cp_cfm_release(projected)
    1331          584 :    END SUBROUTINE lowdin_kp_apply_mo
    1332              : 
    1333              : ! **************************************************************************************************
    1334              : !> \brief Project a Bloch density response and return its orbital potential response, including +J.
    1335              : !> \param qs_env Quickstep environment with selected Lowdin projectors and current U/J.
    1336              : !> \param density Unweighted split-complex Bloch density response (local k point, component, spin).
    1337              : !> \param response Globally summed orbital potential response; ground-state caches are preserved.
    1338              : ! **************************************************************************************************
    1339            0 :    SUBROUTINE lowdin_kp_kernel(qs_env, density, response)
    1340              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1341              :       TYPE(cp_fm_type), INTENT(IN)                       :: density(:, :, :)
    1342              :       REAL(KIND=dp), ALLOCATABLE, INTENT(OUT)            :: response(:, :)
    1343              : 
    1344              :       INTEGER                                            :: i, iatom, ikind, m, nspin
    1345            0 :       INTEGER, ALLOCATABLE                               :: last(:)
    1346              :       REAL(KIND=dp)                                      :: j, u
    1347              :       TYPE(kpoint_type), POINTER                         :: kpoints
    1348            0 :       TYPE(particle_type), POINTER                       :: particles(:)
    1349            0 :       TYPE(qs_kind_type), POINTER                        :: qs_kinds(:)
    1350              : 
    1351            0 :       CALL get_qs_env(qs_env, kpoints=kpoints, particle_set=particles, qs_kind_set=qs_kinds)
    1352            0 :       m = SIZE(kpoints%lowdin_orbitals)
    1353            0 :       nspin = SIZE(density, 3)
    1354            0 :       ALLOCATE (response(m, nspin))
    1355            0 :       response(:, :) = 0.0_dp
    1356            0 :       IF (m == 0) RETURN
    1357            0 :       CALL lowdin_kp_project(kpoints, response, density)
    1358            0 :       ALLOCATE (last(SIZE(particles)))
    1359            0 :       CALL get_particle_set(particles, qs_kinds, last_sgf=last)
    1360            0 :       iatom = 1
    1361            0 :       DO i = 1, m
    1362            0 :          DO WHILE (kpoints%lowdin_orbitals(i) > last(iatom))
    1363            0 :             iatom = iatom + 1
    1364              :          END DO
    1365            0 :          CALL get_atomic_kind(particles(iatom)%atomic_kind, kind_number=ikind)
    1366            0 :          CALL get_qs_kind(qs_kinds(ikind), u_minus_j=u, hund_j=j)
    1367            0 :          response(i, :) = 0.5_dp*REAL(nspin, dp)*(j*response(i, nspin:1:-1) - u*response(i, :))
    1368              :       END DO
    1369            0 :    END SUBROUTINE lowdin_kp_kernel
    1370              : 
    1371              : ! **************************************************************************************************
    1372              : !> \brief Add -dE_U/dS(k) to W(k), before its ordinary inverse Fourier transform.
    1373              : !>        If A=S**(1/2), A*dA+dA*A=dS. In the overlap eigenbasis its adjoint is
    1374              : !>        G_ij=(U**H*(P*A*V+V*A*P)*U)_ij/(sqrt(s_i)+sqrt(s_j)).
    1375              : !>        W <- W-U*G*U**H; the existing overlap derivatives give forces and virial.
    1376              : !>        k-point weights belong to the Fourier transform and are not applied here.
    1377              : !> \param kpoints Final Bloch densities, orbital potentials and cached overlap spectra.
    1378              : ! **************************************************************************************************
    1379            8 :    SUBROUTINE lowdin_kp_forces(kpoints)
    1380              :       TYPE(kpoint_type), POINTER                         :: kpoints
    1381              : 
    1382              :       INTEGER                                            :: handle, ik, ispin, iw, nworkers, thread
    1383            8 :       TYPE(cp_cfm_type), ALLOCATABLE                     :: work(:, :)
    1384              :       TYPE(kpoint_env_type), POINTER                     :: kp
    1385            8 :       TYPE(local_gemm_ctxt_type), ALLOCATABLE            :: gemm(:)
    1386              : 
    1387            8 :       IF (SIZE(kpoints%lowdin_orbitals) == 0) RETURN
    1388            8 :       IF (ALL(kpoints%lowdin_v == 0.0_dp)) RETURN
    1389            8 :       CALL timeset("lowdin_kp_forces", handle)
    1390            8 :       nworkers = 1
    1391            8 : !$    IF (kpoints%para_env_kp%num_pe == 1) &
    1392            8 : !$       nworkers = MIN(omp_get_max_threads(), SIZE(kpoints%kp_env)*SIZE(kpoints%lowdin_v, 2))
    1393           80 :       ALLOCATE (work(3, nworkers), gemm(nworkers))
    1394            8 :       kp => kpoints%kp_env(1)%kpoint_env
    1395           16 :       DO thread = 1, nworkers
    1396           24 :          DO iw = 1, 2
    1397           24 :             CALL cp_cfm_create(work(iw, thread), kp%pmat(1, 1)%matrix_struct)
    1398              :          END DO
    1399            8 :          CALL cp_cfm_create(work(3, thread), kp%lowdin_cb%matrix_struct)
    1400           16 :          CALL gemm(thread)%create(LOCAL_GEMM_PU_GPU, timing=.FALSE.)
    1401              :       END DO
    1402              : !$OMP PARALLEL DO COLLAPSE(2) DEFAULT(NONE) SCHEDULE(DYNAMIC, 1) NUM_THREADS(nworkers) IF(nworkers > 1) &
    1403            8 : !$OMP SHARED(kpoints,work,gemm,nworkers) PRIVATE(ik,ispin,thread)
    1404              :       DO ispin = 1, SIZE(kpoints%lowdin_v, 2)
    1405              :          DO ik = 1, SIZE(kpoints%kp_env)
    1406              :             thread = 1
    1407              : !$          thread = omp_get_thread_num() + 1
    1408              :             CALL lowdin_kp_force_matrix(kpoints%kp_env(ik)%kpoint_env, kpoints%lowdin_orbitals, ispin, &
    1409              :                                         kpoints%lowdin_v(:, ispin), work(:, thread), gemm(thread))
    1410              :          END DO
    1411              :       END DO
    1412              : !$OMP END PARALLEL DO
    1413           16 :       DO thread = 1, nworkers
    1414            8 :          CALL gemm(thread)%destroy()
    1415           40 :          DO iw = 1, 3
    1416           32 :             CALL cp_cfm_release(work(iw, thread))
    1417              :          END DO
    1418              :       END DO
    1419            8 :       CALL timestop(handle)
    1420           16 :    END SUBROUTINE lowdin_kp_forces
    1421              : 
    1422              : ! **************************************************************************************************
    1423              : !> \brief One spin/k-point's Hermitian overlap derivative, factoring through the selected AO columns.
    1424              : !> \param kp K-point state; W is updated, P and the overlap spectrum are preserved.
    1425              : !> \param orbitals Selected AO columns.
    1426              : !> \param ispin Spin channel to update.
    1427              : !> \param v Derivatives of the common U/J functional with respect to this spin's q.
    1428              : !> \param work Two square matrices and selected-column scratch, private to this worker.
    1429              : !> \param gemm Private local GEMM context; concurrent spins must not share the k-point context.
    1430              : ! **************************************************************************************************
    1431           24 :    SUBROUTINE lowdin_kp_force_matrix(kp, orbitals, ispin, v, work, gemm)
    1432              :       TYPE(kpoint_env_type), POINTER                     :: kp
    1433              :       INTEGER, INTENT(IN)                                :: orbitals(:), ispin
    1434              :       REAL(KIND=dp), INTENT(IN)                          :: v(:)
    1435              :       TYPE(cp_cfm_type), INTENT(INOUT)                   :: work(3)
    1436              :       TYPE(local_gemm_ctxt_type), INTENT(INOUT)          :: gemm
    1437              : 
    1438              :       COMPLEX(KIND=dp)                                   :: value
    1439              :       INTEGER                                            :: i, j, m, n, nc, nr
    1440           24 :       INTEGER, POINTER                                   :: columns(:), rows(:)
    1441              :       LOGICAL                                            :: local, real_only
    1442              : 
    1443           24 :       IF (ALL(v == 0.0_dp)) RETURN
    1444           24 :       CPASSERT(ALLOCATED(kp%lowdin_sqrt))
    1445           24 :       CPASSERT(ASSOCIATED(kp%lowdin_evec%local_data))
    1446           24 :       CPASSERT(ASSOCIATED(kp%wmat))
    1447              :       CALL cp_cfm_get_info(work(1), nrow_global=n, nrow_local=nr, ncol_local=nc, &
    1448           24 :                            row_indices=rows, col_indices=columns)
    1449           24 :       m = SIZE(orbitals)
    1450           72 :       local = PRODUCT(work(1)%matrix_struct%context%num_pe) == 1
    1451           24 :       real_only = SIZE(kp%pmat, 1) == 1
    1452           24 :       IF (real_only) THEN
    1453            0 :          CALL cp_fm_to_cfm(kp%pmat(1, ispin), mtarget=work(1))
    1454              :       ELSE
    1455           24 :          CALL cp_fm_to_cfm(kp%pmat(1, ispin), kp%pmat(2, ispin), work(1))
    1456              :       END IF
    1457              :       ! U**H * P * A * V * U = (U**H * P * B) * diag(v) * U(orbitals,:).
    1458              :       ! Keep these products thin: only the final backtransform needs square GEMMs.
    1459           24 :       CALL lowdin_kp_gemm('N', 'N', n, m, n, work(1), kp%lowdin_cb, z_zero, work(2), gemm)
    1460           24 :       CALL lowdin_kp_gemm('C', 'N', n, m, n, kp%lowdin_evec, work(2), z_zero, work(1), gemm)
    1461          576 :       DO j = 1, nc
    1462         3888 :          IF (columns(j) <= m) work(1)%local_data(:nr, j) = v(columns(j))*work(1)%local_data(:nr, j)
    1463              :       END DO
    1464           24 :       IF (local) THEN
    1465          168 :          DO j = 1, m
    1466         3480 :             work(3)%local_data(:n, j) = CONJG(kp%lowdin_evec%local_data(orbitals(j), :n))
    1467              :          END DO
    1468              :       ELSE
    1469            0 :          CALL cp_cfm_transpose(kp%lowdin_evec, 'C', work(2))
    1470            0 :          DO j = 1, m
    1471            0 :             CALL cp_cfm_to_cfm(work(2), work(3), 1, orbitals(j), j)
    1472              :          END DO
    1473              :       END IF
    1474           24 :       CALL lowdin_kp_gemm('N', 'C', n, n, m, work(1), work(3), z_zero, work(2), gemm)
    1475              :       ! Eigenvalue sums remain regular for equal or nearly equal overlap eigenvalues.
    1476          576 :       DO j = 1, nc
    1477        13272 :          DO i = 1, nr
    1478              :             work(2)%local_data(i, j) = work(2)%local_data(i, j)/ &
    1479        13248 :                                        (kp%lowdin_sqrt(rows(i)) + kp%lowdin_sqrt(columns(j)))
    1480              :          END DO
    1481              :       END DO
    1482           24 :       CALL lowdin_kp_gemm('N', 'N', n, n, n, kp%lowdin_evec, work(2), z_zero, work(1), gemm)
    1483           24 :       CALL lowdin_kp_gemm('N', 'C', n, n, n, work(1), kp%lowdin_evec, z_zero, work(2), gemm)
    1484           24 :       IF (.NOT. local) CALL cp_cfm_transpose(work(2), 'C', work(1))
    1485          576 :       DO j = 1, nc
    1486        13272 :          DO i = 1, nr
    1487        12696 :             IF (local) THEN
    1488        12696 :                value = work(2)%local_data(i, j) + CONJG(work(2)%local_data(j, i))
    1489              :             ELSE
    1490            0 :                value = work(2)%local_data(i, j) + work(1)%local_data(i, j)
    1491              :             END IF
    1492        12696 :             kp%wmat(1, ispin)%local_data(i, j) = kp%wmat(1, ispin)%local_data(i, j) - REAL(value, dp)
    1493        13248 :             IF (.NOT. real_only) THEN
    1494        12696 :                kp%wmat(2, ispin)%local_data(i, j) = kp%wmat(2, ispin)%local_data(i, j) - AIMAG(value)
    1495              :             END IF
    1496              :          END DO
    1497              :       END DO
    1498           24 :    END SUBROUTINE lowdin_kp_force_matrix
    1499              : 
    1500              : ! **************************************************************************************************
    1501              : !> \brief C = op(A)*op(B) + beta*C, with a private local context or collective parallel GEMM.
    1502              : !> \param ta Left transpose flag.
    1503              : !> \param tb Right transpose flag.
    1504              : !> \param nrow Output rows.
    1505              : !> \param ncol Output columns.
    1506              : !> \param inner Contraction dimension; may use only the selected columns of a square workspace.
    1507              : !> \param a Left operand.
    1508              : !> \param b Right operand.
    1509              : !> \param beta Scale of the existing output.
    1510              : !> \param c Output, distinct from both inputs.
    1511              : !> \param gemm Context owned by the current k-point or force worker.
    1512              : ! **************************************************************************************************
    1513         3860 :    SUBROUTINE lowdin_kp_gemm(ta, tb, nrow, ncol, inner, a, b, beta, c, gemm)
    1514              :       CHARACTER, INTENT(IN)                              :: ta, tb
    1515              :       INTEGER, INTENT(IN)                                :: nrow, ncol, inner
    1516              :       TYPE(cp_cfm_type), INTENT(IN)                      :: a, b
    1517              :       COMPLEX(KIND=dp), INTENT(IN)                       :: beta
    1518              :       TYPE(cp_cfm_type), INTENT(INOUT)                   :: c
    1519              :       TYPE(local_gemm_ctxt_type), INTENT(INOUT)          :: gemm
    1520              : 
    1521        11580 :       IF (PRODUCT(c%matrix_struct%context%num_pe) == 1) THEN
    1522              :          CALL gemm%gemm(ta, tb, nrow, ncol, inner, z_one, &
    1523              :                         a%local_data, SIZE(a%local_data, 1), b%local_data, SIZE(b%local_data, 1), &
    1524         3860 :                         beta, c%local_data, SIZE(c%local_data, 1))
    1525              :       ELSE
    1526            0 :          CALL parallel_gemm(ta, tb, nrow, ncol, inner, z_one, a, b, beta, c)
    1527              :       END IF
    1528         3860 :    END SUBROUTINE lowdin_kp_gemm
    1529              : 
    1530              : ! **************************************************************************************************
    1531              : !> \brief         Add a DFT+U contribution to the Hamiltonian matrix\n
    1532              : !>                using a method based on the Mulliken population analysis
    1533              : !>                \f[q_{\mu\nu} = \frac{1}{2} (P_{\mu\nu} S_{\nu\mu} +
    1534              : !>                                             S_{\mu\nu} P_{\nu\mu})\f]
    1535              : !>                where \b P and \b S are the density and the
    1536              : !>                overlap matrix, respectively.
    1537              : !> \param[in]     qs_env Quickstep environment
    1538              : !> \param orthonormal_basis ...
    1539              : !> \param[in,out] matrix_h Hamiltonian matrices for each spin
    1540              : !> \param should_output ...
    1541              : !> \param output_unit ...
    1542              : !> \param print_level ...
    1543              : !> \date          03.07.2008
    1544              : !> \par
    1545              : !>  \f{eqnarray*}{
    1546              : !>   E^{\rm DFT+U} & = & E^{\rm DFT} + E^{\rm U}\\\
    1547              : !>                 & = & E^{\rm DFT} + \frac{1}{2}\sum_A(U_A - J_A)(Tr(q_A) - Tr(q^2_A))\\[1ex]
    1548              : !>   V_{\mu\nu}^{\rm DFT+U} & = & V_{\mu\nu}^{\rm DFT} + V_{\mu\nu}^{\rm U}\\\
    1549              : !>                          & = & \frac{\partial E^{\rm DFT}}
    1550              : !>                                     {\partial P_{\mu\nu}} +
    1551              : !>                                \frac{\partial E^{\rm U}}
    1552              : !>                                     {\partial P_{\mu\nu}}\\\
    1553              : !>                          & = & H_{\mu\nu} + \sum_A
    1554              : !>                                \frac{\partial E^{\rm U}}{\partial q_A}
    1555              : !>                                \frac{\partial q_A}{\partial P_{\mu\nu}}\\\
    1556              : !>  \f}
    1557              : !> \author        Matthias Krack (MK)
    1558              : !> \version       1.0
    1559              : ! **************************************************************************************************
    1560         2096 :    SUBROUTINE mulliken(qs_env, orthonormal_basis, matrix_h, should_output, &
    1561              :                        output_unit, print_level)
    1562              : 
    1563              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1564              :       LOGICAL, INTENT(IN)                                :: orthonormal_basis
    1565              :       TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
    1566              :          POINTER                                         :: matrix_h
    1567              :       LOGICAL, INTENT(IN)                                :: should_output
    1568              :       INTEGER, INTENT(IN)                                :: output_unit, print_level
    1569              : 
    1570              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'mulliken'
    1571              : 
    1572              :       CHARACTER(LEN=10)                                  :: spin_info
    1573         2096 :       CHARACTER(LEN=6), ALLOCATABLE, DIMENSION(:)        :: symbol
    1574              :       CHARACTER(LEN=default_string_length)               :: atomic_kind_name
    1575              :       INTEGER :: atom_a, handle, i, i0, iatom, ic, ikind, iorb, isb, iset, isgf, ishell, ispin, j, &
    1576              :          jsb, jset, jsgf, jshell, lu, m, max_scf, n, natom, natom_of_kind, nimg, nkind, norb, nsb, &
    1577              :          nsbsize, nset, nsgf_kind, nspin
    1578              :       INTEGER, DIMENSION(1)                              :: iloc
    1579         2096 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, nshell, orbitals
    1580         2096 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgf, l, last_sgf
    1581              :       LOGICAL                                            :: debug, dft_plus_u_atom, found, &
    1582              :                                                             just_energy, occupation_enforced, smear
    1583         2096 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: is_plus_u_kind, orb_occ
    1584              :       REAL(KIND=dp)                                      :: eps_scf, eps_u_ramping, fspin, occ, trq, &
    1585              :                                                             trq2, u_minus_j, u_minus_j_target, &
    1586              :                                                             u_ramping
    1587         2096 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: q_eigval
    1588         2096 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: q_eigvec, q_matrix, q_work
    1589         2096 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: nelec
    1590         2096 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: h_block, p_block, q_block, s_block, &
    1591         2096 :                                                             v_block
    1592         2096 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1593              :       TYPE(atomic_kind_type), POINTER                    :: kind_a
    1594         2096 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_s
    1595              :       TYPE(dbcsr_type), POINTER                          :: sm_h, sm_p, sm_q, sm_s, sm_v
    1596              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1597              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1598              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1599         2096 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1600              :       TYPE(qs_energy_type), POINTER                      :: energy
    1601         2096 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1602              :       TYPE(qs_rho_type), POINTER                         :: rho
    1603              : 
    1604         2096 :       CALL timeset(routineN, handle)
    1605              : 
    1606         2096 :       debug = .FALSE. ! Set to .TRUE. to print debug information
    1607              : 
    1608         2096 :       NULLIFY (atom_list)
    1609         2096 :       NULLIFY (atomic_kind_set)
    1610         2096 :       NULLIFY (qs_kind_set)
    1611         2096 :       NULLIFY (dft_control)
    1612         2096 :       NULLIFY (energy)
    1613         2096 :       NULLIFY (first_sgf)
    1614         2096 :       NULLIFY (h_block)
    1615         2096 :       NULLIFY (matrix_p)
    1616         2096 :       NULLIFY (matrix_s)
    1617         2096 :       NULLIFY (l)
    1618         2096 :       NULLIFY (last_sgf)
    1619         2096 :       NULLIFY (nelec)
    1620         2096 :       NULLIFY (nshell)
    1621         2096 :       NULLIFY (orb_basis_set)
    1622         2096 :       NULLIFY (p_block)
    1623         2096 :       NULLIFY (particle_set)
    1624         2096 :       NULLIFY (q_block)
    1625         2096 :       NULLIFY (rho)
    1626         2096 :       NULLIFY (s_block)
    1627         2096 :       NULLIFY (orbitals)
    1628         2096 :       NULLIFY (sm_h)
    1629         2096 :       NULLIFY (sm_p)
    1630         2096 :       NULLIFY (sm_q)
    1631         2096 :       NULLIFY (sm_s)
    1632         2096 :       NULLIFY (sm_v)
    1633         2096 :       NULLIFY (v_block)
    1634         2096 :       NULLIFY (para_env)
    1635              : 
    1636         2096 :       smear = .FALSE.
    1637         2096 :       max_scf = -1
    1638         2096 :       eps_scf = 1.0E30_dp
    1639         2096 :       occupation_enforced = .FALSE.
    1640              : 
    1641              :       CALL get_qs_env(qs_env=qs_env, &
    1642              :                       atomic_kind_set=atomic_kind_set, &
    1643              :                       qs_kind_set=qs_kind_set, &
    1644              :                       dft_control=dft_control, &
    1645              :                       energy=energy, &
    1646              :                       particle_set=particle_set, &
    1647              :                       rho=rho, &
    1648         2096 :                       para_env=para_env)
    1649              : 
    1650         2096 :       CPASSERT(ASSOCIATED(atomic_kind_set))
    1651         2096 :       CPASSERT(ASSOCIATED(dft_control))
    1652         2096 :       CPASSERT(ASSOCIATED(energy))
    1653         2096 :       CPASSERT(ASSOCIATED(particle_set))
    1654         2096 :       CPASSERT(ASSOCIATED(rho))
    1655              : 
    1656         2096 :       IF (orthonormal_basis) THEN
    1657              :          NULLIFY (sm_s)
    1658              :       ELSE
    1659              :          ! Get overlap matrix in sparse format
    1660              :          CALL get_qs_env(qs_env=qs_env, &
    1661         2096 :                          matrix_s_kp=matrix_s)
    1662         2096 :          CPASSERT(ASSOCIATED(matrix_s))
    1663              :       END IF
    1664         2096 :       nimg = dft_control%nimages
    1665              : 
    1666              :       ! Get density matrices in sparse format
    1667              : 
    1668         2096 :       CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
    1669              : 
    1670         2096 :       energy%dft_plus_u = 0.0_dp
    1671              : 
    1672         2096 :       nspin = dft_control%nspins
    1673              : 
    1674         2096 :       IF (nspin == 2) THEN
    1675              :          fspin = 1.0_dp
    1676              :       ELSE
    1677         1114 :          fspin = 0.5_dp
    1678              :       END IF
    1679              : 
    1680              :       ! Get the total number of atoms, contracted spherical Gaussian basis
    1681              :       ! functions, and atomic kinds
    1682              : 
    1683              :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
    1684         2096 :                                natom=natom)
    1685              : 
    1686         2096 :       nkind = SIZE(atomic_kind_set)
    1687              : 
    1688         6288 :       ALLOCATE (is_plus_u_kind(nkind))
    1689         2096 :       is_plus_u_kind(:) = .FALSE.
    1690              : 
    1691         2096 :       IF (PRESENT(matrix_h)) THEN
    1692              :          just_energy = .FALSE.
    1693              :       ELSE
    1694          578 :          just_energy = .TRUE.
    1695              :       END IF
    1696              : 
    1697              :       ! Loop over all spins
    1698         5174 :       DO ispin = 1, nspin
    1699              : 
    1700              :          ! Loop over cell images
    1701       101670 :          DO ic = 1, nimg
    1702        96496 :             IF (.NOT. orthonormal_basis) THEN
    1703        96496 :                sm_s => matrix_s(1, ic)%matrix
    1704              :             END IF
    1705              : 
    1706        96496 :             IF (PRESENT(matrix_h)) THEN
    1707              :                ! Hamiltonian matrix for spin ispin in sparse format
    1708        94616 :                sm_h => matrix_h(ispin, ic)%matrix
    1709              :             ELSE
    1710              :                NULLIFY (sm_h)
    1711              :             END IF
    1712              : 
    1713              :             ! Get density matrix for spin ispin in sparse format
    1714              : 
    1715        96496 :             sm_p => matrix_p(ispin, ic)%matrix
    1716              : 
    1717        96496 :             IF (.NOT. ASSOCIATED(sm_q)) THEN
    1718         2096 :                ALLOCATE (sm_q)
    1719         2096 :                CALL dbcsr_get_block_diag(sm_p, sm_q)
    1720              :             END IF
    1721        96496 :             CALL dbcsr_set(sm_q, 0.0_dp)
    1722              : 
    1723        96496 :             IF (.NOT. ASSOCIATED(sm_v)) THEN
    1724         2096 :                ALLOCATE (sm_v)
    1725         2096 :                CALL dbcsr_get_block_diag(sm_p, sm_v)
    1726              :             END IF
    1727        96496 :             CALL dbcsr_set(sm_v, 0.0_dp)
    1728              : 
    1729       385984 :             DO iatom = 1, natom
    1730              : 
    1731              :                CALL dbcsr_get_block_p(matrix=sm_p, &
    1732              :                                       row=iatom, &
    1733              :                                       col=iatom, &
    1734              :                                       block=p_block, &
    1735       289488 :                                       found=found)
    1736              : 
    1737       289488 :                IF (.NOT. ASSOCIATED(p_block)) CYCLE
    1738              : 
    1739              :                CALL dbcsr_get_block_p(matrix=sm_q, &
    1740              :                                       row=iatom, &
    1741              :                                       col=iatom, &
    1742              :                                       block=q_block, &
    1743       144744 :                                       found=found)
    1744       144744 :                CPASSERT(ASSOCIATED(q_block))
    1745              : 
    1746       675472 :                IF (orthonormal_basis) THEN
    1747              :                   ! S is the unit matrix
    1748            0 :                   DO isgf = 1, SIZE(q_block, 1)
    1749            0 :                      q_block(isgf, isgf) = p_block(isgf, isgf)
    1750              :                   END DO
    1751              :                ELSE
    1752              :                   CALL dbcsr_get_block_p(matrix=sm_s, &
    1753              :                                          row=iatom, &
    1754              :                                          col=iatom, &
    1755              :                                          block=s_block, &
    1756       144744 :                                          found=found)
    1757       144744 :                   CPASSERT(ASSOCIATED(s_block))
    1758              :                   ! Exploit that P and S are symmetric
    1759      1219678 :                   DO jsgf = 1, SIZE(p_block, 2)
    1760     11325736 :                      DO isgf = 1, SIZE(p_block, 1)
    1761     11036248 :                         q_block(isgf, jsgf) = p_block(isgf, jsgf)*s_block(isgf, jsgf)
    1762              :                      END DO
    1763              :                   END DO
    1764              :                END IF ! orthonormal basis set
    1765              : 
    1766              :             END DO ! next atom "iatom"
    1767              : 
    1768              :             ! E[DFT+U] = E[DFT] + E[U]
    1769              :             !          = E[DFT] + (U - J)*(Tr(q) - Tr(q*q))/2
    1770              : 
    1771              :             ! V(i,j)[DFT+U] = V(i,j)[DFT] + V(i,j)[U]
    1772              :             !               = dE[DFT]/dP(i,j) + dE[U]/dP(i,j)
    1773              :             !               = dE[DFT]/dP(i,j) + (dE(U)/dq)*(dq/dP(i,j))
    1774              : 
    1775              :             ! Loop over all atomic kinds
    1776              : 
    1777       289488 :             DO ikind = 1, nkind
    1778              : 
    1779              :                ! Load the required atomic kind data
    1780              : 
    1781              :                CALL get_atomic_kind(atomic_kind_set(ikind), &
    1782              :                                     atom_list=atom_list, &
    1783              :                                     name=atomic_kind_name, &
    1784       192992 :                                     natom=natom_of_kind)
    1785              : 
    1786              :                CALL get_qs_kind(qs_kind_set(ikind), &
    1787              :                                 dft_plus_u_atom=dft_plus_u_atom, &
    1788              :                                 l_of_dft_plus_u=lu, &
    1789              :                                 nsgf=nsgf_kind, &
    1790              :                                 basis_set=orb_basis_set, &
    1791              :                                 u_minus_j=u_minus_j, &
    1792              :                                 u_minus_j_target=u_minus_j_target, &
    1793              :                                 u_ramping=u_ramping, &
    1794              :                                 eps_u_ramping=eps_u_ramping, &
    1795              :                                 nelec=nelec, &
    1796              :                                 orbitals=orbitals, &
    1797              :                                 eps_scf=eps_scf, &
    1798              :                                 max_scf=max_scf, &
    1799       192992 :                                 smear=smear)
    1800              : 
    1801              :                ! Check, if the atoms of this atomic kind need a DFT+U correction
    1802              : 
    1803       192992 :                IF (.NOT. ASSOCIATED(orb_basis_set)) CYCLE
    1804       192992 :                IF (.NOT. dft_plus_u_atom) CYCLE
    1805        96496 :                IF (lu < 0) CYCLE
    1806              : 
    1807              :                ! Apply U ramping if requested
    1808              : 
    1809        96496 :                IF ((ispin == 1) .AND. (u_ramping > 0.0_dp)) THEN
    1810          976 :                   IF (qs_env%scf_env%iter_delta <= eps_u_ramping) THEN
    1811          464 :                      u_minus_j = MIN(u_minus_j + u_ramping, u_minus_j_target)
    1812          464 :                      CALL set_qs_kind(qs_kind_set(ikind), u_minus_j=u_minus_j)
    1813              :                   END IF
    1814          976 :                   IF (should_output .AND. (output_unit > 0)) THEN
    1815              :                      WRITE (UNIT=output_unit, FMT="(T3,A,3X,A,F0.3,A)") &
    1816          476 :                         "Kind name: "//TRIM(ADJUSTL(atomic_kind_name)), &
    1817          952 :                         "U(eff) = ", u_minus_j*evolt, " eV"
    1818              :                   END IF
    1819              :                END IF
    1820              : 
    1821        96496 :                IF (u_minus_j == 0.0_dp) CYCLE
    1822              : 
    1823        96496 :                is_plus_u_kind(ikind) = .TRUE.
    1824              : 
    1825              :                ! Load the required Gaussian basis set data
    1826              : 
    1827              :                CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    1828              :                                       first_sgf=first_sgf, &
    1829              :                                       l=l, &
    1830              :                                       last_sgf=last_sgf, &
    1831              :                                       nset=nset, &
    1832        96496 :                                       nshell=nshell)
    1833              : 
    1834              :                ! Count the relevant shell blocks of this atomic kind
    1835              : 
    1836        96496 :                nsb = 0
    1837       194912 :                DO iset = 1, nset
    1838       663484 :                   DO ishell = 1, nshell(iset)
    1839       566988 :                      IF (l(ishell, iset) == lu) nsb = nsb + 1
    1840              :                   END DO
    1841              :                END DO
    1842              : 
    1843        96496 :                nsbsize = (2*lu + 1)
    1844        96496 :                n = nsb*nsbsize
    1845              : 
    1846       385984 :                ALLOCATE (q_matrix(n, n))
    1847        96496 :                q_matrix(:, :) = 0.0_dp
    1848              : 
    1849              :                ! Print headline if requested
    1850              : 
    1851        96496 :                IF (should_output .AND. (print_level > low_print_level)) THEN
    1852            0 :                   IF (output_unit > 0) THEN
    1853            0 :                      ALLOCATE (symbol(nsbsize))
    1854            0 :                      DO m = -lu, lu
    1855            0 :                         symbol(lu + m + 1) = sgf_symbol(0, lu, m)
    1856              :                      END DO
    1857            0 :                      IF (nspin > 1) THEN
    1858            0 :                         WRITE (UNIT=spin_info, FMT="(A8,I2)") " of spin", ispin
    1859              :                      ELSE
    1860            0 :                         spin_info = ""
    1861              :                      END IF
    1862              :                      WRITE (UNIT=output_unit, FMT="(/,T3,A,I0,A,/,/,T5,A,10(2X,A6))") &
    1863            0 :                         "DFT+U occupations"//TRIM(spin_info)//" for the atoms of atomic kind ", ikind, &
    1864            0 :                         ": "//TRIM(atomic_kind_name), &
    1865            0 :                         "Atom   Shell  ", (ADJUSTR(symbol(i)), i=1, nsbsize), " Trace"
    1866            0 :                      DEALLOCATE (symbol)
    1867              :                   END IF
    1868              :                END IF
    1869              : 
    1870              :                ! Loop over all atoms of the current atomic kind
    1871              : 
    1872       192992 :                DO iatom = 1, natom_of_kind
    1873              : 
    1874        96496 :                   atom_a = atom_list(iatom)
    1875              : 
    1876        96496 :                   q_matrix(:, :) = 0.0_dp
    1877              : 
    1878              :                   ! Get diagonal block
    1879              : 
    1880              :                   CALL dbcsr_get_block_p(matrix=sm_q, &
    1881              :                                          row=atom_a, &
    1882              :                                          col=atom_a, &
    1883              :                                          block=q_block, &
    1884        96496 :                                          found=found)
    1885              : 
    1886              :                   ! Calculate energy contribution to E(U)
    1887              : 
    1888        96496 :                   IF (ASSOCIATED(q_block)) THEN
    1889              : 
    1890        48248 :                      i = 0
    1891        97456 :                      DO iset = 1, nset
    1892       331742 :                         DO ishell = 1, nshell(iset)
    1893       234286 :                            IF (l(ishell, iset) /= lu) CYCLE
    1894       421284 :                            DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
    1895       282534 :                               i = i + 1
    1896       282534 :                               j = 0
    1897       805114 :                               DO jset = 1, nset
    1898      1948728 :                                  DO jshell = 1, nshell(jset)
    1899      1377900 :                                     IF (l(jshell, jset) /= lu) CYCLE
    1900      2479026 :                                     DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
    1901      1660434 :                                        j = j + 1
    1902      3038334 :                                        q_matrix(i, j) = q_block(isgf, jsgf)
    1903              :                                     END DO ! next contracted spherical Gaussian function "jsgf"
    1904              :                                  END DO ! next shell "jshell"
    1905              :                               END DO ! next shell set "jset"
    1906              :                            END DO ! next contracted spherical Gaussian function "isgf"
    1907              :                         END DO ! next shell "ishell"
    1908              :                      END DO ! next shell set "iset"
    1909              : 
    1910              :                      ! Perform the requested manipulations of the (initial) orbital occupations
    1911              : 
    1912        48248 :                      IF (ASSOCIATED(orbitals)) THEN
    1913            0 :                         IF ((qs_env%scf_env%iter_delta >= eps_scf) .OR. &
    1914              :                             ((qs_env%scf_env%outer_scf%iter_count == 0) .AND. &
    1915              :                              (qs_env%scf_env%iter_count <= max_scf))) THEN
    1916            0 :                            ALLOCATE (orb_occ(nsbsize))
    1917            0 :                            ALLOCATE (q_eigval(n))
    1918            0 :                            q_eigval(:) = 0.0_dp
    1919            0 :                            ALLOCATE (q_eigvec(n, n))
    1920            0 :                            q_eigvec(:, :) = 0.0_dp
    1921            0 :                            norb = SIZE(orbitals)
    1922            0 :                            CALL jacobi(q_matrix, q_eigval, q_eigvec)
    1923            0 :                            q_matrix(:, :) = 0.0_dp
    1924            0 :                            IF (nelec(ispin) >= 0.5_dp) THEN
    1925            0 :                               trq = nelec(ispin)/SUM(q_eigval(1:n))
    1926            0 :                               q_eigval(1:n) = trq*q_eigval(1:n)
    1927              :                            END IF
    1928            0 :                            DO isb = 1, nsb
    1929            0 :                               trq = 0.0_dp
    1930            0 :                               DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
    1931            0 :                                  trq = trq + q_eigval(i)
    1932              :                               END DO
    1933            0 :                               IF (smear) THEN
    1934            0 :                                  occ = trq/REAL(norb, KIND=dp)
    1935              :                               ELSE
    1936            0 :                                  occ = 1.0_dp/fspin
    1937              :                               END IF
    1938            0 :                               orb_occ(:) = .FALSE.
    1939            0 :                               iloc = MAXLOC(q_eigvec(:, isb*nsbsize))
    1940            0 :                               jsb = INT((iloc(1) - 1)/nsbsize) + 1
    1941            0 :                               i = 0
    1942            0 :                               i0 = (jsb - 1)*nsbsize + 1
    1943            0 :                               iorb = -1000
    1944            0 :                               DO j = i0, jsb*nsbsize
    1945            0 :                                  i = i + 1
    1946            0 :                                  IF (i > norb) THEN
    1947            0 :                                     DO m = -lu, lu
    1948            0 :                                        IF (.NOT. orb_occ(lu + m + 1)) THEN
    1949            0 :                                           iorb = i0 + lu + m
    1950            0 :                                           orb_occ(lu + m + 1) = .TRUE.
    1951              :                                        END IF
    1952              :                                     END DO
    1953              :                                  ELSE
    1954            0 :                                     iorb = i0 + lu + orbitals(i)
    1955            0 :                                     orb_occ(lu + orbitals(i) + 1) = .TRUE.
    1956              :                                  END IF
    1957            0 :                                  CPASSERT(iorb /= -1000)
    1958            0 :                                  iloc = MAXLOC(q_eigvec(iorb, :))
    1959            0 :                                  q_eigval(iloc(1)) = MIN(occ, trq)
    1960            0 :                                  q_matrix(:, iloc(1)) = q_eigval(iloc(1))*q_eigvec(:, iloc(1)) ! backtransform left
    1961            0 :                                  trq = trq - q_eigval(iloc(1))
    1962              :                               END DO
    1963              :                            END DO
    1964            0 :                            q_matrix(:, :) = MATMUL(q_matrix, TRANSPOSE(q_eigvec)) ! backtransform right
    1965            0 :                            DEALLOCATE (orb_occ)
    1966            0 :                            DEALLOCATE (q_eigval)
    1967            0 :                            DEALLOCATE (q_eigvec)
    1968            0 :                            occupation_enforced = .TRUE.
    1969              :                         END IF
    1970              :                      END IF ! orbitals associated
    1971              : 
    1972        48248 :                      trq = 0.0_dp
    1973        48248 :                      trq2 = 0.0_dp
    1974              : 
    1975       330782 :                      DO i = 1, n
    1976       282534 :                         trq = trq + q_matrix(i, i)
    1977      1991216 :                         DO j = 1, n
    1978      1942968 :                            trq2 = trq2 + q_matrix(i, j)*q_matrix(j, i)
    1979              :                         END DO
    1980              :                      END DO
    1981              : 
    1982        48248 :                      trq = fspin*trq
    1983        48248 :                      trq2 = fspin*fspin*trq2
    1984              : 
    1985              :                      ! Calculate energy contribution to E(U)
    1986              : 
    1987        48248 :                      energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*u_minus_j*(trq - trq2)/fspin
    1988              : 
    1989              :                      ! Calculate potential V(U) = dE(U)/dq
    1990              : 
    1991        48248 :                      IF (.NOT. just_energy) THEN
    1992              : 
    1993              :                         CALL dbcsr_get_block_p(matrix=sm_v, &
    1994              :                                                row=atom_a, &
    1995              :                                                col=atom_a, &
    1996              :                                                block=v_block, &
    1997        47308 :                                                found=found)
    1998        47308 :                         CPASSERT(ASSOCIATED(v_block))
    1999              : 
    2000        47308 :                         i = 0
    2001        95152 :                         DO iset = 1, nset
    2002       324738 :                            DO ishell = 1, nshell(iset)
    2003       229586 :                               IF (l(ishell, iset) /= lu) CYCLE
    2004       412400 :                               DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
    2005       276894 :                                  i = i + 1
    2006       276894 :                                  j = 0
    2007       786590 :                                  DO jset = 1, nset
    2008      1906704 :                                     DO jshell = 1, nshell(jset)
    2009      1349700 :                                        IF (l(jshell, jset) /= lu) CYCLE
    2010      2425722 :                                        DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
    2011      1626594 :                                           j = j + 1
    2012      2976294 :                                           IF (isgf == jsgf) THEN
    2013       276894 :                                              v_block(isgf, isgf) = u_minus_j*(0.5_dp - fspin*q_matrix(i, i))
    2014              :                                           ELSE
    2015      1349700 :                                              v_block(isgf, jsgf) = -u_minus_j*fspin*q_matrix(j, i)
    2016              :                                           END IF
    2017              :                                        END DO ! next contracted spherical Gaussian function "jsgf"
    2018              :                                     END DO ! next shell "jshell"
    2019              :                                  END DO ! next shell set "jset"
    2020              :                               END DO ! next contracted spherical Gaussian function "isgf"
    2021              :                            END DO ! next shell "ishell"
    2022              :                         END DO ! next shell set "iset"
    2023              : 
    2024              :                      END IF ! not just energy
    2025              : 
    2026              :                   END IF ! q_block associated
    2027              : 
    2028              :                   ! Consider print requests
    2029              : 
    2030       289488 :                   IF (should_output .AND. (print_level > low_print_level)) THEN
    2031            0 :                      CALL para_env%sum(q_matrix)
    2032            0 :                      IF (output_unit > 0) THEN
    2033            0 :                         ALLOCATE (q_work(nsb, nsbsize))
    2034            0 :                         q_work(:, :) = 0.0_dp
    2035            0 :                         DO isb = 1, nsb
    2036            0 :                            j = 0
    2037            0 :                            DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
    2038            0 :                               j = j + 1
    2039            0 :                               q_work(isb, j) = q_matrix(i, i)
    2040              :                            END DO
    2041              :                         END DO
    2042            0 :                         DO isb = 1, nsb
    2043              :                            WRITE (UNIT=output_unit, FMT="(T3,I6,2X,I6,2X,10F8.3)") &
    2044            0 :                               atom_a, isb, q_work(isb, :), SUM(q_work(isb, :))
    2045              :                         END DO
    2046              :                         WRITE (UNIT=output_unit, FMT="(T12,A,2X,10F8.3)") &
    2047            0 :                            "Total", (SUM(q_work(:, i)), i=1, nsbsize), SUM(q_work)
    2048            0 :                         WRITE (UNIT=output_unit, FMT="(A)") ""
    2049            0 :                         DEALLOCATE (q_work)
    2050              :                         IF (debug) THEN
    2051              :                            ! Print the DFT+U occupation matrix
    2052              :                            WRITE (UNIT=output_unit, FMT="(T9,70I10)") (i, i=1, n)
    2053              :                            DO i = 1, n
    2054              :                               WRITE (UNIT=output_unit, FMT="(T3,I6,70F10.6)") i, q_matrix(i, :)
    2055              :                            END DO
    2056              :                            ! Print the eigenvalues and eigenvectors of the occupation matrix
    2057              :                            ALLOCATE (q_eigval(n))
    2058              :                            q_eigval(:) = 0.0_dp
    2059              :                            ALLOCATE (q_eigvec(n, n))
    2060              :                            q_eigvec(:, :) = 0.0_dp
    2061              :                            CALL jacobi(q_matrix, q_eigval, q_eigvec)
    2062              :                            WRITE (UNIT=output_unit, FMT="(/,T9,70I10)") (i, i=1, n)
    2063              :                            WRITE (UNIT=output_unit, FMT="(T9,71F10.6)") (q_eigval(i), i=1, n), &
    2064              :                               SUM(q_eigval(1:n))
    2065              :                            DO i = 1, n
    2066              :                               WRITE (UNIT=output_unit, FMT="(T3,I6,70F10.6)") i, q_eigvec(i, :)
    2067              :                            END DO
    2068              :                            DEALLOCATE (q_eigval)
    2069              :                            DEALLOCATE (q_eigvec)
    2070              :                         END IF ! debug
    2071              :                      END IF
    2072              :                      IF (debug) THEN
    2073              :                         ! Print the full atomic occupation matrix block
    2074              :                         ALLOCATE (q_work(nsgf_kind, nsgf_kind))
    2075              :                         q_work(:, :) = 0.0_dp
    2076              :                         IF (ASSOCIATED(q_block)) q_work(:, :) = q_block(:, :)
    2077              :                         CALL para_env%sum(q_work)
    2078              :                         IF (output_unit > 0) THEN
    2079              :                            norb = SIZE(q_work, 1)
    2080              :                            WRITE (UNIT=output_unit, FMT="(/,T9,200I10)") (i, i=1, norb)
    2081              :                            DO i = 1, norb
    2082              :                               WRITE (UNIT=output_unit, FMT="(T3,I6,200F10.6)") i, q_work(i, :)
    2083              :                            END DO
    2084              :                            ALLOCATE (q_eigval(norb))
    2085              :                            q_eigval(:) = 0.0_dp
    2086              :                            ALLOCATE (q_eigvec(norb, norb))
    2087              :                            q_eigvec(:, :) = 0.0_dp
    2088              :                            CALL jacobi(q_work, q_eigval, q_eigvec)
    2089              :                            WRITE (UNIT=output_unit, FMT="(/,T9,200I10)") (i, i=1, norb)
    2090              :                            WRITE (UNIT=output_unit, FMT="(T9,201F10.6)") (q_eigval(i), i=1, norb), &
    2091              :                               SUM(q_eigval(1:norb))
    2092              :                            DO i = 1, norb
    2093              :                               WRITE (UNIT=output_unit, FMT="(T3,I6,200F10.6)") i, q_eigvec(i, :)
    2094              :                            END DO
    2095              :                            DEALLOCATE (q_eigval)
    2096              :                            DEALLOCATE (q_eigvec)
    2097              :                         END IF
    2098              :                         DEALLOCATE (q_work)
    2099              :                      END IF ! debug
    2100              :                   END IF ! should output
    2101              : 
    2102              :                END DO ! next atom "iatom" of atomic kind "ikind"
    2103              : 
    2104       482480 :                IF (ALLOCATED(q_matrix)) THEN
    2105        96496 :                   DEALLOCATE (q_matrix)
    2106              :                END IF
    2107              : 
    2108              :             END DO ! next atomic kind "ikind"
    2109              : 
    2110              :             ! Add V(i,j)[U] to V(i,j)[DFT]
    2111              : 
    2112        99574 :             IF (ASSOCIATED(sm_h)) THEN
    2113              : 
    2114       283848 :                DO ikind = 1, nkind
    2115              : 
    2116       189232 :                   IF (.NOT. is_plus_u_kind(ikind)) CYCLE
    2117              : 
    2118        94616 :                   kind_a => atomic_kind_set(ikind)
    2119              : 
    2120              :                   CALL get_atomic_kind(atomic_kind=kind_a, &
    2121              :                                        atom_list=atom_list, &
    2122        94616 :                                        natom=natom_of_kind)
    2123              : 
    2124       283848 :                   DO iatom = 1, natom_of_kind
    2125              : 
    2126        94616 :                      atom_a = atom_list(iatom)
    2127              : 
    2128              :                      CALL dbcsr_get_block_p(matrix=sm_h, &
    2129              :                                             row=atom_a, &
    2130              :                                             col=atom_a, &
    2131              :                                             block=h_block, &
    2132        94616 :                                             found=found)
    2133              : 
    2134        94616 :                      IF (.NOT. ASSOCIATED(h_block)) CYCLE
    2135              : 
    2136              :                      CALL dbcsr_get_block_p(matrix=sm_v, &
    2137              :                                             row=atom_a, &
    2138              :                                             col=atom_a, &
    2139              :                                             block=v_block, &
    2140        47308 :                                             found=found)
    2141        47308 :                      CPASSERT(ASSOCIATED(v_block))
    2142              : 
    2143       378464 :                      IF (orthonormal_basis) THEN
    2144            0 :                         DO isgf = 1, SIZE(h_block, 1)
    2145            0 :                            h_block(isgf, isgf) = h_block(isgf, isgf) + v_block(isgf, isgf)
    2146              :                         END DO
    2147              :                      ELSE
    2148              :                         CALL dbcsr_get_block_p(matrix=sm_s, &
    2149              :                                                row=atom_a, &
    2150              :                                                col=atom_a, &
    2151              :                                                block=s_block, &
    2152        47308 :                                                found=found)
    2153        47308 :                         CPASSERT(ASSOCIATED(s_block))
    2154       641450 :                         DO jsgf = 1, SIZE(h_block, 2)
    2155      8203984 :                            DO isgf = 1, SIZE(h_block, 1)
    2156      8109368 :                               h_block(isgf, jsgf) = h_block(isgf, jsgf) + v_block(isgf, jsgf)*s_block(isgf, jsgf)
    2157              :                            END DO
    2158              :                         END DO
    2159              :                      END IF ! orthonormal basis set
    2160              : 
    2161              :                   END DO ! next atom "iatom" of atomic kind "ikind"
    2162              : 
    2163              :                END DO ! Next atomic kind "ikind"
    2164              : 
    2165              :             END IF ! An update of the Hamiltonian matrix is requested
    2166              : 
    2167              :          END DO ! next cell image
    2168              : 
    2169              :       END DO ! next spin "ispin"
    2170              : 
    2171              :       ! Collect the energy contributions from all processes
    2172              : 
    2173         2096 :       CALL para_env%sum(energy%dft_plus_u)
    2174              : 
    2175         2096 :       IF (energy%dft_plus_u < 0.0_dp) THEN
    2176            2 :          IF (.NOT. occupation_enforced) THEN
    2177              :             CALL cp_warn(__LOCATION__, &
    2178              :                          "DFT+U energy contribution is negative possibly due "// &
    2179            2 :                          "to unphysical Mulliken charges!")
    2180              :          END IF
    2181              :       END IF
    2182              : 
    2183         2096 :       CALL dbcsr_deallocate_matrix(sm_q)
    2184         2096 :       CALL dbcsr_deallocate_matrix(sm_v)
    2185              : 
    2186         2096 :       CALL timestop(handle)
    2187              : 
    2188         6288 :    END SUBROUTINE mulliken
    2189              : 
    2190              : ! **************************************************************************************************
    2191              : !> \brief         Add a DFT+U contribution to the Hamiltonian matrix\n
    2192              : !>                using a method based on Mulliken charges
    2193              : !>                \f[q_\mu = \sum_\nu \frac{1}{2}(P_{\mu\nu} S_{\nu\mu} +
    2194              : !>                                                S_{\mu\nu} P_{\nu\mu})
    2195              : !>                         = \sum_\nu P_{\mu\nu} S_{\nu\mu}\f]
    2196              : !>                where \b P and \b S are the density and the
    2197              : !>                overlap matrix, respectively.
    2198              : !> \param[in]     qs_env Quickstep environment
    2199              : !> \param orthonormal_basis ...
    2200              : !> \param[in,out] matrix_h Hamiltonian matrices for each spin
    2201              : !> \param[in,out] matrix_w Energy weighted density matrices for each spin
    2202              : !> \param should_output ...
    2203              : !> \param output_unit ...
    2204              : !> \param print_level ...
    2205              : !> \date          11.01.2008
    2206              : !> \par
    2207              : !>  \f{eqnarray*}{
    2208              : !>   E^{\rm DFT+U} & = & E^{\rm DFT} +  E^{\rm U}\\\
    2209              : !>                 & = & E^{\rm DFT} +  \frac{1}{2}(U - J)\sum_\mu (q_\mu - q_\mu^2)\\[1ex]
    2210              : !>   V_{\mu\nu}^{\rm DFT+U} & = & V_{\mu\nu}^{\rm DFT} + V_{\mu\nu}^{\rm U}\\\
    2211              : !>                          & = & \frac{\partial E^{\rm DFT}}
    2212              : !>                                     {\partial P_{\mu\nu}} +
    2213              : !>                                \frac{\partial E^{\rm U}}
    2214              : !>                                     {\partial P_{\mu\nu}}\\\
    2215              : !>                          & = & H_{\mu\nu} +
    2216              : !>                                \frac{\partial E^{\rm U}}{\partial q_\mu}
    2217              : !>                                \frac{\partial q_\mu}{\partial P_{\mu\nu}}\\\
    2218              : !>                          & = & H_{\mu\nu} +
    2219              : !>                                \frac{1}{2}(U - J)(1 - q_\mu - q_\nu) S_{\mu\nu}\\\
    2220              : !>  \f}
    2221              : !> \author        Matthias Krack (MK)
    2222              : !> \version       1.0
    2223              : !> \note          The use of any full matrices was avoided. Thus no ScaLAPACK
    2224              : !>                calls are performed
    2225              : ! **************************************************************************************************
    2226          962 :    SUBROUTINE mulliken_charges(qs_env, orthonormal_basis, matrix_h, matrix_w, &
    2227              :                                should_output, output_unit, print_level)
    2228              : 
    2229              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2230              :       LOGICAL, INTENT(IN)                                :: orthonormal_basis
    2231              :       TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
    2232              :          POINTER                                         :: matrix_h, matrix_w
    2233              :       LOGICAL, INTENT(IN)                                :: should_output
    2234              :       INTEGER, INTENT(IN)                                :: output_unit, print_level
    2235              : 
    2236              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'mulliken_charges'
    2237              : 
    2238              :       CHARACTER(LEN=10)                                  :: spin_info
    2239          962 :       CHARACTER(LEN=6), ALLOCATABLE, DIMENSION(:)        :: symbol
    2240              :       CHARACTER(LEN=default_string_length)               :: atomic_kind_name
    2241              :       INTEGER :: atom_a, handle, i, iatom, ic, ikind, isb, iset, isgf, ishell, ispin, jatom, jsgf, &
    2242              :          lu, m, natom, natom_of_kind, nimg, nkind, nsb, nset, nsgf, nspin, sgf
    2243          962 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: first_sgf_atom
    2244          962 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, nshell
    2245          962 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgf, l, last_sgf
    2246              :       LOGICAL                                            :: dft_plus_u_atom, found, just_energy
    2247              :       REAL(KIND=dp)                                      :: eps_u_ramping, fspin, q, u_minus_j, &
    2248              :                                                             u_minus_j_target, u_ramping, v
    2249          962 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: dEdq, trps
    2250          962 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: q_ii
    2251          962 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: h_block, p_block, s_block, w_block
    2252          962 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    2253              :       TYPE(dbcsr_iterator_type)                          :: iter
    2254          962 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p, matrix_s
    2255              :       TYPE(dbcsr_type), POINTER                          :: sm_h, sm_p, sm_s, sm_w
    2256              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2257              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    2258              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2259          962 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    2260              :       TYPE(qs_energy_type), POINTER                      :: energy
    2261          962 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    2262              :       TYPE(qs_rho_type), POINTER                         :: rho
    2263              : 
    2264          962 :       CALL timeset(routineN, handle)
    2265              : 
    2266          962 :       NULLIFY (atom_list)
    2267          962 :       NULLIFY (atomic_kind_set)
    2268          962 :       NULLIFY (qs_kind_set)
    2269          962 :       NULLIFY (dft_control)
    2270          962 :       NULLIFY (energy)
    2271          962 :       NULLIFY (first_sgf)
    2272          962 :       NULLIFY (h_block)
    2273          962 :       NULLIFY (matrix_p)
    2274          962 :       NULLIFY (matrix_s)
    2275          962 :       NULLIFY (l)
    2276          962 :       NULLIFY (last_sgf)
    2277          962 :       NULLIFY (nshell)
    2278          962 :       NULLIFY (orb_basis_set)
    2279          962 :       NULLIFY (p_block)
    2280          962 :       NULLIFY (particle_set)
    2281          962 :       NULLIFY (rho)
    2282          962 :       NULLIFY (s_block)
    2283          962 :       NULLIFY (sm_h)
    2284          962 :       NULLIFY (sm_p)
    2285          962 :       NULLIFY (sm_s)
    2286          962 :       NULLIFY (w_block)
    2287          962 :       NULLIFY (para_env)
    2288              : 
    2289              :       CALL get_qs_env(qs_env=qs_env, &
    2290              :                       atomic_kind_set=atomic_kind_set, &
    2291              :                       qs_kind_set=qs_kind_set, &
    2292              :                       dft_control=dft_control, &
    2293              :                       energy=energy, &
    2294              :                       particle_set=particle_set, &
    2295              :                       rho=rho, &
    2296          962 :                       para_env=para_env)
    2297              : 
    2298          962 :       CPASSERT(ASSOCIATED(atomic_kind_set))
    2299          962 :       CPASSERT(ASSOCIATED(dft_control))
    2300          962 :       CPASSERT(ASSOCIATED(energy))
    2301          962 :       CPASSERT(ASSOCIATED(particle_set))
    2302          962 :       CPASSERT(ASSOCIATED(rho))
    2303              : 
    2304          962 :       IF (orthonormal_basis) THEN
    2305          962 :          NULLIFY (sm_s)
    2306              :       ELSE
    2307              :          ! Get overlap matrix in sparse format
    2308              :          CALL get_qs_env(qs_env=qs_env, &
    2309          962 :                          matrix_s_kp=matrix_s)
    2310          962 :          CPASSERT(ASSOCIATED(matrix_s))
    2311              :       END IF
    2312              : 
    2313              :       ! Get density matrices in sparse format
    2314              : 
    2315          962 :       CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
    2316              : 
    2317          962 :       energy%dft_plus_u = 0.0_dp
    2318              : 
    2319          962 :       nspin = dft_control%nspins
    2320          962 :       nimg = dft_control%nimages
    2321              : 
    2322          962 :       IF (nspin == 2) THEN
    2323              :          fspin = 1.0_dp
    2324              :       ELSE
    2325          576 :          fspin = 0.5_dp
    2326              :       END IF
    2327              : 
    2328              :       ! Get the total number of atoms, contracted spherical Gaussian basis
    2329              :       ! functions, and atomic kinds
    2330              : 
    2331          962 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, natom=natom)
    2332          962 :       CALL get_qs_kind_set(qs_kind_set, nsgf=nsgf)
    2333              : 
    2334          962 :       nkind = SIZE(atomic_kind_set)
    2335              : 
    2336         2886 :       ALLOCATE (first_sgf_atom(natom))
    2337          962 :       first_sgf_atom(:) = 0
    2338              : 
    2339              :       CALL get_particle_set(particle_set, qs_kind_set, &
    2340          962 :                             first_sgf=first_sgf_atom)
    2341              : 
    2342         2886 :       ALLOCATE (trps(nsgf))
    2343          962 :       trps(:) = 0.0_dp
    2344              : 
    2345          962 :       IF (PRESENT(matrix_h) .OR. PRESENT(matrix_w)) THEN
    2346         2664 :          ALLOCATE (dEdq(nsgf))
    2347          888 :          just_energy = .FALSE.
    2348              :       ELSE
    2349              :          just_energy = .TRUE.
    2350              :       END IF
    2351              : 
    2352              :       ! Loop over all spins
    2353              : 
    2354         2310 :       DO ispin = 1, nspin
    2355              : 
    2356         1348 :          IF (.NOT. just_energy) dEdq(:) = 0.0_dp
    2357              : 
    2358              :          ! Calculate Trace(P*S) assuming symmetric matrices
    2359              : 
    2360         1348 :          trps(:) = 0.0_dp
    2361              : 
    2362        78006 :          DO ic = 1, nimg
    2363        76658 :             IF (orthonormal_basis) THEN
    2364              :                NULLIFY (sm_s)
    2365              :             ELSE
    2366        76658 :                sm_s => matrix_s(1, ic)%matrix
    2367              :             END IF
    2368        76658 :             sm_p => matrix_p(ispin, ic)%matrix ! Density matrix for spin ispin in sparse format
    2369              : 
    2370        76658 :             CALL dbcsr_iterator_start(iter, sm_p)
    2371              : 
    2372       306632 :             DO WHILE (dbcsr_iterator_blocks_left(iter))
    2373              : 
    2374       229974 :                CALL dbcsr_iterator_next_block(iter, iatom, jatom, p_block)
    2375              : 
    2376       306632 :                IF (orthonormal_basis) THEN
    2377              : 
    2378            0 :                   IF (iatom /= jatom) CYCLE
    2379              : 
    2380            0 :                   IF (ASSOCIATED(p_block)) THEN
    2381            0 :                      sgf = first_sgf_atom(iatom)
    2382            0 :                      DO isgf = 1, SIZE(p_block, 1)
    2383            0 :                         trps(sgf) = trps(sgf) + p_block(isgf, isgf)
    2384            0 :                         sgf = sgf + 1
    2385              :                      END DO
    2386              :                   END IF
    2387              : 
    2388              :                ELSE
    2389              : 
    2390              :                   CALL dbcsr_get_block_p(matrix=sm_s, &
    2391              :                                          row=iatom, &
    2392              :                                          col=jatom, &
    2393              :                                          block=s_block, &
    2394       229974 :                                          found=found)
    2395       229974 :                   CPASSERT(ASSOCIATED(s_block))
    2396              : 
    2397       229974 :                   sgf = first_sgf_atom(jatom)
    2398      1686476 :                   DO jsgf = 1, SIZE(p_block, 2)
    2399     15791548 :                      DO isgf = 1, SIZE(p_block, 1)
    2400     15791548 :                         trps(sgf) = trps(sgf) + p_block(isgf, jsgf)*s_block(isgf, jsgf)
    2401              :                      END DO
    2402      1686476 :                      sgf = sgf + 1
    2403              :                   END DO
    2404              : 
    2405       229974 :                   IF (iatom /= jatom) THEN
    2406       114987 :                      sgf = first_sgf_atom(iatom)
    2407      1303186 :                      DO isgf = 1, SIZE(p_block, 1)
    2408      7129194 :                         DO jsgf = 1, SIZE(p_block, 2)
    2409      7129194 :                            trps(sgf) = trps(sgf) + p_block(isgf, jsgf)*s_block(isgf, jsgf)
    2410              :                         END DO
    2411      1303186 :                         sgf = sgf + 1
    2412              :                      END DO
    2413              :                   END IF
    2414              : 
    2415              :                END IF ! orthonormal basis set
    2416              : 
    2417              :             END DO ! next atom "iatom"
    2418              : 
    2419       154664 :             CALL dbcsr_iterator_stop(iter)
    2420              : 
    2421              :          END DO ! cell images
    2422              : 
    2423         1348 :          CALL para_env%sum(trps)
    2424              : 
    2425              :          ! q <- Trace(PS)
    2426              : 
    2427              :          ! E[DFT+U] = E[DFT] + E[U]
    2428              :          !          = E[DFT] + (U - J)*(q - q**2))/2
    2429              : 
    2430              :          ! V(i,j)[DFT+U] = V(i,j)[DFT] + V(i,j)[U]
    2431              :          !               = dE[DFT]/dP(i,j) + dE[U]/dP(i,j)
    2432              :          !               = dE[DFT]/dP(i,j) + (dE(U)/dq)*(dq/dP(i,j))
    2433              : 
    2434              :          ! Loop over all atomic kinds
    2435              : 
    2436         4044 :          DO ikind = 1, nkind
    2437              : 
    2438              :             ! Load the required atomic kind data
    2439              :             CALL get_atomic_kind(atomic_kind_set(ikind), &
    2440              :                                  atom_list=atom_list, &
    2441              :                                  name=atomic_kind_name, &
    2442         2696 :                                  natom=natom_of_kind)
    2443              : 
    2444              :             CALL get_qs_kind(qs_kind_set(ikind), &
    2445              :                              dft_plus_u_atom=dft_plus_u_atom, &
    2446              :                              l_of_dft_plus_u=lu, &
    2447              :                              basis_set=orb_basis_set, &
    2448              :                              u_minus_j=u_minus_j, &
    2449              :                              u_minus_j_target=u_minus_j_target, &
    2450              :                              u_ramping=u_ramping, &
    2451         2696 :                              eps_u_ramping=eps_u_ramping)
    2452              : 
    2453              :             ! Check, if this atom needs a DFT+U correction
    2454              : 
    2455         2696 :             IF (.NOT. ASSOCIATED(orb_basis_set)) CYCLE
    2456         2696 :             IF (.NOT. dft_plus_u_atom) CYCLE
    2457         1348 :             IF (lu < 0) CYCLE
    2458              : 
    2459              :             ! Apply U ramping if requested
    2460              : 
    2461         1348 :             IF ((ispin == 1) .AND. (u_ramping > 0.0_dp)) THEN
    2462            0 :                IF (qs_env%scf_env%iter_delta <= eps_u_ramping) THEN
    2463            0 :                   u_minus_j = MIN(u_minus_j + u_ramping, u_minus_j_target)
    2464            0 :                   CALL set_qs_kind(qs_kind_set(ikind), u_minus_j=u_minus_j)
    2465              :                END IF
    2466            0 :                IF (should_output .AND. (output_unit > 0)) THEN
    2467              :                   WRITE (UNIT=output_unit, FMT="(T3,A,3X,A,F0.3,A)") &
    2468            0 :                      "Kind name: "//TRIM(ADJUSTL(atomic_kind_name)), &
    2469            0 :                      "U(eff) = ", u_minus_j*evolt, " eV"
    2470              :                END IF
    2471              :             END IF
    2472              : 
    2473         1348 :             IF (u_minus_j == 0.0_dp) CYCLE
    2474              : 
    2475              :             ! Load the required Gaussian basis set data
    2476              : 
    2477              :             CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    2478              :                                    first_sgf=first_sgf, &
    2479              :                                    l=l, &
    2480              :                                    last_sgf=last_sgf, &
    2481              :                                    nset=nset, &
    2482         1348 :                                    nshell=nshell)
    2483              : 
    2484              :             ! Count the relevant shell blocks of this atomic kind
    2485              : 
    2486         1348 :             nsb = 0
    2487         3158 :             DO iset = 1, nset
    2488         9898 :                DO ishell = 1, nshell(iset)
    2489         8550 :                   IF (l(ishell, iset) == lu) nsb = nsb + 1
    2490              :                END DO
    2491              :             END DO
    2492              : 
    2493         5392 :             ALLOCATE (q_ii(nsb, 2*lu + 1))
    2494              : 
    2495              :             ! Print headline if requested
    2496              : 
    2497         1348 :             IF (should_output .AND. (print_level > low_print_level)) THEN
    2498            0 :                IF (output_unit > 0) THEN
    2499            0 :                   ALLOCATE (symbol(2*lu + 1))
    2500            0 :                   DO m = -lu, lu
    2501            0 :                      symbol(lu + m + 1) = sgf_symbol(0, lu, m)
    2502              :                   END DO
    2503            0 :                   IF (nspin > 1) THEN
    2504            0 :                      WRITE (UNIT=spin_info, FMT="(A8,I2)") " of spin", ispin
    2505              :                   ELSE
    2506            0 :                      spin_info = ""
    2507              :                   END IF
    2508              :                   WRITE (UNIT=output_unit, FMT="(/,T3,A,I0,A,/,/,T5,A,10(2X,A6))") &
    2509            0 :                      "DFT+U occupations"//TRIM(spin_info)//" for the atoms of atomic kind ", ikind, &
    2510            0 :                      ": "//TRIM(atomic_kind_name), &
    2511            0 :                      "Atom   Shell  ", (ADJUSTR(symbol(i)), i=1, 2*lu + 1), " Trace"
    2512            0 :                   DEALLOCATE (symbol)
    2513              :                END IF
    2514              :             END IF
    2515              : 
    2516              :             ! Loop over all atoms of the current atomic kind
    2517              : 
    2518         2696 :             DO iatom = 1, natom_of_kind
    2519              : 
    2520         1348 :                atom_a = atom_list(iatom)
    2521              : 
    2522         1348 :                q_ii(:, :) = 0.0_dp
    2523              : 
    2524              :                ! Get diagonal block
    2525              : 
    2526              :                CALL dbcsr_get_block_p(matrix=sm_p, &
    2527              :                                       row=atom_a, &
    2528              :                                       col=atom_a, &
    2529              :                                       block=p_block, &
    2530         1348 :                                       found=found)
    2531              : 
    2532              :                ! Calculate E(U) and dE(U)/dq
    2533              : 
    2534         1348 :                IF (ASSOCIATED(p_block)) THEN
    2535              : 
    2536          674 :                   sgf = first_sgf_atom(atom_a)
    2537              : 
    2538          674 :                   isb = 0
    2539         1579 :                   DO iset = 1, nset
    2540         4949 :                      DO ishell = 1, nshell(iset)
    2541         4275 :                         IF (l(ishell, iset) == lu) THEN
    2542         1348 :                            isb = isb + 1
    2543         1348 :                            i = 0
    2544         5392 :                            DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
    2545         4044 :                               q = fspin*trps(sgf)
    2546         4044 :                               i = i + 1
    2547         4044 :                               q_ii(isb, i) = q
    2548              :                               energy%dft_plus_u = energy%dft_plus_u + &
    2549         4044 :                                                   0.5_dp*u_minus_j*(q - q**2)/fspin
    2550         4044 :                               IF (.NOT. just_energy) THEN
    2551         3702 :                                  dEdq(sgf) = dEdq(sgf) + u_minus_j*(0.5_dp - q)
    2552              :                               END IF
    2553         5392 :                               sgf = sgf + 1
    2554              :                            END DO ! next contracted spherical Gaussian function "isgf"
    2555              :                         ELSE
    2556         2022 :                            sgf = sgf + last_sgf(ishell, iset) - first_sgf(ishell, iset) + 1
    2557              :                         END IF ! angular momentum requested for DFT+U correction
    2558              :                      END DO ! next shell "ishell"
    2559              :                   END DO ! next shell set "iset"
    2560              : 
    2561              :                END IF ! this process is the owner of the sparse matrix block?
    2562              : 
    2563              :                ! Consider print requests
    2564              : 
    2565         4044 :                IF (should_output .AND. (print_level > low_print_level)) THEN
    2566            0 :                   CALL para_env%sum(q_ii)
    2567            0 :                   IF (output_unit > 0) THEN
    2568            0 :                      DO isb = 1, nsb
    2569              :                         WRITE (UNIT=output_unit, FMT="(T3,I6,2X,I6,2X,10F8.3)") &
    2570            0 :                            atom_a, isb, q_ii(isb, :), SUM(q_ii(isb, :))
    2571              :                      END DO
    2572              :                      WRITE (UNIT=output_unit, FMT="(T12,A,2X,10F8.3)") &
    2573            0 :                         "Total", (SUM(q_ii(:, i)), i=1, 2*lu + 1), SUM(q_ii)
    2574            0 :                      WRITE (UNIT=output_unit, FMT="(A)") ""
    2575              :                   END IF
    2576              :                END IF ! should output
    2577              : 
    2578              :             END DO ! next atom "iatom" of atomic kind "ikind"
    2579              : 
    2580         6740 :             IF (ALLOCATED(q_ii)) THEN
    2581         1348 :                DEALLOCATE (q_ii)
    2582              :             END IF
    2583              : 
    2584              :          END DO ! next atomic kind "ikind"
    2585              : 
    2586         1348 :          IF (.NOT. just_energy) THEN
    2587         1234 :             CALL para_env%sum(dEdq)
    2588              :          END IF
    2589              : 
    2590              :          ! Add V(i,j)[U] to V(i,j)[DFT]
    2591              : 
    2592         1348 :          IF (PRESENT(matrix_h)) THEN
    2593              : 
    2594        76662 :             DO ic = 1, nimg
    2595        75476 :                IF (orthonormal_basis) THEN
    2596              :                   NULLIFY (sm_s)
    2597              :                ELSE
    2598        75476 :                   sm_s => matrix_s(1, ic)%matrix
    2599              :                END IF
    2600        75476 :                sm_h => matrix_h(ispin, ic)%matrix
    2601              : 
    2602        75476 :                CALL dbcsr_iterator_start(iter, sm_h)
    2603              : 
    2604       301904 :                DO WHILE (dbcsr_iterator_blocks_left(iter))
    2605              : 
    2606       226428 :                   CALL dbcsr_iterator_next_block(iter, iatom, jatom, h_block)
    2607              : 
    2608       301904 :                   IF (orthonormal_basis) THEN
    2609              : 
    2610            0 :                      IF (iatom /= jatom) CYCLE
    2611              : 
    2612            0 :                      IF (ASSOCIATED(h_block)) THEN
    2613            0 :                         sgf = first_sgf_atom(iatom)
    2614            0 :                         DO isgf = 1, SIZE(h_block, 1)
    2615            0 :                            h_block(isgf, isgf) = h_block(isgf, isgf) + dEdq(sgf)
    2616            0 :                            sgf = sgf + 1
    2617              :                         END DO
    2618              :                      END IF
    2619              : 
    2620              :                   ELSE
    2621              : 
    2622              :                      ! Request katom just to check for consistent sparse matrix pattern
    2623              : 
    2624              :                      CALL dbcsr_get_block_p(matrix=sm_s, &
    2625              :                                             row=iatom, &
    2626              :                                             col=jatom, &
    2627              :                                             block=s_block, &
    2628       226428 :                                             found=found)
    2629       226428 :                      CPASSERT(ASSOCIATED(s_block))
    2630              : 
    2631              :                      ! Consider the symmetric form 1/2*(P*S + S*P) for the calculation
    2632              : 
    2633       226428 :                      sgf = first_sgf_atom(iatom)
    2634              : 
    2635      2264280 :                      DO isgf = 1, SIZE(h_block, 1)
    2636      2037852 :                         IF (dEdq(sgf) /= 0.0_dp) THEN
    2637       679284 :                            v = 0.5_dp*dEdq(sgf)
    2638      5887128 :                            DO jsgf = 1, SIZE(h_block, 2)
    2639      5887128 :                               h_block(isgf, jsgf) = h_block(isgf, jsgf) + v*s_block(isgf, jsgf)
    2640              :                            END DO
    2641              :                         END IF
    2642      2264280 :                         sgf = sgf + 1
    2643              :                      END DO
    2644              : 
    2645       226428 :                      sgf = first_sgf_atom(jatom)
    2646              : 
    2647      1660472 :                      DO jsgf = 1, SIZE(h_block, 2)
    2648      1434044 :                         IF (dEdq(sgf) /= 0.0_dp) THEN
    2649       226428 :                            v = 0.5_dp*dEdq(sgf)
    2650      3169992 :                            DO isgf = 1, SIZE(h_block, 1)
    2651      3169992 :                               h_block(isgf, jsgf) = h_block(isgf, jsgf) + v*s_block(isgf, jsgf)
    2652              :                            END DO
    2653              :                         END IF
    2654      1660472 :                         sgf = sgf + 1
    2655              :                      END DO
    2656              : 
    2657              :                   END IF ! orthonormal basis set
    2658              : 
    2659              :                END DO ! Next atom "iatom"
    2660              : 
    2661       152138 :                CALL dbcsr_iterator_stop(iter)
    2662              : 
    2663              :             END DO
    2664              : 
    2665              :          END IF ! An update of the Hamiltonian matrix is requested
    2666              : 
    2667              :          ! Calculate the contribution (non-Pulay part) to the derivatives
    2668              :          ! w.r.t. the nuclear positions, which requires an update of the
    2669              :          ! energy weighted density W.
    2670              : 
    2671         2310 :          IF (PRESENT(matrix_w) .AND. (.NOT. orthonormal_basis)) THEN
    2672              : 
    2673         1116 :             DO ic = 1, nimg
    2674         1068 :                sm_s => matrix_s(1, ic)%matrix
    2675         1068 :                sm_p => matrix_p(ispin, ic)%matrix
    2676         1068 :                sm_w => matrix_w(ispin, ic)%matrix
    2677              : 
    2678         1068 :                CALL dbcsr_iterator_start(iter, sm_p)
    2679              : 
    2680         4272 :                DO WHILE (dbcsr_iterator_blocks_left(iter))
    2681              : 
    2682         3204 :                   CALL dbcsr_iterator_next_block(iter, iatom, jatom, p_block)
    2683              : 
    2684              :                   ! Skip the diagonal blocks of the W matrix
    2685              : 
    2686         3204 :                   IF (iatom == jatom) CYCLE
    2687              : 
    2688              :                   ! Request katom just to check for consistent sparse matrix patterns
    2689              : 
    2690              :                   CALL dbcsr_get_block_p(matrix=sm_w, &
    2691              :                                          row=iatom, &
    2692              :                                          col=jatom, &
    2693              :                                          block=w_block, &
    2694         1602 :                                          found=found)
    2695         1602 :                   CPASSERT(ASSOCIATED(w_block))
    2696              : 
    2697              :                   ! Consider the symmetric form 1/2*(P*S + S*P) for the calculation
    2698              : 
    2699         1602 :                   sgf = first_sgf_atom(iatom)
    2700              : 
    2701        18156 :                   DO isgf = 1, SIZE(w_block, 1)
    2702        16554 :                      IF (dEdq(sgf) /= 0.0_dp) THEN
    2703         6408 :                         v = -0.5_dp*dEdq(sgf)
    2704        38448 :                         DO jsgf = 1, SIZE(w_block, 2)
    2705        38448 :                            w_block(isgf, jsgf) = w_block(isgf, jsgf) + v*p_block(isgf, jsgf)
    2706              :                         END DO
    2707              :                      END IF
    2708        18156 :                      sgf = sgf + 1
    2709              :                   END DO
    2710              : 
    2711         1602 :                   sgf = first_sgf_atom(jatom)
    2712              : 
    2713        10680 :                   DO jsgf = 1, SIZE(w_block, 2)
    2714         8010 :                      IF (dEdq(sgf) /= 0.0_dp) THEN
    2715            0 :                         v = -0.5_dp*dEdq(sgf)
    2716            0 :                         DO isgf = 1, SIZE(w_block, 1)
    2717            0 :                            w_block(isgf, jsgf) = w_block(isgf, jsgf) + v*p_block(isgf, jsgf)
    2718              :                         END DO
    2719              :                      END IF
    2720        11214 :                      sgf = sgf + 1
    2721              :                   END DO
    2722              : 
    2723              :                END DO ! next block node "jatom"
    2724              : 
    2725         2184 :                CALL dbcsr_iterator_stop(iter)
    2726              : 
    2727              :             END DO
    2728              : 
    2729              :          END IF ! W matrix update requested
    2730              : 
    2731              :       END DO ! next spin "ispin"
    2732              : 
    2733              :       ! Collect the energy contributions from all processes
    2734              : 
    2735          962 :       CALL para_env%sum(energy%dft_plus_u)
    2736              : 
    2737          962 :       IF (energy%dft_plus_u < 0.0_dp) THEN
    2738              :          CALL cp_warn(__LOCATION__, &
    2739              :                       "DFT+U energy contribution is negative possibly due "// &
    2740            4 :                       "to unphysical Mulliken charges!")
    2741              :       END IF
    2742              : 
    2743              :       ! Release local work storage
    2744              : 
    2745          962 :       IF (ALLOCATED(first_sgf_atom)) THEN
    2746          962 :          DEALLOCATE (first_sgf_atom)
    2747              :       END IF
    2748              : 
    2749          962 :       IF (ALLOCATED(trps)) THEN
    2750          962 :          DEALLOCATE (trps)
    2751              :       END IF
    2752              : 
    2753          962 :       IF (ALLOCATED(dEdq)) THEN
    2754          888 :          DEALLOCATE (dEdq)
    2755              :       END IF
    2756              : 
    2757          962 :       CALL timestop(handle)
    2758              : 
    2759         2886 :    END SUBROUTINE mulliken_charges
    2760              : 
    2761              : ! **************************************************************************************************
    2762              : !> \brief Calculate the tensorial DFT+U+J energy contribution, Hamiltonian correction,
    2763              : !>        and optional force contribution.
    2764              : !> \param[in]     qs_env         Quickstep environment
    2765              : !> \param[in,out] matrix_h       Hamiltonian matrices
    2766              : !> \param[in,out] matrix_w       Energy-weighted density matrices for each spin channel
    2767              : !> \param[in]     should_output  Whether detailed output should be printed
    2768              : !> \param[in]     output_unit     ...
    2769              : !> \param[in]     print_level     ...
    2770              : !> \date          14.03.2026
    2771              : !> \author        Ziwei Chai (ZC)
    2772              : ! **************************************************************************************************
    2773          772 :    SUBROUTINE tensorial(qs_env, matrix_h, matrix_w, should_output, output_unit, print_level)
    2774              : 
    2775              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2776              :       TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
    2777              :          POINTER                                         :: matrix_h, matrix_w
    2778              :       LOGICAL, INTENT(IN)                                :: should_output
    2779              :       INTEGER, INTENT(IN)                                :: output_unit, print_level
    2780              : 
    2781              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'tensorial'
    2782              : 
    2783              :       CHARACTER(LEN=10)                                  :: spin_info
    2784          772 :       CHARACTER(LEN=6), ALLOCATABLE                      :: symbol(:)
    2785              :       CHARACTER(LEN=default_string_length)               :: atomic_kind_name
    2786              :       INTEGER :: atom_a, atom_aa, handle, i, i0, iatom, ikind, iorb, isb, iset, isgf, ishell, &
    2787              :          ispin, j, jatom, jj, jkind, jsb, jset, jsgf, jshell, katom, lu, m, matom_of_kind, &
    2788              :          max_scf, n, natom, natom_of_kind, nkind, norb, nsb, nsbsize, nset, nsgf, nsgf_kind, &
    2789              :          nsgf_kind2, nspin, timevalues(8)
    2790          772 :       INTEGER, ALLOCATABLE                               :: first_sgf_atom(:)
    2791              :       INTEGER, DIMENSION(1)                              :: iloc
    2792          772 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, atom_list2, nshell, orbitals
    2793          772 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgf, l, last_sgf
    2794              :       LOGICAL                                            :: debug, dft_plus_u_atom, found, &
    2795              :                                                             just_energy, smear
    2796          772 :       LOGICAL, ALLOCATABLE                               :: orb_occ(:)
    2797              :       REAL(KIND=dp) :: eps_scf, eps_u_ramping, fspin, hund_j, occ, perturbation_strength, &
    2798              :          some_real, trq, trq2, trqxq_hund_j, u_minus_j, u_minus_j_target, u_ramping
    2799          772 :       REAL(KIND=dp), ALLOCATABLE :: a(:), q_a_matrix(:, :), q_b_matrix(:, :), q_eigval(:), &
    2800          772 :          q_eigvec(:, :), q_work(:, :), s_inv_matrix(:, :), s_matrix(:, :), tmp_matrix1(:, :), &
    2801          772 :          tmp_matrix2(:, :), tmp_matrix3(:, :), v_matrix(:, :), vhxc_matrix(:, :)
    2802              : 
    2803              :       TYPE :: block3d
    2804              :          REAL(KIND=dp), ALLOCATABLE                       :: matrix(:, :, :)
    2805              :       END TYPE block3d
    2806              :       TYPE :: block4d
    2807              :          REAL(KIND=dp), ALLOCATABLE                       :: matrix(:, :, :, :)
    2808              :       END TYPE block4d
    2809          772 :       TYPE(block3d), ALLOCATABLE                          :: a_matrix(:, :), d_matrix(:, :), &
    2810          772 :                                                              e_matrix(:, :), i_matrix(:, :), &
    2811          772 :                                                              j_matrix(:, :)
    2812          772 :       TYPE(block4d), ALLOCATABLE                          :: dd_matrix(:, :), ee_matrix(:, :), &
    2813          772 :                                                              ff_matrix(:, :)
    2814          772 :       REAL(KIND=dp), DIMENSION(:), POINTER                :: ao_coef
    2815          772 :       REAL(KIND=dp), DIMENSION(:, :), POINTER             :: a_block, d_block, e_block, f_block, &
    2816          772 :                                                              i_block, j_block, q_a_block, q_b_block, &
    2817          772 :                                                              s_block, tmp_block, v_block, vhxc_block
    2818              : 
    2819          772 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER       :: atomic_kind_set
    2820              :       TYPE(mp_para_env_type), POINTER                     :: para_env
    2821          772 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER           :: matrix_p, matrix_s, matrix_vhxc
    2822          772 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER        :: matrixkp_s
    2823              :       TYPE(dbcsr_type), POINTER                           :: sm_a, sm_b, sm_c, sm_d, sm_e, sm_f, &
    2824              :                                                              sm_h, sm_i, sm_j, sm_k, sm_q_a, sm_q_b, &
    2825              :                                                              sm_s, sm_v, sm_w, sm_mid, sm_vhxc, sm_p
    2826              :       TYPE(dbcsr_iterator_type)                           :: iter
    2827              :       TYPE(dft_control_type), POINTER                     :: dft_control
    2828              :       TYPE(gto_basis_set_type), POINTER                   :: orb_basis_set
    2829          772 :       TYPE(particle_type), DIMENSION(:), POINTER          :: particle_set
    2830              :       TYPE(qs_energy_type), POINTER                       :: energy
    2831          772 :       TYPE(qs_force_type), DIMENSION(:), POINTER          :: force
    2832          772 :       TYPE(qs_kind_type), DIMENSION(:), POINTER           :: qs_kind_set
    2833              :       TYPE(qs_rho_type), POINTER                          :: rho
    2834              :       TYPE(qs_scf_env_type), POINTER                      :: scf_env
    2835              : 
    2836          772 :       CALL timeset(routineN, handle)
    2837              : 
    2838          772 :       debug = .FALSE.
    2839          772 :       smear = .FALSE.
    2840          772 :       max_scf = -1
    2841          772 :       eps_scf = 1.0E30_dp
    2842              : 
    2843          772 :       NULLIFY (atom_list)
    2844          772 :       NULLIFY (atom_list2)
    2845          772 :       NULLIFY (atomic_kind_set)
    2846          772 :       NULLIFY (qs_kind_set)
    2847          772 :       NULLIFY (dft_control)
    2848          772 :       NULLIFY (energy)
    2849          772 :       NULLIFY (force)
    2850          772 :       NULLIFY (first_sgf)
    2851          772 :       NULLIFY (matrix_p)
    2852          772 :       NULLIFY (matrix_s)
    2853          772 :       NULLIFY (matrix_vhxc)
    2854          772 :       NULLIFY (l)
    2855          772 :       NULLIFY (last_sgf)
    2856          772 :       NULLIFY (nshell)
    2857          772 :       NULLIFY (orb_basis_set)
    2858          772 :       NULLIFY (orbitals)
    2859          772 :       NULLIFY (ao_coef)
    2860          772 :       NULLIFY (particle_set)
    2861          772 :       NULLIFY (q_a_block)
    2862          772 :       NULLIFY (q_b_block)
    2863          772 :       NULLIFY (vhxc_block)
    2864          772 :       NULLIFY (rho)
    2865          772 :       NULLIFY (scf_env)
    2866          772 :       NULLIFY (sm_h)
    2867          772 :       NULLIFY (sm_p)
    2868          772 :       NULLIFY (sm_q_a)
    2869          772 :       NULLIFY (sm_q_b)
    2870          772 :       NULLIFY (sm_s)
    2871          772 :       NULLIFY (sm_v)
    2872          772 :       NULLIFY (sm_a)
    2873          772 :       NULLIFY (sm_b)
    2874          772 :       NULLIFY (sm_c)
    2875          772 :       NULLIFY (sm_d)
    2876          772 :       NULLIFY (sm_e)
    2877          772 :       NULLIFY (sm_f)
    2878          772 :       NULLIFY (sm_i)
    2879          772 :       NULLIFY (sm_j)
    2880          772 :       NULLIFY (sm_k)
    2881          772 :       NULLIFY (sm_mid)
    2882          772 :       NULLIFY (sm_vhxc)
    2883          772 :       NULLIFY (v_block)
    2884          772 :       NULLIFY (a_block)
    2885          772 :       NULLIFY (d_block)
    2886          772 :       NULLIFY (e_block)
    2887          772 :       NULLIFY (f_block)
    2888          772 :       NULLIFY (i_block)
    2889          772 :       NULLIFY (j_block)
    2890          772 :       NULLIFY (para_env)
    2891          772 :       NULLIFY (s_block)
    2892          772 :       NULLIFY (tmp_block)
    2893              : 
    2894              :       CALL get_qs_env(qs_env=qs_env, &
    2895              :                       atomic_kind_set=atomic_kind_set, &
    2896              :                       qs_kind_set=qs_kind_set, &
    2897              :                       dft_control=dft_control, &
    2898              :                       energy=energy, &
    2899              :                       matrix_s=matrix_s, &
    2900              :                       matrix_vhxc=matrix_vhxc, &
    2901              :                       matrix_s_kp=matrixkp_s, &
    2902              :                       particle_set=particle_set, &
    2903              :                       rho=rho, &
    2904              :                       scf_env=scf_env, &
    2905          772 :                       para_env=para_env)
    2906              : 
    2907          772 :       CPASSERT(ASSOCIATED(atomic_kind_set))
    2908          772 :       CPASSERT(ASSOCIATED(dft_control))
    2909          772 :       CPASSERT(ASSOCIATED(energy))
    2910          772 :       CPASSERT(ASSOCIATED(matrix_s))
    2911          772 :       CPASSERT(ASSOCIATED(particle_set))
    2912          772 :       CPASSERT(ASSOCIATED(rho))
    2913              : 
    2914          772 :       sm_s => matrix_s(1)%matrix
    2915          772 :       CALL qs_rho_get(rho, rho_ao=matrix_p)
    2916              : 
    2917          772 :       energy%dft_plus_u = 0.0_dp
    2918              : 
    2919          772 :       nspin = dft_control%nspins
    2920          772 :       IF (dft_control%mtlr_dft_with_perturbation) THEN
    2921          396 :          IF (.NOT. ASSOCIATED(matrix_vhxc)) THEN
    2922            0 :             CPABORT("MTLR requires the projected Hxc matrix for every spin channel.")
    2923              :          END IF
    2924          396 :          IF (SIZE(matrix_vhxc) /= nspin) THEN
    2925            0 :             CPABORT("The number of projected Hxc matrices does not match the spin channels.")
    2926              :          END IF
    2927              :       END IF
    2928              : 
    2929          772 :       IF (nspin == 2) THEN
    2930              :          fspin = 1.0_dp
    2931              :       ELSE
    2932            0 :          fspin = 0.5_dp
    2933              :       END IF
    2934              : 
    2935              :       ! Get the total number of atoms, contracted spherical Gaussian basis
    2936              :       ! functions, and atomic kinds
    2937              : 
    2938          772 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, natom=natom)
    2939          772 :       CALL get_qs_kind_set(qs_kind_set, nsgf=nsgf)
    2940              : 
    2941          772 :       nkind = SIZE(atomic_kind_set)
    2942              : 
    2943         2316 :       ALLOCATE (first_sgf_atom(natom))
    2944          772 :       first_sgf_atom(:) = 0
    2945              : 
    2946          772 :       CALL get_particle_set(particle_set, qs_kind_set, first_sgf=first_sgf_atom)
    2947              : 
    2948          772 :       IF (PRESENT(matrix_h) .OR. PRESENT(matrix_w)) THEN
    2949              :          just_energy = .FALSE.
    2950              :       ELSE
    2951          116 :          just_energy = .TRUE.
    2952              :       END IF
    2953              : 
    2954          772 :       CALL dbcsr_init_p(sm_mid)
    2955          772 :       CALL dbcsr_create(sm_mid, template=sm_s, matrix_type="N")
    2956              : 
    2957              :       ! Create local block diagonal matrices
    2958              : 
    2959          772 :       ALLOCATE (sm_q_a)
    2960          772 :       CALL dbcsr_get_block_diag(sm_s, sm_q_a)
    2961              : 
    2962          772 :       ALLOCATE (sm_q_b)
    2963          772 :       CALL dbcsr_get_block_diag(sm_s, sm_q_b)
    2964              : 
    2965          772 :       CALL dbcsr_set(sm_q_a, 0.0_dp)
    2966          772 :       CALL dbcsr_set(sm_q_b, 0.0_dp)
    2967              : 
    2968              :       ! Loop over all spins for calculating sm_q_a and sm_q_b
    2969              : 
    2970         2316 :       DO ispin = 1, nspin
    2971              : 
    2972         1544 :          sm_p => matrix_p(ispin)%matrix
    2973              : 
    2974         2316 :          IF (nspin == 2) THEN
    2975         1544 :             IF (ispin == 1) THEN
    2976          772 :                CALL dbcsr_multiply("N", "N", 1.0_dp, sm_s, sm_p, 0.0_dp, sm_mid)
    2977          772 :                CALL dbcsr_multiply("N", "N", 1.0_dp, sm_mid, sm_s, 0.0_dp, sm_q_a)
    2978              :             ELSE
    2979          772 :                CALL dbcsr_multiply("N", "N", 1.0_dp, sm_s, sm_p, 0.0_dp, sm_mid)
    2980          772 :                CALL dbcsr_multiply("N", "N", 1.0_dp, sm_mid, sm_s, 0.0_dp, sm_q_b)
    2981              :             END IF
    2982              :          ELSE
    2983            0 :             CALL dbcsr_multiply("N", "N", 1.0_dp, sm_s, sm_p, 0.0_dp, sm_mid)
    2984            0 :             CALL dbcsr_multiply("N", "N", 1.0_dp, sm_mid, sm_s, 0.0_dp, sm_q_a)
    2985            0 :             CALL dbcsr_copy(sm_q_b, sm_q_a)
    2986              :          END IF
    2987              : 
    2988              :       END DO
    2989              : 
    2990          772 :       ALLOCATE (sm_v)
    2991          772 :       CALL dbcsr_get_block_diag(sm_s, sm_v)
    2992              : 
    2993          772 :       IF (PRESENT(matrix_w)) THEN
    2994              : 
    2995            2 :          CALL dbcsr_init_p(sm_b)
    2996            2 :          CALL dbcsr_create(sm_b, template=matrix_s(1)%matrix, matrix_type="N")
    2997              : 
    2998            2 :          CALL dbcsr_init_p(sm_d)
    2999            2 :          CALL dbcsr_create(sm_d, template=matrix_s(1)%matrix, matrix_type="N")
    3000              : 
    3001            2 :          CALL dbcsr_init_p(sm_c)
    3002            2 :          CALL dbcsr_create(sm_c, template=matrix_s(1)%matrix, matrix_type="N")
    3003              : 
    3004            2 :          CALL dbcsr_init_p(sm_e)
    3005            2 :          CALL dbcsr_create(sm_e, template=matrix_s(1)%matrix, matrix_type="N")
    3006              : 
    3007            2 :          CALL dbcsr_init_p(sm_f)
    3008            2 :          CALL dbcsr_create(sm_f, template=matrix_s(1)%matrix, matrix_type="N")
    3009              : 
    3010            2 :          CALL dbcsr_init_p(sm_i)
    3011            2 :          CALL dbcsr_create(sm_i, template=matrix_s(1)%matrix, matrix_type="N")
    3012              : 
    3013            2 :          CALL dbcsr_init_p(sm_j)
    3014            2 :          CALL dbcsr_create(sm_j, template=matrix_s(1)%matrix, matrix_type="N")
    3015              : 
    3016            2 :          CALL dbcsr_init_p(sm_k)
    3017            2 :          CALL dbcsr_create(sm_k, template=matrix_s(1)%matrix, matrix_type="N")
    3018              : 
    3019              :       END IF
    3020              : 
    3021          772 :       ALLOCATE (sm_a)
    3022          772 :       CALL dbcsr_get_block_diag(sm_s, sm_a)
    3023              : 
    3024              :       ! Loop over all spins
    3025              : 
    3026         2316 :       DO ispin = 1, nspin
    3027              : 
    3028         1544 :          IF (PRESENT(matrix_h)) THEN
    3029         1308 :             sm_h => matrix_h(ispin, 1)%matrix
    3030              :          ELSE
    3031              :             NULLIFY (sm_h)
    3032              :          END IF
    3033              : 
    3034              :          IF (PRESENT(matrix_w)) THEN
    3035         1544 :             sm_w => matrix_w(ispin, 1)%matrix
    3036              :          ELSE
    3037         1544 :             NULLIFY (sm_w)
    3038              :          END IF
    3039              : 
    3040         1544 :          CALL dbcsr_set(sm_v, 0.0_dp)
    3041         1544 :          CALL dbcsr_set(sm_a, 0.0_dp)
    3042              : 
    3043         1544 :          IF (dft_control%mtlr_dft_with_perturbation) THEN
    3044          792 :             IF (ispin == 1) perturbation_strength = 0.9_dp*dft_control%perturbation_strength
    3045          792 :             IF (ispin == 2) perturbation_strength = 1.1_dp*dft_control%perturbation_strength
    3046          792 :             IF (.NOT. ASSOCIATED(matrix_vhxc(ispin)%matrix)) THEN
    3047            0 :                CPABORT("MTLR projected Hxc matrix is not initialized.")
    3048              :             END IF
    3049          792 :             sm_vhxc => matrix_vhxc(ispin)%matrix
    3050              :          END IF
    3051              : 
    3052              :          ! Loop over all atomic kinds
    3053              : 
    3054         3568 :          DO ikind = 1, nkind
    3055              : 
    3056              :             CALL get_atomic_kind(atomic_kind_set(ikind), &
    3057              :                                  atom_list=atom_list, &
    3058              :                                  name=atomic_kind_name, &
    3059         2024 :                                  natom=natom_of_kind)
    3060              : 
    3061              :             CALL get_qs_kind(qs_kind_set(ikind), &
    3062              :                              dft_plus_u_atom=dft_plus_u_atom, &
    3063              :                              l_of_dft_plus_u=lu, &
    3064              :                              nsgf=nsgf_kind, &
    3065              :                              basis_set=orb_basis_set, &
    3066              :                              u_minus_j=u_minus_j, &
    3067              :                              hund_j=hund_j, &
    3068              :                              ao_coef=ao_coef, &
    3069              :                              u_minus_j_target=u_minus_j_target, &
    3070              :                              u_ramping=u_ramping, &
    3071              :                              eps_u_ramping=eps_u_ramping, &
    3072              :                              orbitals=orbitals, &
    3073              :                              eps_scf=eps_scf, &
    3074              :                              max_scf=max_scf, &
    3075         2024 :                              smear=smear)
    3076              : 
    3077         2024 :             IF (.NOT. ASSOCIATED(orb_basis_set)) CYCLE
    3078         2024 :             IF (.NOT. dft_plus_u_atom) CYCLE
    3079         1544 :             IF (lu < 0) CYCLE
    3080         1544 :             IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) CYCLE
    3081         1544 :             IF (.NOT. ASSOCIATED(ao_coef)) THEN
    3082            0 :                CPABORT("Tensorial DFT+U requires associated ao_coef")
    3083              :             END IF
    3084              : 
    3085         4632 :             ALLOCATE (a(SIZE(ao_coef)))
    3086         4632 :             a(:) = ao_coef(:)
    3087              : 
    3088              :             ! Apply U ramping if requested
    3089              : 
    3090         1544 :             IF ((ispin == 1) .AND. (u_ramping > 0.0_dp)) THEN
    3091            0 :                IF (qs_env%scf_env%iter_delta <= eps_u_ramping) THEN
    3092            0 :                   u_minus_j = MIN(u_minus_j + u_ramping, u_minus_j_target)
    3093            0 :                   CALL set_qs_kind(qs_kind_set(ikind), u_minus_j=u_minus_j)
    3094              :                END IF
    3095              : 
    3096            0 :                IF (should_output .AND. (output_unit > 0)) THEN
    3097              :                   WRITE (UNIT=output_unit, FMT="(T3,A,3X,A,F0.3,A)") &
    3098            0 :                      "Kind name: "//TRIM(ADJUSTL(atomic_kind_name)), &
    3099            0 :                      "U(eff) = ", u_minus_j*evolt, " eV"
    3100              :                END IF
    3101              :             END IF
    3102              : 
    3103              :             CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    3104              :                                    first_sgf=first_sgf, &
    3105              :                                    l=l, &
    3106              :                                    last_sgf=last_sgf, &
    3107              :                                    nset=nset, &
    3108         1544 :                                    nshell=nshell)
    3109              : 
    3110         1544 :             nsb = 1
    3111         1544 :             nsbsize = (2*lu + 1)
    3112         1544 :             n = nsb*nsbsize
    3113              : 
    3114         6176 :             ALLOCATE (q_a_matrix(n, n))
    3115         4632 :             ALLOCATE (q_b_matrix(n, n))
    3116         4632 :             ALLOCATE (s_matrix(n, n))
    3117         4632 :             ALLOCATE (s_inv_matrix(n, n))
    3118         4632 :             ALLOCATE (v_matrix(n, n))
    3119              : 
    3120         1544 :             q_a_matrix(:, :) = 0.0_dp
    3121         1544 :             q_b_matrix(:, :) = 0.0_dp
    3122         1544 :             s_matrix(:, :) = 0.0_dp
    3123         1544 :             s_inv_matrix(:, :) = 0.0_dp
    3124         1544 :             v_matrix(:, :) = 0.0_dp
    3125              : 
    3126              :             ! Print headline if requested
    3127              : 
    3128         1544 :             IF (should_output .AND. (print_level > low_print_level)) THEN
    3129            0 :                IF (output_unit > 0) THEN
    3130            0 :                   ALLOCATE (symbol(nsbsize))
    3131            0 :                   DO m = -lu, lu
    3132            0 :                      symbol(lu + m + 1) = sgf_symbol(0, lu, m)
    3133              :                   END DO
    3134              : 
    3135            0 :                   IF (nspin > 1) THEN
    3136            0 :                      WRITE (UNIT=spin_info, FMT="(A8,I2)") " of spin", ispin
    3137              :                   ELSE
    3138            0 :                      spin_info = ""
    3139              :                   END IF
    3140              : 
    3141              :                   WRITE (UNIT=output_unit, FMT="(/,T3,A,I0,A,/,/,T5,A,10(2X,A6))") &
    3142            0 :                      "DFT+U occupations"//TRIM(spin_info)//" for the atoms of atomic kind ", ikind, &
    3143            0 :                      ": "//TRIM(atomic_kind_name), &
    3144            0 :                      "Atom   Shell  ", (ADJUSTR(symbol(i)), i=1, nsbsize), " Trace"
    3145              : 
    3146            0 :                   DEALLOCATE (symbol)
    3147              :                END IF
    3148              :             END IF
    3149              : 
    3150         1544 :             IF (dft_control%mtlr_dft_with_perturbation .AND. &
    3151              :                 dft_control%mtlr_ikind == ikind) THEN
    3152          792 :                dft_control%vhxc(ispin) = 0.0_dp
    3153          792 :                dft_control%trq(ispin) = 0.0_dp
    3154         2376 :                ALLOCATE (vhxc_matrix(n, n))
    3155          792 :                vhxc_matrix(:, :) = 0.0_dp
    3156              :             END IF
    3157              : 
    3158              :             ! Loop over all atoms of the current atomic kind
    3159              : 
    3160         4152 :             DO iatom = 1, natom_of_kind
    3161              : 
    3162         2608 :                atom_a = atom_list(iatom)
    3163              : 
    3164         2608 :                q_a_matrix(:, :) = 0.0_dp
    3165         2608 :                q_b_matrix(:, :) = 0.0_dp
    3166         2608 :                s_matrix(:, :) = 0.0_dp
    3167         2608 :                s_inv_matrix(:, :) = 0.0_dp
    3168         2608 :                v_matrix(:, :) = 0.0_dp
    3169              : 
    3170              :                CALL dbcsr_get_block_p(matrix=sm_q_a, &
    3171              :                                       row=atom_a, &
    3172              :                                       col=atom_a, &
    3173              :                                       block=q_a_block, &
    3174         2608 :                                       found=found)
    3175              : 
    3176              :                CALL dbcsr_get_block_p(matrix=sm_q_b, &
    3177              :                                       row=atom_a, &
    3178              :                                       col=atom_a, &
    3179              :                                       block=q_b_block, &
    3180         2608 :                                       found=found)
    3181              : 
    3182              :                CALL dbcsr_get_block_p(matrix=sm_s, &
    3183              :                                       row=atom_a, &
    3184              :                                       col=atom_a, &
    3185              :                                       block=s_block, &
    3186         2608 :                                       found=found)
    3187              : 
    3188              :                IF (dft_control%mtlr_dft_with_perturbation .AND. &
    3189         2608 :                    dft_control%mtlr_ikind == ikind .AND. &
    3190              :                    qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a) THEN
    3191              :                   CALL dbcsr_get_block_p(matrix=sm_vhxc, &
    3192              :                                          row=atom_a, &
    3193              :                                          col=atom_a, &
    3194              :                                          block=vhxc_block, &
    3195          792 :                                          found=found)
    3196              :                END IF
    3197              : 
    3198         2608 :                IF (ASSOCIATED(q_a_block) .AND. ASSOCIATED(q_b_block) .AND. ASSOCIATED(s_block)) THEN
    3199              : 
    3200         1304 :                   isb = 0
    3201         2848 :                   DO iset = 1, nset
    3202         6176 :                      DO ishell = 1, nshell(iset)
    3203         3328 :                         IF (l(ishell, iset) /= lu) CYCLE
    3204         2608 :                         isb = isb + 1
    3205         2608 :                         i = 0
    3206         7720 :                         DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
    3207         3568 :                            i = i + 1
    3208         3568 :                            jsb = 0
    3209        11904 :                            DO jset = 1, nset
    3210        20032 :                               DO jshell = 1, nshell(jset)
    3211        11456 :                                  IF (l(jshell, jset) /= lu) CYCLE
    3212         7136 :                                  jsb = jsb + 1
    3213         7136 :                                  j = 0
    3214        25040 :                                  DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
    3215        12896 :                                     j = j + 1
    3216        12896 :                                     q_a_matrix(i, j) = q_a_matrix(i, j) + q_a_block(isgf, jsgf)*a(isb)*a(jsb)
    3217        12896 :                                     q_b_matrix(i, j) = q_b_matrix(i, j) + q_b_block(isgf, jsgf)*a(isb)*a(jsb)
    3218        12896 :                                     s_matrix(i, j) = s_matrix(i, j) + s_block(isgf, jsgf)*a(isb)*a(jsb)
    3219              :                                     IF (ASSOCIATED(vhxc_block) .AND. &
    3220              :                                         dft_control%mtlr_dft_with_perturbation .AND. &
    3221        12896 :                                         dft_control%mtlr_ikind == ikind .AND. &
    3222        11456 :                                         qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a) THEN
    3223         1584 :                                        vhxc_matrix(i, j) = vhxc_matrix(i, j) + vhxc_block(isgf, jsgf)*a(isb)*a(jsb)
    3224              :                                     END IF
    3225              :                                  END DO
    3226              :                               END DO
    3227              :                            END DO
    3228              :                         END DO
    3229              :                      END DO
    3230              :                   END DO
    3231              : 
    3232         1304 :                   CALL invert_matrix(s_matrix, s_inv_matrix, some_real)
    3233              : 
    3234        59192 :                   q_a_matrix(:, :) = MATMUL(q_a_matrix, s_inv_matrix)
    3235        59192 :                   q_b_matrix(:, :) = MATMUL(q_b_matrix, s_inv_matrix)
    3236              : 
    3237              :                   IF (ASSOCIATED(vhxc_block) .AND. &
    3238              :                       dft_control%mtlr_dft_with_perturbation .AND. &
    3239         1304 :                       dft_control%mtlr_ikind == ikind .AND. &
    3240              :                       qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a) THEN
    3241         5148 :                      vhxc_matrix(:, :) = MATMUL(vhxc_matrix, s_inv_matrix)
    3242          792 :                      DO i = 1, n
    3243          396 :                         dft_control%vhxc(ispin) = dft_control%vhxc(ispin) + vhxc_matrix(i, i)
    3244          396 :                         IF (ispin == 1) dft_control%trq(1) = dft_control%trq(1) + q_a_matrix(i, i)
    3245          792 :                         IF (ispin == 2) dft_control%trq(2) = dft_control%trq(2) + q_b_matrix(i, i)
    3246              :                      END DO
    3247              :                   END IF
    3248              : 
    3249              :                   ! Perform the requested manipulations of the (initial) orbital occupations
    3250              : 
    3251         1304 :                   IF (ASSOCIATED(orbitals)) THEN
    3252            0 :                      IF ((qs_env%scf_env%iter_delta >= eps_scf) .OR. &
    3253              :                          ((qs_env%scf_env%outer_scf%iter_count == 0) .AND. &
    3254              :                           (qs_env%scf_env%iter_count <= max_scf))) THEN
    3255              : 
    3256            0 :                         ALLOCATE (orb_occ(nsbsize))
    3257            0 :                         ALLOCATE (q_eigval(n))
    3258            0 :                         ALLOCATE (q_eigvec(n, n))
    3259              : 
    3260            0 :                         q_eigval(:) = 0.0_dp
    3261            0 :                         q_eigvec(:, :) = 0.0_dp
    3262            0 :                         norb = SIZE(orbitals)
    3263              : 
    3264            0 :                         IF (ispin == 1) THEN
    3265            0 :                            CALL jacobi(q_a_matrix, q_eigval, q_eigvec)
    3266            0 :                            q_a_matrix(:, :) = 0.0_dp
    3267              :                         ELSE
    3268            0 :                            CALL jacobi(q_b_matrix, q_eigval, q_eigvec)
    3269            0 :                            q_b_matrix(:, :) = 0.0_dp
    3270              :                         END IF
    3271              : 
    3272            0 :                         DO isb = 1, nsb
    3273            0 :                            trq = 0.0_dp
    3274            0 :                            DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
    3275            0 :                               trq = trq + q_eigval(i)
    3276              :                            END DO
    3277              : 
    3278            0 :                            IF (smear) THEN
    3279            0 :                               occ = trq/REAL(norb, KIND=dp)
    3280              :                            ELSE
    3281            0 :                               occ = 1.0_dp/fspin
    3282              :                            END IF
    3283              : 
    3284            0 :                            orb_occ(:) = .FALSE.
    3285            0 :                            iloc = MAXLOC(q_eigvec(:, isb*nsbsize))
    3286            0 :                            jsb = INT((iloc(1) - 1)/nsbsize) + 1
    3287            0 :                            i = 0
    3288            0 :                            i0 = (jsb - 1)*nsbsize + 1
    3289            0 :                            iorb = -1000
    3290              : 
    3291            0 :                            DO j = i0, jsb*nsbsize
    3292            0 :                               i = i + 1
    3293            0 :                               IF (i > norb) THEN
    3294            0 :                                  DO m = -lu, lu
    3295            0 :                                     IF (.NOT. orb_occ(lu + m + 1)) THEN
    3296            0 :                                        iorb = i0 + lu + m
    3297            0 :                                        orb_occ(lu + m + 1) = .TRUE.
    3298              :                                     END IF
    3299              :                                  END DO
    3300              :                               ELSE
    3301            0 :                                  iorb = i0 + lu + orbitals(i)
    3302            0 :                                  orb_occ(lu + orbitals(i) + 1) = .TRUE.
    3303              :                               END IF
    3304              : 
    3305            0 :                               CPASSERT(iorb /= -1000)
    3306              : 
    3307            0 :                               iloc = MAXLOC(q_eigvec(iorb, :))
    3308            0 :                               q_eigval(iloc(1)) = MIN(occ, trq)
    3309              : 
    3310            0 :                               IF (ispin == 1) THEN
    3311            0 :                                  q_a_matrix(:, iloc(1)) = q_eigval(iloc(1))*q_eigvec(:, iloc(1))
    3312              :                               ELSE
    3313            0 :                                  q_b_matrix(:, iloc(1)) = q_eigval(iloc(1))*q_eigvec(:, iloc(1))
    3314              :                               END IF
    3315              : 
    3316            0 :                               trq = trq - q_eigval(iloc(1))
    3317              :                            END DO
    3318              :                         END DO
    3319              : 
    3320            0 :                         IF (ispin == 1) THEN
    3321            0 :                            q_a_matrix(:, :) = MATMUL(q_a_matrix, TRANSPOSE(q_eigvec))
    3322              :                         ELSE
    3323            0 :                            q_b_matrix(:, :) = MATMUL(q_b_matrix, TRANSPOSE(q_eigvec))
    3324              :                         END IF
    3325              : 
    3326            0 :                         DEALLOCATE (orb_occ)
    3327            0 :                         DEALLOCATE (q_eigval)
    3328            0 :                         DEALLOCATE (q_eigvec)
    3329              :                      END IF
    3330              :                   END IF
    3331              : 
    3332         1304 :                   trq = 0.0_dp
    3333         1304 :                   trq2 = 0.0_dp
    3334         1304 :                   trqxq_hund_j = 0.0_dp
    3335              : 
    3336         1304 :                   IF (ispin == 1) THEN
    3337         1544 :                      DO i = 1, n
    3338          892 :                         trq = trq + q_a_matrix(i, i)
    3339         3156 :                         DO j = 1, n
    3340         1612 :                            trq2 = trq2 + q_a_matrix(i, j)*q_a_matrix(j, i)
    3341         1612 :                            trqxq_hund_j = trqxq_hund_j + q_a_matrix(i, j)*q_b_matrix(j, i)
    3342              : 
    3343         2504 :                            IF (i == j) THEN
    3344          892 :                               v_matrix(i, i) = u_minus_j*(0.5_dp - fspin*q_a_matrix(i, i))
    3345          892 :                               v_matrix(i, i) = v_matrix(i, i) + hund_j*fspin*q_b_matrix(i, i)
    3346              :                               IF (dft_control%mtlr_dft_with_perturbation .AND. &
    3347          892 :                                   dft_control%mtlr_ikind == ikind .AND. &
    3348              :                                   qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a) THEN
    3349          198 :                                  v_matrix(i, i) = v_matrix(i, i) + perturbation_strength
    3350              :                               END IF
    3351              :                            ELSE
    3352          720 :                               v_matrix(i, j) = -u_minus_j*fspin*q_a_matrix(j, i)
    3353          720 :                               v_matrix(i, j) = v_matrix(i, j) + hund_j*fspin*q_b_matrix(j, i)
    3354              :                            END IF
    3355              :                         END DO
    3356              :                      END DO
    3357              :                   ELSE
    3358         1544 :                      DO i = 1, n
    3359          892 :                         trq = trq + q_b_matrix(i, i)
    3360         3156 :                         DO j = 1, n
    3361         1612 :                            trq2 = trq2 + q_b_matrix(i, j)*q_b_matrix(j, i)
    3362         1612 :                            trqxq_hund_j = trqxq_hund_j + q_b_matrix(i, j)*q_a_matrix(j, i)
    3363              : 
    3364         2504 :                            IF (i == j) THEN
    3365          892 :                               v_matrix(i, i) = u_minus_j*(0.5_dp - fspin*q_b_matrix(i, i))
    3366          892 :                               v_matrix(i, i) = v_matrix(i, i) + hund_j*fspin*q_a_matrix(i, i)
    3367              :                               IF (dft_control%mtlr_dft_with_perturbation .AND. &
    3368          892 :                                   dft_control%mtlr_ikind == ikind .AND. &
    3369              :                                   qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a) THEN
    3370          198 :                                  v_matrix(i, i) = v_matrix(i, i) + perturbation_strength
    3371              :                               END IF
    3372              :                            ELSE
    3373          720 :                               v_matrix(i, j) = -u_minus_j*fspin*q_b_matrix(j, i)
    3374          720 :                               v_matrix(i, j) = v_matrix(i, j) + hund_j*fspin*q_a_matrix(j, i)
    3375              :                            END IF
    3376              :                         END DO
    3377              :                      END DO
    3378              :                   END IF
    3379              : 
    3380        41496 :                   v_matrix(:, :) = MATMUL(s_inv_matrix, v_matrix)
    3381              : 
    3382         1304 :                   trq = fspin*trq
    3383         1304 :                   trq2 = fspin*fspin*trq2
    3384         1304 :                   trqxq_hund_j = fspin*fspin*trqxq_hund_j
    3385              : 
    3386         1304 :                   energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*u_minus_j*(trq - trq2)/fspin
    3387         1304 :                   energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*hund_j*trqxq_hund_j/fspin
    3388              : 
    3389              :                   ! Calculate potential V(U) = dE(U)/dq
    3390              : 
    3391         2608 :                   IF (.NOT. just_energy) THEN
    3392              : 
    3393              :                      CALL dbcsr_get_block_p(matrix=sm_v, &
    3394              :                                             row=atom_a, &
    3395              :                                             col=atom_a, &
    3396              :                                             block=v_block, &
    3397         1188 :                                             found=found)
    3398         1188 :                      CPASSERT(ASSOCIATED(v_block))
    3399              : 
    3400              :                      CALL dbcsr_get_block_p(matrix=sm_a, &
    3401              :                                             row=atom_a, &
    3402              :                                             col=atom_a, &
    3403              :                                             block=a_block, &
    3404         1188 :                                             found=found)
    3405         1188 :                      CPASSERT(ASSOCIATED(a_block))
    3406              : 
    3407         1188 :                      isb = 0
    3408         2500 :                      DO iset = 1, nset
    3409         5248 :                         DO ishell = 1, nshell(iset)
    3410         2748 :                            IF (l(ishell, iset) /= lu) CYCLE
    3411         2376 :                            isb = isb + 1
    3412         2376 :                            i = 0
    3413         6560 :                            DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
    3414         2872 :                               i = i + 1
    3415         2872 :                               jsb = 0
    3416         9236 :                               DO jset = 1, nset
    3417        14464 :                                  DO jshell = 1, nshell(jset)
    3418         7976 :                                     IF (l(jshell, jset) /= lu) CYCLE
    3419         5744 :                                     jsb = jsb + 1
    3420         5744 :                                     j = 0
    3421        18080 :                                     DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
    3422         8720 :                                        j = j + 1
    3423         8720 :                                        v_block(isgf, jsgf) = v_matrix(i, j)*a(isb)*a(jsb)
    3424        16696 :                                        a_block(isgf, jsgf) = s_inv_matrix(i, j)*a(isb)*a(jsb)
    3425              :                                     END DO
    3426              :                                  END DO
    3427              :                               END DO
    3428              :                            END DO
    3429              :                         END DO
    3430              :                      END DO
    3431              : 
    3432              :                   END IF
    3433              : 
    3434              :                END IF
    3435              : 
    3436              :                ! Consider print requests
    3437              : 
    3438         6760 :                IF (should_output .AND. (print_level > low_print_level)) THEN
    3439            0 :                   IF (ispin == 1) THEN
    3440            0 :                      CALL para_env%sum(q_a_matrix)
    3441              :                   ELSE
    3442            0 :                      CALL para_env%sum(q_b_matrix)
    3443              :                   END IF
    3444              : 
    3445            0 :                   IF (output_unit > 0) THEN
    3446            0 :                      ALLOCATE (q_work(nsb, nsbsize))
    3447            0 :                      q_work(:, :) = 0.0_dp
    3448              : 
    3449            0 :                      DO isb = 1, nsb
    3450            0 :                         j = 0
    3451            0 :                         DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
    3452            0 :                            j = j + 1
    3453            0 :                            IF (ispin == 1) THEN
    3454            0 :                               q_work(isb, j) = q_a_matrix(i, i)
    3455              :                            ELSE
    3456            0 :                               q_work(isb, j) = q_b_matrix(i, i)
    3457              :                            END IF
    3458              :                         END DO
    3459              :                      END DO
    3460              : 
    3461            0 :                      DO isb = 1, nsb
    3462              :                         WRITE (UNIT=output_unit, FMT="(T3,I6,2X,I6,2X,10F8.3)") &
    3463            0 :                            atom_a, isb, q_work(isb, :), SUM(q_work(isb, :))
    3464              :                      END DO
    3465              : 
    3466              :                      WRITE (UNIT=output_unit, FMT="(T12,A,2X,10F8.3)") &
    3467            0 :                         "Total", (SUM(q_work(:, i)), i=1, nsbsize), SUM(q_work)
    3468            0 :                      WRITE (UNIT=output_unit, FMT="(A)") ""
    3469              : 
    3470            0 :                      DEALLOCATE (q_work)
    3471              : 
    3472              :                      IF (debug) THEN
    3473              :                         WRITE (UNIT=output_unit, FMT="(T9,70I10)") (i, i=1, n)
    3474              :                         DO i = 1, n
    3475              :                            IF (ispin == 1) THEN
    3476              :                               WRITE (UNIT=output_unit, FMT="(T3,I6,70F10.6)") i, q_a_matrix(i, :)
    3477              :                            ELSE
    3478              :                               WRITE (UNIT=output_unit, FMT="(T3,I6,70F10.6)") i, q_b_matrix(i, :)
    3479              :                            END IF
    3480              :                         END DO
    3481              : 
    3482              :                         ALLOCATE (q_eigval(n))
    3483              :                         ALLOCATE (q_eigvec(n, n))
    3484              :                         q_eigval(:) = 0.0_dp
    3485              :                         q_eigvec(:, :) = 0.0_dp
    3486              : 
    3487              :                         IF (ispin == 1) THEN
    3488              :                            CALL jacobi(q_a_matrix, q_eigval, q_eigvec)
    3489              :                         ELSE
    3490              :                            CALL jacobi(q_b_matrix, q_eigval, q_eigvec)
    3491              :                         END IF
    3492              : 
    3493              :                         WRITE (UNIT=output_unit, FMT="(/,T9,70I10)") (i, i=1, n)
    3494              :                         WRITE (UNIT=output_unit, FMT="(T9,71F10.6)") (q_eigval(i), i=1, n), SUM(q_eigval(1:n))
    3495              : 
    3496              :                         DO i = 1, n
    3497              :                            WRITE (UNIT=output_unit, FMT="(T3,I6,70F10.6)") i, q_eigvec(i, :)
    3498              :                         END DO
    3499              : 
    3500              :                         DEALLOCATE (q_eigval)
    3501              :                         DEALLOCATE (q_eigvec)
    3502              :                      END IF
    3503              :                   END IF
    3504              : 
    3505              :                   IF (debug) THEN
    3506              :                      ALLOCATE (q_work(nsgf_kind, nsgf_kind))
    3507              :                      q_work(:, :) = 0.0_dp
    3508              : 
    3509              :                      IF (ispin == 1) THEN
    3510              :                         IF (ASSOCIATED(q_a_block)) q_work(:, :) = q_a_block(:, :)
    3511              :                      ELSE
    3512              :                         IF (ASSOCIATED(q_b_block)) q_work(:, :) = q_b_block(:, :)
    3513              :                      END IF
    3514              : 
    3515              :                      CALL para_env%sum(q_work)
    3516              : 
    3517              :                      IF (output_unit > 0) THEN
    3518              :                         norb = SIZE(q_work, 1)
    3519              : 
    3520              :                         WRITE (UNIT=output_unit, FMT="(/,T9,200I10)") (i, i=1, norb)
    3521              :                         DO i = 1, norb
    3522              :                            WRITE (UNIT=output_unit, FMT="(T3,I6,200F10.6)") i, q_work(i, :)
    3523              :                         END DO
    3524              : 
    3525              :                         ALLOCATE (q_eigval(norb))
    3526              :                         ALLOCATE (q_eigvec(norb, norb))
    3527              :                         q_eigval(:) = 0.0_dp
    3528              :                         q_eigvec(:, :) = 0.0_dp
    3529              : 
    3530              :                         CALL jacobi(q_work, q_eigval, q_eigvec)
    3531              : 
    3532              :                         WRITE (UNIT=output_unit, FMT="(/,T9,200I10)") (i, i=1, norb)
    3533              :                         WRITE (UNIT=output_unit, FMT="(T9,201F10.6)") (q_eigval(i), i=1, norb), SUM(q_eigval(1:norb))
    3534              : 
    3535              :                         DO i = 1, norb
    3536              :                            WRITE (UNIT=output_unit, FMT="(T3,I6,200F10.6)") i, q_eigvec(i, :)
    3537              :                         END DO
    3538              : 
    3539              :                         DEALLOCATE (q_eigval)
    3540              :                         DEALLOCATE (q_eigvec)
    3541              :                      END IF
    3542              : 
    3543              :                      DEALLOCATE (q_work)
    3544              :                   END IF
    3545              :                END IF
    3546              : 
    3547              :             END DO
    3548              : 
    3549         1544 :             IF (ALLOCATED(q_a_matrix)) DEALLOCATE (q_a_matrix)
    3550         1544 :             IF (ALLOCATED(q_b_matrix)) DEALLOCATE (q_b_matrix)
    3551         1544 :             IF (ALLOCATED(s_matrix)) DEALLOCATE (s_matrix)
    3552         1544 :             IF (ALLOCATED(s_inv_matrix)) DEALLOCATE (s_inv_matrix)
    3553         1544 :             IF (ALLOCATED(v_matrix)) DEALLOCATE (v_matrix)
    3554              : 
    3555         1544 :             DEALLOCATE (a)
    3556              : 
    3557         1544 :             IF (dft_control%mtlr_dft_with_perturbation .AND. &
    3558         5112 :                 dft_control%mtlr_ikind == ikind) THEN
    3559          792 :                dft_control%vhxc(ispin) = dft_control%vhxc(ispin)/REAL(n, dp)
    3560          792 :                CALL para_env%sum(dft_control%vhxc(ispin))
    3561          792 :                CALL para_env%sum(dft_control%trq(ispin))
    3562          792 :                DEALLOCATE (vhxc_matrix)
    3563              :             END IF
    3564              : 
    3565              :          END DO
    3566              : 
    3567              :          ! Add V(i,j)[U] to V(i,j)[DFT]
    3568              : 
    3569         2316 :          IF (ASSOCIATED(sm_h)) THEN
    3570         1308 :             CALL dbcsr_multiply("N", "N", 1.0_dp, sm_s, sm_v, 0.0_dp, sm_mid)
    3571         1308 :             CALL dbcsr_multiply("N", "N", 1.0_dp, sm_mid, sm_s, 1.0_dp, sm_h)
    3572              :          END IF
    3573              : 
    3574              :       END DO
    3575              : 
    3576          772 :       CALL dbcsr_deallocate_matrix(sm_mid)
    3577              : 
    3578          772 :       IF (PRESENT(matrix_w)) THEN
    3579              : 
    3580            2 :          CALL get_qs_env(qs_env=qs_env, force=force)
    3581            6 :          DO ikind = 1, nkind
    3582           30 :             force(ikind)%tensorial_u(:, :) = 0.0_dp
    3583              :          END DO
    3584            2 :          IF (nspin == 2) THEN
    3585            2 :             CALL dbcsr_multiply("N", "N", 1.0_dp, sm_s, matrix_p(1)%matrix, 0.0_dp, sm_b)
    3586            2 :             CALL dbcsr_multiply("N", "N", 1.0_dp, sm_s, matrix_p(2)%matrix, 0.0_dp, sm_c)
    3587              :          ELSE
    3588            0 :             CALL dbcsr_multiply("N", "N", 0.5_dp, sm_s, matrix_p(1)%matrix, 0.0_dp, sm_b)
    3589            0 :             CALL dbcsr_multiply("N", "N", 0.5_dp, sm_s, matrix_p(1)%matrix, 0.0_dp, sm_c)
    3590              :          END IF
    3591            2 :          CALL dbcsr_multiply("N", "N", 1.0_dp, sm_b, sm_s, 0.0_dp, sm_i)
    3592            2 :          CALL dbcsr_multiply("N", "N", 1.0_dp, sm_c, sm_s, 0.0_dp, sm_j)
    3593              : 
    3594            8 :          DO jj = 1, 3
    3595            6 :             CALL dbcsr_desymmetrize(matrixkp_s(jj + 1, 1)%matrix, sm_k)
    3596              : 
    3597            6 :             CALL dbcsr_set(sm_f, 0.0_dp)
    3598              : 
    3599            6 :             CALL dbcsr_iterator_start(iter, sm_k)
    3600           33 :             DO WHILE (dbcsr_iterator_blocks_left(iter))
    3601           27 :                NULLIFY (tmp_block)
    3602           27 :                CALL dbcsr_iterator_next_block(iter, jatom, katom, tmp_block)
    3603           27 :                IF (jatom == katom) CYCLE
    3604           27 :                CALL dbcsr_put_block(matrix=sm_f, row=jatom, col=katom, block=tmp_block)
    3605              :             END DO
    3606            6 :             CALL dbcsr_iterator_stop(iter)
    3607            6 :             CALL dbcsr_finalize(sm_f)
    3608              : 
    3609            6 :             CALL dbcsr_multiply("N", "N", 1.0_dp, sm_b, sm_f, 0.0_dp, sm_d)
    3610            6 :             CALL dbcsr_multiply("N", "N", 1.0_dp, sm_c, sm_f, 0.0_dp, sm_e)
    3611              : 
    3612           60 :             ALLOCATE (a_matrix(nkind, nkind))
    3613           54 :             ALLOCATE (d_matrix(nkind, nkind))
    3614           54 :             ALLOCATE (e_matrix(nkind, nkind))
    3615           54 :             ALLOCATE (i_matrix(nkind, nkind))
    3616           54 :             ALLOCATE (j_matrix(nkind, nkind))
    3617           60 :             ALLOCATE (dd_matrix(nkind, nkind))
    3618           54 :             ALLOCATE (ee_matrix(nkind, nkind))
    3619           54 :             ALLOCATE (ff_matrix(nkind, nkind))
    3620              : 
    3621           18 :             DO ikind = 1, nkind
    3622              : 
    3623              :                CALL get_atomic_kind(atomic_kind_set(ikind), &
    3624              :                                     atom_list=atom_list, &
    3625           12 :                                     natom=natom_of_kind)
    3626              : 
    3627              :                CALL get_qs_kind(qs_kind_set(ikind), &
    3628              :                                 u_minus_j=u_minus_j, &
    3629              :                                 l_of_dft_plus_u=lu, &
    3630              :                                 basis_set=orb_basis_set, &
    3631              :                                 hund_j=hund_j, &
    3632              :                                 nsgf=nsgf_kind, &
    3633           12 :                                 dft_plus_u_atom=dft_plus_u_atom)
    3634              : 
    3635           12 :                IF (.NOT. dft_plus_u_atom) CYCLE
    3636            6 :                IF (.NOT. ASSOCIATED(orb_basis_set)) CYCLE
    3637            6 :                IF (lu < 0) CYCLE
    3638            6 :                IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) CYCLE
    3639              : 
    3640              :                CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    3641              :                                       first_sgf=first_sgf, &
    3642              :                                       l=l, &
    3643              :                                       last_sgf=last_sgf, &
    3644              :                                       nset=nset, &
    3645            6 :                                       nshell=nshell)
    3646              : 
    3647            6 :                nsb = 0
    3648           18 :                DO iset = 1, nset
    3649           48 :                   DO ishell = 1, nshell(iset)
    3650           42 :                      IF (l(ishell, iset) == lu) nsb = nsb + 1
    3651              :                   END DO
    3652              :                END DO
    3653              : 
    3654            6 :                nsbsize = (2*lu + 1)
    3655            6 :                n = nsb*nsbsize
    3656              : 
    3657           30 :                ALLOCATE (a_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
    3658           24 :                ALLOCATE (d_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
    3659           24 :                ALLOCATE (e_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
    3660           24 :                ALLOCATE (i_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
    3661           24 :                ALLOCATE (j_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
    3662              : 
    3663          264 :                a_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
    3664          264 :                d_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
    3665          264 :                e_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
    3666          264 :                i_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
    3667          264 :                j_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
    3668              : 
    3669           36 :                DO iatom = 1, natom_of_kind
    3670              : 
    3671            6 :                   atom_aa = atom_list(iatom)
    3672              : 
    3673            6 :                   NULLIFY (a_block)
    3674              :                   CALL dbcsr_get_block_p(matrix=sm_a, &
    3675              :                                          row=atom_aa, &
    3676              :                                          col=atom_aa, &
    3677              :                                          block=a_block, &
    3678            6 :                                          found=found)
    3679              : 
    3680            6 :                   NULLIFY (d_block)
    3681              :                   CALL dbcsr_get_block_p(matrix=sm_d, &
    3682              :                                          row=atom_aa, &
    3683              :                                          col=atom_aa, &
    3684              :                                          block=d_block, &
    3685            6 :                                          found=found)
    3686              : 
    3687            6 :                   NULLIFY (e_block)
    3688              :                   CALL dbcsr_get_block_p(matrix=sm_e, &
    3689              :                                          row=atom_aa, &
    3690              :                                          col=atom_aa, &
    3691              :                                          block=e_block, &
    3692            6 :                                          found=found)
    3693              : 
    3694            6 :                   NULLIFY (i_block)
    3695              :                   CALL dbcsr_get_block_p(matrix=sm_i, &
    3696              :                                          row=atom_aa, &
    3697              :                                          col=atom_aa, &
    3698              :                                          block=i_block, &
    3699            6 :                                          found=found)
    3700              : 
    3701            6 :                   NULLIFY (j_block)
    3702              :                   CALL dbcsr_get_block_p(matrix=sm_j, &
    3703              :                                          row=atom_aa, &
    3704              :                                          col=atom_aa, &
    3705              :                                          block=j_block, &
    3706            6 :                                          found=found)
    3707              : 
    3708              :                   IF (ASSOCIATED(a_block) .AND. ASSOCIATED(d_block) .AND. ASSOCIATED(e_block) &
    3709            6 :                       .AND. ASSOCIATED(i_block) .AND. ASSOCIATED(j_block)) THEN
    3710              : 
    3711            3 :                      i = 0
    3712            9 :                      DO iset = 1, nset
    3713           24 :                         DO ishell = 1, nshell(iset)
    3714           15 :                            IF (l(ishell, iset) /= lu) CYCLE
    3715           30 :                            DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
    3716           18 :                               i = i + 1
    3717           18 :                               j = 0
    3718           69 :                               DO jset = 1, nset
    3719          144 :                                  DO jshell = 1, nshell(jset)
    3720           90 :                                     IF (l(jshell, jset) /= lu) CYCLE
    3721          180 :                                     DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
    3722          108 :                                        j = j + 1
    3723          108 :                                        a_matrix(ikind, ikind)%matrix(i, j, iatom) = a_block(isgf, jsgf)
    3724          108 :                                        d_matrix(ikind, ikind)%matrix(i, j, iatom) = -d_block(isgf, jsgf)
    3725          108 :                                        e_matrix(ikind, ikind)%matrix(i, j, iatom) = -e_block(isgf, jsgf)
    3726          108 :                                        i_matrix(ikind, ikind)%matrix(i, j, iatom) = i_block(isgf, jsgf)
    3727          198 :                                        j_matrix(ikind, ikind)%matrix(i, j, iatom) = j_block(isgf, jsgf)
    3728              :                                     END DO
    3729              :                                  END DO
    3730              :                               END DO
    3731              :                            END DO
    3732              :                         END DO
    3733              :                      END DO
    3734              : 
    3735              :                   END IF
    3736              : 
    3737           36 :                   DO jkind = 1, nkind
    3738              : 
    3739              :                      CALL get_atomic_kind(atomic_kind_set(jkind), &
    3740              :                                           atom_list=atom_list2, &
    3741           12 :                                           natom=matom_of_kind)
    3742              : 
    3743           12 :                      CALL get_qs_kind(qs_kind_set(jkind), nsgf=nsgf_kind2)
    3744              : 
    3745           12 :                      IF (.NOT. ALLOCATED(dd_matrix(ikind, jkind)%matrix)) THEN
    3746           72 :                         ALLOCATE (dd_matrix(ikind, jkind)%matrix(n, nsgf_kind2, natom_of_kind, matom_of_kind))
    3747         1014 :                         dd_matrix(ikind, jkind)%matrix(:, :, :, :) = 0.0_dp
    3748              :                      END IF
    3749              : 
    3750           12 :                      IF (.NOT. ALLOCATED(ee_matrix(ikind, jkind)%matrix)) THEN
    3751           72 :                         ALLOCATE (ee_matrix(ikind, jkind)%matrix(n, nsgf_kind2, natom_of_kind, matom_of_kind))
    3752         1014 :                         ee_matrix(ikind, jkind)%matrix(:, :, :, :) = 0.0_dp
    3753              :                      END IF
    3754              : 
    3755           12 :                      IF (.NOT. ALLOCATED(ff_matrix(ikind, jkind)%matrix)) THEN
    3756           72 :                         ALLOCATE (ff_matrix(ikind, jkind)%matrix(nsgf_kind2, n, natom_of_kind, matom_of_kind))
    3757          984 :                         ff_matrix(ikind, jkind)%matrix(:, :, :, :) = 0.0_dp
    3758              :                      END IF
    3759              : 
    3760           48 :                      DO jatom = 1, matom_of_kind
    3761              : 
    3762           18 :                         atom_a = atom_list2(jatom)
    3763              : 
    3764           18 :                         NULLIFY (d_block)
    3765              :                         CALL dbcsr_get_block_p(matrix=sm_b, &
    3766              :                                                row=atom_aa, &
    3767              :                                                col=atom_a, &
    3768              :                                                block=d_block, &
    3769           18 :                                                found=found)
    3770              : 
    3771           18 :                         NULLIFY (e_block)
    3772              :                         CALL dbcsr_get_block_p(matrix=sm_c, &
    3773              :                                                row=atom_aa, &
    3774              :                                                col=atom_a, &
    3775              :                                                block=e_block, &
    3776           18 :                                                found=found)
    3777              : 
    3778           18 :                         IF (ASSOCIATED(d_block) .AND. ASSOCIATED(e_block)) THEN
    3779            9 :                            i = 0
    3780           27 :                            DO iset = 1, nset
    3781           72 :                               DO ishell = 1, nshell(iset)
    3782           45 :                                  IF (l(ishell, iset) /= lu) CYCLE
    3783           90 :                                  DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
    3784           54 :                                     i = i + 1
    3785          468 :                                     dd_matrix(ikind, jkind)%matrix(i, :, iatom, jatom) = d_block(isgf, :)
    3786          513 :                                     ee_matrix(ikind, jkind)%matrix(i, :, iatom, jatom) = e_block(isgf, :)
    3787              :                                  END DO
    3788              :                               END DO
    3789              :                            END DO
    3790              :                         END IF
    3791              : 
    3792           18 :                         NULLIFY (f_block)
    3793              :                         CALL dbcsr_get_block_p(matrix=sm_f, &
    3794              :                                                row=atom_a, &
    3795              :                                                col=atom_aa, &
    3796              :                                                block=f_block, &
    3797           18 :                                                found=found)
    3798              : 
    3799           48 :                         IF (ASSOCIATED(f_block)) THEN
    3800            6 :                            i = 0
    3801           18 :                            DO iset = 1, nset
    3802           48 :                               DO ishell = 1, nshell(iset)
    3803           30 :                                  IF (l(ishell, iset) /= lu) CYCLE
    3804           60 :                                  DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
    3805           36 :                                     i = i + 1
    3806          246 :                                     ff_matrix(ikind, jkind)%matrix(:, i, iatom, jatom) = f_block(:, isgf)
    3807              :                                  END DO
    3808              :                               END DO
    3809              :                            END DO
    3810              :                         END IF
    3811              : 
    3812              :                      END DO
    3813              :                   END DO
    3814              :                END DO
    3815              :             END DO
    3816              : 
    3817           18 :             DO ikind = 1, nkind
    3818              : 
    3819              :                CALL get_atomic_kind(atomic_kind_set(ikind), &
    3820              :                                     atom_list=atom_list, &
    3821           12 :                                     natom=natom_of_kind)
    3822              : 
    3823              :                CALL get_qs_kind(qs_kind_set(ikind), &
    3824              :                                 u_minus_j=u_minus_j, &
    3825              :                                 l_of_dft_plus_u=lu, &
    3826              :                                 basis_set=orb_basis_set, &
    3827              :                                 hund_j=hund_j, &
    3828              :                                 nsgf=nsgf_kind, &
    3829           12 :                                 dft_plus_u_atom=dft_plus_u_atom)
    3830              : 
    3831           12 :                IF (.NOT. dft_plus_u_atom) CYCLE
    3832            6 :                IF (.NOT. ASSOCIATED(orb_basis_set)) CYCLE
    3833            6 :                IF (lu < 0) CYCLE
    3834            6 :                IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) CYCLE
    3835              : 
    3836              :                CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    3837              :                                       first_sgf=first_sgf, &
    3838              :                                       l=l, &
    3839              :                                       last_sgf=last_sgf, &
    3840              :                                       nset=nset, &
    3841            6 :                                       nshell=nshell)
    3842              : 
    3843            6 :                CALL para_env%sum(a_matrix(ikind, ikind)%matrix(:, :, :))
    3844            6 :                CALL para_env%sum(d_matrix(ikind, ikind)%matrix(:, :, :))
    3845            6 :                CALL para_env%sum(e_matrix(ikind, ikind)%matrix(:, :, :))
    3846            6 :                CALL para_env%sum(i_matrix(ikind, ikind)%matrix(:, :, :))
    3847            6 :                CALL para_env%sum(j_matrix(ikind, ikind)%matrix(:, :, :))
    3848              : 
    3849           42 :                DO jkind = 1, nkind
    3850           12 :                   CALL para_env%sum(dd_matrix(ikind, jkind)%matrix(:, :, :, :))
    3851           12 :                   CALL para_env%sum(ee_matrix(ikind, jkind)%matrix(:, :, :, :))
    3852           24 :                   CALL para_env%sum(ff_matrix(ikind, jkind)%matrix(:, :, :, :))
    3853              :                END DO
    3854              : 
    3855              :             END DO
    3856              : 
    3857              :             ! Force calculation
    3858              : 
    3859           18 :             DO ikind = 1, nkind
    3860              : 
    3861              :                CALL get_atomic_kind(atomic_kind_set(ikind), &
    3862              :                                     atom_list=atom_list, &
    3863           12 :                                     natom=natom_of_kind)
    3864              : 
    3865              :                CALL get_qs_kind(qs_kind_set(ikind), &
    3866              :                                 u_minus_j=u_minus_j, &
    3867              :                                 l_of_dft_plus_u=lu, &
    3868              :                                 basis_set=orb_basis_set, &
    3869              :                                 hund_j=hund_j, &
    3870              :                                 nsgf=nsgf_kind, &
    3871           12 :                                 dft_plus_u_atom=dft_plus_u_atom)
    3872              : 
    3873           12 :                IF (.NOT. dft_plus_u_atom) CYCLE
    3874            6 :                IF (.NOT. ASSOCIATED(orb_basis_set)) CYCLE
    3875            6 :                IF (lu < 0) CYCLE
    3876            6 :                IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) CYCLE
    3877              : 
    3878              :                CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    3879              :                                       first_sgf=first_sgf, &
    3880              :                                       l=l, &
    3881              :                                       last_sgf=last_sgf, &
    3882              :                                       nset=nset, &
    3883            6 :                                       nshell=nshell)
    3884              : 
    3885            6 :                nsb = 0
    3886           18 :                DO iset = 1, nset
    3887           48 :                   DO ishell = 1, nshell(iset)
    3888           42 :                      IF (l(ishell, iset) == lu) nsb = nsb + 1
    3889              :                   END DO
    3890              :                END DO
    3891              : 
    3892            6 :                nsbsize = (2*lu + 1)
    3893            6 :                n = nsb*nsbsize
    3894              : 
    3895           24 :                ALLOCATE (tmp_matrix1(n, n))
    3896           18 :                ALLOCATE (tmp_matrix2(n, n))
    3897           18 :                ALLOCATE (tmp_matrix3(n, n))
    3898              : 
    3899           12 :                DO iatom = 1, natom_of_kind
    3900              : 
    3901            6 :                   atom_aa = atom_list(iatom)
    3902              : 
    3903            6 :                   tmp_matrix1(:, :) = MATMUL(d_matrix(ikind, ikind)%matrix(:, :, iatom), &
    3904         8034 :                                              a_matrix(ikind, ikind)%matrix(:, :, iatom))
    3905            6 :                   tmp_matrix2(:, :) = MATMUL(e_matrix(ikind, ikind)%matrix(:, :, iatom), &
    3906         8034 :                                              a_matrix(ikind, ikind)%matrix(:, :, iatom))
    3907              : 
    3908            6 :                   i_matrix(ikind, ikind)%matrix(:, :, iatom) = MATMUL(i_matrix(ikind, ikind)%matrix(:, :, iatom), &
    3909         8544 :                                                                       a_matrix(ikind, ikind)%matrix(:, :, iatom))
    3910            6 :                   j_matrix(ikind, ikind)%matrix(:, :, iatom) = MATMUL(j_matrix(ikind, ikind)%matrix(:, :, iatom), &
    3911         8544 :                                                                       a_matrix(ikind, ikind)%matrix(:, :, iatom))
    3912              : 
    3913              :                   tmp_matrix3(:, :) = 0.5_dp*u_minus_j*tmp_matrix1 - &
    3914            6 :                                       u_minus_j*MATMUL(tmp_matrix1, i_matrix(ikind, ikind)%matrix(:, :, iatom)) &
    3915        11154 :                                       + hund_j*MATMUL(tmp_matrix2, i_matrix(ikind, ikind)%matrix(:, :, iatom))
    3916              :                   tmp_matrix3(:, :) = tmp_matrix3 + 0.5_dp*u_minus_j*tmp_matrix2 - &
    3917           24 :                                       u_minus_j*MATMUL(tmp_matrix2, j_matrix(ikind, ikind)%matrix(:, :, iatom)) &
    3918        11154 :                                       + hund_j*MATMUL(tmp_matrix1, j_matrix(ikind, ikind)%matrix(:, :, iatom))
    3919              : 
    3920           42 :                   DO i = 1, n
    3921           42 :                      force(ikind)%tensorial_u(jj, iatom) = force(ikind)%tensorial_u(jj, iatom) + tmp_matrix3(i, i)
    3922              :                   END DO
    3923              : 
    3924           24 :                   DO jkind = 1, nkind
    3925              : 
    3926              :                      CALL get_atomic_kind(atomic_kind_set(jkind), &
    3927              :                                           atom_list=atom_list2, &
    3928           12 :                                           natom=matom_of_kind)
    3929              : 
    3930           12 :                      CALL get_qs_kind(qs_kind_set(jkind), nsgf=nsgf_kind2)
    3931              : 
    3932           36 :                      DO jatom = 1, matom_of_kind
    3933              : 
    3934           18 :                         atom_a = atom_list2(jatom)
    3935              : 
    3936           18 :                         tmp_matrix1(:, :) = MATMUL(dd_matrix(ikind, jkind)%matrix(:, :, iatom, jatom), &
    3937        30762 :                                                    ff_matrix(ikind, jkind)%matrix(:, :, iatom, jatom))
    3938        24894 :                         tmp_matrix1(:, :) = MATMUL(tmp_matrix1, a_matrix(ikind, ikind)%matrix(:, :, iatom))
    3939              : 
    3940           18 :                         tmp_matrix2(:, :) = MATMUL(ee_matrix(ikind, jkind)%matrix(:, :, iatom, jatom), &
    3941        30762 :                                                    ff_matrix(ikind, jkind)%matrix(:, :, iatom, jatom))
    3942        24894 :                         tmp_matrix2(:, :) = MATMUL(tmp_matrix2, a_matrix(ikind, ikind)%matrix(:, :, iatom))
    3943              : 
    3944              :                         tmp_matrix3(:, :) = 0.5_dp*u_minus_j*tmp_matrix1 - &
    3945           18 :                                             u_minus_j*MATMUL(tmp_matrix1, i_matrix(ikind, ikind)%matrix(:, :, iatom)) &
    3946        33462 :                                             + hund_j*MATMUL(tmp_matrix2, i_matrix(ikind, ikind)%matrix(:, :, iatom))
    3947              :                         tmp_matrix3(:, :) = tmp_matrix3 + 0.5_dp*u_minus_j*tmp_matrix2 - &
    3948           72 :                                             u_minus_j*MATMUL(tmp_matrix2, j_matrix(ikind, ikind)%matrix(:, :, iatom)) &
    3949        33462 :                                             + hund_j*MATMUL(tmp_matrix1, j_matrix(ikind, ikind)%matrix(:, :, iatom))
    3950              : 
    3951           30 :                         IF (atom_a /= atom_aa) THEN
    3952           84 :                            DO i = 1, n
    3953              :                               force(jkind)%tensorial_u(jj, jatom) = force(jkind)%tensorial_u(jj, jatom) &
    3954           84 :                                                                     + tmp_matrix3(i, i)
    3955              :                            END DO
    3956              :                         END IF
    3957              : 
    3958              :                      END DO
    3959              :                   END DO
    3960              :                END DO
    3961              : 
    3962            6 :                DEALLOCATE (tmp_matrix1)
    3963            6 :                DEALLOCATE (tmp_matrix2)
    3964           36 :                DEALLOCATE (tmp_matrix3)
    3965              : 
    3966              :             END DO
    3967              : 
    3968           18 :             DO ikind = 1, nkind
    3969              : 
    3970           12 :                IF (ALLOCATED(a_matrix(ikind, ikind)%matrix)) DEALLOCATE (a_matrix(ikind, ikind)%matrix)
    3971           12 :                IF (ALLOCATED(d_matrix(ikind, ikind)%matrix)) DEALLOCATE (d_matrix(ikind, ikind)%matrix)
    3972           12 :                IF (ALLOCATED(e_matrix(ikind, ikind)%matrix)) DEALLOCATE (e_matrix(ikind, ikind)%matrix)
    3973           12 :                IF (ALLOCATED(i_matrix(ikind, ikind)%matrix)) DEALLOCATE (i_matrix(ikind, ikind)%matrix)
    3974           12 :                IF (ALLOCATED(j_matrix(ikind, ikind)%matrix)) DEALLOCATE (j_matrix(ikind, ikind)%matrix)
    3975              : 
    3976           42 :                DO jkind = 1, nkind
    3977           24 :                   IF (ALLOCATED(dd_matrix(ikind, jkind)%matrix)) DEALLOCATE (dd_matrix(ikind, jkind)%matrix)
    3978           24 :                   IF (ALLOCATED(ee_matrix(ikind, jkind)%matrix)) DEALLOCATE (ee_matrix(ikind, jkind)%matrix)
    3979           36 :                   IF (ALLOCATED(ff_matrix(ikind, jkind)%matrix)) DEALLOCATE (ff_matrix(ikind, jkind)%matrix)
    3980              :                END DO
    3981              : 
    3982              :             END DO
    3983              : 
    3984           30 :             DEALLOCATE (a_matrix)
    3985           30 :             DEALLOCATE (d_matrix)
    3986           30 :             DEALLOCATE (e_matrix)
    3987           30 :             DEALLOCATE (i_matrix)
    3988           30 :             DEALLOCATE (j_matrix)
    3989           30 :             DEALLOCATE (dd_matrix)
    3990           30 :             DEALLOCATE (ee_matrix)
    3991           38 :             DEALLOCATE (ff_matrix)
    3992              : 
    3993              :          END DO
    3994              : 
    3995            6 :          DO ikind = 1, nkind
    3996           30 :             force(ikind)%tensorial_u(:, :) = force(ikind)%tensorial_u(:, :)*2.0_dp
    3997              :          END DO
    3998              : 
    3999            2 :          CALL DATE_AND_TIME(values=timevalues)
    4000              : 
    4001              :       END IF
    4002              : 
    4003              :       ! Collect the energy contributions from all processes
    4004              : 
    4005          772 :       CALL para_env%sum(energy%dft_plus_u)
    4006              : 
    4007          772 :       IF (energy%dft_plus_u < 0.0_dp) THEN
    4008              :          CALL cp_warn(__LOCATION__, &
    4009              :                       "DFT+U energy contibution is negative possibly due "// &
    4010              :                       "to unphysical Lowdin charges. Check your input, "// &
    4011            0 :                       "if this warning persists or try a different method!")
    4012              :       END IF
    4013              : 
    4014              :       ! Release local sparse matrices
    4015              : 
    4016          772 :       CALL dbcsr_deallocate_matrix(sm_q_a)
    4017          772 :       CALL dbcsr_deallocate_matrix(sm_q_b)
    4018          772 :       CALL dbcsr_deallocate_matrix(sm_v)
    4019          772 :       CALL dbcsr_deallocate_matrix(sm_a)
    4020              : 
    4021          772 :       IF (PRESENT(matrix_w)) THEN
    4022            2 :          CALL dbcsr_deallocate_matrix(sm_b)
    4023            2 :          CALL dbcsr_deallocate_matrix(sm_c)
    4024            2 :          CALL dbcsr_deallocate_matrix(sm_d)
    4025            2 :          CALL dbcsr_deallocate_matrix(sm_e)
    4026            2 :          CALL dbcsr_deallocate_matrix(sm_f)
    4027            2 :          CALL dbcsr_deallocate_matrix(sm_k)
    4028            2 :          CALL dbcsr_deallocate_matrix(sm_i)
    4029            2 :          CALL dbcsr_deallocate_matrix(sm_j)
    4030              :       END IF
    4031              : 
    4032          772 :       CALL timestop(handle)
    4033              : 
    4034         2316 :    END SUBROUTINE tensorial
    4035              : 
    4036           60 : END MODULE dft_plus_u
        

Generated by: LCOV version 2.0-1