LCOV - code coverage report
Current view: top level - src - qs_matrix_w.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:92574dc) Lines: 100.0 % 80 80
Test Date: 2026-09-24 01:27:39 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Utility subroutine for qs energy calculation
      10              : !> \par History
      11              : !>      none
      12              : !> \author MK (29.10.2002)
      13              : ! **************************************************************************************************
      14              : MODULE qs_matrix_w
      15              :    USE cp_control_types,                ONLY: dft_control_type
      16              :    USE cp_dbcsr_api,                    ONLY: dbcsr_init_p,&
      17              :                                               dbcsr_p_type,&
      18              :                                               dbcsr_release_p,&
      19              :                                               dbcsr_set,&
      20              :                                               dbcsr_type
      21              :    USE cp_dbcsr_operations,             ONLY: cp_dbcsr_sm_fm_multiply
      22              :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      23              :                                               cp_fm_struct_release,&
      24              :                                               cp_fm_struct_type
      25              :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      26              :                                               cp_fm_release,&
      27              :                                               cp_fm_type
      28              :    USE kinds,                           ONLY: dp
      29              :    USE kpoint_methods,                  ONLY: kpoint_density_matrices,&
      30              :                                               kpoint_density_transform,&
      31              :                                               kpoint_ot_energy_weighted_density
      32              :    USE kpoint_types,                    ONLY: kpoint_env_type,&
      33              :                                               kpoint_type
      34              :    USE qs_density_matrices,             ONLY: calculate_w_matrix,&
      35              :                                               calculate_w_matrix_ot
      36              :    USE qs_environment_types,            ONLY: get_qs_env,&
      37              :                                               qs_environment_type
      38              :    USE qs_kpoint_operators,             ONLY: kpoint_operator_context_create,&
      39              :                                               kpoint_operator_context_release,&
      40              :                                               kpoint_operator_context_type,&
      41              :                                               kpoint_operator_get,&
      42              :                                               kpoint_operator_prepare,&
      43              :                                               kpoint_slot_ks
      44              :    USE qs_mo_types,                     ONLY: get_mo_set,&
      45              :                                               mo_set_type
      46              :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
      47              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      48              :                                               qs_rho_type
      49              :    USE scf_control_types,               ONLY: scf_control_type
      50              : #include "./base/base_uses.f90"
      51              : 
      52              :    IMPLICIT NONE
      53              : 
      54              :    PRIVATE
      55              : 
      56              : ! *** Global parameters ***
      57              : 
      58              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_matrix_w'
      59              : 
      60              :    PUBLIC :: compute_matrix_w
      61              : 
      62              : CONTAINS
      63              : 
      64              : ! **************************************************************************************************
      65              : !> \brief Refactoring of qs_energies_scf. Moves computation of matrix_w
      66              : !>        into separate subroutine
      67              : !> \param qs_env ...
      68              : !> \param calc_forces ...
      69              : !> \par History
      70              : !>      05.2013 created [Florian Schiffmann]
      71              : ! **************************************************************************************************
      72              : 
      73        26979 :    SUBROUTINE compute_matrix_w(qs_env, calc_forces)
      74              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      75              :       LOGICAL, INTENT(IN)                                :: calc_forces
      76              : 
      77              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'compute_matrix_w'
      78              : 
      79              :       INTEGER                                            :: handle, is, ispin, nao, nspin
      80              :       LOGICAL                                            :: do_kpoints, has_unit_metric
      81        26979 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks, matrix_s, matrix_w, &
      82        26979 :                                                             mo_derivs, rho_ao
      83              :       TYPE(dft_control_type), POINTER                    :: dft_control
      84        26979 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
      85              :       TYPE(mo_set_type), POINTER                         :: mo_set
      86              :       TYPE(qs_rho_type), POINTER                         :: rho
      87              :       TYPE(scf_control_type), POINTER                    :: scf_control
      88              : 
      89        26979 :       CALL timeset(routineN, handle)
      90              : 
      91              :       ! if calculate forces, time to compute the w matrix
      92        26979 :       CALL get_qs_env(qs_env, has_unit_metric=has_unit_metric)
      93              : 
      94        26979 :       IF (calc_forces .AND. .NOT. has_unit_metric) THEN
      95         6747 :          CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
      96              : 
      97         6747 :          IF (do_kpoints) THEN
      98          458 :             BLOCK
      99         1374 :                TYPE(cp_fm_type), DIMENSION(2)                   :: fmwork
     100              :                TYPE(cp_fm_struct_type), POINTER                   :: ao_ao_fmstruct
     101              :                TYPE(cp_fm_type), POINTER                          :: mo_coeff
     102          458 :                TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks_kp, matrix_s_kp, &
     103          458 :                                                                      matrix_w_kp
     104              :                TYPE(kpoint_type), POINTER                         :: kpoints
     105              :                TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     106          458 :                   POINTER                                         :: sab_nl
     107              : 
     108              :                CALL get_qs_env(qs_env, &
     109              :                                matrix_w_kp=matrix_w_kp, &
     110              :                                matrix_ks_kp=matrix_ks_kp, &
     111              :                                matrix_s_kp=matrix_s_kp, &
     112              :                                sab_orb=sab_nl, &
     113              :                                mos=mos, &
     114              :                                kpoints=kpoints, &
     115          458 :                                scf_control=scf_control)
     116              : 
     117          458 :                CALL get_mo_set(mos(1), mo_coeff=mo_coeff, nao=nao)
     118              :                CALL cp_fm_struct_create(fmstruct=ao_ao_fmstruct, nrow_global=nao, ncol_global=nao, &
     119          458 :                                         template_fmstruct=mo_coeff%matrix_struct)
     120              : 
     121         1374 :                DO is = 1, SIZE(fmwork)
     122         1374 :                   CALL cp_fm_create(fmwork(is), matrix_struct=ao_ao_fmstruct)
     123              :                END DO
     124          458 :                CALL cp_fm_struct_release(ao_ao_fmstruct)
     125              : 
     126              :                ! energy weighted density matrices in k-space
     127          458 :                IF (scf_control%use_ot) THEN
     128           24 :                   CALL kpoint_ot_energy_weighted_matrices(kpoints, matrix_ks_kp, fmwork(1))
     129              :                ELSE
     130          434 :                   CALL kpoint_density_matrices(kpoints, energy_weighted=.TRUE.)
     131              :                END IF
     132              :                ! energy weighted density matrices in real space
     133              :                CALL kpoint_density_transform(kpoints, matrix_w_kp, .TRUE., &
     134          458 :                                              matrix_s_kp(1, 1)%matrix, sab_nl, fmwork)
     135              : 
     136         1832 :                DO is = 1, SIZE(fmwork)
     137         1374 :                   CALL cp_fm_release(fmwork(is))
     138              :                END DO
     139              : 
     140              :             END BLOCK
     141              :          ELSE
     142              : 
     143         6289 :             NULLIFY (dft_control, rho_ao)
     144              :             CALL get_qs_env(qs_env, &
     145              :                             matrix_w=matrix_w, &
     146              :                             matrix_ks=matrix_ks, &
     147              :                             matrix_s=matrix_s, &
     148              :                             mo_derivs=mo_derivs, &
     149              :                             scf_control=scf_control, &
     150              :                             mos=mos, &
     151              :                             rho=rho, &
     152         6289 :                             dft_control=dft_control)
     153              : 
     154         6289 :             CALL qs_rho_get(rho, rho_ao=rho_ao)
     155              : 
     156         6289 :             nspin = SIZE(mos)
     157        13326 :             DO ispin = 1, nspin
     158         7037 :                mo_set => mos(ispin)
     159        13326 :                IF (dft_control%roks) THEN
     160          168 :                   IF (scf_control%use_ot) THEN
     161          116 :                      IF (ispin > 1) THEN
     162              :                         ! not very elegant, indeed ...
     163           58 :                         CALL dbcsr_set(matrix_w(ispin)%matrix, 0.0_dp)
     164              :                      ELSE
     165              :                         CALL calculate_w_matrix_ot(mo_set, mo_derivs(ispin)%matrix, &
     166           58 :                                                    matrix_w(ispin)%matrix, matrix_s(1)%matrix)
     167              :                      END IF
     168              :                   ELSE
     169              :                      CALL calculate_w_matrix(mo_set=mo_set, &
     170              :                                              matrix_ks=matrix_ks(ispin)%matrix, &
     171              :                                              matrix_p=rho_ao(ispin)%matrix, &
     172           52 :                                              matrix_w=matrix_w(ispin)%matrix)
     173              :                   END IF
     174              :                ELSE
     175         6869 :                   IF (scf_control%use_ot) THEN
     176              :                      CALL calculate_w_matrix_ot(mo_set, mo_derivs(ispin)%matrix, &
     177         2773 :                                                 matrix_w(ispin)%matrix, matrix_s(1)%matrix)
     178              :                   ELSE
     179         4096 :                      CALL calculate_w_matrix(mo_set, matrix_w(ispin)%matrix)
     180              :                   END IF
     181              :                END IF
     182              :             END DO
     183              : 
     184              :          END IF
     185              : 
     186              :       END IF
     187              : 
     188        26979 :       CALL timestop(handle)
     189              : 
     190        26979 :    END SUBROUTINE compute_matrix_w
     191              : 
     192              : ! **************************************************************************************************
     193              : !> \brief Build OT energy-weighted densities using Hamiltonians on the k-point groups.
     194              : !> \param kpoint K-point environment
     195              : !> \param matrix_ks current real-space Kohn-Sham matrices
     196              : !> \param ao_ao_fm square full-matrix template on the global parallel environment
     197              : ! **************************************************************************************************
     198           24 :    SUBROUTINE kpoint_ot_energy_weighted_matrices(kpoint, matrix_ks, ao_ao_fm)
     199              : 
     200              :       TYPE(kpoint_type), POINTER                         :: kpoint
     201              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks
     202              :       TYPE(cp_fm_type), INTENT(IN)                       :: ao_ao_fm
     203              : 
     204              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'kpoint_ot_energy_weighted_matrices'
     205              : 
     206              :       INTEGER                                            :: handle, ikpgr, ispin, kplocal, kpmax, &
     207              :                                                             nmo, nspin
     208           24 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: occupation
     209              :       TYPE(cp_fm_type)                                   :: hc_im, hc_re
     210              :       TYPE(cp_fm_type), POINTER                          :: coeff_im, coeff_re
     211              :       TYPE(dbcsr_type), POINTER                          :: matrix_k_im, matrix_k_re
     212              :       TYPE(kpoint_env_type), POINTER                     :: kp
     213           24 :       TYPE(kpoint_operator_context_type)                 :: op_ctx
     214              : 
     215           24 :       CALL timeset(routineN, handle)
     216           24 :       NULLIFY (coeff_im, coeff_re, matrix_k_im, matrix_k_re, occupation)
     217           24 :       CPASSERT(.NOT. kpoint%use_real_wfn)
     218           24 :       CPASSERT(ASSOCIATED(matrix_ks))
     219              : 
     220           24 :       nspin = SIZE(matrix_ks, 1)
     221           24 :       kplocal = SIZE(kpoint%kp_env)
     222           58 :       kpmax = MAXVAL(kpoint%kp_dist(2, :) - kpoint%kp_dist(1, :) + 1)
     223           24 :       CALL kpoint_operator_context_create(op_ctx, kpoint, ao_ao_fm, nspin)
     224              :       ! Capture the current Hamiltonian after SCF, independently of OT's iteration caches.
     225           24 :       CALL kpoint_operator_prepare(op_ctx, matrix_ks, kpoint_slot_ks)
     226              : 
     227           50 :       DO ikpgr = 1, kpmax
     228           86 :          DO ispin = 1, nspin
     229           36 :             CALL dbcsr_init_p(matrix_k_re)
     230           36 :             CALL dbcsr_init_p(matrix_k_im)
     231              :             ! All groups participate in the operator calls, including inactive groups in the
     232              :             ! last round. The fallback may communicate over the global parallel environment.
     233              :             CALL kpoint_operator_get(op_ctx, ikpgr, ispin, matrix_ks, &
     234              :                                      mat_re=matrix_k_re, mat_im=matrix_k_im, &
     235           36 :                                      matrix_row=ispin, slot=kpoint_slot_ks)
     236           36 :             IF (ikpgr <= kplocal) THEN
     237           34 :                kp => kpoint%kp_env(ikpgr)%kpoint_env
     238              :                CALL get_mo_set(kp%mos(1, ispin), mo_coeff=coeff_re, nmo=nmo, &
     239           34 :                                occupation_numbers=occupation)
     240           34 :                CALL get_mo_set(kp%mos(2, ispin), mo_coeff=coeff_im)
     241           34 :                CPASSERT(nmo >= 1)
     242           34 :                CPASSERT(SIZE(occupation) >= nmo)
     243              : 
     244              :                ! Smearing occupations are k-point resolved, whereas mo_set%homo is not.
     245           34 :                CALL cp_fm_create(hc_re, coeff_re%matrix_struct, set_zero=.TRUE.)
     246           34 :                CALL cp_fm_create(hc_im, coeff_im%matrix_struct, set_zero=.TRUE.)
     247           34 :                CALL cp_dbcsr_sm_fm_multiply(matrix_k_re, coeff_re, hc_re, nmo)
     248              :                CALL cp_dbcsr_sm_fm_multiply(matrix_k_im, coeff_im, hc_re, nmo, &
     249           34 :                                             alpha=-1.0_dp, beta=1.0_dp)
     250           34 :                CALL cp_dbcsr_sm_fm_multiply(matrix_k_re, coeff_im, hc_im, nmo)
     251              :                CALL cp_dbcsr_sm_fm_multiply(matrix_k_im, coeff_re, hc_im, nmo, &
     252           34 :                                             alpha=1.0_dp, beta=1.0_dp)
     253              : 
     254              :                CALL kpoint_ot_energy_weighted_density( &
     255              :                   coeff_re, coeff_im, hc_re, hc_im, occupation, &
     256           34 :                   kp%wmat(1, ispin), kp%wmat(2, ispin))
     257              : 
     258           34 :                CALL cp_fm_release(hc_im)
     259           34 :                CALL cp_fm_release(hc_re)
     260              :             END IF
     261           36 :             CALL dbcsr_release_p(matrix_k_im)
     262           62 :             CALL dbcsr_release_p(matrix_k_re)
     263              :          END DO
     264              :       END DO
     265              : 
     266           24 :       CALL kpoint_operator_context_release(op_ctx)
     267           24 :       CALL timestop(handle)
     268              : 
     269           48 :    END SUBROUTINE kpoint_ot_energy_weighted_matrices
     270              : 
     271              : END MODULE qs_matrix_w
        

Generated by: LCOV version 2.0-1