LCOV - code coverage report
Current view: top level - src/emd - rt_bse_types.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:15a58fb) Lines: 263 276 95.3 %
Date: 2025-02-18 08:24:35 Functions: 11 15 73.3 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Data storage and other types for propagation via RT-BSE method.
      10             : !> \author Stepan Marek (01.24)
      11             : ! **************************************************************************************************
      12             : 
      13             : MODULE rt_bse_types
      14             : 
      15             :    USE kinds, ONLY: dp
      16             :    USE cp_fm_types, ONLY: cp_fm_type, &
      17             :                           cp_fm_p_type, &
      18             :                           cp_fm_release, &
      19             :                           cp_fm_create, &
      20             :                           cp_fm_set_all, &
      21             :                           cp_fm_write_formatted, &
      22             :                           cp_fm_to_fm
      23             :    USE cp_cfm_types, ONLY: cp_cfm_p_type, &
      24             :                            cp_cfm_type, &
      25             :                            cp_cfm_set_all, &
      26             :                            cp_cfm_create, &
      27             :                            cp_fm_to_cfm, &
      28             :                            cp_cfm_to_fm, &
      29             :                            cp_cfm_to_cfm, &
      30             :                            cp_cfm_release
      31             :    USE cp_fm_basic_linalg, ONLY: cp_fm_invert, &
      32             :                                  cp_fm_transpose, &
      33             :                                  cp_fm_column_scale, &
      34             :                                  cp_fm_scale_and_add
      35             :    USE cp_cfm_basic_linalg, ONLY: cp_cfm_column_scale
      36             :    USE cp_dbcsr_api, ONLY: dbcsr_type, &
      37             :                            dbcsr_p_type, &
      38             :                            dbcsr_create, &
      39             :                            dbcsr_release, &
      40             :                            dbcsr_print, &
      41             :                            dbcsr_get_info, &
      42             :                            dbcsr_copy, &
      43             :                            dbcsr_set, &
      44             :                            dbcsr_scale
      45             :    USE parallel_gemm_api, ONLY: parallel_gemm
      46             :    USE dbt_api, ONLY: dbt_type, &
      47             :                       dbt_pgrid_type, &
      48             :                       dbt_pgrid_create, &
      49             :                       dbt_pgrid_destroy, &
      50             :                       dbt_mp_environ_pgrid, &
      51             :                       dbt_default_distvec, &
      52             :                       dbt_distribution_type, &
      53             :                       dbt_distribution_new, &
      54             :                       dbt_distribution_destroy, &
      55             :                       dbt_create, &
      56             :                       dbt_copy_matrix_to_tensor, &
      57             :                       dbt_get_num_blocks, &
      58             :                       dbt_destroy
      59             :    USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm, &
      60             :                                   copy_fm_to_dbcsr
      61             :    USE qs_mo_types, ONLY: mo_set_type
      62             :    USE basis_set_types, ONLY: gto_basis_set_p_type
      63             :    USE basis_set_types, ONLY: gto_basis_set_p_type
      64             :    USE cp_control_types, ONLY: dft_control_type
      65             :    USE qs_environment_types, ONLY: qs_environment_type, &
      66             :                                    get_qs_env
      67             :    USE force_env_types, ONLY: force_env_type
      68             :    USE post_scf_bandstructure_types, ONLY: post_scf_bandstructure_type
      69             :    USE post_scf_bandstructure_utils, ONLY: create_and_init_bs_env
      70             :    USE rt_propagation_types, ONLY: rt_prop_type, &
      71             :                                    get_rtp
      72             :    USE rt_propagation_utils, ONLY: warn_section_unused
      73             :    USE rt_propagator_init, ONLY: rt_initialize_rho_from_mos
      74             :    USE rt_propagation_methods, ONLY: s_matrices_create
      75             :    USE qs_moments, ONLY: build_local_moment_matrix
      76             :    USE moments_utils, ONLY: get_reference_point
      77             :    USE matrix_exp, ONLY: get_nsquare_norder
      78             :    USE gw_integrals, ONLY: build_3c_integral_block
      79             :    USE gw_large_cell_Gamma, ONLY: compute_3c_integrals
      80             :    USE qs_tensors, ONLY: neighbor_list_3c_destroy
      81             : !    USE gw_utils,                        ONLY: create_and_init_bs_env_for_gw,&
      82             : !                                               setup_AO_and_RI_basis_set,&
      83             : !                                               get_RI_basis_and_basis_function_indices,&
      84             : !                                               set_heuristic_parameters,&
      85             : !                                               set_parallelization_parameters,&
      86             : !                                               allocate_and_fill_matrices_and_arrays,&
      87             : !                                               create_tensors
      88             :    USE libint_wrapper, ONLY: cp_libint_static_init
      89             :    USE libint_2c_3c, ONLY: libint_potential_type
      90             :    USE input_constants, ONLY: use_mom_ref_coac, &
      91             :                               use_mom_ref_zero, &
      92             :                               use_mom_ref_user, &
      93             :                               use_mom_ref_com, &
      94             :                               rtp_bse_ham_g0w0, &
      95             :                               rtp_bse_ham_ks, &
      96             :                               do_taylor, &
      97             :                               do_bch, &
      98             :                               do_exact
      99             :    USE physcon, ONLY: angstrom
     100             :    USE mathconstants, ONLY: z_zero
     101             :    USE input_section_types, ONLY: section_vals_type, &
     102             :                                   section_vals_val_get, &
     103             :                                   section_vals_get_subs_vals
     104             : 
     105             : #include "../base/base_uses.f90"
     106             : 
     107             :    IMPLICIT NONE
     108             : 
     109             :    PRIVATE
     110             : 
     111             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = "rt_bse"
     112             : 
     113             :    #:include "rt_bse_macros.fypp"
     114             : 
     115             :    PUBLIC :: rtbse_env_type, &
     116             :              create_rtbse_env, &
     117             :              release_rtbse_env, &
     118             :              multiply_cfm_fm, &
     119             :              multiply_fm_cfm, &
     120             :              create_hartree_ri_3c, &
     121             :              create_sigma_workspace_qs_only
     122             : 
     123             :    ! Created so that we can have an array of pointers to arrays
     124             :    TYPE series_real_type
     125             :       REAL(kind=dp), DIMENSION(:), POINTER                      :: series => NULL()
     126             :    END TYPE series_real_type
     127             :    TYPE series_complex_type
     128             :       COMPLEX(kind=dp), DIMENSION(:), POINTER                   :: series => NULL()
     129             :    END TYPE series_complex_type
     130             : 
     131             : ! **************************************************************************************************
     132             : !> \param n_spin Number of spin channels that are present
     133             : !> \param n_ao Number of atomic orbitals
     134             : !> \param n_RI Number of RI orbitals
     135             : !> \param n_occ Number of occupied orbitals, spin dependent
     136             : !> \param spin_degeneracy Number of electrons per orbital
     137             : !> \param field Electric field calculated at the given timestep
     138             : !> \param moments Moment operators along cartesian directions - centered at zero charge - used for plotting
     139             : !> \param moments_field Moment operators along cartesian directions - used to coupling to the field -
     140             : !>                origin bound to unit cell
     141             : !> \param sim_step Current step of the simulation
     142             : !> \param sim_start Starting step of the simulation
     143             : !> \param sim_nsteps Number of steps of the simulation
     144             : !> \param sim_time Current time of the simulation
     145             : !> \param sim_dt Timestep of the simulation
     146             : !> \param etrs_threshold Self-consistency threshold for enforced time reversal symmetry propagation
     147             : !> \param exp_accuracy Threshold for matrix exponential calculation
     148             : !> \param dft_control DFT control parameters
     149             : !> \param ham_effective Real and imaginary part of the effective Hamiltonian used to propagate
     150             : !>                      the density matrix
     151             : !> \param ham_reference Reference Hamiltonian, which does not change in the propagation = DFT+G0W0 - initial Hartree - initial COHSEX
     152             : !> \param ham_workspace Workspace matrices for use with the Hamiltonian propagation - storage of
     153             : !>                      exponential propagators etc.
     154             : !> \param rho Density matrix at the current time step
     155             : !> \param rho_new Density matrix - workspace in ETRS
     156             : !> \param rho_last Density matrix - workspace in ETRS
     157             : !> \param rho_new_last Density matrix - workspace in ETRS
     158             : !> \param rho_M Density matrix - workspace in ETRS
     159             : !> \param S_inv_fm Inverse overlap matrix, full matrix
     160             : !> \param S_fm Overlap matrix, full matrix
     161             : !> \param S_inv Inverse overlap matrix, sparse matrix
     162             : !> \param rho_dbcsr Density matrix, sparse matrix
     163             : !> \param rho_workspace Matrices for storage of density matrix at different timesteps for
     164             : !>                      interpolation and self-consistency checks etc.
     165             : !> \param complex_workspace Workspace for complex density (exact diagonalisation)
     166             : !> \param complex_s Complex overlap matrix (exact diagonalisation)
     167             : !> \param real_eigvals Eigenvalues of hermitian matrix (exact diagonalisation)
     168             : !> \param exp_eigvals Exponentiated eigenvalues (exact diagonalisation)
     169             : !> \param v_dbcsr Sparse matrix with bare Coulomb in RI basis
     170             : !> \param w_dbcsr Sparse matrix with correlation part of dressed Coulomb in RI basis (without bare Coulomb)
     171             : !> \param screened_dbt Tensor for screened Coulomb interaction
     172             : !> \param greens_dbt Tensor for greens function/density matrix
     173             : !> \param t_3c_w Tensor containing 3c integrals
     174             : !> \param t_3c_work_RI_AO__AO Tensor sigma contraction
     175             : !> \param t_3c_work2_RI_AO__AO Tensor sigma contraction
     176             : !> \param sigma_SEX Screened exchange self-energy
     177             : !> \param sigma_COH Coulomb hole self-energy
     178             : !> \param hartree_curr Current Hartree matrix
     179             : !> \param etrs_max_iter Maximum number of ETRS iterations
     180             : !> \param ham_reference_type Which Hamiltonian to use as single particle basis
     181             : !> \param mat_exp_method Which method to use for matrix exponentiation
     182             : !> \param unit_nr Number of output unit
     183             : !> \param int_3c_array Array containing the local 3c integrals
     184             : !> \author Stepan Marek (01.24)
     185             : ! **************************************************************************************************
     186             :    TYPE rtbse_env_type
     187             :       INTEGER                                                   :: n_spin = 1, &
     188             :                                                                    n_ao = -1, &
     189             :                                                                    n_RI = -1
     190             :       INTEGER, DIMENSION(2)                                     :: n_occ = -1
     191             :       REAL(kind=dp)                                             :: spin_degeneracy = 2
     192             :       REAL(kind=dp), DIMENSION(3)                               :: field = 0.0_dp
     193             :       TYPE(cp_fm_type), DIMENSION(:), POINTER                   :: moments => NULL(), &
     194             :                                                                    moments_field => NULL()
     195             :       INTEGER                                                   :: sim_step = 0, &
     196             :                                                                    sim_start = 0, &
     197             :                                                                    ! Needed for continuation runs for loading of previous moments trace
     198             :                                                                    sim_start_orig = 0, &
     199             :                                                                    sim_nsteps = -1
     200             :       REAL(kind=dp)                                             :: sim_time = 0.0_dp, &
     201             :                                                                    sim_dt = 0.1_dp, &
     202             :                                                                    etrs_threshold = 1.0e-7_dp, &
     203             :                                                                    exp_accuracy = 1.0e-10_dp, &
     204             :                                                                    ft_damping = 0.0_dp, &
     205             :                                                                    ft_start = 0.0_dp
     206             :       ! Which element of polarizability to print out
     207             :       INTEGER, DIMENSION(2)                                     :: pol_element = [1, 1]
     208             :       TYPE(dft_control_type), POINTER                           :: dft_control => NULL()
     209             :       ! DEBUG : Trying keeping the reference to previous environments inside this one
     210             :       TYPE(qs_environment_type), POINTER                        :: qs_env => NULL()
     211             :       TYPE(post_scf_bandstructure_type), POINTER                :: bs_env => NULL()
     212             :       ! Stores data needed for reading/writing to the restart files
     213             :       TYPE(section_vals_type), POINTER                          :: restart_section => NULL(), &
     214             :                                                                    field_section => NULL(), &
     215             :                                                                    rho_section => NULL(), &
     216             :                                                                    ft_section => NULL(), &
     217             :                                                                    pol_section => NULL(), &
     218             :                                                                    moments_section => NULL()
     219             :       LOGICAL                                                   :: restart_extracted = .FALSE.
     220             : 
     221             :       ! Different indices signify different spins
     222             :       TYPE(cp_cfm_type), DIMENSION(:), POINTER                  :: ham_effective => NULL()
     223             :       TYPE(cp_cfm_type), DIMENSION(:), POINTER                  :: ham_reference => NULL()
     224             :       TYPE(cp_cfm_type), DIMENSION(:), POINTER                  :: ham_workspace => NULL()
     225             :       TYPE(cp_cfm_type), DIMENSION(:), POINTER                  :: sigma_SEX => NULL()
     226             :       TYPE(cp_fm_type), DIMENSION(:), POINTER                   :: sigma_COH => NULL(), &
     227             :                                                                    hartree_curr => NULL()
     228             : 
     229             :       TYPE(cp_cfm_type), DIMENSION(:), POINTER                  :: rho => NULL(), &
     230             :                                                                    rho_new => NULL(), &
     231             :                                                                    rho_new_last => NULL(), &
     232             :                                                                    rho_M => NULL(), &
     233             :                                                                    rho_orig => NULL()
     234             :       TYPE(cp_fm_type)                                          :: S_inv_fm = cp_fm_type(), &
     235             :                                                                    S_fm = cp_fm_type()
     236             :       ! Many routines require overlap in the complex format
     237             :       TYPE(cp_cfm_type)                                         :: S_cfm = cp_cfm_type()
     238             :       TYPE(dbcsr_type)                                          :: rho_dbcsr = dbcsr_type(), &
     239             :                                                                    v_ao_dbcsr = dbcsr_type()
     240             :       ! Indices only correspond to different workspaces
     241             :       TYPE(cp_cfm_type), DIMENSION(:), POINTER                  :: rho_workspace => NULL()
     242             :       ! Many methods use real and imaginary parts separately - prevent unnecessary reallocation
     243             :       TYPE(cp_fm_type), DIMENSION(:), POINTER                   :: real_workspace => NULL()
     244             :       ! Workspace required for exact matrix exponentiation
     245             :       REAL(kind=dp), DIMENSION(:), POINTER                      :: real_eigvals => NULL()
     246             :       COMPLEX(kind=dp), DIMENSION(:), POINTER                   :: exp_eigvals => NULL()
     247             :       ! Workspace for saving the values for FT
     248             :       TYPE(series_complex_type), DIMENSION(3)                   :: moments_trace = series_complex_type()
     249             :       TYPE(series_real_type)                                    :: time_trace = series_real_type()
     250             :       TYPE(series_real_type), DIMENSION(3)                      :: field_trace = series_real_type()
     251             :       ! Workspace required for hartree_pw
     252             :       TYPE(dbcsr_type)                                          :: v_dbcsr = dbcsr_type(), &
     253             :                                                                    w_dbcsr = dbcsr_type()
     254             : #if defined(FTN_NO_DEFAULT_INIT)
     255             :       TYPE(dbt_type)                                            :: screened_dbt, &
     256             :                                                                    greens_dbt, &
     257             :                                                                    t_3c_w, &
     258             :                                                                    t_3c_work_RI_AO__AO, &
     259             :                                                                    t_3c_work2_RI_AO__AO
     260             : #else
     261             :       TYPE(dbt_type)                                            :: screened_dbt = dbt_type(), &
     262             :                                                                    greens_dbt = dbt_type(), &
     263             :                                                                    t_3c_w = dbt_type(), &
     264             :                                                                    t_3c_work_RI_AO__AO = dbt_type(), &
     265             :                                                                    t_3c_work2_RI_AO__AO = dbt_type()
     266             : #endif
     267             :       ! These matrices are always real
     268             :       INTEGER                                                   :: etrs_max_iter = 10
     269             :       INTEGER                                                   :: ham_reference_type = 2
     270             :       INTEGER                                                   :: mat_exp_method = 4
     271             :       INTEGER                                                   :: unit_nr = -1
     272             :       REAL(kind=dp), DIMENSION(:, :, :), POINTER                :: int_3c_array => NULL()
     273             : 
     274             :    END TYPE rtbse_env_type
     275             : 
     276             : CONTAINS
     277             : 
     278             : ! **************************************************************************************************
     279             : !> \brief Allocates structures and prepares rtbse_env for run
     280             : !> \param rtbse_env rtbse_env_type that is initialised
     281             : !> \param qs_env Entry point of the calculation
     282             : !> \author Stepan Marek
     283             : !> \date 02.2024
     284             : ! **************************************************************************************************
     285          12 :    SUBROUTINE create_rtbse_env(rtbse_env, qs_env, force_env)
     286             :       TYPE(rtbse_env_type), POINTER                             :: rtbse_env
     287             :       TYPE(qs_environment_type), POINTER                        :: qs_env
     288             :       TYPE(force_env_type), POINTER                             :: force_env
     289             :       TYPE(post_scf_bandstructure_type), POINTER                :: bs_env
     290             :       TYPE(rt_prop_type), POINTER                               :: rtp
     291          12 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER                 :: matrix_s
     292          12 :       TYPE(mo_set_type), DIMENSION(:), POINTER                  :: mos
     293             :       INTEGER                                                   :: i, k
     294             :       TYPE(section_vals_type), POINTER                          :: input, bs_sec, md_sec
     295          12 :       INTEGER, DIMENSION(:), POINTER                            :: pol_tmp
     296             : 
     297             :       ! Allocate the storage for the gwbse environment
     298             :       NULLIFY (rtbse_env)
     299         684 :       ALLOCATE (rtbse_env)
     300             :       ! Extract the other types first
     301             :       CALL get_qs_env(qs_env, &
     302             :                       bs_env=bs_env, &
     303             :                       rtp=rtp, &
     304             :                       matrix_s=matrix_s, &
     305             :                       mos=mos, &
     306             :                       dft_control=rtbse_env%dft_control, &
     307          12 :                       input=input)
     308          12 :       bs_sec => section_vals_get_subs_vals(input, "PROPERTIES%BANDSTRUCTURE")
     309          12 :       IF (.NOT. ASSOCIATED(bs_env)) THEN
     310           0 :          CPABORT("Cannot run RT-BSE without running GW calculation (PROPERTIES) before")
     311             :       END IF
     312             :       ! Number of spins
     313          12 :       rtbse_env%n_spin = bs_env%n_spin
     314             :       ! Number of atomic orbitals
     315          12 :       rtbse_env%n_ao = bs_env%n_ao
     316             :       ! Number of auxiliary basis orbitals
     317          12 :       rtbse_env%n_RI = bs_env%n_RI
     318             :       ! Number of occupied orbitals - for closed shell equals to half the number of electrons
     319          72 :       rtbse_env%n_occ(:) = bs_env%n_occ(:)
     320             :       ! Spin degeneracy - number of spins per orbital
     321          12 :       rtbse_env%spin_degeneracy = bs_env%spin_degeneracy
     322             :       ! Default field is zero
     323          48 :       rtbse_env%field(:) = 0.0_dp
     324             :       ! Default time is zero
     325          12 :       rtbse_env%sim_step = 0
     326          12 :       rtbse_env%sim_time = 0
     327             :       ! Time step is taken from rtp
     328          12 :       md_sec => section_vals_get_subs_vals(force_env%root_section, "MOTION%MD")
     329          12 :       CALL section_vals_val_get(md_sec, "TIMESTEP", r_val=rtbse_env%sim_dt)
     330             :       ! rtbse_env%sim_dt = rtp%dt
     331             :       ! Threshold for etrs is taken from the eps_energy from RT propagation
     332          12 :       rtbse_env%etrs_threshold = rtbse_env%dft_control%rtp_control%eps_ener
     333          12 :       rtbse_env%exp_accuracy = rtbse_env%dft_control%rtp_control%eps_exp
     334             :       ! Recover custom options
     335             :       CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%RTBSE%RTBSE_HAMILTONIAN", &
     336          12 :                                 i_val=rtbse_env%ham_reference_type)
     337             :       CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%MAX_ITER", &
     338          12 :                                 i_val=rtbse_env%etrs_max_iter)
     339             :       CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%MAT_EXP", &
     340          12 :                                 i_val=rtbse_env%mat_exp_method)
     341             :       ! Output unit number, recovered from the post_scf_bandstructure_type
     342          12 :       rtbse_env%unit_nr = bs_env%unit_nr
     343             :       ! Sim start index and total number of steps as well
     344          12 :       CALL section_vals_val_get(md_sec, "STEP_START_VAL", i_val=rtbse_env%sim_start)
     345             :       ! Copy this value to sim_start_orig for continuation runs
     346          12 :       rtbse_env%sim_start_orig = rtbse_env%sim_start
     347          12 :       CALL section_vals_val_get(md_sec, "STEPS", i_val=rtbse_env%sim_nsteps)
     348             :       ! Get the values for the FT
     349             :       CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%PRINT%MOMENTS_FT%DAMPING", &
     350          12 :                                 r_val=rtbse_env%ft_damping)
     351             :       CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%PRINT%MOMENTS_FT%START_TIME", &
     352          12 :                                 r_val=rtbse_env%ft_start)
     353             :       ! TODO : Units for starting time and damping - so far give atomic units
     354             :       CALL section_vals_val_get(input, "DFT%REAL_TIME_PROPAGATION%PRINT%POLARIZABILITY%ELEMENT", &
     355          12 :                                 i_vals=pol_tmp)
     356          12 :       IF (SIZE(pol_tmp) < 2) CPABORT("Less than two elements provided for polarizability")
     357          72 :       rtbse_env%pol_element(:) = pol_tmp(:)
     358             :       ! Do basic sanity checks for pol_element
     359          36 :       DO k = 1, 2
     360          24 :          IF (rtbse_env%pol_element(k) > 3 .OR. rtbse_env%pol_element(k) < 1) &
     361          12 :             CPABORT("Polarisation tensor element not 1,2 or 3 in at least one index")
     362             :       END DO
     363             : 
     364             :       ! Get the restart section
     365          12 :       rtbse_env%restart_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION%PRINT%RESTART")
     366          12 :       rtbse_env%restart_extracted = .FALSE.
     367          12 :       rtbse_env%field_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION%PRINT%FIELD")
     368          12 :       rtbse_env%moments_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION%PRINT%MOMENTS")
     369          12 :       rtbse_env%rho_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION%PRINT%DENSITY_MATRIX")
     370          12 :       rtbse_env%ft_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION%PRINT%MOMENTS_FT")
     371          12 :       rtbse_env%pol_section => section_vals_get_subs_vals(input, "DFT%REAL_TIME_PROPAGATION%PRINT%POLARIZABILITY")
     372             :       ! Warn the user about print sections which are not yet implemented in the RTBSE run
     373             :       CALL warn_section_unused(input, "DFT%REAL_TIME_PROPAGATION%PRINT%CURRENT", &
     374          12 :                                "CURRENT print section not yet implemented for RTBSE.")
     375             :       CALL warn_section_unused(input, "DFT%REAL_TIME_PROPAGATION%PRINT%E_CONSTITUENTS", &
     376          12 :                                "E_CONSTITUENTS print section not yet implemented for RTBSE.")
     377             :       CALL warn_section_unused(input, "DFT%REAL_TIME_PROPAGATION%PRINT%PROGRAM_RUN_INFO", &
     378          12 :                                "PROGRAM_RUN_INFO print section not yet implemented for RTBSE.")
     379             :       CALL warn_section_unused(input, "DFT%REAL_TIME_PROPAGATION%PRINT%PROJECTION_MO", &
     380          12 :                                "PROJECTION_MO print section not yet implemented for RTBSE.")
     381             :       CALL warn_section_unused(input, "DFT%REAL_TIME_PROPAGATION%PRINT%RESTART_HISTORY", &
     382          12 :                                "RESTART_HISTORY print section not yet implemented for RTBSE.")
     383             :       ! DEBUG : References to previous environments
     384          12 :       rtbse_env%qs_env => qs_env
     385          12 :       rtbse_env%bs_env => bs_env
     386             : 
     387             :       ! Allocate moments matrices
     388          12 :       NULLIFY (rtbse_env%moments)
     389          48 :       ALLOCATE (rtbse_env%moments(3))
     390          12 :       NULLIFY (rtbse_env%moments_field)
     391          48 :       ALLOCATE (rtbse_env%moments_field(3))
     392          48 :       DO k = 1, 3
     393             :          ! Matrices are created from overlap template
     394             :          ! Values are initialized in initialize_rtbse_env
     395          36 :          CALL cp_fm_create(rtbse_env%moments(k), bs_env%fm_s_Gamma%matrix_struct)
     396          48 :          CALL cp_fm_create(rtbse_env%moments_field(k), bs_env%fm_s_Gamma%matrix_struct)
     397             :       END DO
     398             : 
     399             :       ! Allocate space for density propagation and other operations
     400          12 :       NULLIFY (rtbse_env%rho_workspace)
     401          60 :       ALLOCATE (rtbse_env%rho_workspace(4))
     402          60 :       DO i = 1, SIZE(rtbse_env%rho_workspace)
     403          48 :          CALL cp_cfm_create(rtbse_env%rho_workspace(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     404          60 :          CALL cp_cfm_set_all(rtbse_env%rho_workspace(i), CMPLX(0.0, 0.0, kind=dp))
     405             :       END DO
     406             :       ! Allocate real workspace
     407          12 :       NULLIFY (rtbse_env%real_workspace)
     408          12 :       SELECT CASE (rtbse_env%mat_exp_method)
     409             :       CASE (do_exact)
     410           0 :          ALLOCATE (rtbse_env%real_workspace(4))
     411             :       CASE (do_bch)
     412          36 :          ALLOCATE (rtbse_env%real_workspace(2))
     413             :       CASE DEFAULT
     414          12 :          CPABORT("Only exact and BCH matrix propagation implemented in RT-BSE")
     415             :       END SELECT
     416          36 :       DO i = 1, SIZE(rtbse_env%real_workspace)
     417          24 :          CALL cp_fm_create(rtbse_env%real_workspace(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     418          36 :          CALL cp_fm_set_all(rtbse_env%real_workspace(i), 0.0_dp)
     419             :       END DO
     420             :       ! Allocate density matrix
     421          12 :       NULLIFY (rtbse_env%rho)
     422          48 :       ALLOCATE (rtbse_env%rho(rtbse_env%n_spin))
     423          24 :       DO i = 1, rtbse_env%n_spin
     424          24 :          CALL cp_cfm_create(rtbse_env%rho(i), matrix_struct=bs_env%fm_s_Gamma%matrix_struct)
     425             :       END DO
     426             :       ! Create the inverse overlap matrix, for use in density propagation
     427             :       ! Start by creating the actual overlap matrix
     428          12 :       CALL cp_fm_create(rtbse_env%S_fm, bs_env%fm_s_Gamma%matrix_struct)
     429          12 :       CALL cp_fm_create(rtbse_env%S_inv_fm, bs_env%fm_s_Gamma%matrix_struct)
     430          12 :       CALL cp_cfm_create(rtbse_env%S_cfm, bs_env%fm_s_Gamma%matrix_struct)
     431             : 
     432             :       ! Create the single particle hamiltonian
     433             :       ! Allocate workspace
     434          12 :       NULLIFY (rtbse_env%ham_workspace)
     435          48 :       ALLOCATE (rtbse_env%ham_workspace(rtbse_env%n_spin))
     436          24 :       DO i = 1, rtbse_env%n_spin
     437          12 :          CALL cp_cfm_create(rtbse_env%ham_workspace(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     438          24 :          CALL cp_cfm_set_all(rtbse_env%ham_workspace(i), CMPLX(0.0, 0.0, kind=dp))
     439             :       END DO
     440             :       ! Now onto the Hamiltonian itself
     441          12 :       NULLIFY (rtbse_env%ham_reference)
     442          48 :       ALLOCATE (rtbse_env%ham_reference(rtbse_env%n_spin))
     443          24 :       DO i = 1, rtbse_env%n_spin
     444          24 :          CALL cp_cfm_create(rtbse_env%ham_reference(i), bs_env%fm_ks_Gamma(i)%matrix_struct)
     445             :       END DO
     446             : 
     447             :       ! Create the matrices and workspaces for ETRS propagation
     448          12 :       NULLIFY (rtbse_env%ham_effective)
     449          12 :       NULLIFY (rtbse_env%rho_new)
     450          12 :       NULLIFY (rtbse_env%rho_new_last)
     451          12 :       NULLIFY (rtbse_env%rho_M)
     452          12 :       NULLIFY (rtbse_env%rho_orig)
     453          48 :       ALLOCATE (rtbse_env%ham_effective(rtbse_env%n_spin))
     454          48 :       ALLOCATE (rtbse_env%rho_new(rtbse_env%n_spin))
     455          48 :       ALLOCATE (rtbse_env%rho_new_last(rtbse_env%n_spin))
     456          48 :       ALLOCATE (rtbse_env%rho_M(rtbse_env%n_spin))
     457          48 :       ALLOCATE (rtbse_env%rho_orig(rtbse_env%n_spin))
     458          24 :       DO i = 1, rtbse_env%n_spin
     459          12 :          CALL cp_cfm_create(rtbse_env%ham_effective(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     460          12 :          CALL cp_cfm_set_all(rtbse_env%ham_effective(i), CMPLX(0.0, 0.0, kind=dp))
     461          12 :          CALL cp_cfm_create(rtbse_env%rho_new(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     462          12 :          CALL cp_cfm_set_all(rtbse_env%rho_new(i), CMPLX(0.0, 0.0, kind=dp))
     463          12 :          CALL cp_cfm_create(rtbse_env%rho_new_last(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     464          12 :          CALL cp_cfm_set_all(rtbse_env%rho_new_last(i), CMPLX(0.0, 0.0, kind=dp))
     465          12 :          CALL cp_cfm_create(rtbse_env%rho_M(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     466          12 :          CALL cp_cfm_set_all(rtbse_env%rho_M(i), CMPLX(0.0, 0.0, kind=dp))
     467          24 :          CALL cp_cfm_create(rtbse_env%rho_orig(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     468             :       END DO
     469             : 
     470             :       ! Fields for exact diagonalisation
     471          12 :       NULLIFY (rtbse_env%real_eigvals)
     472          36 :       ALLOCATE (rtbse_env%real_eigvals(rtbse_env%n_ao))
     473          36 :       rtbse_env%real_eigvals(:) = 0.0_dp
     474          12 :       NULLIFY (rtbse_env%exp_eigvals)
     475          36 :       ALLOCATE (rtbse_env%exp_eigvals(rtbse_env%n_ao))
     476          36 :       rtbse_env%exp_eigvals(:) = CMPLX(0.0, 0.0, kind=dp)
     477             : 
     478             :       ! Workspace for FT - includes (in principle) the zeroth step and the extra last step
     479          48 :       DO i = 1, 3
     480          36 :          NULLIFY (rtbse_env%moments_trace(i)%series)
     481        2580 :          ALLOCATE (rtbse_env%moments_trace(i)%series(rtbse_env%sim_nsteps + 2), source=z_zero)
     482          36 :          NULLIFY (rtbse_env%field_trace(i)%series)
     483        2592 :          ALLOCATE (rtbse_env%field_trace(i)%series(rtbse_env%sim_nsteps + 2), source=0.0_dp)
     484             :       END DO
     485          12 :       NULLIFY (rtbse_env%time_trace%series)
     486         860 :       ALLOCATE (rtbse_env%time_trace%series(rtbse_env%sim_nsteps + 2), source=0.0_dp)
     487             : 
     488             :       ! Allocate self-energy parts and dynamic Hartree potential
     489          12 :       NULLIFY (rtbse_env%hartree_curr)
     490          12 :       NULLIFY (rtbse_env%sigma_SEX)
     491          12 :       NULLIFY (rtbse_env%sigma_COH)
     492          48 :       ALLOCATE (rtbse_env%hartree_curr(rtbse_env%n_spin))
     493          48 :       ALLOCATE (rtbse_env%sigma_SEX(rtbse_env%n_spin))
     494          48 :       ALLOCATE (rtbse_env%sigma_COH(rtbse_env%n_spin))
     495          24 :       DO i = 1, rtbse_env%n_spin
     496          12 :          CALL cp_fm_create(rtbse_env%sigma_COH(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     497          12 :          CALL cp_cfm_create(rtbse_env%sigma_SEX(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     498          12 :          CALL cp_fm_create(rtbse_env%hartree_curr(i), bs_env%fm_ks_Gamma(1)%matrix_struct)
     499          12 :          CALL cp_fm_set_all(rtbse_env%sigma_COH(i), 0.0_dp)
     500          12 :          CALL cp_cfm_set_all(rtbse_env%sigma_SEX(i), CMPLX(0.0, 0.0, kind=dp))
     501          24 :          CALL cp_fm_set_all(rtbse_env%hartree_curr(i), 0.0_dp)
     502             :       END DO
     503             : 
     504             :       ! Allocate workspaces for get_sigma
     505          12 :       CALL create_sigma_workspace(rtbse_env, qs_env)
     506             : 
     507             :       ! Depending on the chosen methods, allocate extra workspace
     508          12 :       CALL create_hartree_ri_workspace(rtbse_env, qs_env)
     509             : 
     510          12 :    END SUBROUTINE
     511             : 
     512             : ! **************************************************************************************************
     513             : !> \brief Simple reimplementation of cp_fm_release_pp1 for complex matrices
     514             : !> \param matrices cp_cfm_p_type(:)
     515             : !> \author Stepan Marek
     516             : !> \date 02.2024
     517             : ! **************************************************************************************************
     518         120 :    SUBROUTINE cp_cfm_release_pa1(matrices)
     519             :       TYPE(cp_cfm_type), DIMENSION(:), POINTER                  :: matrices
     520             :       INTEGER                                                   :: i
     521             : 
     522         276 :       DO i = 1, SIZE(matrices)
     523         276 :          CALL cp_cfm_release(matrices(i))
     524             :       END DO
     525         120 :       DEALLOCATE (matrices)
     526             :       NULLIFY (matrices)
     527         120 :    END SUBROUTINE cp_cfm_release_pa1
     528             : 
     529             : ! **************************************************************************************************
     530             : !> \brief Releases the environment allocated structures
     531             : !> \param rtbse_env
     532             : !> \author Stepan Marek
     533             : !> \date 02.2024
     534             : ! **************************************************************************************************
     535          12 :    SUBROUTINE release_rtbse_env(rtbse_env)
     536             :       TYPE(rtbse_env_type), POINTER                             :: rtbse_env
     537             :       INTEGER                                                   :: i
     538             : 
     539          12 :       CALL cp_cfm_release_pa1(rtbse_env%ham_effective)
     540          12 :       CALL cp_cfm_release_pa1(rtbse_env%ham_workspace)
     541          12 :       CALL cp_fm_release(rtbse_env%sigma_COH)
     542          12 :       CALL cp_cfm_release_pa1(rtbse_env%sigma_SEX)
     543          12 :       CALL cp_fm_release(rtbse_env%hartree_curr)
     544          12 :       CALL cp_cfm_release_pa1(rtbse_env%ham_reference)
     545          12 :       CALL cp_cfm_release_pa1(rtbse_env%rho)
     546          12 :       CALL cp_cfm_release_pa1(rtbse_env%rho_workspace)
     547          12 :       CALL cp_cfm_release_pa1(rtbse_env%rho_new)
     548          12 :       CALL cp_cfm_release_pa1(rtbse_env%rho_new_last)
     549          12 :       CALL cp_cfm_release_pa1(rtbse_env%rho_M)
     550          12 :       CALL cp_cfm_release_pa1(rtbse_env%rho_orig)
     551          12 :       CALL cp_fm_release(rtbse_env%real_workspace)
     552          12 :       CALL cp_fm_release(rtbse_env%S_inv_fm)
     553          12 :       CALL cp_fm_release(rtbse_env%S_fm)
     554          12 :       CALL cp_cfm_release(rtbse_env%S_cfm)
     555             : 
     556             :       ! DO i = 1, 3
     557             :       !    CALL cp_fm_release(rtbse_env%moments(i)%matrix)
     558             :       !    CALL cp_fm_release(rtbse_env%moments_field(i)%matrix)
     559             :       ! END DO
     560          12 :       CALL cp_fm_release(rtbse_env%moments)
     561          12 :       CALL cp_fm_release(rtbse_env%moments_field)
     562             : 
     563          12 :       CALL release_sigma_workspace(rtbse_env)
     564             : 
     565          12 :       CALL release_hartree_ri_workspace(rtbse_env)
     566             : 
     567          12 :       DEALLOCATE (rtbse_env%real_eigvals)
     568          12 :       DEALLOCATE (rtbse_env%exp_eigvals)
     569          48 :       DO i = 1, 3
     570          36 :          DEALLOCATE (rtbse_env%moments_trace(i)%series)
     571          48 :          DEALLOCATE (rtbse_env%field_trace(i)%series)
     572             :       END DO
     573          12 :       DEALLOCATE (rtbse_env%time_trace%series)
     574             : 
     575             :       ! Deallocate the neighbour list that is not deallocated in gw anymore
     576          12 :       IF (ASSOCIATED(rtbse_env%bs_env%nl_3c%ij_list)) CALL neighbor_list_3c_destroy(rtbse_env%bs_env%nl_3c)
     577             :       ! Deallocate the storage for the environment itself
     578          12 :       DEALLOCATE (rtbse_env)
     579             :       ! Nullify to make sure it is not used again
     580             :       NULLIFY (rtbse_env)
     581             : 
     582          12 :    END SUBROUTINE
     583             : ! **************************************************************************************************
     584             : !> \brief Allocates the workspaces for Hartree RI method
     585             : !> \note RI method calculates the Hartree contraction without the use of DBT, as it cannot emulate vectors
     586             : !> \param rtbse_env
     587             : !> \param qs_env Quickstep environment - entry point of calculation
     588             : !> \author Stepan Marek
     589             : !> \date 05.2024
     590             : ! **************************************************************************************************
     591          12 :    SUBROUTINE create_hartree_ri_workspace(rtbse_env, qs_env)
     592             :       TYPE(rtbse_env_type)                              :: rtbse_env
     593             :       TYPE(qs_environment_type), POINTER                :: qs_env
     594             :       TYPE(post_scf_bandstructure_type), POINTER        :: bs_env
     595             : 
     596          12 :       CALL get_qs_env(qs_env, bs_env=bs_env)
     597             : 
     598          12 :       CALL dbcsr_create(rtbse_env%rho_dbcsr, name="Sparse density", template=bs_env%mat_ao_ao%matrix)
     599          12 :       CALL dbcsr_create(rtbse_env%v_ao_dbcsr, name="Sparse Hartree", template=bs_env%mat_ao_ao%matrix)
     600             : 
     601             :       CALL create_hartree_ri_3c(rtbse_env%rho_dbcsr, rtbse_env%int_3c_array, rtbse_env%n_ao, rtbse_env%n_RI, &
     602             :                                 bs_env%basis_set_AO, bs_env%basis_set_RI, bs_env%i_RI_start_from_atom, &
     603          12 :                                 bs_env%ri_metric, qs_env, rtbse_env%unit_nr)
     604          12 :    END SUBROUTINE create_hartree_ri_workspace
     605             : ! **************************************************************************************************
     606             : !> \brief Separated method for allocating the 3c integrals for RI Hartree
     607             : !> \note RI method calculates the Hartree contraction without the use of DBT, as it cannot emulate vectors
     608             : !> \param rho_dbcsr matrix used for the description of shape of 3c array
     609             : !> \param int_3c 3-center integral array to be allocated and filled
     610             : !> \param n_ao Number of atomic orbitals
     611             : !> \param n_RI Number of auxiliary RI orbitals
     612             : !> \param basis_set_AO AO basis set
     613             : !> \param basis_set_RI RI auxiliary basis set
     614             : !> \param i_RI_start_from_atom Array of indices where functions of a given atom in RI basis start
     615             : !> \param unit_nr Unit number used for printing information about the size of int_3c
     616             : !> \author Stepan Marek
     617             : !> \date 01.2025
     618             : ! **************************************************************************************************
     619          12 :    SUBROUTINE create_hartree_ri_3c(rho_dbcsr, int_3c, n_ao, n_RI, basis_set_AO, basis_set_RI, &
     620          12 :                                    i_RI_start_from_atom, ri_metric, qs_env, unit_nr)
     621             :       TYPE(dbcsr_type)                                  :: rho_dbcsr
     622             :       REAL(kind=dp), DIMENSION(:, :, :), POINTER          :: int_3c
     623             :       INTEGER                                           :: n_ao, n_RI
     624             :       TYPE(gto_basis_set_p_type), DIMENSION(:)          :: basis_set_AO, &
     625             :                                                            basis_set_RI
     626             :       INTEGER, DIMENSION(:)                             :: i_RI_start_from_atom
     627             :       TYPE(libint_potential_type)                       :: ri_metric
     628             :       TYPE(qs_environment_type), POINTER                :: qs_env
     629             :       INTEGER                                           :: unit_nr
     630             :       REAL(kind=dp)                                     :: size_mb
     631             :       INTEGER                                           :: nblkrows_local, &
     632             :                                                            nblkcols_local, &
     633             :                                                            i_blk_local, &
     634             :                                                            j_blk_local, &
     635             :                                                            nrows_local, &
     636             :                                                            ncols_local, &
     637             :                                                            col_local_offset, &
     638             :                                                            row_local_offset, &
     639             :                                                            start_col_index, &
     640             :                                                            end_col_index, &
     641             :                                                            start_row_index, &
     642             :                                                            end_row_index
     643          12 :       INTEGER, DIMENSION(:), POINTER                    :: local_blk_rows, &
     644          12 :                                                            local_blk_cols, &
     645          12 :                                                            row_blk_size, &
     646          12 :                                                            col_blk_size
     647             :       ! TODO : Implement option/decision to not precompute all the 3c integrals
     648             :       size_mb = REAL(n_ao, kind=dp)*REAL(n_ao, kind=dp)*REAL(n_RI, kind=dp)* &
     649          12 :                 REAL(STORAGE_SIZE(size_mb), kind=dp)/8.0_dp/1024.0_dp/1024.0_dp
     650          12 :       IF (unit_nr > 0) WRITE (unit_nr, '(A44,E32.2E3,A4)') &
     651           6 :          " RTBSE| Approximate size of the 3c integrals", size_mb, " MiB"
     652             : 
     653             :       ! Get the number of block rows and columns
     654          12 :       CALL dbcsr_get_info(rho_dbcsr, nblkrows_local=nblkrows_local, nblkcols_local=nblkcols_local)
     655             :       ! Get the global indices of local rows and columns
     656          12 :       CALL dbcsr_get_info(rho_dbcsr, local_rows=local_blk_rows, local_cols=local_blk_cols)
     657             :       ! Get the sizes of all blocks
     658          12 :       CALL dbcsr_get_info(rho_dbcsr, row_blk_size=row_blk_size, col_blk_size=col_blk_size)
     659             : 
     660             :       ! Get the total required local rows and cols
     661          12 :       nrows_local = 0
     662          24 :       DO i_blk_local = 1, nblkrows_local
     663          24 :          nrows_local = nrows_local + row_blk_size(local_blk_rows(i_blk_local))
     664             :       END DO
     665          12 :       ncols_local = 0
     666          36 :       DO j_blk_local = 1, nblkcols_local
     667          36 :          ncols_local = ncols_local + col_blk_size(local_blk_cols(j_blk_local))
     668             :       END DO
     669             : 
     670             :       ! Allocate the appropriate storage
     671          60 :       ALLOCATE (int_3c(nrows_local, ncols_local, n_RI))
     672             : 
     673             :       ! Fill the storage with appropriate values, block by block
     674          12 :       row_local_offset = 1
     675          24 :       DO i_blk_local = 1, nblkrows_local
     676             :          col_local_offset = 1
     677          36 :          DO j_blk_local = 1, nblkcols_local
     678          24 :             start_row_index = row_local_offset
     679          24 :             end_row_index = start_row_index + row_blk_size(local_blk_rows(i_blk_local)) - 1
     680          24 :             start_col_index = col_local_offset
     681          24 :             end_col_index = start_col_index + col_blk_size(local_blk_cols(j_blk_local)) - 1
     682             :             CALL build_3c_integral_block(int_3c(start_row_index:end_row_index, &
     683             :                                                 start_col_index:end_col_index, &
     684             :                                                 1:n_RI), &
     685             :                                          qs_env, potential_parameter=ri_metric, &
     686             :                                          basis_j=basis_set_AO, basis_k=basis_set_AO, &
     687             :                                          basis_i=basis_set_RI, &
     688             :                                          atom_j=local_blk_rows(i_blk_local), &
     689             :                                          atom_k=local_blk_cols(j_blk_local), &
     690          24 :                                          i_bf_start_from_atom=i_RI_start_from_atom)
     691          36 :             col_local_offset = col_local_offset + col_blk_size(local_blk_cols(j_blk_local))
     692             :          END DO
     693          24 :          row_local_offset = row_local_offset + row_blk_size(local_blk_rows(i_blk_local))
     694             :       END DO
     695          18 :    END SUBROUTINE create_hartree_ri_3c
     696             : ! **************************************************************************************************
     697             : !> \brief Releases the workspace for the Hartree RI method
     698             : !> \param rtbse_env RT-BSE Environment, containing specific RI Hartree storage
     699             : !> \author Stepan Marek
     700             : !> \date 09.2024
     701             : ! **************************************************************************************************
     702          12 :    SUBROUTINE release_hartree_ri_workspace(rtbse_env)
     703             :       TYPE(rtbse_env_type)                              :: rtbse_env
     704             : 
     705          12 :       DEALLOCATE (rtbse_env%int_3c_array)
     706             : 
     707          12 :       CALL dbcsr_release(rtbse_env%rho_dbcsr)
     708             : 
     709          12 :       CALL dbcsr_release(rtbse_env%v_dbcsr)
     710             : 
     711          12 :       CALL dbcsr_release(rtbse_env%v_ao_dbcsr)
     712             : 
     713          12 :    END SUBROUTINE release_hartree_ri_workspace
     714             : ! **************************************************************************************************
     715             : !> \brief Allocates the workspaces for self-energy determination routine
     716             : !> \param rtbse_env Structure for holding information and workspace structures
     717             : !> \param qs_env Quickstep environment - entry point of calculation
     718             : !> \author Stepan Marek
     719             : !> \date 02.2024
     720             : ! **************************************************************************************************
     721          12 :    SUBROUTINE create_sigma_workspace(rtbse_env, qs_env)
     722             :       TYPE(rtbse_env_type)                               :: rtbse_env
     723             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     724             : 
     725             :       CALL create_sigma_workspace_qs_only(qs_env, rtbse_env%screened_dbt, rtbse_env%w_dbcsr, &
     726             :                                           rtbse_env%t_3c_w, rtbse_env%t_3c_work_RI_AO__AO, &
     727          12 :                                           rtbse_env%t_3c_work2_RI_AO__AO, rtbse_env%greens_dbt)
     728          12 :    END SUBROUTINE create_sigma_workspace
     729             : ! **************************************************************************************************
     730             : !> \brief Allocates the workspaces for self-energy determination routine
     731             : !> \note Does so without referencing the rtbse_env
     732             : !> \note References bs_env
     733             : !> \param rtbse_env Structure for holding information and workspace structures
     734             : !> \param qs_env Quickstep environment - entry point of calculation
     735             : !> \author Stepan Marek
     736             : !> \date 02.2024
     737             : ! **************************************************************************************************
     738          12 :    SUBROUTINE create_sigma_workspace_qs_only(qs_env, screened_dbt, screened_dbcsr, int_3c_dbt, &
     739             :                                              work_dbt_3c_1, work_dbt_3c_2, work_dbt_2c)
     740             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     741             :       TYPE(dbcsr_type)                                   :: screened_dbcsr
     742             :       TYPE(dbt_type)                                     :: screened_dbt, &
     743             :                                                             int_3c_dbt, &
     744             :                                                             work_dbt_3c_1, &
     745             :                                                             work_dbt_3c_2, &
     746             :                                                             work_dbt_2c
     747             :       TYPE(post_scf_bandstructure_type), POINTER         :: bs_env
     748             : 
     749          12 :       CALL get_qs_env(qs_env, bs_env=bs_env)
     750             : 
     751             :       ! t_3c_w
     752          12 :       CALL dbt_create(bs_env%t_RI__AO_AO, int_3c_dbt)
     753             :       ! TODO : Provide option/decision whether to store the 3c integrals precomputed
     754          12 :       CALL compute_3c_integrals(qs_env, bs_env, int_3c_dbt)
     755             :       ! t_3c_work_RI_AO__AO
     756          12 :       CALL dbt_create(bs_env%t_RI_AO__AO, work_dbt_3c_1)
     757             :       ! t_3c_work2_RI_AO__AO
     758          12 :       CALL dbt_create(bs_env%t_RI_AO__AO, work_dbt_3c_2)
     759             :       ! t_W
     760             :       ! Populate screened_dbt from gw run
     761          12 :       CALL dbcsr_create(screened_dbcsr, name="W", template=bs_env%mat_RI_RI%matrix)
     762          12 :       CALL dbt_create(screened_dbcsr, screened_dbt)
     763             :       ! greens_dbt
     764          12 :       CALL dbt_create(bs_env%mat_ao_ao%matrix, work_dbt_2c)
     765          12 :    END SUBROUTINE
     766             : ! **************************************************************************************************
     767             : !> \brief Releases the workspaces for self-energy determination
     768             : !> \param rtbse_env
     769             : !> \author Stepan Marek
     770             : !> \date 02.2024
     771             : ! **************************************************************************************************
     772          12 :    SUBROUTINE release_sigma_workspace(rtbse_env)
     773             :       TYPE(rtbse_env_type)                               :: rtbse_env
     774             : 
     775          12 :       CALL dbt_destroy(rtbse_env%t_3c_w)
     776          12 :       CALL dbt_destroy(rtbse_env%t_3c_work_RI_AO__AO)
     777          12 :       CALL dbt_destroy(rtbse_env%t_3c_work2_RI_AO__AO)
     778          12 :       CALL dbt_destroy(rtbse_env%screened_dbt)
     779          12 :       CALL dbt_destroy(rtbse_env%greens_dbt)
     780          12 :       CALL dbcsr_release(rtbse_env%w_dbcsr)
     781          12 :    END SUBROUTINE
     782             : ! **************************************************************************************************
     783             : !> \brief Multiplies real matrix by a complex matrix from the right
     784             : !> \note So far only converts the real matrix to complex one, potentially doubling the work
     785             : !> \param rtbse_env
     786             : !> \author Stepan Marek
     787             : !> \date 09.2024
     788             : ! **************************************************************************************************
     789       12960 :    SUBROUTINE multiply_fm_cfm(trans_r, trans_c, na, nb, nc, &
     790             :                               alpha, matrix_r, matrix_c, beta, res)
     791             :       ! Transposition
     792             :       CHARACTER(len=1)                                   :: trans_r, trans_c
     793             :       INTEGER                                            :: na, nb, nc
     794             :       ! accept real numbers
     795             :       ! TODO : Just use complex numbers and import z_one, z_zero etc.
     796             :       REAL(kind=dp)                                      :: alpha, beta
     797             :       TYPE(cp_fm_type)                                   :: matrix_r
     798             :       TYPE(cp_cfm_type)                                  :: matrix_c, res
     799             :       TYPE(cp_fm_type)                                   :: work_re, work_im, res_re, res_im
     800             :       REAL(kind=dp)                                      :: i_unit
     801             :       CHARACTER(len=1)                                   :: trans_cr
     802             : 
     803        3240 :       CALL cp_fm_create(work_re, matrix_c%matrix_struct)
     804        3240 :       CALL cp_fm_create(work_im, matrix_c%matrix_struct)
     805        3240 :       CALL cp_fm_create(res_re, res%matrix_struct)
     806        3240 :       CALL cp_fm_create(res_im, res%matrix_struct)
     807        3240 :       CALL cp_cfm_to_fm(matrix_c, work_re, work_im)
     808           0 :       SELECT CASE (trans_c)
     809             :       CASE ("C")
     810           0 :          i_unit = -1.0_dp
     811           0 :          trans_cr = "T"
     812             :       CASE ("T")
     813           0 :          i_unit = 1.0_dp
     814           0 :          trans_cr = "T"
     815             :       CASE default
     816        3240 :          i_unit = 1.0_dp
     817        3240 :          trans_cr = "N"
     818             :       END SELECT
     819             :       ! Actual multiplication
     820             :       CALL parallel_gemm(trans_r, trans_cr, na, nb, nc, &
     821        3240 :                          alpha, matrix_r, work_re, beta, res_re)
     822             :       CALL parallel_gemm(trans_r, trans_cr, na, nb, nc, &
     823        3240 :                          i_unit*alpha, matrix_r, work_im, beta, res_im)
     824        3240 :       CALL cp_fm_to_cfm(res_re, res_im, res)
     825        3240 :       CALL cp_fm_release(work_re)
     826        3240 :       CALL cp_fm_release(work_im)
     827        3240 :       CALL cp_fm_release(res_re)
     828        3240 :       CALL cp_fm_release(res_im)
     829             : 
     830        3240 :    END SUBROUTINE multiply_fm_cfm
     831             : ! **************************************************************************************************
     832             : !> \brief Multiplies complex matrix by a real matrix from the right
     833             : !> \note So far only converts the real matrix to complex one, potentially doubling the work
     834             : !> \param rtbse_env
     835             : !> \author Stepan Marek
     836             : !> \date 09.2024
     837             : ! **************************************************************************************************
     838        4864 :    SUBROUTINE multiply_cfm_fm(trans_c, trans_r, na, nb, nc, &
     839             :                               alpha, matrix_c, matrix_r, beta, res)
     840             :       ! Transposition
     841             :       CHARACTER(len=1)                                   :: trans_c, trans_r
     842             :       INTEGER                                            :: na, nb, nc
     843             :       ! accept real numbers
     844             :       ! TODO : complex number support via interface?
     845             :       REAL(kind=dp)                                      :: alpha, beta
     846             :       TYPE(cp_cfm_type)                                  :: matrix_c, res
     847             :       TYPE(cp_fm_type)                                   :: matrix_r
     848             :       TYPE(cp_fm_type)                                   :: work_re, work_im, res_re, res_im
     849             :       REAL(kind=dp)                                      :: i_unit
     850             :       CHARACTER(len=1)                                   :: trans_cr
     851             : 
     852        1216 :       CALL cp_fm_create(work_re, matrix_c%matrix_struct)
     853        1216 :       CALL cp_fm_create(work_im, matrix_c%matrix_struct)
     854        1216 :       CALL cp_fm_create(res_re, res%matrix_struct)
     855        1216 :       CALL cp_fm_create(res_im, res%matrix_struct)
     856        1216 :       CALL cp_cfm_to_fm(matrix_c, work_re, work_im)
     857           0 :       SELECT CASE (trans_c)
     858             :       CASE ("C")
     859           0 :          i_unit = -1.0_dp
     860           0 :          trans_cr = "T"
     861             :       CASE ("T")
     862           0 :          i_unit = 1.0_dp
     863           0 :          trans_cr = "T"
     864             :       CASE default
     865        1216 :          i_unit = 1.0_dp
     866        1216 :          trans_cr = "N"
     867             :       END SELECT
     868             :       ! Actual multiplication
     869             :       CALL parallel_gemm(trans_cr, trans_r, na, nb, nc, &
     870        1216 :                          alpha, work_re, matrix_r, beta, res_re)
     871             :       CALL parallel_gemm(trans_cr, trans_r, na, nb, nc, &
     872        1216 :                          i_unit*alpha, work_im, matrix_r, beta, res_im)
     873        1216 :       CALL cp_fm_to_cfm(res_re, res_im, res)
     874        1216 :       CALL cp_fm_release(work_re)
     875        1216 :       CALL cp_fm_release(work_im)
     876        1216 :       CALL cp_fm_release(res_re)
     877        1216 :       CALL cp_fm_release(res_im)
     878             : 
     879        1216 :    END SUBROUTINE multiply_cfm_fm
     880           0 : END MODULE

Generated by: LCOV version 1.15