LCOV - code coverage report
Current view: top level - src - qs_ot_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:92574dc) Lines: 97.0 % 1017 986
Test Date: 2026-09-24 01:27:39 Functions: 73.7 % 19 14

            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 orbital transformations
      10              : !> \par History
      11              : !>      Added Taylor expansion based computation of the matrix functions (01.2004)
      12              : !>      added additional rotation variables for non-equivalent occupied orbs (08.2004)
      13              : !> \author Joost VandeVondele (06.2002)
      14              : ! **************************************************************************************************
      15              : MODULE qs_ot_types
      16              :    USE bibliography,                    ONLY: VandeVondele2003,&
      17              :                                               Weber2008,&
      18              :                                               cite_reference
      19              :    USE cp_blacs_env,                    ONLY: cp_blacs_env_release,&
      20              :                                               cp_blacs_env_type
      21              :    USE cp_dbcsr_api,                    ONLY: dbcsr_copy,&
      22              :                                               dbcsr_get_info,&
      23              :                                               dbcsr_init_p,&
      24              :                                               dbcsr_p_type,&
      25              :                                               dbcsr_release_p,&
      26              :                                               dbcsr_set,&
      27              :                                               dbcsr_type,&
      28              :                                               dbcsr_type_no_symmetry
      29              :    USE cp_dbcsr_contrib,                ONLY: dbcsr_add_on_diag
      30              :    USE cp_dbcsr_operations,             ONLY: cp_dbcsr_m_by_n_from_row_template,&
      31              :                                               cp_dbcsr_m_by_n_from_template,&
      32              :                                               dbcsr_allocate_matrix_set,&
      33              :                                               dbcsr_deallocate_matrix_set
      34              :    USE cp_fm_struct,                    ONLY: cp_fm_struct_get,&
      35              :                                               cp_fm_struct_type
      36              :    USE cp_fm_types,                     ONLY: cp_fm_release,&
      37              :                                               cp_fm_type
      38              :    USE input_constants,                 ONLY: &
      39              :         cholesky_reduce, ls_2pnt, ls_3pnt, ls_adapt, ls_gold, ls_none, ot_algo_irac, &
      40              :         ot_algo_taylor_or_diag, ot_chol_irac, ot_lattice_fft_auto, ot_lattice_fft_off, &
      41              :         ot_lattice_fft_on, ot_low_rank_base_lattice_fft, ot_low_rank_base_overlap, ot_lwdn_irac, &
      42              :         ot_mini_broyden, ot_mini_cg, ot_mini_diis, ot_mini_lbfgs, ot_mini_sd, ot_poly_irac, &
      43              :         ot_precond_fermi_low_rank, ot_precond_full_all, ot_precond_full_all_covariant, &
      44              :         ot_precond_full_kinetic, ot_precond_full_single, ot_precond_full_single_inverse, &
      45              :         ot_precond_none, ot_precond_s_inverse, ot_precond_solver_chebyshev, &
      46              :         ot_precond_solver_default, ot_precond_solver_direct, ot_precond_solver_inv_chol, &
      47              :         ot_precond_solver_update
      48              :    USE input_section_types,             ONLY: section_vals_type,&
      49              :                                               section_vals_val_get
      50              :    USE kinds,                           ONLY: dp
      51              :    USE message_passing,                 ONLY: mp_para_env_release,&
      52              :                                               mp_para_env_type
      53              :    USE preconditioner_types,            ONLY: preconditioner_type
      54              : #include "./base/base_uses.f90"
      55              : 
      56              :    IMPLICIT NONE
      57              : 
      58              :    PRIVATE
      59              : 
      60              :    PUBLIC  :: qs_ot_type
      61              :    PUBLIC  :: qs_ot_physical_secant_type
      62              :    PUBLIC  :: qs_ot_settings_type
      63              :    PUBLIC  :: qs_ot_destroy
      64              :    PUBLIC  :: qs_ot_allocate
      65              :    PUBLIC  :: qs_ot_allocate_complex_state
      66              :    PUBLIC  :: qs_ot_channel_index
      67              :    PUBLIC  :: qs_ot_check_channel_context
      68              :    PUBLIC  :: qs_ot_init
      69              :    PUBLIC  :: qs_ot_kpoint_preconditioner_solver_supported
      70              :    PUBLIC  :: qs_ot_kpoint_preconditioner_scale
      71              :    PUBLIC  :: qs_ot_kpoint_preconditioner_supported
      72              :    PUBLIC  :: qs_ot_number_of_channels
      73              :    PUBLIC  :: qs_ot_settings_init
      74              :    PUBLIC  :: qs_ot_set_context
      75              :    PUBLIC  :: ot_readwrite_input
      76              : 
      77              : ! **************************************************************************************************
      78              : !> \brief notice, this variable needs to be copyable, needed for spins as e.g. in qs_ot_scf
      79              : ! **************************************************************************************************
      80              :    TYPE qs_ot_settings_type
      81              :       LOGICAL           :: do_rotation = .FALSE., do_ener = .FALSE.
      82              :       LOGICAL           :: ks = .FALSE.
      83              :       CHARACTER(LEN=4)  :: ot_method = ""
      84              :       CHARACTER(LEN=3)  :: ot_algorithm = ""
      85              :       CHARACTER(LEN=4)  :: line_search_method = ""
      86              :       CHARACTER(LEN=20) :: preconditioner_name = ""
      87              :       INTEGER           :: preconditioner_type = -1
      88              :       CHARACTER(LEN=20) :: low_rank_base_name = ""
      89              :       INTEGER           :: low_rank_base = ot_low_rank_base_overlap
      90              :       CHARACTER(LEN=20) :: lattice_fft_name = ""
      91              :       INTEGER           :: lattice_fft = ot_lattice_fft_off
      92              :       INTEGER           :: lattice_fft_local_cells = 0
      93              :       INTEGER           :: cholesky_type = -1
      94              :       INTEGER           :: ot_state = 0
      95              :       CHARACTER(LEN=20) :: precond_solver_name = ""
      96              :       INTEGER           :: precond_solver_type = -1
      97              :       INTEGER           :: chebyshev_degree = 8
      98              :       INTEGER           :: fermi_low_rank_max_rank = 48
      99              :       LOGICAL           :: safer_diis = .FALSE.
     100              :       REAL(KIND=dp)     :: ds_min = -1.0_dp
     101              :       REAL(KIND=dp)     :: energy_gap = -1.0_dp
     102              :       INTEGER           :: diis_m = -1
     103              :       REAL(KIND=dp)     :: lbfgs_curvature_tol = 1.0E-4_dp
     104              :       LOGICAL           :: lbfgs_damping = .TRUE.
     105              :       INTEGER           :: max_scf_diis = 0
     106              :       REAL(KIND=dp)     :: gold_target = -1.0_dp
     107              :       REAL(KIND=dp)     :: eps_taylor = -1.0_dp ! minimum accuracy of Taylor expansion
     108              :       INTEGER           :: max_taylor = -1 ! maximum order of Taylor expansion before switching to diagonalization
     109              :       INTEGER           :: irac_degree = -1 ! used to control the refinement polynomial degree
     110              :       INTEGER           :: max_irac = -1 ! maximum number of iteration for refinement
     111              :       REAL(KIND=dp)     :: eps_irac = -1.0_dp ! target accuracy for refinement
     112              :       REAL(KIND=dp)     :: eps_irac_quick_exit = -1.0_dp
     113              :       REAL(KIND=dp)     :: eps_irac_filter_matrix = -1.0_dp
     114              :       REAL(KIND=dp)     :: eps_irac_switch = -1.0_dp
     115              :       LOGICAL           :: on_the_fly_loc = .FALSE.
     116              :       CHARACTER(LEN=4)  :: ortho_irac = ""
     117              :       LOGICAL           :: occupation_preconditioner = .FALSE., add_nondiag_energy = .FALSE.
     118              :       REAL(KIND=dp)     :: nondiag_energy_strength = -1.0_dp
     119              :       REAL(KIND=dp)     :: broyden_beta = -1.0_dp, broyden_gamma = -1.0_dp, broyden_sigma = -1.0_dp
     120              :       REAL(KIND=dp)     :: broyden_eta = -1.0_dp, broyden_omega = -1.0_dp, broyden_sigma_decrease = -1.0_dp
     121              :       REAL(KIND=dp)     :: broyden_sigma_min = -1.0_dp
     122              :       LOGICAL           :: broyden_forget_history = .FALSE., broyden_adaptive_sigma = .FALSE.
     123              :       LOGICAL           :: broyden_enable_flip = .FALSE.
     124              :    END TYPE qs_ot_settings_type
     125              : 
     126              : ! **************************************************************************************************
     127              : !> \brief bounded physical endpoint history for one spin density at one K point
     128              : ! **************************************************************************************************
     129              :    TYPE qs_ot_physical_secant_type
     130              :       TYPE(cp_fm_type), POINTER :: c0 => NULL(), c0_im => NULL()
     131              :       TYPE(cp_fm_type), POINTER :: h0 => NULL(), h0_im => NULL()
     132              :       TYPE(cp_fm_type), POINTER :: c_previous => NULL(), c_previous_im => NULL()
     133              :       TYPE(cp_fm_type), POINTER :: y_previous => NULL(), y_previous_im => NULL()
     134              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: occupation0, occupation_previous
     135              :       LOGICAL :: reference_valid = .FALSE., secant_valid = .FALSE.
     136              :    END TYPE qs_ot_physical_secant_type
     137              : 
     138              : ! **************************************************************************************************
     139              :    TYPE qs_ot_type
     140              :       ! this sets the method to be used
     141              :       TYPE(qs_ot_settings_type) :: settings = qs_ot_settings_type()
     142              :       LOGICAL                   :: restricted = .FALSE.
     143              :       INTEGER                   :: spin_index = 0, kpoint_index = 0, local_kpoint_index = 0
     144              :       REAL(KIND=dp)             :: kpoint_weight = 1.0_dp
     145              :       LOGICAL                   :: has_kpoint_context = .FALSE.
     146              :       LOGICAL                   :: state_allocated = .FALSE.
     147              :       LOGICAL                   :: has_complex_kpoint_state = .FALSE.
     148              : 
     149              :       ! first part of the variables, for occupied subspace invariant optimisation
     150              : 
     151              :       ! add a preconditioner matrix. should be symmetric and positive definite
     152              :       ! the type of this matrix might change in the future
     153              :       TYPE(preconditioner_type), POINTER :: preconditioner => NULL()
     154              : 
     155              :       ! these will/might change during iterations
     156              : 
     157              :       ! OT / TOD
     158              :       TYPE(dbcsr_type), POINTER :: matrix_p => NULL(), matrix_p_im => NULL()
     159              :       TYPE(dbcsr_type), POINTER :: matrix_r => NULL(), matrix_r_im => NULL()
     160              :       TYPE(dbcsr_type), POINTER :: matrix_sinp => NULL(), matrix_sinp_im => NULL()
     161              :       TYPE(dbcsr_type), POINTER :: matrix_cosp => NULL(), matrix_cosp_im => NULL()
     162              :       TYPE(dbcsr_type), POINTER :: matrix_sinp_b => NULL()
     163              :       TYPE(dbcsr_type), POINTER :: matrix_cosp_b => NULL()
     164              :       TYPE(dbcsr_type), POINTER :: matrix_buf1 => NULL(), matrix_buf1_im => NULL()
     165              :       TYPE(dbcsr_type), POINTER :: matrix_buf2 => NULL(), matrix_buf2_im => NULL()
     166              :       TYPE(dbcsr_type), POINTER :: matrix_buf3 => NULL(), matrix_buf3_im => NULL()
     167              :       TYPE(dbcsr_type), POINTER :: matrix_buf4 => NULL(), matrix_buf4_im => NULL()
     168              :       TYPE(dbcsr_type), POINTER :: matrix_os => NULL(), matrix_os_im => NULL()
     169              :       TYPE(dbcsr_type), POINTER :: matrix_buf1_ortho => NULL(), matrix_buf1_ortho_im => NULL()
     170              :       TYPE(dbcsr_type), POINTER :: matrix_buf2_ortho => NULL(), matrix_buf2_ortho_im => NULL()
     171              :       TYPE(dbcsr_type), POINTER :: matrix_tmp_ortho => NULL()
     172              :       TYPE(dbcsr_type), POINTER :: matrix_buf_nk => NULL(), matrix_buf_nk_im => NULL(), &
     173              :                                    matrix_tmp_nk => NULL()
     174              : 
     175              :       REAL(KIND=dp), DIMENSION(:), POINTER :: evals => NULL()
     176              :       REAL(KIND=dp), DIMENSION(:), POINTER :: dum => NULL()
     177              : 
     178              :       ! matrix os valid
     179              :       LOGICAL :: os_valid = .FALSE.
     180              : 
     181              :       ! for efficient/parallel writing to the blacs_matrix
     182              :       TYPE(mp_para_env_type), POINTER :: para_env => NULL()
     183              :       TYPE(cp_blacs_env_type), POINTER :: blacs_env => NULL()
     184              : 
     185              :       ! mo-like vectors
     186              :       TYPE(dbcsr_type), POINTER :: matrix_c0 => NULL(), matrix_sc0 => NULL(), matrix_psc0 => NULL()
     187              :       TYPE(dbcsr_type), POINTER :: matrix_c0_im => NULL(), matrix_sc0_im => NULL(), matrix_psc0_im => NULL()
     188              : 
     189              :       ! OT / IR
     190              :       TYPE(dbcsr_type), POINTER :: buf1_k_k_nosym => NULL(), buf2_k_k_nosym => NULL(), &
     191              :                                    buf3_k_k_nosym => NULL(), buf4_k_k_nosym => NULL(), &
     192              :                                    buf1_k_k_sym => NULL(), buf2_k_k_sym => NULL(), &
     193              :                                    buf3_k_k_sym => NULL(), buf4_k_k_sym => NULL(), &
     194              :                                    p_k_k_sym => NULL(), buf1_n_k => NULL(), buf1_n_k_dp => NULL()
     195              : 
     196              :       ! only here for the ease of programming. These will have to be supplied
     197              :       ! explicitly at all times
     198              :       TYPE(dbcsr_type), POINTER :: matrix_x => NULL(), matrix_sx => NULL(), matrix_gx => NULL()
     199              :       TYPE(dbcsr_type), POINTER :: matrix_x_im => NULL(), matrix_sx_im => NULL(), matrix_gx_im => NULL()
     200              :       TYPE(dbcsr_type), POINTER :: matrix_preconditioned_gx => NULL(), &
     201              :                                    matrix_preconditioned_gx_im => NULL()
     202              :       TYPE(dbcsr_type), POINTER :: matrix_response_gx => NULL(), matrix_response_gx_im => NULL()
     203              :       TYPE(dbcsr_type), POINTER :: matrix_mermin_g0 => NULL(), matrix_mermin_g0_im => NULL()
     204              :       TYPE(dbcsr_type), POINTER :: matrix_ref_inv_sqrt => NULL(), matrix_ref_inv_sqrt_im => NULL()
     205              :       ! ROKS shares one orbital channel between two physical spin-density histories.
     206              :       TYPE(qs_ot_physical_secant_type), DIMENSION(2) :: mermin_physical
     207              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: ener_mermin_g0
     208              :       LOGICAL :: mermin_gradient_ref_valid = .FALSE.
     209              :       TYPE(dbcsr_type), POINTER :: matrix_dx => NULL(), matrix_gx_old => NULL()
     210              :       TYPE(dbcsr_type), POINTER :: matrix_dx_im => NULL(), matrix_gx_old_im => NULL()
     211              : 
     212              :       LOGICAL :: use_gx_old = .FALSE., use_dx = .FALSE.
     213              : 
     214              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_h_e => NULL(), matrix_h_x => NULL()
     215              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_h_e_im => NULL(), matrix_h_x_im => NULL()
     216              :       REAL(KIND=dp), DIMENSION(:), POINTER      :: lbfgs_rho => NULL(), lbfgs_yy => NULL()
     217              :       REAL(KIND=dp), DIMENSION(:), POINTER      :: lbfgs_sy_rotation => NULL(), &
     218              :                                                    lbfgs_yy_rotation => NULL()
     219              : 
     220              :       REAL(KIND=dp), DIMENSION(:, :), POINTER  :: ls_diis => NULL()
     221              :       REAL(KIND=dp), DIMENSION(:, :), POINTER  :: lss_diis => NULL()
     222              :       REAL(KIND=dp), DIMENSION(:), POINTER  :: c_diis => NULL()
     223              :       REAL(KIND=dp), DIMENSION(:), POINTER  :: c_broy => NULL()
     224              :       REAL(KIND=dp), DIMENSION(:), POINTER  :: energy_h => NULL()
     225              :       INTEGER, DIMENSION(:), POINTER         :: ipivot => NULL()
     226              : 
     227              :       REAL(KIND=dp)    :: ot_pos(53) = -1.0_dp, ot_energy(53) = -1.0_dp, ot_grad(53) = -1.0_dp ! HARD LIMIT FOR THE LS
     228              :       INTEGER          :: line_search_left = -1, line_search_right = -1, line_search_mid = -1
     229              :       INTEGER          :: line_search_count = -1
     230              :       LOGICAL          :: line_search_might_be_done = .FALSE.
     231              :       REAL(KIND=dp)    :: delta = -1.0_dp, gnorm = -1.0_dp, gnorm_old = -1.0_dp, etotal = -1.0_dp, gradient = -1.0_dp
     232              :       LOGICAL          :: energy_only = .FALSE.
     233              :       INTEGER          :: diis_iter = -1
     234              :       CHARACTER(LEN=8) :: OT_METHOD_FULL = ""
     235              :       INTEGER          :: OT_count = -1
     236              :       REAL(KIND=dp)    :: ds_min = -1.0_dp
     237              :       REAL(KIND=dp)    :: broyden_adaptive_sigma = -1.0_dp
     238              : 
     239              :       LOGICAL          :: do_taylor = .FALSE.
     240              :       INTEGER          :: taylor_order = -1
     241              :       REAL(KIND=dp)    :: largest_eval_upper_bound = -1.0_dp
     242              : 
     243              :       ! second part of the variables, if an explicit rotation is required as well
     244              :       TYPE(dbcsr_type), POINTER :: rot_mat_u => NULL() ! rotation matrix
     245              :       TYPE(dbcsr_type), POINTER :: rot_mat_u_im => NULL() ! imaginary part at complex k points
     246              :       TYPE(dbcsr_type), POINTER :: rot_mat_x => NULL() ! antisymmetric matrix that parametrises rot_matrix_u
     247              :       TYPE(dbcsr_type), POINTER :: rot_mat_x_im => NULL() ! symmetric imaginary generator component
     248              :       TYPE(dbcsr_type), POINTER :: rot_mat_dedu => NULL() ! derivative of the total energy wrt to u
     249              :       TYPE(dbcsr_type), POINTER :: rot_mat_dedu_im => NULL()
     250              :       TYPE(dbcsr_type), POINTER :: rot_mat_chc => NULL() ! for convencience, the matrix c^T H c
     251              :       TYPE(dbcsr_type), POINTER :: rot_mat_chc_im => NULL()
     252              : 
     253              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rot_mat_h_e => NULL()
     254              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rot_mat_h_x => NULL()
     255              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rot_mat_h_e_im => NULL()
     256              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rot_mat_h_x_im => NULL()
     257              :       TYPE(dbcsr_type), POINTER :: rot_mat_gx => NULL()
     258              :       TYPE(dbcsr_type), POINTER :: rot_mat_gx_im => NULL()
     259              :       TYPE(dbcsr_type), POINTER :: rot_mat_response_gx => NULL()
     260              :       TYPE(dbcsr_type), POINTER :: rot_mat_response_gx_im => NULL()
     261              :       TYPE(dbcsr_type), POINTER :: rot_mat_mermin_g0 => NULL()
     262              :       TYPE(dbcsr_type), POINTER :: rot_mat_mermin_g0_im => NULL()
     263              :       TYPE(dbcsr_type), POINTER :: rot_mat_gx_old => NULL()
     264              :       TYPE(dbcsr_type), POINTER :: rot_mat_gx_old_im => NULL()
     265              :       TYPE(dbcsr_type), POINTER :: rot_mat_dx => NULL()
     266              :       TYPE(dbcsr_type), POINTER :: rot_mat_dx_im => NULL()
     267              : 
     268              :       REAL(KIND=dp), DIMENSION(:), POINTER :: rot_mat_evals => NULL()
     269              :       TYPE(dbcsr_type), POINTER :: rot_mat_evec_re => NULL()
     270              :       TYPE(dbcsr_type), POINTER :: rot_mat_evec_im => NULL()
     271              :       LOGICAL                   :: rotation_response_valid = .FALSE.
     272              :       LOGICAL                   :: response_candidate_pending = .FALSE.
     273              :       LOGICAL                   :: response_shadow_pending = .FALSE.
     274              :       INTEGER                   :: response_candidate_directions = 0
     275              :       INTEGER                   :: response_candidate_good_samples = 0
     276              :       INTEGER                   :: response_candidate_cooldown = 0
     277              :       INTEGER                   :: response_shadow_good_samples = 0
     278              :       REAL(KIND=dp)             :: response_model_curvature = 0.0_dp
     279              :       REAL(KIND=dp)             :: response_shadow_curvature = 0.0_dp
     280              :       LOGICAL                   :: response_hxc_direction_valid = .FALSE.
     281              :       REAL(KIND=dp)             :: response_reference_energy = 0.0_dp
     282              :       REAL(KIND=dp)             :: response_reference_residual = 0.0_dp
     283              :       REAL(KIND=dp)             :: response_predicted_slope = 0.0_dp
     284              :       REAL(KIND=dp)             :: response_predicted_curvature = 0.0_dp
     285              : 
     286              :       ! third part of the variables, if we need to optimize orbital energies
     287              :       REAL(KIND=dp), POINTER, DIMENSION(:) :: ener_x => NULL()
     288              :       REAL(KIND=dp), POINTER, DIMENSION(:) :: ener_rayleigh => NULL()
     289              :       REAL(KIND=dp), POINTER, DIMENSION(:) :: ener_dx => NULL()
     290              :       REAL(KIND=dp), POINTER, DIMENSION(:) :: ener_gx => NULL()
     291              :       REAL(KIND=dp), POINTER, DIMENSION(:) :: ener_preconditioned_gx => NULL()
     292              :       REAL(KIND=dp), POINTER, DIMENSION(:) :: ener_response_gx => NULL()
     293              :       REAL(KIND=dp), POINTER, DIMENSION(:) :: ener_gx_old => NULL()
     294              :       REAL(KIND=dp), POINTER, DIMENSION(:, :) :: ener_h_e => NULL()
     295              :       REAL(KIND=dp), POINTER, DIMENSION(:, :) :: ener_h_x => NULL()
     296              :    END TYPE qs_ot_type
     297              : 
     298              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_ot_types'
     299              : 
     300              : CONTAINS
     301              : 
     302              : ! **************************************************************************************************
     303              : !> \brief sets default values for the settings type
     304              : !> \param settings ...
     305              : !> \par History
     306              : !>      10.2004 created [Joost VandeVondele]
     307              : ! **************************************************************************************************
     308        17447 :    SUBROUTINE qs_ot_settings_init(settings)
     309              :       TYPE(qs_ot_settings_type)                          :: settings
     310              : 
     311        17447 :       settings%ot_method = "CG"
     312        17447 :       settings%ot_algorithm = "TOD"
     313        17447 :       settings%diis_m = 7
     314        17447 :       settings%lbfgs_curvature_tol = 1.0E-4_dp
     315        17447 :       settings%lbfgs_damping = .TRUE.
     316        17447 :       settings%preconditioner_name = "FULL_KINETIC"
     317        17447 :       settings%preconditioner_type = ot_precond_full_kinetic
     318        17447 :       settings%low_rank_base_name = "OVERLAP_INVERSE"
     319        17447 :       settings%low_rank_base = ot_low_rank_base_overlap
     320        17447 :       settings%lattice_fft_name = "OFF"
     321        17447 :       settings%lattice_fft = ot_lattice_fft_off
     322        17447 :       settings%lattice_fft_local_cells = 0
     323        17447 :       settings%cholesky_type = cholesky_reduce
     324        17447 :       settings%precond_solver_name = "CHOLESKY_INVERSE"
     325        17447 :       settings%precond_solver_type = ot_precond_solver_inv_chol
     326        17447 :       settings%chebyshev_degree = 8
     327        17447 :       settings%fermi_low_rank_max_rank = 48
     328        17447 :       settings%line_search_method = "2PNT"
     329        17447 :       settings%ds_min = 0.15_dp
     330        17447 :       settings%safer_diis = .TRUE.
     331        17447 :       settings%energy_gap = 0.2_dp
     332        17447 :       settings%eps_taylor = 1.0E-16_dp
     333        17447 :       settings%max_taylor = 4
     334        17447 :       settings%gold_target = 0.01_dp
     335        17447 :       settings%do_rotation = .FALSE.
     336        17447 :       settings%do_ener = .FALSE.
     337        17447 :       settings%irac_degree = 4
     338        17447 :       settings%max_irac = 50
     339        17447 :       settings%max_scf_diis = 0
     340        17447 :       settings%eps_irac = 1.0E-10_dp
     341        17447 :       settings%eps_irac_quick_exit = 1.0E-5_dp
     342        17447 :       settings%eps_irac_switch = 1.0E-2_dp
     343        17447 :       settings%eps_irac_filter_matrix = 0.0_dp
     344        17447 :       settings%on_the_fly_loc = .FALSE.
     345        17447 :       settings%ortho_irac = "CHOL"
     346        17447 :       settings%ks = .TRUE.
     347        17447 :       settings%occupation_preconditioner = .FALSE.
     348        17447 :       settings%add_nondiag_energy = .FALSE.
     349        17447 :       settings%nondiag_energy_strength = 0.0_dp
     350              : 
     351        17447 :    END SUBROUTINE qs_ot_settings_init
     352              : 
     353              : ! **************************************************************************************************
     354              : !> \brief label an OT environment by spin and optional irreducible k-point context
     355              : !> \param qs_ot_env ...
     356              : !> \param spin_index ...
     357              : !> \param kpoint_index ...
     358              : !> \param local_kpoint_index ...
     359              : !> \param kpoint_weight ...
     360              : ! **************************************************************************************************
     361        18542 :    SUBROUTINE qs_ot_set_context(qs_ot_env, spin_index, kpoint_index, local_kpoint_index, kpoint_weight)
     362              :       TYPE(qs_ot_type)                                   :: qs_ot_env
     363              :       INTEGER, INTENT(IN), OPTIONAL                      :: spin_index, kpoint_index, &
     364              :                                                             local_kpoint_index
     365              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: kpoint_weight
     366              : 
     367        18542 :       IF (PRESENT(spin_index)) qs_ot_env%spin_index = spin_index
     368        18542 :       IF (PRESENT(kpoint_index)) qs_ot_env%kpoint_index = kpoint_index
     369        18542 :       IF (PRESENT(local_kpoint_index)) qs_ot_env%local_kpoint_index = local_kpoint_index
     370        18542 :       IF (PRESENT(kpoint_weight)) qs_ot_env%kpoint_weight = kpoint_weight
     371        18542 :       qs_ot_env%has_kpoint_context = PRESENT(kpoint_index) .OR. PRESENT(local_kpoint_index)
     372              : 
     373        18542 :    END SUBROUTINE qs_ot_set_context
     374              : 
     375              : ! **************************************************************************************************
     376              : !> \brief number of OT optimization channels for spin and k-point resolved state
     377              : !> \param nspin ...
     378              : !> \param nkpoint ...
     379              : !> \param restricted ...
     380              : !> \return ...
     381              : ! **************************************************************************************************
     382        18290 :    INTEGER FUNCTION qs_ot_number_of_channels(nspin, nkpoint, restricted)
     383              :       INTEGER, INTENT(IN)                                :: nspin
     384              :       INTEGER, INTENT(IN), OPTIONAL                      :: nkpoint
     385              :       LOGICAL, INTENT(IN), OPTIONAL                      :: restricted
     386              : 
     387              :       INTEGER                                            :: nkpoint_eff, nspin_eff
     388              : 
     389        18290 :       nspin_eff = nspin
     390        18290 :       IF (PRESENT(restricted)) THEN
     391        18290 :          IF (restricted) nspin_eff = 1
     392              :       END IF
     393        18290 :       nkpoint_eff = 1
     394        18290 :       IF (PRESENT(nkpoint)) nkpoint_eff = nkpoint
     395              : 
     396        18290 :       CPASSERT(nspin_eff >= 1)
     397        18290 :       CPASSERT(nkpoint_eff >= 1)
     398        18290 :       qs_ot_number_of_channels = nspin_eff*nkpoint_eff
     399              : 
     400        18290 :    END FUNCTION qs_ot_number_of_channels
     401              : 
     402              : ! **************************************************************************************************
     403              : !> \brief Return whether a preconditioner is implemented for complex k-point OT.
     404              : !> \param preconditioner_type selected OT preconditioner
     405              : !> \param use_real_wfn whether the k-point channel stores a real wavefunction
     406              : !> \return ...
     407              : ! **************************************************************************************************
     408          362 :    PURE ELEMENTAL FUNCTION qs_ot_kpoint_preconditioner_supported(preconditioner_type, use_real_wfn) &
     409              :       RESULT(supported)
     410              :       INTEGER, INTENT(IN)                                :: preconditioner_type
     411              :       LOGICAL, INTENT(IN)                                :: use_real_wfn
     412              :       LOGICAL                                            :: supported
     413              : 
     414          362 :       supported = .FALSE.
     415          362 :       IF (.NOT. use_real_wfn) THEN
     416              :          supported = preconditioner_type == ot_precond_none .OR. &
     417              :                      preconditioner_type == ot_precond_fermi_low_rank .OR. &
     418              :                      preconditioner_type == ot_precond_full_all .OR. &
     419              :                      preconditioner_type == ot_precond_full_single .OR. &
     420              :                      preconditioner_type == ot_precond_full_all_covariant .OR. &
     421              :                      preconditioner_type == ot_precond_full_single_inverse .OR. &
     422              :                      preconditioner_type == ot_precond_full_kinetic .OR. &
     423          360 :                      preconditioner_type == ot_precond_s_inverse
     424              :       END IF
     425              : 
     426          362 :    END FUNCTION qs_ot_kpoint_preconditioner_supported
     427              : 
     428              : ! **************************************************************************************************
     429              : !> \brief Return whether a solver is implemented for a complex k-point OT preconditioner.
     430              : !> \param preconditioner_type selected OT preconditioner
     431              : !> \param solver_type selected preconditioner solver
     432              : !> \param use_real_wfn whether the k-point channel stores a real wavefunction
     433              : !> \return ...
     434              : ! **************************************************************************************************
     435          190 :    PURE ELEMENTAL FUNCTION qs_ot_kpoint_preconditioner_solver_supported( &
     436              :       preconditioner_type, solver_type, use_real_wfn) RESULT(supported)
     437              :       INTEGER, INTENT(IN)                                :: preconditioner_type, solver_type
     438              :       LOGICAL, INTENT(IN)                                :: use_real_wfn
     439              :       LOGICAL                                            :: supported
     440              : 
     441          190 :       supported = qs_ot_kpoint_preconditioner_supported(preconditioner_type, use_real_wfn)
     442          190 :       IF (.NOT. supported) RETURN
     443              :       IF (preconditioner_type == ot_precond_fermi_low_rank .OR. &
     444              :           preconditioner_type == ot_precond_full_all .OR. &
     445          190 :           preconditioner_type == ot_precond_full_all_covariant .OR. &
     446              :           preconditioner_type == ot_precond_full_single) THEN
     447          102 :          supported = solver_type == ot_precond_solver_default
     448              :       ELSE IF (preconditioner_type == ot_precond_full_single_inverse .OR. &
     449              :                preconditioner_type == ot_precond_full_kinetic .OR. &
     450              :                preconditioner_type == ot_precond_s_inverse) THEN
     451              :          supported = solver_type == ot_precond_solver_default .OR. &
     452           80 :                      solver_type == ot_precond_solver_inv_chol
     453              :       END IF
     454              : 
     455              :    END FUNCTION qs_ot_kpoint_preconditioner_solver_supported
     456              : 
     457              : ! **************************************************************************************************
     458              : !> \brief Scale an inverse k-point Hessian block consistently with its irreducible weight.
     459              : !> \param kpoint_weight positive irreducible k-point weight
     460              : !> \return ...
     461              : ! **************************************************************************************************
     462         4703 :    PURE ELEMENTAL REAL(KIND=dp) FUNCTION qs_ot_kpoint_preconditioner_scale(kpoint_weight)
     463              :       REAL(KIND=dp), INTENT(IN)                          :: kpoint_weight
     464              : 
     465         4703 :       qs_ot_kpoint_preconditioner_scale = 1.0_dp/kpoint_weight
     466              : 
     467         4703 :    END FUNCTION qs_ot_kpoint_preconditioner_scale
     468              : 
     469              : ! **************************************************************************************************
     470              : !> \brief flat OT channel index for a spin/k-point pair
     471              : !> \param ispin ...
     472              : !> \param ikpoint ...
     473              : !> \param nspin ...
     474              : !> \return ...
     475              : ! **************************************************************************************************
     476        52940 :    INTEGER FUNCTION qs_ot_channel_index(ispin, ikpoint, nspin)
     477              :       INTEGER, INTENT(IN)                                :: ispin, ikpoint, nspin
     478              : 
     479        52940 :       CPASSERT(ispin >= 1)
     480        52940 :       CPASSERT(ikpoint >= 1)
     481        52940 :       CPASSERT(nspin >= 1)
     482        52940 :       CPASSERT(ispin <= nspin)
     483        52940 :       qs_ot_channel_index = (ikpoint - 1)*nspin + ispin
     484              : 
     485        52940 :    END FUNCTION qs_ot_channel_index
     486              : 
     487              : ! **************************************************************************************************
     488              : !> \brief validate the flat OT channel identity for spin and optional irreducible k-points
     489              : !> \param qs_ot_env ...
     490              : !> \param nspin ...
     491              : !> \param nkpoint ...
     492              : !> \param restricted ...
     493              : !> \param require_kpoint ...
     494              : !> \param kp_range ...
     495              : !> \param wkp ...
     496              : !> \param require_local_state ...
     497              : !> \param require_complex_state ...
     498              : ! **************************************************************************************************
     499        10557 :    SUBROUTINE qs_ot_check_channel_context(qs_ot_env, nspin, nkpoint, restricted, require_kpoint, &
     500              :                                           kp_range, wkp, require_local_state, require_complex_state)
     501              :       TYPE(qs_ot_type), DIMENSION(:), INTENT(IN)         :: qs_ot_env
     502              :       INTEGER, INTENT(IN)                                :: nspin
     503              :       INTEGER, INTENT(IN), OPTIONAL                      :: nkpoint
     504              :       LOGICAL, INTENT(IN), OPTIONAL                      :: restricted, require_kpoint
     505              :       INTEGER, DIMENSION(2), INTENT(IN), OPTIONAL        :: kp_range
     506              :       REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER     :: wkp
     507              :       LOGICAL, INTENT(IN), OPTIONAL                      :: require_local_state, &
     508              :                                                             require_complex_state
     509              : 
     510              :       INTEGER                                            :: expected_local_kpoint, ikpoint, ispin, &
     511              :                                                             nkpoint_eff, nspin_eff, ot_channel
     512              :       LOGICAL                                            :: check_complex_state, &
     513              :                                                             check_kpoint_context, &
     514              :                                                             check_local_state, check_weights, &
     515              :                                                             context_ok, restricted_eff
     516              :       REAL(KIND=dp)                                      :: weight_tol
     517              : 
     518        10557 :       nkpoint_eff = 1
     519        10557 :       IF (PRESENT(nkpoint)) nkpoint_eff = nkpoint
     520        10557 :       nspin_eff = nspin
     521        10557 :       restricted_eff = .FALSE.
     522        10557 :       IF (PRESENT(restricted)) THEN
     523        10557 :          restricted_eff = restricted
     524        10557 :          IF (restricted_eff) nspin_eff = 1
     525              :       END IF
     526              : 
     527        10557 :       check_kpoint_context = (nkpoint_eff > 1)
     528        10557 :       IF (PRESENT(require_kpoint)) check_kpoint_context = require_kpoint
     529        10557 :       check_weights = .FALSE.
     530        10557 :       IF (PRESENT(wkp)) check_weights = ASSOCIATED(wkp)
     531        10557 :       check_local_state = .FALSE.
     532        10557 :       IF (PRESENT(require_local_state)) check_local_state = require_local_state
     533        10557 :       check_complex_state = .FALSE.
     534        10557 :       IF (PRESENT(require_complex_state)) check_complex_state = require_complex_state
     535              : 
     536              :       context_ok = (SIZE(qs_ot_env) == qs_ot_number_of_channels(nspin, &
     537              :                                                                 nkpoint=nkpoint_eff, &
     538        10557 :                                                                 restricted=restricted_eff))
     539        10557 :       CPASSERT(context_ok)
     540        24066 :       DO ikpoint = 1, nkpoint_eff
     541        13509 :          expected_local_kpoint = 0
     542        13509 :          IF (PRESENT(kp_range)) THEN
     543        13509 :             IF (ikpoint >= kp_range(1) .AND. ikpoint <= kp_range(2)) THEN
     544         4471 :                expected_local_kpoint = ikpoint - kp_range(1) + 1
     545              :             END IF
     546              :          END IF
     547        39576 :          DO ispin = 1, nspin_eff
     548        15510 :             ot_channel = qs_ot_channel_index(ispin, ikpoint, nspin_eff)
     549        15510 :             CPASSERT(qs_ot_env(ot_channel)%spin_index == ispin)
     550        15510 :             IF (check_kpoint_context) THEN
     551         6410 :                CPASSERT(qs_ot_env(ot_channel)%has_kpoint_context)
     552         6410 :                CPASSERT(qs_ot_env(ot_channel)%kpoint_index == ikpoint)
     553         6410 :                IF (PRESENT(kp_range)) THEN
     554         6410 :                   context_ok = (qs_ot_env(ot_channel)%local_kpoint_index == expected_local_kpoint)
     555         6410 :                   CPASSERT(context_ok)
     556              :                END IF
     557         6410 :                IF (check_weights) THEN
     558         6068 :                   weight_tol = 1000.0_dp*EPSILON(1.0_dp)*MAX(1.0_dp, ABS(wkp(ikpoint)))
     559         6068 :                   context_ok = (ABS(qs_ot_env(ot_channel)%kpoint_weight - wkp(ikpoint)) <= weight_tol)
     560         6068 :                   CPASSERT(context_ok)
     561              :                END IF
     562              :             END IF
     563        29019 :             IF (check_local_state) THEN
     564         6068 :                IF (expected_local_kpoint > 0 .OR. .NOT. PRESENT(kp_range)) THEN
     565         4558 :                   CPASSERT(qs_ot_env(ot_channel)%state_allocated)
     566         4558 :                   IF (check_complex_state) THEN
     567         4558 :                      CPASSERT(qs_ot_env(ot_channel)%has_complex_kpoint_state)
     568              :                   END IF
     569              :                ELSE
     570         1510 :                   CPASSERT(.NOT. qs_ot_env(ot_channel)%state_allocated)
     571              :                END IF
     572              :             END IF
     573              :          END DO
     574              :       END DO
     575              : 
     576        10557 :    END SUBROUTINE qs_ot_check_channel_context
     577              : 
     578              : ! **************************************************************************************************
     579              : !> \brief init matrices, needs c0 and sc0 so that c0*sc0=1
     580              : !> \param qs_ot_env ...
     581              : ! **************************************************************************************************
     582        10218 :    SUBROUTINE qs_ot_init(qs_ot_env)
     583              :       TYPE(qs_ot_type)                                   :: qs_ot_env
     584              : 
     585       551772 :       qs_ot_env%OT_energy(:) = 0.0_dp
     586       551772 :       qs_ot_env%OT_pos(:) = 0.0_dp
     587       551772 :       qs_ot_env%OT_grad(:) = 0.0_dp
     588        10218 :       qs_ot_env%line_search_count = 0
     589              : 
     590        10218 :       qs_ot_env%energy_only = .FALSE.
     591        10218 :       qs_ot_env%gnorm_old = 1.0_dp
     592        10218 :       qs_ot_env%diis_iter = 0
     593        10218 :       qs_ot_env%ds_min = qs_ot_env%settings%ds_min
     594        10218 :       qs_ot_env%os_valid = .FALSE.
     595              : 
     596        10218 :       CALL dbcsr_set(qs_ot_env%matrix_gx, 0.0_dp)
     597        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_gx_im)) THEN
     598          446 :          CALL dbcsr_set(qs_ot_env%matrix_gx_im, 0.0_dp)
     599              :       END IF
     600        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_preconditioned_gx)) THEN
     601          116 :          CALL dbcsr_set(qs_ot_env%matrix_preconditioned_gx, 0.0_dp)
     602              :       END IF
     603        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_preconditioned_gx_im)) THEN
     604          116 :          CALL dbcsr_set(qs_ot_env%matrix_preconditioned_gx_im, 0.0_dp)
     605              :       END IF
     606        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_response_gx)) CALL dbcsr_set(qs_ot_env%matrix_response_gx, 0.0_dp)
     607        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_response_gx_im)) THEN
     608           68 :          CALL dbcsr_set(qs_ot_env%matrix_response_gx_im, 0.0_dp)
     609              :       END IF
     610        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_mermin_g0)) CALL dbcsr_set(qs_ot_env%matrix_mermin_g0, 0.0_dp)
     611        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_mermin_g0_im)) THEN
     612           68 :          CALL dbcsr_set(qs_ot_env%matrix_mermin_g0_im, 0.0_dp)
     613              :       END IF
     614        10218 :       qs_ot_env%mermin_gradient_ref_valid = .FALSE.
     615              : 
     616        10218 :       IF (qs_ot_env%use_dx) THEN
     617         4342 :          CALL dbcsr_set(qs_ot_env%matrix_dx, 0.0_dp)
     618              :       END IF
     619        10218 :       IF (qs_ot_env%use_dx .AND. ASSOCIATED(qs_ot_env%matrix_dx_im)) THEN
     620          311 :          CALL dbcsr_set(qs_ot_env%matrix_dx_im, 0.0_dp)
     621              :       END IF
     622              : 
     623        10218 :       IF (qs_ot_env%use_gx_old) THEN
     624         4342 :          CALL dbcsr_set(qs_ot_env%matrix_gx_old, 0.0_dp)
     625              :       END IF
     626        10218 :       IF (qs_ot_env%use_gx_old .AND. ASSOCIATED(qs_ot_env%matrix_gx_old_im)) THEN
     627          311 :          CALL dbcsr_set(qs_ot_env%matrix_gx_old_im, 0.0_dp)
     628              :       END IF
     629              : 
     630        10218 :       IF (qs_ot_env%settings%ot_method == "LBFG") THEN
     631         1172 :          qs_ot_env%lbfgs_rho = 0.0_dp
     632         1172 :          qs_ot_env%lbfgs_yy = 0.0_dp
     633         1172 :          qs_ot_env%lbfgs_sy_rotation = 0.0_dp
     634         1172 :          qs_ot_env%lbfgs_yy_rotation = 0.0_dp
     635              :       END IF
     636              : 
     637        10218 :       IF (qs_ot_env%settings%do_rotation) THEN
     638          407 :          CALL dbcsr_set(qs_ot_env%rot_mat_u, 0.0_dp)
     639          407 :          CALL dbcsr_add_on_diag(qs_ot_env%rot_mat_u, 1.0_dp)
     640          407 :          CALL dbcsr_set(qs_ot_env%rot_mat_x, 0.0_dp)
     641          407 :          CALL dbcsr_set(qs_ot_env%rot_mat_dedu, 0.0_dp)
     642          407 :          CALL dbcsr_set(qs_ot_env%rot_mat_chc, 0.0_dp)
     643          407 :          CALL dbcsr_set(qs_ot_env%rot_mat_gx, 0.0_dp)
     644          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_response_gx)) THEN
     645          116 :             CALL dbcsr_set(qs_ot_env%rot_mat_response_gx, 0.0_dp)
     646              :          END IF
     647          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_u_im)) CALL dbcsr_set(qs_ot_env%rot_mat_u_im, 0.0_dp)
     648          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_x_im)) CALL dbcsr_set(qs_ot_env%rot_mat_x_im, 0.0_dp)
     649          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_dedu_im)) CALL dbcsr_set(qs_ot_env%rot_mat_dedu_im, 0.0_dp)
     650          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_chc_im)) CALL dbcsr_set(qs_ot_env%rot_mat_chc_im, 0.0_dp)
     651          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_gx_im)) CALL dbcsr_set(qs_ot_env%rot_mat_gx_im, 0.0_dp)
     652          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_response_gx_im)) THEN
     653          116 :             CALL dbcsr_set(qs_ot_env%rot_mat_response_gx_im, 0.0_dp)
     654              :          END IF
     655          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_mermin_g0)) THEN
     656           68 :             CALL dbcsr_set(qs_ot_env%rot_mat_mermin_g0, 0.0_dp)
     657              :          END IF
     658          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_mermin_g0_im)) THEN
     659           68 :             CALL dbcsr_set(qs_ot_env%rot_mat_mermin_g0_im, 0.0_dp)
     660              :          END IF
     661          407 :          qs_ot_env%rotation_response_valid = .FALSE.
     662          407 :          qs_ot_env%response_candidate_pending = .FALSE.
     663          407 :          qs_ot_env%response_shadow_pending = .FALSE.
     664          407 :          qs_ot_env%response_candidate_directions = 0
     665          407 :          qs_ot_env%response_candidate_good_samples = 0
     666          407 :          qs_ot_env%response_candidate_cooldown = 0
     667          407 :          qs_ot_env%response_shadow_good_samples = 0
     668          407 :          qs_ot_env%response_model_curvature = 0.0_dp
     669          407 :          qs_ot_env%response_shadow_curvature = 0.0_dp
     670          407 :          qs_ot_env%response_hxc_direction_valid = .FALSE.
     671          407 :          qs_ot_env%response_reference_energy = 0.0_dp
     672          407 :          qs_ot_env%response_reference_residual = 0.0_dp
     673          407 :          qs_ot_env%response_predicted_slope = 0.0_dp
     674          407 :          qs_ot_env%response_predicted_curvature = 0.0_dp
     675          407 :          IF (qs_ot_env%use_dx) THEN
     676          321 :             CALL dbcsr_set(qs_ot_env%rot_mat_dx, 0.0_dp)
     677          321 :             IF (ASSOCIATED(qs_ot_env%rot_mat_dx_im)) CALL dbcsr_set(qs_ot_env%rot_mat_dx_im, 0.0_dp)
     678              :          END IF
     679          407 :          IF (qs_ot_env%use_gx_old) THEN
     680          321 :             CALL dbcsr_set(qs_ot_env%rot_mat_gx_old, 0.0_dp)
     681          321 :             IF (ASSOCIATED(qs_ot_env%rot_mat_gx_old_im)) CALL dbcsr_set(qs_ot_env%rot_mat_gx_old_im, 0.0_dp)
     682              :          END IF
     683              :       END IF
     684        10218 :       IF (qs_ot_env%settings%do_ener) THEN
     685          986 :          qs_ot_env%ener_rayleigh(:) = 0.0_dp
     686          986 :          qs_ot_env%ener_gx(:) = 0.0_dp
     687          120 :          IF (ASSOCIATED(qs_ot_env%ener_preconditioned_gx)) THEN
     688          894 :             qs_ot_env%ener_preconditioned_gx(:) = 0.0_dp
     689              :          END IF
     690          898 :          IF (ASSOCIATED(qs_ot_env%ener_response_gx)) qs_ot_env%ener_response_gx(:) = 0.0_dp
     691          562 :          IF (ALLOCATED(qs_ot_env%ener_mermin_g0)) qs_ot_env%ener_mermin_g0(:) = 0.0_dp
     692          120 :          IF (qs_ot_env%use_dx) THEN
     693          602 :             qs_ot_env%ener_dx(:) = 0.0_dp
     694              :          END IF
     695          120 :          IF (qs_ot_env%use_gx_old) THEN
     696          602 :             qs_ot_env%ener_gx_old(:) = 0.0_dp
     697              :          END IF
     698              :       END IF
     699              : 
     700        10218 :    END SUBROUTINE qs_ot_init
     701              : 
     702              : ! **************************************************************************************************
     703              : !> \brief allocates the data in qs_ot_env, for a calculation with fm_struct_ref
     704              : !>        ortho_k allows for specifying an additional orthogonal subspace (i.e. c will
     705              : !>        be kept orthogonal provided c0 was, used in qs_ot_eigensolver)
     706              : !> \param qs_ot_env ...
     707              : !> \param matrix_s ...
     708              : !> \param fm_struct_ref ...
     709              : !> \param ortho_k ...
     710              : !> \param energy_dimension number of auxiliary energy variables, defaults to the orbital count
     711              : ! **************************************************************************************************
     712        10218 :    SUBROUTINE qs_ot_allocate(qs_ot_env, matrix_s, fm_struct_ref, ortho_k, energy_dimension)
     713              :       TYPE(qs_ot_type)                                   :: qs_ot_env
     714              :       TYPE(dbcsr_type), POINTER                          :: matrix_s
     715              :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct_ref
     716              :       INTEGER, OPTIONAL                                  :: ortho_k, energy_dimension
     717              : 
     718              :       INTEGER                                            :: i, k, m_diis, my_energy_dimension, &
     719              :                                                             my_ortho_k, n, ncoef, nhistory
     720              :       TYPE(cp_blacs_env_type), POINTER                   :: context
     721              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     722              : 
     723        10218 :       CALL cite_reference(VandeVondele2003)
     724              : 
     725        10218 :       CPASSERT(.NOT. qs_ot_env%state_allocated)
     726        10218 :       qs_ot_env%has_complex_kpoint_state = .FALSE.
     727        10218 :       NULLIFY (qs_ot_env%preconditioner)
     728        10218 :       NULLIFY (qs_ot_env%matrix_psc0)
     729        10218 :       NULLIFY (qs_ot_env%matrix_psc0_im)
     730        10218 :       NULLIFY (qs_ot_env%para_env)
     731        10218 :       NULLIFY (qs_ot_env%blacs_env)
     732              : 
     733              :       CALL cp_fm_struct_get(fm_struct_ref, nrow_global=n, ncol_global=k, &
     734        10218 :                             para_env=para_env, context=context)
     735              : 
     736        10218 :       qs_ot_env%para_env => para_env
     737        10218 :       qs_ot_env%blacs_env => context
     738        10218 :       CALL para_env%retain()
     739        10218 :       CALL context%retain()
     740              : 
     741        10218 :       IF (PRESENT(ortho_k)) THEN
     742          672 :          my_ortho_k = ortho_k
     743              :       ELSE
     744         9546 :          my_ortho_k = k
     745              :       END IF
     746        10218 :       my_energy_dimension = k
     747        10218 :       IF (PRESENT(energy_dimension)) my_energy_dimension = energy_dimension
     748        10218 :       IF (qs_ot_env%settings%do_ener) THEN
     749          120 :          CPASSERT(my_energy_dimension > 0)
     750              :       END IF
     751              : 
     752        10218 :       m_diis = qs_ot_env%settings%diis_m
     753              : 
     754        10218 :       qs_ot_env%use_gx_old = .FALSE.
     755        10218 :       qs_ot_env%use_dx = .FALSE.
     756              : 
     757         4342 :       SELECT CASE (qs_ot_env%settings%ot_method)
     758              :       CASE ("SD")
     759              :          ! nothing
     760              :       CASE ("CG", "LBFG")
     761         4342 :          qs_ot_env%use_gx_old = .TRUE.
     762         4342 :          qs_ot_env%use_dx = .TRUE.
     763         4342 :          IF (qs_ot_env%settings%ot_method == "LBFG" .AND. m_diis < 1) CPABORT("m_diis less than one")
     764              :       CASE ("DIIS", "BROY")
     765         5858 :          IF (m_diis < 1) CPABORT("m_diis less than one")
     766              :       CASE DEFAULT
     767        10218 :          CPABORT("Unknown option")
     768              :       END SELECT
     769              : 
     770        10218 :       IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
     771              :           qs_ot_env%settings%ot_method == "BROY") THEN
     772        23432 :          ALLOCATE (qs_ot_env%ls_diis(m_diis + 1, m_diis + 1))
     773       417228 :          qs_ot_env%ls_diis = 0.0_dp
     774        17574 :          ALLOCATE (qs_ot_env%lss_diis(m_diis + 1, m_diis + 1))
     775        17574 :          ALLOCATE (qs_ot_env%c_diis(m_diis + 1))
     776        17574 :          ALLOCATE (qs_ot_env%c_broy(m_diis))
     777        11716 :          ALLOCATE (qs_ot_env%energy_h(m_diis))
     778        17574 :          ALLOCATE (qs_ot_env%ipivot(m_diis + 1))
     779              :       END IF
     780        10218 :       IF (qs_ot_env%settings%ot_method == "LBFG") THEN
     781              :          ALLOCATE (qs_ot_env%lbfgs_rho(m_diis), qs_ot_env%lbfgs_yy(m_diis), &
     782          972 :                    qs_ot_env%lbfgs_sy_rotation(m_diis), qs_ot_env%lbfgs_yy_rotation(m_diis))
     783         1172 :          qs_ot_env%lbfgs_rho = 0.0_dp
     784         1172 :          qs_ot_env%lbfgs_yy = 0.0_dp
     785         1172 :          qs_ot_env%lbfgs_sy_rotation = 0.0_dp
     786         1172 :          qs_ot_env%lbfgs_yy_rotation = 0.0_dp
     787              :       END IF
     788              : 
     789        30244 :       ALLOCATE (qs_ot_env%evals(k))
     790        20026 :       ALLOCATE (qs_ot_env%dum(k))
     791              : 
     792        10218 :       NULLIFY (qs_ot_env%matrix_os)
     793        10218 :       NULLIFY (qs_ot_env%matrix_os_im)
     794        10218 :       NULLIFY (qs_ot_env%matrix_buf1_ortho)
     795        10218 :       NULLIFY (qs_ot_env%matrix_buf1_ortho_im)
     796        10218 :       NULLIFY (qs_ot_env%matrix_buf2_ortho)
     797        10218 :       NULLIFY (qs_ot_env%matrix_buf2_ortho_im)
     798        10218 :       NULLIFY (qs_ot_env%matrix_tmp_ortho)
     799        10218 :       NULLIFY (qs_ot_env%matrix_buf_nk)
     800        10218 :       NULLIFY (qs_ot_env%matrix_buf_nk_im)
     801        10218 :       NULLIFY (qs_ot_env%matrix_tmp_nk)
     802        10218 :       NULLIFY (qs_ot_env%matrix_p)
     803        10218 :       NULLIFY (qs_ot_env%matrix_p_im)
     804        10218 :       NULLIFY (qs_ot_env%matrix_r)
     805        10218 :       NULLIFY (qs_ot_env%matrix_r_im)
     806        10218 :       NULLIFY (qs_ot_env%matrix_sinp)
     807        10218 :       NULLIFY (qs_ot_env%matrix_sinp_im)
     808        10218 :       NULLIFY (qs_ot_env%matrix_cosp)
     809        10218 :       NULLIFY (qs_ot_env%matrix_cosp_im)
     810        10218 :       NULLIFY (qs_ot_env%matrix_sinp_b)
     811        10218 :       NULLIFY (qs_ot_env%matrix_cosp_b)
     812        10218 :       NULLIFY (qs_ot_env%matrix_buf1)
     813        10218 :       NULLIFY (qs_ot_env%matrix_buf1_im)
     814        10218 :       NULLIFY (qs_ot_env%matrix_buf2)
     815        10218 :       NULLIFY (qs_ot_env%matrix_buf2_im)
     816        10218 :       NULLIFY (qs_ot_env%matrix_buf3)
     817        10218 :       NULLIFY (qs_ot_env%matrix_buf3_im)
     818        10218 :       NULLIFY (qs_ot_env%matrix_buf4)
     819        10218 :       NULLIFY (qs_ot_env%matrix_buf4_im)
     820        10218 :       NULLIFY (qs_ot_env%matrix_c0)
     821        10218 :       NULLIFY (qs_ot_env%matrix_sc0)
     822        10218 :       NULLIFY (qs_ot_env%matrix_c0_im)
     823        10218 :       NULLIFY (qs_ot_env%matrix_sc0_im)
     824        10218 :       NULLIFY (qs_ot_env%matrix_x)
     825        10218 :       NULLIFY (qs_ot_env%matrix_sx)
     826        10218 :       NULLIFY (qs_ot_env%matrix_x_im)
     827        10218 :       NULLIFY (qs_ot_env%matrix_sx_im)
     828        10218 :       NULLIFY (qs_ot_env%matrix_gx)
     829        10218 :       NULLIFY (qs_ot_env%matrix_gx_im)
     830        10218 :       NULLIFY (qs_ot_env%matrix_preconditioned_gx)
     831        10218 :       NULLIFY (qs_ot_env%matrix_preconditioned_gx_im)
     832        10218 :       NULLIFY (qs_ot_env%matrix_response_gx)
     833        10218 :       NULLIFY (qs_ot_env%matrix_response_gx_im)
     834        10218 :       NULLIFY (qs_ot_env%matrix_mermin_g0)
     835        10218 :       NULLIFY (qs_ot_env%matrix_mermin_g0_im)
     836        10218 :       NULLIFY (qs_ot_env%matrix_ref_inv_sqrt)
     837        10218 :       NULLIFY (qs_ot_env%matrix_ref_inv_sqrt_im)
     838        30654 :       DO i = 1, SIZE(qs_ot_env%mermin_physical)
     839        20436 :          NULLIFY (qs_ot_env%mermin_physical(i)%c0)
     840        20436 :          NULLIFY (qs_ot_env%mermin_physical(i)%c0_im)
     841        20436 :          NULLIFY (qs_ot_env%mermin_physical(i)%h0)
     842        20436 :          NULLIFY (qs_ot_env%mermin_physical(i)%h0_im)
     843        20436 :          NULLIFY (qs_ot_env%mermin_physical(i)%c_previous)
     844        20436 :          NULLIFY (qs_ot_env%mermin_physical(i)%c_previous_im)
     845        20436 :          NULLIFY (qs_ot_env%mermin_physical(i)%y_previous)
     846        20436 :          NULLIFY (qs_ot_env%mermin_physical(i)%y_previous_im)
     847        20436 :          qs_ot_env%mermin_physical(i)%reference_valid = .FALSE.
     848        30654 :          qs_ot_env%mermin_physical(i)%secant_valid = .FALSE.
     849              :       END DO
     850        10218 :       qs_ot_env%mermin_gradient_ref_valid = .FALSE.
     851        10218 :       NULLIFY (qs_ot_env%matrix_gx_old)
     852        10218 :       NULLIFY (qs_ot_env%matrix_gx_old_im)
     853        10218 :       NULLIFY (qs_ot_env%matrix_dx)
     854        10218 :       NULLIFY (qs_ot_env%matrix_dx_im)
     855        10218 :       NULLIFY (qs_ot_env%buf1_k_k_nosym)
     856        10218 :       NULLIFY (qs_ot_env%buf2_k_k_nosym)
     857        10218 :       NULLIFY (qs_ot_env%buf3_k_k_nosym)
     858        10218 :       NULLIFY (qs_ot_env%buf4_k_k_nosym)
     859        10218 :       NULLIFY (qs_ot_env%buf1_k_k_sym)
     860        10218 :       NULLIFY (qs_ot_env%buf2_k_k_sym)
     861        10218 :       NULLIFY (qs_ot_env%buf3_k_k_sym)
     862        10218 :       NULLIFY (qs_ot_env%buf4_k_k_sym)
     863        10218 :       NULLIFY (qs_ot_env%buf1_n_k)
     864        10218 :       NULLIFY (qs_ot_env%buf1_n_k_dp)
     865        10218 :       NULLIFY (qs_ot_env%p_k_k_sym)
     866              : 
     867              :       ! COMMON MATRICES
     868        10218 :       CALL dbcsr_init_p(qs_ot_env%matrix_c0)
     869              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_c0, template=matrix_s, n=k, &
     870        10218 :                                              sym=dbcsr_type_no_symmetry)
     871              : 
     872        10218 :       CALL dbcsr_init_p(qs_ot_env%matrix_sc0)
     873              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_sc0, template=matrix_s, n=my_ortho_k, &
     874        10218 :                                              sym=dbcsr_type_no_symmetry)
     875              : 
     876        10218 :       CALL dbcsr_init_p(qs_ot_env%matrix_x)
     877              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_x, template=matrix_s, n=k, &
     878        10218 :                                              sym=dbcsr_type_no_symmetry)
     879              : 
     880        10218 :       CALL dbcsr_init_p(qs_ot_env%matrix_sx)
     881              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_sx, template=matrix_s, n=k, &
     882        10218 :                                              sym=dbcsr_type_no_symmetry)
     883              : 
     884        10218 :       CALL dbcsr_init_p(qs_ot_env%matrix_gx)
     885              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_gx, template=matrix_s, n=k, &
     886        10218 :                                              sym=dbcsr_type_no_symmetry)
     887              : 
     888        10218 :       IF (qs_ot_env%settings%occupation_preconditioner) THEN
     889          116 :          CALL dbcsr_init_p(qs_ot_env%matrix_preconditioned_gx)
     890              :          CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_preconditioned_gx, &
     891              :                                                 template=matrix_s, n=k, &
     892          116 :                                                 sym=dbcsr_type_no_symmetry)
     893              :       END IF
     894              : 
     895        10218 :       IF (qs_ot_env%use_dx) THEN
     896         4342 :          CALL dbcsr_init_p(qs_ot_env%matrix_dx)
     897              :          CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_dx, template=matrix_s, n=k, &
     898         4342 :                                                 sym=dbcsr_type_no_symmetry)
     899              :       END IF
     900              : 
     901        10218 :       IF (qs_ot_env%use_gx_old) THEN
     902         4342 :          CALL dbcsr_init_p(qs_ot_env%matrix_gx_old)
     903              :          CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_gx_old, template=matrix_s, n=k, &
     904         4342 :                                                 sym=dbcsr_type_no_symmetry)
     905              :       END IF
     906              : 
     907         8858 :       SELECT CASE (qs_ot_env%settings%ot_algorithm)
     908              :       CASE ("TOD")
     909         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_p)
     910              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_p, template=matrix_s, m=k, n=k, &
     911         8858 :                                             sym=dbcsr_type_no_symmetry)
     912              : 
     913         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_r)
     914              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_r, template=matrix_s, m=k, n=k, &
     915         8858 :                                             sym=dbcsr_type_no_symmetry)
     916              : 
     917         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_sinp)
     918              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_sinp, template=matrix_s, m=k, n=k, &
     919         8858 :                                             sym=dbcsr_type_no_symmetry)
     920              : 
     921         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_cosp)
     922              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_cosp, template=matrix_s, m=k, n=k, &
     923         8858 :                                             sym=dbcsr_type_no_symmetry)
     924              : 
     925         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_sinp_b)
     926              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_sinp_b, template=matrix_s, m=k, n=k, &
     927         8858 :                                             sym=dbcsr_type_no_symmetry)
     928              : 
     929         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_cosp_b)
     930              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_cosp_b, template=matrix_s, m=k, n=k, &
     931         8858 :                                             sym=dbcsr_type_no_symmetry)
     932              : 
     933         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_buf1)
     934              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_buf1, template=matrix_s, m=k, n=k, &
     935         8858 :                                             sym=dbcsr_type_no_symmetry)
     936              : 
     937         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_buf2)
     938              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_buf2, template=matrix_s, m=k, n=k, &
     939         8858 :                                             sym=dbcsr_type_no_symmetry)
     940              : 
     941         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_buf3)
     942              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_buf3, template=matrix_s, m=k, n=k, &
     943         8858 :                                             sym=dbcsr_type_no_symmetry)
     944              : 
     945         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_buf4)
     946              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_buf4, template=matrix_s, m=k, n=k, &
     947         8858 :                                             sym=dbcsr_type_no_symmetry)
     948              : 
     949         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_os)
     950              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_os, template=matrix_s, m=my_ortho_k, n=my_ortho_k, &
     951         8858 :                                             sym=dbcsr_type_no_symmetry)
     952              : 
     953         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_buf1_ortho)
     954              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_buf1_ortho, template=matrix_s, m=my_ortho_k, n=k, &
     955         8858 :                                             sym=dbcsr_type_no_symmetry)
     956              : 
     957         8858 :          CALL dbcsr_init_p(qs_ot_env%matrix_buf2_ortho)
     958              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_buf2_ortho, template=matrix_s, m=my_ortho_k, n=k, &
     959         8858 :                                             sym=dbcsr_type_no_symmetry)
     960              : 
     961              :       CASE ("REF")
     962         1360 :          CALL dbcsr_init_p(qs_ot_env%buf1_k_k_nosym)
     963              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%buf1_k_k_nosym, template=matrix_s, m=k, n=k, &
     964         1360 :                                             sym=dbcsr_type_no_symmetry)
     965              : 
     966         1360 :          CALL dbcsr_init_p(qs_ot_env%buf2_k_k_nosym)
     967              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%buf2_k_k_nosym, template=matrix_s, m=k, n=k, &
     968         1360 :                                             sym=dbcsr_type_no_symmetry)
     969              : 
     970         1360 :          CALL dbcsr_init_p(qs_ot_env%buf3_k_k_nosym)
     971              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%buf3_k_k_nosym, template=matrix_s, m=k, n=k, &
     972         1360 :                                             sym=dbcsr_type_no_symmetry)
     973              : 
     974         1360 :          CALL dbcsr_init_p(qs_ot_env%buf4_k_k_nosym)
     975              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%buf4_k_k_nosym, template=matrix_s, m=k, n=k, &
     976         1360 :                                             sym=dbcsr_type_no_symmetry)
     977              : 
     978              :          ! It claims to be symmetric but to avoid dbcsr confusion nonsymmetric is kept
     979         1360 :          CALL dbcsr_init_p(qs_ot_env%buf1_k_k_sym)
     980              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%buf1_k_k_sym, template=matrix_s, m=k, n=k, &
     981         1360 :                                             sym=dbcsr_type_no_symmetry)
     982              : 
     983         1360 :          CALL dbcsr_init_p(qs_ot_env%buf2_k_k_sym)
     984              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%buf2_k_k_sym, template=matrix_s, m=k, n=k, &
     985         1360 :                                             sym=dbcsr_type_no_symmetry)
     986              : 
     987         1360 :          CALL dbcsr_init_p(qs_ot_env%buf3_k_k_sym)
     988              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%buf3_k_k_sym, template=matrix_s, m=k, n=k, &
     989         1360 :                                             sym=dbcsr_type_no_symmetry)
     990              :          !
     991         1360 :          CALL dbcsr_init_p(qs_ot_env%buf4_k_k_sym)
     992              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%buf4_k_k_sym, template=matrix_s, m=k, n=k, &
     993         1360 :                                             sym=dbcsr_type_no_symmetry)
     994              :          !
     995         1360 :          CALL dbcsr_init_p(qs_ot_env%p_k_k_sym)
     996              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%p_k_k_sym, template=matrix_s, m=k, n=k, &
     997         1360 :                                             sym=dbcsr_type_no_symmetry)
     998              :          !
     999         1360 :          CALL dbcsr_init_p(qs_ot_env%buf1_n_k)
    1000              :          CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%buf1_n_k, template=matrix_s, n=k, &
    1001         1360 :                                                 sym=dbcsr_type_no_symmetry)
    1002              :          !
    1003         1360 :          CALL dbcsr_init_p(qs_ot_env%matrix_buf1)
    1004              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_buf1, template=matrix_s, m=k, n=k, &
    1005        11578 :                                             sym=dbcsr_type_no_symmetry)
    1006              : 
    1007              :       END SELECT
    1008              : 
    1009              :       IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
    1010        10218 :           qs_ot_env%settings%ot_method == "BROY" .OR. &
    1011              :           qs_ot_env%settings%ot_method == "LBFG") THEN
    1012         6020 :          NULLIFY (qs_ot_env%matrix_h_e)
    1013         6020 :          NULLIFY (qs_ot_env%matrix_h_x)
    1014         6020 :          NULLIFY (qs_ot_env%matrix_h_e_im)
    1015         6020 :          NULLIFY (qs_ot_env%matrix_h_x_im)
    1016         6020 :          ncoef = m_diis
    1017         6020 :          IF (qs_ot_env%settings%ot_method == "LBFG") ncoef = m_diis + 1
    1018         6020 :          CALL dbcsr_allocate_matrix_set(qs_ot_env%matrix_h_e, ncoef)
    1019         6020 :          CALL dbcsr_allocate_matrix_set(qs_ot_env%matrix_h_x, ncoef)
    1020        46996 :          DO i = 1, ncoef
    1021        40976 :             CALL dbcsr_init_p(qs_ot_env%matrix_h_x(i)%matrix)
    1022              :             CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_h_x(i)%matrix, template=matrix_s, n=k, &
    1023        40976 :                                                    sym=dbcsr_type_no_symmetry)
    1024              : 
    1025        40976 :             CALL dbcsr_init_p(qs_ot_env%matrix_h_e(i)%matrix)
    1026              :             CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_h_e(i)%matrix, template=matrix_s, n=k, &
    1027        51194 :                                                    sym=dbcsr_type_no_symmetry)
    1028              :          END DO
    1029              :       END IF
    1030              : 
    1031        10218 :       NULLIFY (qs_ot_env%rot_mat_u, qs_ot_env%rot_mat_u_im, &
    1032        10218 :                qs_ot_env%rot_mat_x, qs_ot_env%rot_mat_x_im, &
    1033        10218 :                qs_ot_env%rot_mat_h_e, qs_ot_env%rot_mat_h_x, &
    1034        10218 :                qs_ot_env%rot_mat_h_e_im, qs_ot_env%rot_mat_h_x_im, qs_ot_env%rot_mat_gx, &
    1035        10218 :                qs_ot_env%rot_mat_gx_im, qs_ot_env%rot_mat_response_gx, &
    1036        10218 :                qs_ot_env%rot_mat_response_gx_im, qs_ot_env%rot_mat_mermin_g0, &
    1037        10218 :                qs_ot_env%rot_mat_mermin_g0_im, qs_ot_env%rot_mat_gx_old, &
    1038        10218 :                qs_ot_env%rot_mat_gx_old_im, qs_ot_env%rot_mat_dx, qs_ot_env%rot_mat_dx_im, &
    1039        10218 :                qs_ot_env%rot_mat_evals, qs_ot_env%rot_mat_dedu, qs_ot_env%rot_mat_dedu_im, &
    1040        10218 :                qs_ot_env%rot_mat_chc, qs_ot_env%rot_mat_chc_im, &
    1041        10218 :                qs_ot_env%rot_mat_evec_re, qs_ot_env%rot_mat_evec_im)
    1042              : 
    1043        10218 :       IF (qs_ot_env%settings%do_rotation) THEN
    1044          407 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_u)
    1045              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_u, template=matrix_s, m=k, n=k, &
    1046          407 :                                             sym=dbcsr_type_no_symmetry)
    1047              : 
    1048          407 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_x)
    1049              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_x, template=matrix_s, m=k, n=k, &
    1050          407 :                                             sym=dbcsr_type_no_symmetry)
    1051              : 
    1052          407 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_dedu)
    1053              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_dedu, template=matrix_s, m=k, n=k, &
    1054          407 :                                             sym=dbcsr_type_no_symmetry)
    1055              : 
    1056          407 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_chc)
    1057              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_chc, template=matrix_s, m=k, n=k, &
    1058          407 :                                             sym=dbcsr_type_no_symmetry)
    1059              : 
    1060              :          IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
    1061          407 :              qs_ot_env%settings%ot_method == "BROY" .OR. &
    1062              :              qs_ot_env%settings%ot_method == "LBFG") THEN
    1063          144 :             ncoef = m_diis
    1064          144 :             IF (qs_ot_env%settings%ot_method == "LBFG") ncoef = m_diis + 1
    1065          144 :             CALL dbcsr_allocate_matrix_set(qs_ot_env%rot_mat_h_e, ncoef)
    1066          144 :             CALL dbcsr_allocate_matrix_set(qs_ot_env%rot_mat_h_x, ncoef)
    1067         1106 :             DO i = 1, ncoef
    1068          962 :                CALL dbcsr_init_p(qs_ot_env%rot_mat_h_e(i)%matrix)
    1069              :                CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_h_e(i)%matrix, template=matrix_s, m=k, n=k, &
    1070          962 :                                                   sym=dbcsr_type_no_symmetry)
    1071              : 
    1072          962 :                CALL dbcsr_init_p(qs_ot_env%rot_mat_h_x(i)%matrix)
    1073              :                CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_h_x(i)%matrix, template=matrix_s, m=k, n=k, &
    1074         1369 :                                                   sym=dbcsr_type_no_symmetry)
    1075              :             END DO
    1076              :          END IF
    1077              : 
    1078         1217 :          ALLOCATE (qs_ot_env%rot_mat_evals(k))
    1079          407 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_evec_re)
    1080              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_evec_re, template=matrix_s, m=k, n=k, &
    1081          407 :                                             sym=dbcsr_type_no_symmetry)
    1082          407 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_evec_im)
    1083              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_evec_im, template=matrix_s, m=k, n=k, &
    1084          407 :                                             sym=dbcsr_type_no_symmetry)
    1085              : 
    1086          407 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_gx)
    1087              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_gx, template=matrix_s, m=k, n=k, &
    1088          407 :                                             sym=dbcsr_type_no_symmetry)
    1089              : 
    1090          407 :          IF (qs_ot_env%settings%occupation_preconditioner) THEN
    1091          116 :             CALL dbcsr_init_p(qs_ot_env%rot_mat_response_gx)
    1092              :             CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_response_gx, &
    1093              :                                                template=matrix_s, m=k, n=k, &
    1094          116 :                                                sym=dbcsr_type_no_symmetry)
    1095              :          END IF
    1096              : 
    1097          407 :          IF (qs_ot_env%use_gx_old) THEN
    1098          321 :             CALL dbcsr_init_p(qs_ot_env%rot_mat_gx_old)
    1099              :             CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_gx_old, template=matrix_s, m=k, n=k, &
    1100          321 :                                                sym=dbcsr_type_no_symmetry)
    1101              :          END IF
    1102              : 
    1103          407 :          IF (qs_ot_env%use_dx) THEN
    1104          321 :             CALL dbcsr_init_p(qs_ot_env%rot_mat_dx)
    1105              :             CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_dx, template=matrix_s, m=k, n=k, &
    1106          321 :                                                sym=dbcsr_type_no_symmetry)
    1107              :          END IF
    1108              : 
    1109              :       END IF
    1110              : 
    1111        10218 :       IF (qs_ot_env%settings%do_ener) THEN
    1112              :          ncoef = my_energy_dimension
    1113          360 :          ALLOCATE (qs_ot_env%ener_x(ncoef))
    1114          240 :          ALLOCATE (qs_ot_env%ener_rayleigh(ncoef))
    1115              : 
    1116              :          IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
    1117          120 :              qs_ot_env%settings%ot_method == "BROY" .OR. &
    1118              :              qs_ot_env%settings%ot_method == "LBFG") THEN
    1119           60 :             nhistory = m_diis
    1120           60 :             IF (qs_ot_env%settings%ot_method == "LBFG") nhistory = m_diis + 1
    1121          240 :             ALLOCATE (qs_ot_env%ener_h_e(nhistory, ncoef))
    1122          180 :             ALLOCATE (qs_ot_env%ener_h_x(nhistory, ncoef))
    1123         4096 :             qs_ot_env%ener_h_e = 0.0_dp
    1124         4096 :             qs_ot_env%ener_h_x = 0.0_dp
    1125              :          END IF
    1126              : 
    1127          240 :          ALLOCATE (qs_ot_env%ener_gx(ncoef))
    1128          120 :          IF (qs_ot_env%settings%occupation_preconditioner) THEN
    1129          232 :             ALLOCATE (qs_ot_env%ener_preconditioned_gx(ncoef))
    1130          232 :             ALLOCATE (qs_ot_env%ener_response_gx(ncoef))
    1131              :          END IF
    1132              : 
    1133          120 :          IF (qs_ot_env%use_gx_old) THEN
    1134          144 :             ALLOCATE (qs_ot_env%ener_gx_old(ncoef))
    1135              :          END IF
    1136              : 
    1137          120 :          IF (qs_ot_env%use_dx) THEN
    1138          144 :             ALLOCATE (qs_ot_env%ener_dx(ncoef))
    1139          602 :             qs_ot_env%ener_dx = 0.0_dp
    1140              :          END IF
    1141              :       END IF
    1142              : 
    1143        10218 :       qs_ot_env%state_allocated = .TRUE.
    1144              : 
    1145        10218 :    END SUBROUTINE qs_ot_allocate
    1146              : 
    1147              : ! **************************************************************************************************
    1148              : !> \brief ...
    1149              : !> \param qs_ot_env ...
    1150              : !> \param matrix_s ...
    1151              : ! **************************************************************************************************
    1152         1338 :    SUBROUTINE qs_ot_allocate_complex_state(qs_ot_env, matrix_s)
    1153              :       TYPE(qs_ot_type)                                   :: qs_ot_env
    1154              :       TYPE(dbcsr_type), POINTER                          :: matrix_s
    1155              : 
    1156              :       INTEGER                                            :: i, ncoef, nmo, nmo_ortho
    1157              : 
    1158          446 :       CPASSERT(qs_ot_env%state_allocated)
    1159          446 :       CPASSERT(.NOT. qs_ot_env%has_complex_kpoint_state)
    1160          446 :       CPASSERT(ASSOCIATED(matrix_s))
    1161              : 
    1162          446 :       CALL dbcsr_get_info(qs_ot_env%matrix_c0, nfullcols_total=nmo)
    1163          446 :       CALL dbcsr_get_info(qs_ot_env%matrix_sc0, nfullcols_total=nmo_ortho)
    1164              : 
    1165          446 :       CALL dbcsr_init_p(qs_ot_env%matrix_c0_im)
    1166              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_c0_im, template=matrix_s, n=nmo, &
    1167          446 :                                              sym=dbcsr_type_no_symmetry)
    1168          446 :       CALL dbcsr_init_p(qs_ot_env%matrix_sc0_im)
    1169              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_sc0_im, template=matrix_s, n=nmo_ortho, &
    1170          446 :                                              sym=dbcsr_type_no_symmetry)
    1171          446 :       CALL dbcsr_init_p(qs_ot_env%matrix_x_im)
    1172              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_x_im, template=matrix_s, n=nmo, &
    1173          446 :                                              sym=dbcsr_type_no_symmetry)
    1174          446 :       CALL dbcsr_init_p(qs_ot_env%matrix_sx_im)
    1175              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_sx_im, template=matrix_s, n=nmo, &
    1176          446 :                                              sym=dbcsr_type_no_symmetry)
    1177          446 :       CALL dbcsr_init_p(qs_ot_env%matrix_gx_im)
    1178              :       CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_gx_im, template=matrix_s, n=nmo, &
    1179          446 :                                              sym=dbcsr_type_no_symmetry)
    1180          446 :       IF (qs_ot_env%settings%occupation_preconditioner) THEN
    1181          116 :          CALL dbcsr_init_p(qs_ot_env%matrix_preconditioned_gx_im)
    1182              :          CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_preconditioned_gx_im, &
    1183              :                                                 template=matrix_s, n=nmo, &
    1184          116 :                                                 sym=dbcsr_type_no_symmetry)
    1185          116 :          IF (qs_ot_env%use_dx) THEN
    1186           68 :             CALL dbcsr_init_p(qs_ot_env%matrix_response_gx)
    1187              :             CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_response_gx, &
    1188              :                                                    template=matrix_s, n=nmo, &
    1189           68 :                                                    sym=dbcsr_type_no_symmetry)
    1190           68 :             CALL dbcsr_init_p(qs_ot_env%matrix_response_gx_im)
    1191              :             CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_response_gx_im, &
    1192              :                                                    template=matrix_s, n=nmo, &
    1193           68 :                                                    sym=dbcsr_type_no_symmetry)
    1194           68 :             CALL dbcsr_init_p(qs_ot_env%matrix_mermin_g0)
    1195              :             CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_mermin_g0, &
    1196              :                                                    template=matrix_s, n=nmo, &
    1197           68 :                                                    sym=dbcsr_type_no_symmetry)
    1198           68 :             CALL dbcsr_init_p(qs_ot_env%matrix_mermin_g0_im)
    1199              :             CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_mermin_g0_im, &
    1200              :                                                    template=matrix_s, n=nmo, &
    1201           68 :                                                    sym=dbcsr_type_no_symmetry)
    1202           68 :             IF (qs_ot_env%settings%do_ener) THEN
    1203           68 :                CPASSERT(ASSOCIATED(qs_ot_env%ener_x))
    1204          204 :                ALLOCATE (qs_ot_env%ener_mermin_g0(SIZE(qs_ot_env%ener_x)))
    1205              :             END IF
    1206              :          END IF
    1207              :       END IF
    1208          198 :       SELECT CASE (qs_ot_env%settings%ot_algorithm)
    1209              :       CASE ("TOD")
    1210          198 :          CPASSERT(nmo_ortho == nmo)
    1211          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_p_im, qs_ot_env%matrix_p, "matrix_p_im")
    1212          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_r_im, qs_ot_env%matrix_r, "matrix_r_im")
    1213          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_sinp_im, qs_ot_env%matrix_sinp, "matrix_sinp_im")
    1214          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_cosp_im, qs_ot_env%matrix_cosp, "matrix_cosp_im")
    1215          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_buf1_im, qs_ot_env%matrix_buf1, "matrix_buf1_im")
    1216          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_buf2_im, qs_ot_env%matrix_buf2, "matrix_buf2_im")
    1217          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_buf3_im, qs_ot_env%matrix_buf3, "matrix_buf3_im")
    1218          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_buf4_im, qs_ot_env%matrix_buf4, "matrix_buf4_im")
    1219          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_os_im, qs_ot_env%matrix_os, "matrix_os_im")
    1220              :          CALL allocate_complex_copy(qs_ot_env%matrix_buf1_ortho_im, qs_ot_env%matrix_buf1_ortho, &
    1221          198 :                                     "matrix_buf1_ortho_im")
    1222              :          CALL allocate_complex_copy(qs_ot_env%matrix_buf2_ortho_im, qs_ot_env%matrix_buf2_ortho, &
    1223          198 :                                     "matrix_buf2_ortho_im")
    1224              :          CALL allocate_complex_copy(qs_ot_env%matrix_tmp_ortho, qs_ot_env%matrix_buf1_ortho, &
    1225          198 :                                     "matrix_tmp_ortho")
    1226          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_buf_nk, qs_ot_env%matrix_x, "matrix_buf_nk")
    1227          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_buf_nk_im, qs_ot_env%matrix_x, "matrix_buf_nk_im")
    1228          198 :          CALL allocate_complex_copy(qs_ot_env%matrix_tmp_nk, qs_ot_env%matrix_x, "matrix_tmp_nk")
    1229              :       CASE ("REF")
    1230          248 :          CALL dbcsr_init_p(qs_ot_env%matrix_ref_inv_sqrt)
    1231              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_ref_inv_sqrt, template=matrix_s, m=nmo, n=nmo, &
    1232          248 :                                             sym=dbcsr_type_no_symmetry)
    1233          248 :          CALL dbcsr_init_p(qs_ot_env%matrix_ref_inv_sqrt_im)
    1234              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%matrix_ref_inv_sqrt_im, template=matrix_s, m=nmo, n=nmo, &
    1235          248 :                                             sym=dbcsr_type_no_symmetry)
    1236          248 :          CALL dbcsr_init_p(qs_ot_env%buf1_n_k_dp)
    1237              :          CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%buf1_n_k_dp, template=matrix_s, n=nmo, &
    1238          248 :                                                 sym=dbcsr_type_no_symmetry)
    1239              :       CASE DEFAULT
    1240          446 :          CPABORT("Complex K-point OT state requires ALGORITHM STRICT or IRAC")
    1241              :       END SELECT
    1242          446 :       IF (qs_ot_env%use_dx) THEN
    1243          311 :          CALL dbcsr_init_p(qs_ot_env%matrix_dx_im)
    1244              :          CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_dx_im, template=matrix_s, n=nmo, &
    1245          311 :                                                 sym=dbcsr_type_no_symmetry)
    1246              :       END IF
    1247          446 :       IF (qs_ot_env%use_gx_old) THEN
    1248          311 :          CALL dbcsr_init_p(qs_ot_env%matrix_gx_old_im)
    1249              :          CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_gx_old_im, template=matrix_s, n=nmo, &
    1250          311 :                                                 sym=dbcsr_type_no_symmetry)
    1251              :       END IF
    1252              :       IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
    1253          446 :           qs_ot_env%settings%ot_method == "BROY" .OR. &
    1254              :           qs_ot_env%settings%ot_method == "LBFG") THEN
    1255          277 :          ncoef = qs_ot_env%settings%diis_m
    1256          277 :          IF (qs_ot_env%settings%ot_method == "LBFG") ncoef = ncoef + 1
    1257          277 :          CALL dbcsr_allocate_matrix_set(qs_ot_env%matrix_h_e_im, ncoef)
    1258          277 :          CALL dbcsr_allocate_matrix_set(qs_ot_env%matrix_h_x_im, ncoef)
    1259         2142 :          DO i = 1, ncoef
    1260         1865 :             CALL dbcsr_init_p(qs_ot_env%matrix_h_e_im(i)%matrix)
    1261              :             CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_h_e_im(i)%matrix, &
    1262              :                                                    template=matrix_s, n=nmo, &
    1263         1865 :                                                    sym=dbcsr_type_no_symmetry)
    1264         1865 :             CALL dbcsr_init_p(qs_ot_env%matrix_h_x_im(i)%matrix)
    1265              :             CALL cp_dbcsr_m_by_n_from_row_template(qs_ot_env%matrix_h_x_im(i)%matrix, &
    1266              :                                                    template=matrix_s, n=nmo, &
    1267         2311 :                                                    sym=dbcsr_type_no_symmetry)
    1268              :          END DO
    1269              :       END IF
    1270              : 
    1271          446 :       IF (qs_ot_env%settings%do_rotation) THEN
    1272          173 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_u_im)
    1273              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_u_im, template=matrix_s, m=nmo, n=nmo, &
    1274          173 :                                             sym=dbcsr_type_no_symmetry)
    1275          173 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_x_im)
    1276              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_x_im, template=matrix_s, m=nmo, n=nmo, &
    1277          173 :                                             sym=dbcsr_type_no_symmetry)
    1278          173 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_dedu_im)
    1279              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_dedu_im, template=matrix_s, m=nmo, n=nmo, &
    1280          173 :                                             sym=dbcsr_type_no_symmetry)
    1281          173 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_chc_im)
    1282              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_chc_im, template=matrix_s, m=nmo, n=nmo, &
    1283          173 :                                             sym=dbcsr_type_no_symmetry)
    1284          173 :          CALL dbcsr_init_p(qs_ot_env%rot_mat_gx_im)
    1285              :          CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_gx_im, template=matrix_s, m=nmo, n=nmo, &
    1286          173 :                                             sym=dbcsr_type_no_symmetry)
    1287          173 :          IF (qs_ot_env%settings%occupation_preconditioner) THEN
    1288          116 :             CALL dbcsr_init_p(qs_ot_env%rot_mat_response_gx_im)
    1289              :             CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_response_gx_im, &
    1290              :                                                template=matrix_s, m=nmo, n=nmo, &
    1291          116 :                                                sym=dbcsr_type_no_symmetry)
    1292          116 :             IF (qs_ot_env%use_dx) THEN
    1293           68 :                CALL dbcsr_init_p(qs_ot_env%rot_mat_mermin_g0)
    1294              :                CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_mermin_g0, &
    1295              :                                                   template=matrix_s, m=nmo, n=nmo, &
    1296           68 :                                                   sym=dbcsr_type_no_symmetry)
    1297           68 :                CALL dbcsr_init_p(qs_ot_env%rot_mat_mermin_g0_im)
    1298              :                CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_mermin_g0_im, &
    1299              :                                                   template=matrix_s, m=nmo, n=nmo, &
    1300           68 :                                                   sym=dbcsr_type_no_symmetry)
    1301              :             END IF
    1302              :          END IF
    1303          173 :          IF (qs_ot_env%use_dx) THEN
    1304          117 :             CALL dbcsr_init_p(qs_ot_env%rot_mat_dx_im)
    1305              :             CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_dx_im, template=matrix_s, m=nmo, n=nmo, &
    1306          117 :                                                sym=dbcsr_type_no_symmetry)
    1307              :          END IF
    1308          173 :          IF (qs_ot_env%use_gx_old) THEN
    1309          117 :             CALL dbcsr_init_p(qs_ot_env%rot_mat_gx_old_im)
    1310              :             CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_gx_old_im, template=matrix_s, m=nmo, n=nmo, &
    1311          117 :                                                sym=dbcsr_type_no_symmetry)
    1312              :          END IF
    1313              :          IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
    1314          173 :              qs_ot_env%settings%ot_method == "BROY" .OR. &
    1315              :              qs_ot_env%settings%ot_method == "LBFG") THEN
    1316          110 :             ncoef = qs_ot_env%settings%diis_m
    1317          110 :             IF (qs_ot_env%settings%ot_method == "LBFG") ncoef = ncoef + 1
    1318          110 :             CALL dbcsr_allocate_matrix_set(qs_ot_env%rot_mat_h_e_im, ncoef)
    1319          110 :             CALL dbcsr_allocate_matrix_set(qs_ot_env%rot_mat_h_x_im, ncoef)
    1320          830 :             DO i = 1, ncoef
    1321          720 :                CALL dbcsr_init_p(qs_ot_env%rot_mat_h_e_im(i)%matrix)
    1322              :                CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_h_e_im(i)%matrix, &
    1323              :                                                   template=matrix_s, m=nmo, n=nmo, &
    1324          720 :                                                   sym=dbcsr_type_no_symmetry)
    1325          720 :                CALL dbcsr_init_p(qs_ot_env%rot_mat_h_x_im(i)%matrix)
    1326              :                CALL cp_dbcsr_m_by_n_from_template(qs_ot_env%rot_mat_h_x_im(i)%matrix, &
    1327              :                                                   template=matrix_s, m=nmo, n=nmo, &
    1328          893 :                                                   sym=dbcsr_type_no_symmetry)
    1329              :             END DO
    1330              :          END IF
    1331              :       END IF
    1332              : 
    1333          446 :       qs_ot_env%has_complex_kpoint_state = .TRUE.
    1334              : 
    1335              :    CONTAINS
    1336              : 
    1337              : ! **************************************************************************************************
    1338              : !> \brief allocate a zeroed matrix with the distribution and sparsity of a real companion
    1339              : !> \param matrix output matrix
    1340              : !> \param template real companion matrix
    1341              : !> \param name DBCSR matrix name
    1342              : ! **************************************************************************************************
    1343         2970 :       SUBROUTINE allocate_complex_copy(matrix, template, name)
    1344              :       TYPE(dbcsr_type), POINTER                          :: matrix, template
    1345              :       CHARACTER(LEN=*), INTENT(IN)                       :: name
    1346              : 
    1347         2970 :          CALL dbcsr_init_p(matrix)
    1348         2970 :          CALL dbcsr_copy(matrix, template, name=name)
    1349         2970 :          CALL dbcsr_set(matrix, 0.0_dp)
    1350         2970 :       END SUBROUTINE allocate_complex_copy
    1351              : 
    1352              :    END SUBROUTINE qs_ot_allocate_complex_state
    1353              : 
    1354              : ! **************************************************************************************************
    1355              : !> \brief deallocates data
    1356              : !> \param qs_ot_env ...
    1357              : ! **************************************************************************************************
    1358        10281 :    SUBROUTINE qs_ot_destroy(qs_ot_env)
    1359              :       TYPE(qs_ot_type)                                   :: qs_ot_env
    1360              : 
    1361              :       INTEGER                                            :: physical_spin
    1362              : 
    1363        10281 :       IF (.NOT. qs_ot_env%state_allocated) RETURN
    1364              : 
    1365        10218 :       CALL mp_para_env_release(qs_ot_env%para_env)
    1366        10218 :       CALL cp_blacs_env_release(qs_ot_env%blacs_env)
    1367              : 
    1368        10218 :       IF (ASSOCIATED(qs_ot_env%evals)) DEALLOCATE (qs_ot_env%evals)
    1369        10218 :       IF (ASSOCIATED(qs_ot_env%dum)) DEALLOCATE (qs_ot_env%dum)
    1370              : 
    1371        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_os)) CALL dbcsr_release_p(qs_ot_env%matrix_os)
    1372        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_os_im)) CALL dbcsr_release_p(qs_ot_env%matrix_os_im)
    1373        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_p)) CALL dbcsr_release_p(qs_ot_env%matrix_p)
    1374        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_p_im)) CALL dbcsr_release_p(qs_ot_env%matrix_p_im)
    1375        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_cosp)) CALL dbcsr_release_p(qs_ot_env%matrix_cosp)
    1376        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_cosp_im)) CALL dbcsr_release_p(qs_ot_env%matrix_cosp_im)
    1377        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_sinp)) CALL dbcsr_release_p(qs_ot_env%matrix_sinp)
    1378        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_sinp_im)) CALL dbcsr_release_p(qs_ot_env%matrix_sinp_im)
    1379        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_r)) CALL dbcsr_release_p(qs_ot_env%matrix_r)
    1380        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_r_im)) CALL dbcsr_release_p(qs_ot_env%matrix_r_im)
    1381        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_cosp_b)) CALL dbcsr_release_p(qs_ot_env%matrix_cosp_b)
    1382        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_sinp_b)) CALL dbcsr_release_p(qs_ot_env%matrix_sinp_b)
    1383        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf1)) CALL dbcsr_release_p(qs_ot_env%matrix_buf1)
    1384        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf1_im)) CALL dbcsr_release_p(qs_ot_env%matrix_buf1_im)
    1385        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf2)) CALL dbcsr_release_p(qs_ot_env%matrix_buf2)
    1386        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf2_im)) CALL dbcsr_release_p(qs_ot_env%matrix_buf2_im)
    1387        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf3)) CALL dbcsr_release_p(qs_ot_env%matrix_buf3)
    1388        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf3_im)) CALL dbcsr_release_p(qs_ot_env%matrix_buf3_im)
    1389        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf4)) CALL dbcsr_release_p(qs_ot_env%matrix_buf4)
    1390        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf4_im)) CALL dbcsr_release_p(qs_ot_env%matrix_buf4_im)
    1391        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf1_ortho)) CALL dbcsr_release_p(qs_ot_env%matrix_buf1_ortho)
    1392        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf1_ortho_im)) CALL dbcsr_release_p(qs_ot_env%matrix_buf1_ortho_im)
    1393        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf2_ortho)) CALL dbcsr_release_p(qs_ot_env%matrix_buf2_ortho)
    1394        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf2_ortho_im)) CALL dbcsr_release_p(qs_ot_env%matrix_buf2_ortho_im)
    1395        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_tmp_ortho)) CALL dbcsr_release_p(qs_ot_env%matrix_tmp_ortho)
    1396        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf_nk)) CALL dbcsr_release_p(qs_ot_env%matrix_buf_nk)
    1397        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_buf_nk_im)) CALL dbcsr_release_p(qs_ot_env%matrix_buf_nk_im)
    1398        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_tmp_nk)) CALL dbcsr_release_p(qs_ot_env%matrix_tmp_nk)
    1399        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_c0)) CALL dbcsr_release_p(qs_ot_env%matrix_c0)
    1400        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_sc0)) CALL dbcsr_release_p(qs_ot_env%matrix_sc0)
    1401        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_psc0)) CALL dbcsr_release_p(qs_ot_env%matrix_psc0)
    1402        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_psc0_im)) CALL dbcsr_release_p(qs_ot_env%matrix_psc0_im)
    1403        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_c0_im)) CALL dbcsr_release_p(qs_ot_env%matrix_c0_im)
    1404        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_sc0_im)) CALL dbcsr_release_p(qs_ot_env%matrix_sc0_im)
    1405        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_x)) CALL dbcsr_release_p(qs_ot_env%matrix_x)
    1406        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_sx)) CALL dbcsr_release_p(qs_ot_env%matrix_sx)
    1407        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_x_im)) CALL dbcsr_release_p(qs_ot_env%matrix_x_im)
    1408        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_sx_im)) CALL dbcsr_release_p(qs_ot_env%matrix_sx_im)
    1409        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_gx)) CALL dbcsr_release_p(qs_ot_env%matrix_gx)
    1410        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_gx_im)) CALL dbcsr_release_p(qs_ot_env%matrix_gx_im)
    1411        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_preconditioned_gx)) THEN
    1412          116 :          CALL dbcsr_release_p(qs_ot_env%matrix_preconditioned_gx)
    1413              :       END IF
    1414        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_preconditioned_gx_im)) THEN
    1415          116 :          CALL dbcsr_release_p(qs_ot_env%matrix_preconditioned_gx_im)
    1416              :       END IF
    1417        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_response_gx)) CALL dbcsr_release_p(qs_ot_env%matrix_response_gx)
    1418        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_response_gx_im)) THEN
    1419           68 :          CALL dbcsr_release_p(qs_ot_env%matrix_response_gx_im)
    1420              :       END IF
    1421        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_mermin_g0)) CALL dbcsr_release_p(qs_ot_env%matrix_mermin_g0)
    1422        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_mermin_g0_im)) THEN
    1423           68 :          CALL dbcsr_release_p(qs_ot_env%matrix_mermin_g0_im)
    1424              :       END IF
    1425        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_ref_inv_sqrt)) CALL dbcsr_release_p(qs_ot_env%matrix_ref_inv_sqrt)
    1426        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_ref_inv_sqrt_im)) CALL dbcsr_release_p(qs_ot_env%matrix_ref_inv_sqrt_im)
    1427        30654 :       DO physical_spin = 1, SIZE(qs_ot_env%mermin_physical)
    1428        20436 :          IF (ASSOCIATED(qs_ot_env%mermin_physical(physical_spin)%c0)) THEN
    1429          124 :             CALL cp_fm_release(qs_ot_env%mermin_physical(physical_spin)%c0)
    1430          124 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%c0)
    1431              :          END IF
    1432        20436 :          IF (ASSOCIATED(qs_ot_env%mermin_physical(physical_spin)%c0_im)) THEN
    1433          124 :             CALL cp_fm_release(qs_ot_env%mermin_physical(physical_spin)%c0_im)
    1434          124 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%c0_im)
    1435              :          END IF
    1436        20436 :          IF (ASSOCIATED(qs_ot_env%mermin_physical(physical_spin)%h0)) THEN
    1437          124 :             CALL cp_fm_release(qs_ot_env%mermin_physical(physical_spin)%h0)
    1438          124 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%h0)
    1439              :          END IF
    1440        20436 :          IF (ASSOCIATED(qs_ot_env%mermin_physical(physical_spin)%h0_im)) THEN
    1441          124 :             CALL cp_fm_release(qs_ot_env%mermin_physical(physical_spin)%h0_im)
    1442          124 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%h0_im)
    1443              :          END IF
    1444        20436 :          IF (ASSOCIATED(qs_ot_env%mermin_physical(physical_spin)%c_previous)) THEN
    1445          102 :             CALL cp_fm_release(qs_ot_env%mermin_physical(physical_spin)%c_previous)
    1446          102 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%c_previous)
    1447              :          END IF
    1448        20436 :          IF (ASSOCIATED(qs_ot_env%mermin_physical(physical_spin)%c_previous_im)) THEN
    1449          102 :             CALL cp_fm_release(qs_ot_env%mermin_physical(physical_spin)%c_previous_im)
    1450          102 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%c_previous_im)
    1451              :          END IF
    1452        20436 :          IF (ASSOCIATED(qs_ot_env%mermin_physical(physical_spin)%y_previous)) THEN
    1453          102 :             CALL cp_fm_release(qs_ot_env%mermin_physical(physical_spin)%y_previous)
    1454          102 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%y_previous)
    1455              :          END IF
    1456        20436 :          IF (ASSOCIATED(qs_ot_env%mermin_physical(physical_spin)%y_previous_im)) THEN
    1457          102 :             CALL cp_fm_release(qs_ot_env%mermin_physical(physical_spin)%y_previous_im)
    1458          102 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%y_previous_im)
    1459              :          END IF
    1460        20436 :          IF (ALLOCATED(qs_ot_env%mermin_physical(physical_spin)%occupation0)) THEN
    1461          124 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%occupation0)
    1462              :          END IF
    1463        20436 :          IF (ALLOCATED(qs_ot_env%mermin_physical(physical_spin)%occupation_previous)) THEN
    1464          102 :             DEALLOCATE (qs_ot_env%mermin_physical(physical_spin)%occupation_previous)
    1465              :          END IF
    1466        20436 :          qs_ot_env%mermin_physical(physical_spin)%reference_valid = .FALSE.
    1467        30654 :          qs_ot_env%mermin_physical(physical_spin)%secant_valid = .FALSE.
    1468              :       END DO
    1469        10218 :       IF (ALLOCATED(qs_ot_env%ener_mermin_g0)) DEALLOCATE (qs_ot_env%ener_mermin_g0)
    1470        10218 :       qs_ot_env%mermin_gradient_ref_valid = .FALSE.
    1471        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_dx)) CALL dbcsr_release_p(qs_ot_env%matrix_dx)
    1472        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_dx_im)) CALL dbcsr_release_p(qs_ot_env%matrix_dx_im)
    1473        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_gx_old)) CALL dbcsr_release_p(qs_ot_env%matrix_gx_old)
    1474        10218 :       IF (ASSOCIATED(qs_ot_env%matrix_gx_old_im)) CALL dbcsr_release_p(qs_ot_env%matrix_gx_old_im)
    1475        10218 :       IF (ASSOCIATED(qs_ot_env%buf1_k_k_nosym)) CALL dbcsr_release_p(qs_ot_env%buf1_k_k_nosym)
    1476        10218 :       IF (ASSOCIATED(qs_ot_env%buf2_k_k_nosym)) CALL dbcsr_release_p(qs_ot_env%buf2_k_k_nosym)
    1477        10218 :       IF (ASSOCIATED(qs_ot_env%buf3_k_k_nosym)) CALL dbcsr_release_p(qs_ot_env%buf3_k_k_nosym)
    1478        10218 :       IF (ASSOCIATED(qs_ot_env%buf4_k_k_nosym)) CALL dbcsr_release_p(qs_ot_env%buf4_k_k_nosym)
    1479        10218 :       IF (ASSOCIATED(qs_ot_env%p_k_k_sym)) CALL dbcsr_release_p(qs_ot_env%p_k_k_sym)
    1480        10218 :       IF (ASSOCIATED(qs_ot_env%buf1_k_k_sym)) CALL dbcsr_release_p(qs_ot_env%buf1_k_k_sym)
    1481        10218 :       IF (ASSOCIATED(qs_ot_env%buf2_k_k_sym)) CALL dbcsr_release_p(qs_ot_env%buf2_k_k_sym)
    1482        10218 :       IF (ASSOCIATED(qs_ot_env%buf3_k_k_sym)) CALL dbcsr_release_p(qs_ot_env%buf3_k_k_sym)
    1483        10218 :       IF (ASSOCIATED(qs_ot_env%buf4_k_k_sym)) CALL dbcsr_release_p(qs_ot_env%buf4_k_k_sym)
    1484        10218 :       IF (ASSOCIATED(qs_ot_env%buf1_n_k)) CALL dbcsr_release_p(qs_ot_env%buf1_n_k)
    1485        10218 :       IF (ASSOCIATED(qs_ot_env%buf1_n_k_dp)) CALL dbcsr_release_p(qs_ot_env%buf1_n_k_dp)
    1486              : 
    1487              :       IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
    1488        10218 :           qs_ot_env%settings%ot_method == "BROY" .OR. &
    1489              :           qs_ot_env%settings%ot_method == "LBFG") THEN
    1490         6020 :          CALL dbcsr_deallocate_matrix_set(qs_ot_env%matrix_h_x)
    1491         6020 :          CALL dbcsr_deallocate_matrix_set(qs_ot_env%matrix_h_e)
    1492         6020 :          IF (ASSOCIATED(qs_ot_env%matrix_h_x_im)) THEN
    1493          277 :             CALL dbcsr_deallocate_matrix_set(qs_ot_env%matrix_h_x_im)
    1494              :          END IF
    1495         6020 :          IF (ASSOCIATED(qs_ot_env%matrix_h_e_im)) THEN
    1496          277 :             CALL dbcsr_deallocate_matrix_set(qs_ot_env%matrix_h_e_im)
    1497              :          END IF
    1498              :       END IF
    1499        10218 :       IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
    1500              :           qs_ot_env%settings%ot_method == "BROY") THEN
    1501         5858 :          DEALLOCATE (qs_ot_env%ls_diis)
    1502         5858 :          DEALLOCATE (qs_ot_env%lss_diis)
    1503         5858 :          DEALLOCATE (qs_ot_env%c_diis)
    1504         5858 :          DEALLOCATE (qs_ot_env%c_broy)
    1505         5858 :          DEALLOCATE (qs_ot_env%energy_h)
    1506         5858 :          DEALLOCATE (qs_ot_env%ipivot)
    1507              :       END IF
    1508        10218 :       IF (qs_ot_env%settings%ot_method == "LBFG") THEN
    1509            0 :          DEALLOCATE (qs_ot_env%lbfgs_rho, qs_ot_env%lbfgs_yy, &
    1510          162 :                      qs_ot_env%lbfgs_sy_rotation, qs_ot_env%lbfgs_yy_rotation)
    1511              :       END IF
    1512              : 
    1513        10218 :       IF (qs_ot_env%settings%do_rotation) THEN
    1514              : 
    1515          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_u)) CALL dbcsr_release_p(qs_ot_env%rot_mat_u)
    1516          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_u_im)) CALL dbcsr_release_p(qs_ot_env%rot_mat_u_im)
    1517          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_x)) CALL dbcsr_release_p(qs_ot_env%rot_mat_x)
    1518          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_x_im)) CALL dbcsr_release_p(qs_ot_env%rot_mat_x_im)
    1519          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_dedu)) CALL dbcsr_release_p(qs_ot_env%rot_mat_dedu)
    1520          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_dedu_im)) CALL dbcsr_release_p(qs_ot_env%rot_mat_dedu_im)
    1521          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_chc)) CALL dbcsr_release_p(qs_ot_env%rot_mat_chc)
    1522          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_chc_im)) CALL dbcsr_release_p(qs_ot_env%rot_mat_chc_im)
    1523              : 
    1524              :          IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
    1525          407 :              qs_ot_env%settings%ot_method == "BROY" .OR. &
    1526              :              qs_ot_env%settings%ot_method == "LBFG") THEN
    1527          144 :             CALL dbcsr_deallocate_matrix_set(qs_ot_env%rot_mat_h_x)
    1528          144 :             CALL dbcsr_deallocate_matrix_set(qs_ot_env%rot_mat_h_e)
    1529          144 :             IF (ASSOCIATED(qs_ot_env%rot_mat_h_x_im)) THEN
    1530          110 :                CALL dbcsr_deallocate_matrix_set(qs_ot_env%rot_mat_h_x_im)
    1531              :             END IF
    1532          144 :             IF (ASSOCIATED(qs_ot_env%rot_mat_h_e_im)) THEN
    1533          110 :                CALL dbcsr_deallocate_matrix_set(qs_ot_env%rot_mat_h_e_im)
    1534              :             END IF
    1535              :          END IF
    1536              : 
    1537          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_evals)) DEALLOCATE (qs_ot_env%rot_mat_evals)
    1538          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_evec_re)) CALL dbcsr_release_p(qs_ot_env%rot_mat_evec_re)
    1539          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_evec_im)) CALL dbcsr_release_p(qs_ot_env%rot_mat_evec_im)
    1540          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_gx)) CALL dbcsr_release_p(qs_ot_env%rot_mat_gx)
    1541          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_gx_im)) CALL dbcsr_release_p(qs_ot_env%rot_mat_gx_im)
    1542          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_response_gx)) THEN
    1543          116 :             CALL dbcsr_release_p(qs_ot_env%rot_mat_response_gx)
    1544              :          END IF
    1545          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_response_gx_im)) THEN
    1546          116 :             CALL dbcsr_release_p(qs_ot_env%rot_mat_response_gx_im)
    1547              :          END IF
    1548          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_mermin_g0)) THEN
    1549           68 :             CALL dbcsr_release_p(qs_ot_env%rot_mat_mermin_g0)
    1550              :          END IF
    1551          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_mermin_g0_im)) THEN
    1552           68 :             CALL dbcsr_release_p(qs_ot_env%rot_mat_mermin_g0_im)
    1553              :          END IF
    1554          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_gx_old)) CALL dbcsr_release_p(qs_ot_env%rot_mat_gx_old)
    1555          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_gx_old_im)) CALL dbcsr_release_p(qs_ot_env%rot_mat_gx_old_im)
    1556          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_dx)) CALL dbcsr_release_p(qs_ot_env%rot_mat_dx)
    1557          407 :          IF (ASSOCIATED(qs_ot_env%rot_mat_dx_im)) CALL dbcsr_release_p(qs_ot_env%rot_mat_dx_im)
    1558              :       END IF
    1559              : 
    1560        10218 :       IF (qs_ot_env%settings%do_ener) THEN
    1561          120 :          IF (ASSOCIATED(qs_ot_env%ener_x)) DEALLOCATE (qs_ot_env%ener_x)
    1562          120 :          IF (ASSOCIATED(qs_ot_env%ener_rayleigh)) DEALLOCATE (qs_ot_env%ener_rayleigh)
    1563          120 :          IF (ASSOCIATED(qs_ot_env%ener_gx)) DEALLOCATE (qs_ot_env%ener_gx)
    1564          120 :          IF (ASSOCIATED(qs_ot_env%ener_preconditioned_gx)) THEN
    1565          116 :             DEALLOCATE (qs_ot_env%ener_preconditioned_gx)
    1566              :          END IF
    1567          120 :          IF (ASSOCIATED(qs_ot_env%ener_response_gx)) DEALLOCATE (qs_ot_env%ener_response_gx)
    1568              :          IF (qs_ot_env%settings%ot_method == "DIIS" .OR. &
    1569          120 :              qs_ot_env%settings%ot_method == "BROY" .OR. &
    1570              :              qs_ot_env%settings%ot_method == "LBFG") THEN
    1571           60 :             IF (ASSOCIATED(qs_ot_env%ener_h_x)) DEALLOCATE (qs_ot_env%ener_h_x)
    1572           60 :             IF (ASSOCIATED(qs_ot_env%ener_h_e)) DEALLOCATE (qs_ot_env%ener_h_e)
    1573              :          END IF
    1574          120 :          IF (qs_ot_env%use_dx) THEN
    1575          120 :             IF (ASSOCIATED(qs_ot_env%ener_dx)) DEALLOCATE (qs_ot_env%ener_dx)
    1576              :          END IF
    1577          120 :          IF (qs_ot_env%use_gx_old) THEN
    1578           72 :             IF (ASSOCIATED(qs_ot_env%ener_gx_old)) DEALLOCATE (qs_ot_env%ener_gx_old)
    1579              :          END IF
    1580              :       END IF
    1581              : 
    1582        10218 :       qs_ot_env%state_allocated = .FALSE.
    1583        10218 :       qs_ot_env%has_complex_kpoint_state = .FALSE.
    1584              : 
    1585              :    END SUBROUTINE qs_ot_destroy
    1586              : 
    1587              : ! **************************************************************************************************
    1588              : !> \brief ...
    1589              : !> \param settings ...
    1590              : !> \param ot_section ...
    1591              : !> \param output_unit ...
    1592              : !> \param complex_kpoints whether defaults are for complex k-point OT
    1593              : !> \param eigensolver whether OT minimizes a fixed-H orbital subspace for DIAGONALIZATION
    1594              : ! **************************************************************************************************
    1595        62056 :    SUBROUTINE ot_readwrite_input(settings, ot_section, output_unit, complex_kpoints, eigensolver)
    1596              :       TYPE(qs_ot_settings_type)                          :: settings
    1597              :       TYPE(section_vals_type), POINTER                   :: ot_section
    1598              :       INTEGER, INTENT(IN)                                :: output_unit
    1599              :       LOGICAL, INTENT(IN), OPTIONAL                      :: complex_kpoints, eigensolver
    1600              : 
    1601              :       CHARACTER(len=*), PARAMETER :: routineN = 'ot_readwrite_input'
    1602              : 
    1603              :       INTEGER                                            :: handle, ls_method, ot_algorithm, &
    1604              :                                                             ot_method, ot_ortho_irac
    1605              :       LOGICAL                                            :: energy_gap_explicit, &
    1606              :                                                             lattice_fft_explicit, &
    1607              :                                                             low_rank_base_explicit, &
    1608              :                                                             use_complex_kpoints, use_eigensolver
    1609              : 
    1610         7757 :       CALL timeset(routineN, handle)
    1611              : 
    1612         7757 :       use_complex_kpoints = .FALSE.
    1613         7757 :       IF (PRESENT(complex_kpoints)) use_complex_kpoints = complex_kpoints
    1614         7757 :       use_eigensolver = .FALSE.
    1615         7757 :       IF (PRESENT(eigensolver)) use_eigensolver = eigensolver
    1616              : 
    1617              :       ! choose algorithm
    1618         7757 :       CALL section_vals_val_get(ot_section, "ALGORITHM", i_val=ot_algorithm)
    1619         7083 :       SELECT CASE (ot_algorithm)
    1620              :       CASE (ot_algo_taylor_or_diag)
    1621         7083 :          settings%ot_algorithm = "TOD"
    1622              :       CASE (ot_algo_irac)
    1623          674 :          CALL cite_reference(Weber2008)
    1624          674 :          settings%ot_algorithm = "REF"
    1625              :       CASE DEFAULT
    1626         7757 :          CPABORT("Value unknown")
    1627              :       END SELECT
    1628              : 
    1629              :       ! irac input
    1630         7757 :       CALL section_vals_val_get(ot_section, "IRAC_DEGREE", i_val=settings%irac_degree)
    1631         7757 :       IF (settings%irac_degree < 2 .OR. settings%irac_degree > 4) THEN
    1632            0 :          CPABORT("READ OT IRAC_DEGREE: Value unknown")
    1633              :       END IF
    1634         7757 :       CALL section_vals_val_get(ot_section, "MAX_IRAC", i_val=settings%max_irac)
    1635         7757 :       IF (settings%max_irac < 1) THEN
    1636            0 :          CPABORT("READ OT MAX_IRAC: VALUE MUST BE GREATER THAN ZERO")
    1637              :       END IF
    1638         7757 :       CALL section_vals_val_get(ot_section, "EPS_IRAC_FILTER_MATRIX", r_val=settings%eps_irac_filter_matrix)
    1639         7757 :       CALL section_vals_val_get(ot_section, "EPS_IRAC", r_val=settings%eps_irac)
    1640         7757 :       IF (settings%eps_irac < 0.0_dp) THEN
    1641            0 :          CPABORT("READ OT EPS_IRAC: VALUE MUST BE GREATER THAN ZERO")
    1642              :       END IF
    1643         7757 :       CALL section_vals_val_get(ot_section, "EPS_IRAC_QUICK_EXIT", r_val=settings%eps_irac_quick_exit)
    1644         7757 :       IF (settings%eps_irac_quick_exit < 0.0_dp) THEN
    1645            0 :          CPABORT("READ OT EPS_IRAC_QUICK_EXIT: VALUE MUST BE GREATER THAN ZERO")
    1646              :       END IF
    1647              : 
    1648         7757 :       CALL section_vals_val_get(ot_section, "EPS_IRAC_SWITCH", r_val=settings%eps_irac_switch)
    1649         7757 :       IF (settings%eps_irac_switch < 0.0_dp) THEN
    1650            0 :          CPABORT("READ OT EPS_IRAC_SWITCH: VALUE MUST BE GREATER THAN ZERO")
    1651              :       END IF
    1652              : 
    1653         7757 :       CALL section_vals_val_get(ot_section, "ORTHO_IRAC", i_val=ot_ortho_irac)
    1654         7673 :       SELECT CASE (ot_ortho_irac)
    1655              :       CASE (ot_chol_irac)
    1656         7673 :          settings%ortho_irac = "CHOL"
    1657              :       CASE (ot_poly_irac)
    1658           34 :          settings%ortho_irac = "POLY"
    1659              :       CASE (ot_lwdn_irac)
    1660           50 :          settings%ortho_irac = "LWDN"
    1661              :       CASE DEFAULT
    1662         7757 :          CPABORT("READ OT ORTHO_IRAC: Value unknown")
    1663              :       END SELECT
    1664              : 
    1665         7757 :       CALL section_vals_val_get(ot_section, "ON_THE_FLY_LOC", l_val=settings%on_the_fly_loc)
    1666              : 
    1667         7757 :       CALL section_vals_val_get(ot_section, "MINIMIZER", i_val=ot_method)
    1668              :       ! overwrite input if ot_state is set
    1669         7757 :       IF (settings%ot_state == 1) THEN
    1670            6 :          ot_method = ot_mini_diis
    1671              :       END IF
    1672              :       ! compatibility
    1673           14 :       SELECT CASE (ot_method)
    1674              :       CASE (ot_mini_sd)
    1675           14 :          settings%ot_method = "SD"
    1676              :       CASE (ot_mini_cg)
    1677         2532 :          settings%ot_method = "CG"
    1678              :       CASE (ot_mini_diis)
    1679         5145 :          settings%ot_method = "DIIS"
    1680         5145 :          CALL section_vals_val_get(ot_section, "N_HISTORY_VEC", i_val=settings%diis_m)
    1681              :       CASE (ot_mini_broyden)
    1682           16 :          CALL section_vals_val_get(ot_section, "N_HISTORY_VEC", i_val=settings%diis_m)
    1683           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_BETA", r_val=settings%broyden_beta)
    1684           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_GAMMA", r_val=settings%broyden_gamma)
    1685           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_SIGMA", r_val=settings%broyden_sigma)
    1686           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_ETA", r_val=settings%broyden_eta)
    1687           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_OMEGA", r_val=settings%broyden_omega)
    1688           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_SIGMA_DECREASE", r_val=settings%broyden_sigma_decrease)
    1689           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_SIGMA_MIN", r_val=settings%broyden_sigma_min)
    1690           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_FORGET_HISTORY", l_val=settings%broyden_forget_history)
    1691           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_ADAPTIVE_SIGMA", l_val=settings%broyden_adaptive_sigma)
    1692           16 :          CALL section_vals_val_get(ot_section, "BROYDEN_ENABLE_FLIP", l_val=settings%broyden_enable_flip)
    1693           16 :          settings%ot_method = "BROY"
    1694              :       CASE (ot_mini_lbfgs)
    1695           50 :          CALL section_vals_val_get(ot_section, "N_HISTORY_VEC", i_val=settings%diis_m)
    1696              :          CALL section_vals_val_get(ot_section, "LBFGS_CURVATURE_TOL", &
    1697           50 :                                    r_val=settings%lbfgs_curvature_tol)
    1698              :          CALL section_vals_val_get(ot_section, "LBFGS_DAMPING", &
    1699           50 :                                    l_val=settings%lbfgs_damping)
    1700           50 :          IF (settings%lbfgs_curvature_tol < 0.0_dp .OR. &
    1701              :              settings%lbfgs_curvature_tol >= 1.0_dp) THEN
    1702            0 :             CPABORT("READ OT LBFGS_CURVATURE_TOL: Value must be in [0, 1)")
    1703              :          END IF
    1704           50 :          settings%ot_method = "LBFG"
    1705              :       CASE DEFAULT
    1706         7757 :          CPABORT("READ OTSCF MINIMIZER: Value unknown")
    1707              :       END SELECT
    1708         7757 :       CALL section_vals_val_get(ot_section, "SAFER_DIIS", l_val=settings%safer_diis)
    1709         7757 :       CALL section_vals_val_get(ot_section, "LINESEARCH", i_val=ls_method)
    1710            2 :       SELECT CASE (ls_method)
    1711              :       CASE (ls_none)
    1712            2 :          settings%line_search_method = "NONE"
    1713              :       CASE (ls_2pnt)
    1714         7597 :          settings%line_search_method = "2PNT"
    1715              :       CASE (ls_3pnt)
    1716           40 :          settings%line_search_method = "3PNT"
    1717              :       CASE (ls_adapt)
    1718          106 :          settings%line_search_method = "ADPT"
    1719              :       CASE (ls_gold)
    1720           12 :          settings%line_search_method = "GOLD"
    1721           12 :          CALL section_vals_val_get(ot_section, "GOLD_TARGET", r_val=settings%gold_target)
    1722              :       CASE DEFAULT
    1723         7757 :          CPABORT("READ OTSCF LS: Value unknown")
    1724              :       END SELECT
    1725              : 
    1726         7757 :       CALL section_vals_val_get(ot_section, "PRECOND_SOLVER", i_val=settings%precond_solver_type)
    1727        15490 :       SELECT CASE (settings%precond_solver_type)
    1728              :       CASE (ot_precond_solver_default)
    1729         7733 :          settings%precond_solver_name = "DEFAULT"
    1730              :       CASE (ot_precond_solver_inv_chol)
    1731           16 :          settings%precond_solver_name = "INVERSE_CHOLESKY"
    1732              :       CASE (ot_precond_solver_direct)
    1733            0 :          settings%precond_solver_name = "DIRECT"
    1734              :       CASE (ot_precond_solver_update)
    1735            6 :          settings%precond_solver_name = "INVERSE_UPDATE"
    1736              :       CASE (ot_precond_solver_chebyshev)
    1737            2 :          settings%precond_solver_name = "CHEBYSHEV"
    1738              :       CASE DEFAULT
    1739         7757 :          CPABORT("READ OTSCF SOLVER: Value unknown")
    1740              :       END SELECT
    1741         7757 :       CALL section_vals_val_get(ot_section, "CHEBYSHEV_DEGREE", i_val=settings%chebyshev_degree)
    1742         7757 :       IF (settings%chebyshev_degree < 1 .OR. settings%chebyshev_degree > 100) THEN
    1743            0 :          CPABORT("READ OT CHEBYSHEV_DEGREE: Value must be between 1 and 100")
    1744              :       END IF
    1745              :       CALL section_vals_val_get(ot_section, "FERMI_LOW_RANK_MAX_RANK", &
    1746         7757 :                                 i_val=settings%fermi_low_rank_max_rank)
    1747         7757 :       IF (settings%fermi_low_rank_max_rank == 0 .OR. &
    1748              :           settings%fermi_low_rank_max_rank < -1) THEN
    1749            0 :          CPABORT("READ OT FERMI_LOW_RANK_MAX_RANK: Value must be -1 or a positive integer")
    1750              :       END IF
    1751              : 
    1752         7757 :       CALL section_vals_val_get(ot_section, "MAX_SCF_DIIS", i_val=settings%max_scf_diis)
    1753              : 
    1754              :       !If these values are negative we will set them "optimal" for a given precondtioner below
    1755         7757 :       CALL section_vals_val_get(ot_section, "STEPSIZE", r_val=settings%ds_min)
    1756              :       CALL section_vals_val_get(ot_section, "ENERGY_GAP", r_val=settings%energy_gap, &
    1757         7757 :                                 explicit=energy_gap_explicit)
    1758              : 
    1759         7757 :       CALL section_vals_val_get(ot_section, "PRECONDITIONER", i_val=settings%preconditioner_type)
    1760         8489 :       SELECT CASE (settings%preconditioner_type)
    1761              :       CASE (ot_precond_none)
    1762          732 :          settings%preconditioner_name = "NONE"
    1763          732 :          IF (settings%ds_min < 0.0_dp) settings%ds_min = 0.15_dp
    1764          732 :          IF (settings%energy_gap < 0.0_dp) settings%energy_gap = 0.2_dp
    1765              :       CASE (ot_precond_full_single)
    1766           34 :          settings%preconditioner_name = "FULL_SINGLE"
    1767           34 :          IF (settings%ds_min < 0.0_dp) settings%ds_min = 0.15_dp
    1768           34 :          IF (settings%energy_gap < 0.0_dp) settings%energy_gap = 0.2_dp
    1769              :       CASE (ot_precond_full_single_inverse)
    1770         2994 :          settings%preconditioner_name = "FULL_SINGLE_INVERSE"
    1771         2994 :          IF (settings%ds_min < 0.0_dp) settings%ds_min = 0.08_dp
    1772         2994 :          IF (settings%energy_gap < 0.0_dp) settings%energy_gap = 0.08_dp
    1773              :       CASE (ot_precond_full_all)
    1774         2616 :          settings%preconditioner_name = "FULL_ALL"
    1775         2616 :          IF (settings%ds_min < 0.0_dp) settings%ds_min = 0.15_dp
    1776         2616 :          IF (settings%energy_gap < 0.0_dp) settings%energy_gap = 0.08_dp
    1777              :       CASE (ot_precond_fermi_low_rank)
    1778           12 :          settings%preconditioner_name = "FERMI_LOW_RANK"
    1779           12 :          IF (settings%ds_min < 0.0_dp) settings%ds_min = 0.12_dp
    1780           12 :          IF (settings%energy_gap < 0.0_dp) settings%energy_gap = 0.08_dp
    1781              :       CASE (ot_precond_full_all_covariant)
    1782           20 :          settings%preconditioner_name = "FULL_ALL_COVARIANT"
    1783           20 :          IF (settings%ds_min < 0.0_dp) settings%ds_min = 0.15_dp
    1784           20 :          IF (settings%energy_gap < 0.0_dp) settings%energy_gap = 0.08_dp
    1785              :       CASE (ot_precond_full_kinetic)
    1786         1293 :          settings%preconditioner_name = "FULL_KINETIC"
    1787         1293 :          IF (settings%ds_min < 0.0_dp) settings%ds_min = 0.15_dp
    1788         1293 :          IF (settings%energy_gap < 0.0_dp) settings%energy_gap = 0.2_dp
    1789              :       CASE (ot_precond_s_inverse)
    1790           56 :          settings%preconditioner_name = "FULL_S_INVERSE"
    1791           56 :          IF (settings%ds_min < 0.0_dp) settings%ds_min = 0.15_dp
    1792           56 :          IF (settings%energy_gap < 0.0_dp) settings%energy_gap = 0.2_dp
    1793              :       CASE DEFAULT
    1794         7757 :          CPABORT("READ OTSCF PRECONDITIONER: Value unknown")
    1795              :       END SELECT
    1796              :       IF (use_complex_kpoints .AND. &
    1797         7757 :           settings%preconditioner_type == ot_precond_full_single_inverse .AND. &
    1798            2 :           .NOT. energy_gap_explicit) settings%energy_gap = 0.20_dp
    1799              :       CALL section_vals_val_get(ot_section, "FERMI_LOW_RANK_BASE", &
    1800         7757 :                                 i_val=settings%low_rank_base, explicit=low_rank_base_explicit)
    1801        15514 :       SELECT CASE (settings%low_rank_base)
    1802              :       CASE (ot_low_rank_base_overlap)
    1803         7757 :          settings%low_rank_base_name = "OVERLAP_INVERSE"
    1804              :       CASE (ot_low_rank_base_lattice_fft)
    1805            0 :          settings%low_rank_base_name = "LATTICE_FFT"
    1806              :       CASE DEFAULT
    1807         7757 :          CPABORT("READ OT FERMI_LOW_RANK_BASE: Value unknown")
    1808              :       END SELECT
    1809              :       CALL section_vals_val_get(ot_section, "LATTICE_FFT", &
    1810         7757 :                                 i_val=settings%lattice_fft, explicit=lattice_fft_explicit)
    1811        15494 :       SELECT CASE (settings%lattice_fft)
    1812              :       CASE (ot_lattice_fft_off)
    1813         7737 :          settings%lattice_fft_name = "OFF"
    1814              :       CASE (ot_lattice_fft_on)
    1815           14 :          settings%lattice_fft_name = "ON"
    1816              :       CASE (ot_lattice_fft_auto)
    1817            6 :          settings%lattice_fft_name = "AUTO"
    1818              :       CASE DEFAULT
    1819         7757 :          CPABORT("READ OT LATTICE_FFT: Value unknown")
    1820              :       END SELECT
    1821              :       CALL section_vals_val_get(ot_section, "LATTICE_FFT_LOCAL_CELLS", &
    1822         7757 :                                 i_val=settings%lattice_fft_local_cells)
    1823         7757 :       IF (settings%lattice_fft_local_cells < 0) THEN
    1824            0 :          CPABORT("READ OT LATTICE_FFT_LOCAL_CELLS: Value must not be negative")
    1825              :       END IF
    1826         7757 :       IF (settings%low_rank_base == ot_low_rank_base_lattice_fft) THEN
    1827            0 :          IF (settings%preconditioner_type /= ot_precond_fermi_low_rank) THEN
    1828            0 :             CPABORT("FERMI_LOW_RANK_BASE LATTICE_FFT requires PRECONDITIONER FERMI_LOW_RANK")
    1829              :          END IF
    1830            0 :          IF (lattice_fft_explicit .AND. settings%lattice_fft /= ot_lattice_fft_on) THEN
    1831            0 :             CPABORT("FERMI_LOW_RANK_BASE LATTICE_FFT conflicts with LATTICE_FFT OFF or AUTO")
    1832              :          END IF
    1833            0 :          settings%lattice_fft = ot_lattice_fft_on
    1834            0 :          settings%lattice_fft_name = "ON"
    1835         7757 :       ELSE IF (low_rank_base_explicit) THEN
    1836            0 :          IF (settings%preconditioner_type /= ot_precond_fermi_low_rank) THEN
    1837            0 :             CPWARN("FERMI_LOW_RANK_BASE is ignored unless PRECONDITIONER FERMI_LOW_RANK is selected")
    1838            0 :          ELSE IF (lattice_fft_explicit .AND. settings%lattice_fft /= ot_lattice_fft_off) THEN
    1839            0 :             CPABORT("FERMI_LOW_RANK_BASE OVERLAP_INVERSE conflicts with LATTICE_FFT ON or AUTO")
    1840              :          END IF
    1841              :       END IF
    1842         7757 :       IF (settings%lattice_fft_local_cells > 0 .AND. &
    1843              :           settings%lattice_fft /= ot_lattice_fft_on) THEN
    1844            0 :          CPABORT("LATTICE_FFT_LOCAL_CELLS requires LATTICE_FFT ON")
    1845              :       END IF
    1846         7757 :       IF (use_complex_kpoints .AND. settings%lattice_fft_local_cells > 0) THEN
    1847              :          CALL cp_abort(__LOCATION__, &
    1848              :                        "LATTICE_FFT_LOCAL_CELLS is a Gamma-point supercell approximation; "// &
    1849            0 :                        "explicit K points already use native Bloch blocks")
    1850              :       END IF
    1851         7757 :       CALL section_vals_val_get(ot_section, "CHOLESKY", i_val=settings%cholesky_type)
    1852         7757 :       CALL section_vals_val_get(ot_section, "EPS_TAYLOR", r_val=settings%eps_taylor)
    1853         7757 :       CALL section_vals_val_get(ot_section, "MAX_TAYLOR", i_val=settings%max_taylor)
    1854         7757 :       CALL section_vals_val_get(ot_section, "ROTATION", l_val=settings%do_rotation)
    1855         7757 :       CALL section_vals_val_get(ot_section, "ENERGIES", l_val=settings%do_ener)
    1856              :       CALL section_vals_val_get(ot_section, "OCCUPATION_PRECONDITIONER", &
    1857         7757 :                                 l_val=settings%occupation_preconditioner)
    1858         7757 :       CALL section_vals_val_get(ot_section, "NONDIAG_ENERGY", l_val=settings%add_nondiag_energy)
    1859              :       CALL section_vals_val_get(ot_section, "NONDIAG_ENERGY_STRENGTH", &
    1860         7757 :                                 r_val=settings%nondiag_energy_strength)
    1861         7757 :       IF (settings%ot_method == "LBFG") THEN
    1862           50 :          IF (settings%ot_algorithm /= "TOD" .AND. settings%ot_algorithm /= "REF") THEN
    1863            0 :             CPABORT("MINIMIZER LBFGS requires ALGORITHM STRICT or IRAC")
    1864              :          END IF
    1865              :       END IF
    1866         7757 :       IF (settings%do_ener .AND. .NOT. use_complex_kpoints .AND. .NOT. use_eigensolver) THEN
    1867            0 :          CPABORT("OT%ENERGIES is currently supported only by the complex K-point Mermin path.")
    1868              :       END IF
    1869         7757 :       IF (use_eigensolver .AND. &
    1870              :           (settings%do_rotation .OR. settings%do_ener .OR. &
    1871              :            settings%occupation_preconditioner .OR. settings%add_nondiag_energy)) THEN
    1872              :          CALL cp_warn(__LOCATION__, &
    1873              :                       "DIAGONALIZATION%OT ignores ROTATION, ENERGIES, "// &
    1874              :                       "OCCUPATION_PRECONDITIONER, and NONDIAG_ENERGY because occupations "// &
    1875            2 :                       "are assigned after eigenspace minimization.")
    1876            2 :          settings%do_rotation = .FALSE.
    1877            2 :          settings%do_ener = .FALSE.
    1878            2 :          settings%occupation_preconditioner = .FALSE.
    1879            2 :          settings%add_nondiag_energy = .FALSE.
    1880              :       END IF
    1881              : 
    1882              :       ! write OT output
    1883              : 
    1884         7757 :       IF (output_unit > 0) THEN
    1885         3995 :          WRITE (output_unit, '(/,A)') "  ----------------------------------- OT ---------------------------------------"
    1886         3995 :          IF (settings%do_rotation) THEN
    1887          165 :             WRITE (output_unit, '(A)') "  Allowing for rotations "
    1888              :          END IF
    1889         3995 :          IF (settings%do_ener) THEN
    1890           44 :             WRITE (output_unit, '(A,L2)') "  Optimizing orbital energies "
    1891              :          END IF
    1892            7 :          SELECT CASE (settings%OT_METHOD)
    1893              :          CASE ("SD")
    1894            7 :             WRITE (output_unit, '(A)') "  Minimizer      : SD                  : steepest descent"
    1895              :          CASE ("CG")
    1896         1295 :             WRITE (output_unit, '(A)') "  Minimizer      : CG                  : conjugate gradient"
    1897              :          CASE ("DIIS")
    1898         2660 :             WRITE (output_unit, '(A)') "  Minimizer      : DIIS                : direct inversion"
    1899         2660 :             WRITE (output_unit, '(A)') "                                         in the iterative subspace"
    1900         2660 :             WRITE (output_unit, '(A,I3,A)') "                                         using ", settings%diis_m, " DIIS vectors"
    1901         2660 :             IF (settings%safer_diis) THEN
    1902         2660 :                WRITE (output_unit, '(A,I3,A)') "                                         safer DIIS on"
    1903              :             ELSE
    1904            0 :                WRITE (output_unit, '(A,I3,A)') "                                         safer DIIS off"
    1905              :             END IF
    1906              :          CASE ("BROY")
    1907            8 :             WRITE (output_unit, '(A)') "  Minimizer      : BROYDEN             : Broyden "
    1908            8 :             WRITE (output_unit, '(A,F16.8)') "                   BETA                : ", settings%broyden_beta
    1909            8 :             WRITE (output_unit, '(A,F16.8)') "                   GAMMA               : ", settings%broyden_gamma
    1910            8 :             WRITE (output_unit, '(A,F16.8)') "                   SIGMA               : ", settings%broyden_sigma
    1911            8 :             WRITE (output_unit, '(A,I3,A)') "                            using      : - ", &
    1912           16 :                settings%diis_m, " BROYDEN vectors"
    1913              :          CASE ("LBFG")
    1914           25 :             WRITE (output_unit, '(A)') "  Minimizer      : LBFGS               : limited-memory BFGS"
    1915           25 :             WRITE (output_unit, '(A,I3,A)') "                            using      :   ", &
    1916           50 :                settings%diis_m, " secant pairs"
    1917           25 :             WRITE (output_unit, '(A,ES12.4)') "                   curvature tolerance : ", &
    1918           50 :                settings%lbfgs_curvature_tol
    1919           25 :             WRITE (output_unit, '(A,L7)') "                   damp weak curvature : ", &
    1920           50 :                settings%lbfgs_damping
    1921              :          CASE DEFAULT
    1922         3995 :             WRITE (output_unit, '(3A)') "  Minimizer      :      ", settings%OT_METHOD, " : UNKNOWN"
    1923              :          END SELECT
    1924           17 :          SELECT CASE (settings%preconditioner_name)
    1925              :          CASE ("FULL_SINGLE")
    1926           17 :             WRITE (output_unit, '(A)') "  Preconditioner : FULL_SINGLE         : diagonalization based"
    1927              :          CASE ("FULL_SINGLE_INVERSE")
    1928         1564 :             WRITE (output_unit, '(A,/,A)') "  Preconditioner : FULL_SINGLE_INVERSE : inversion of ", &
    1929         3128 :                "                                         H + eS - 2*(Sc)(c^T*H*c+const)(Sc)^T"
    1930              :          CASE ("FULL_ALL")
    1931         1338 :             WRITE (output_unit, '(A)') "  Preconditioner : FULL_ALL            : diagonalization, state selective"
    1932              :          CASE ("FERMI_LOW_RANK")
    1933              :             WRITE (output_unit, '(A)') &
    1934            6 :                "  Preconditioner : FERMI_LOW_RANK       : rotationally covariant low-rank correction"
    1935              :          CASE ("FULL_ALL_COVARIANT")
    1936              :             WRITE (output_unit, '(A)') &
    1937           10 :                "  Preconditioner : FULL_ALL_COVARIANT  : rotation-covariant Sylvester inverse"
    1938              :          CASE ("FULL_KINETIC")
    1939          666 :             WRITE (output_unit, '(A)') "  Preconditioner : FULL_KINETIC        : inversion of T + eS"
    1940              :          CASE ("FULL_S_INVERSE")
    1941           28 :             WRITE (output_unit, '(A)') "  Preconditioner : FULL_S_INVERSE      : cholesky inversion of S"
    1942              :          CASE ("SPARSE_DIAG")
    1943              :             WRITE (output_unit, '(A)') &
    1944            0 :                "  Preconditioner : SPARSE_DIAG    : diagonal atomic block diagonalization"
    1945              :          CASE ("SPARSE_KINETIC")
    1946            0 :             WRITE (output_unit, '(A)') "  Preconditioner : SPARSE_KINETIC      : sparse linear solver for T + eS"
    1947              :          CASE ("NONE")
    1948          366 :             WRITE (output_unit, '(A)') "  Preconditioner : NONE"
    1949              :          CASE DEFAULT
    1950         3995 :             WRITE (output_unit, '(3A)') "  Preconditioner : ", settings%preconditioner_name, " : UNKNOWN"
    1951              :          END SELECT
    1952              : 
    1953         3995 :          IF (settings%preconditioner_type == ot_precond_fermi_low_rank) THEN
    1954            6 :             IF (use_complex_kpoints .AND. settings%lattice_fft /= ot_lattice_fft_off) THEN
    1955            1 :                WRITE (output_unit, '(A)') "  Low-rank base : native K-point inverse of S(k)"
    1956            5 :             ELSE IF (settings%lattice_fft == ot_lattice_fft_auto) THEN
    1957            0 :                WRITE (output_unit, '(A)') "  Low-rank base : LATTICE_FFT (AUTO)"
    1958            5 :             ELSE IF (settings%lattice_fft == ot_lattice_fft_on) THEN
    1959            1 :                WRITE (output_unit, '(A)') "  Low-rank base : LATTICE_FFT"
    1960              :             ELSE
    1961            4 :                WRITE (output_unit, '(A,A)') "  Low-rank base : ", TRIM(settings%low_rank_base_name)
    1962              :             END IF
    1963              :          END IF
    1964         3995 :          IF (use_complex_kpoints .AND. settings%lattice_fft /= ot_lattice_fft_off) THEN
    1965            1 :             WRITE (output_unit, '(A)') "  Lattice FFT   : native Bloch blocks (no additional FFT)"
    1966              :          ELSE
    1967         3994 :             WRITE (output_unit, '(A,A)') "  Lattice FFT   : ", TRIM(settings%lattice_fft_name)
    1968              :          END IF
    1969         3995 :          IF (settings%lattice_fft_local_cells > 0) THEN
    1970            2 :             WRITE (output_unit, '(A,I0)') "  Local FFT cells: ", settings%lattice_fft_local_cells
    1971              :          END IF
    1972              : 
    1973         3995 :          WRITE (output_unit, '(A)') "  Precond_solver : "//TRIM(settings%precond_solver_name)
    1974         3995 :          IF (settings%precond_solver_type == ot_precond_solver_chebyshev) THEN
    1975            1 :             WRITE (output_unit, '(A,I14)') "  Chebyshev degree:", settings%chebyshev_degree
    1976              :          END IF
    1977         3995 :          IF (settings%preconditioner_type == ot_precond_fermi_low_rank) THEN
    1978            6 :             WRITE (output_unit, '(A,I14)') "  Low-rank cap    :", settings%fermi_low_rank_max_rank
    1979              :          END IF
    1980              : 
    1981         3995 :          IF (settings%OT_METHOD == "SD" .OR. settings%OT_METHOD == "CG" .OR. &
    1982              :              settings%OT_METHOD == "LBFG") THEN
    1983         1286 :             SELECT CASE (settings%line_search_method)
    1984              :             CASE ("2PNT")
    1985         1286 :                WRITE (output_unit, '(A)') "  Line search    : 2PNT                : 2 energies, one gradient"
    1986              :             CASE ("3PNT")
    1987           18 :                WRITE (output_unit, '(A)') "  Line search    : 3PNT                : 3 energies"
    1988              :             CASE ("GOLD")
    1989            6 :                WRITE (output_unit, '(A)') "  Line search    : GOLD                : bracketing and golden section search"
    1990            6 :                WRITE (output_unit, '(A,F14.8)') "                   target rel accuracy : ", settings%gold_target
    1991              :             CASE ("NONE")
    1992            1 :                WRITE (output_unit, '(A)') "  Line search    : NONE"
    1993              :             CASE DEFAULT
    1994         3995 :                WRITE (output_unit, '(3A)') "  Line search : ", settings%line_search_method, " : UNKNOWN"
    1995              :             END SELECT
    1996              :          END IF
    1997         3995 :          WRITE (output_unit, '(A,F14.8,T49,A,F14.8)') "  stepsize       :", settings%ds_min, &
    1998         7990 :             "  energy_gap     :", settings%energy_gap
    1999         3995 :          IF (settings%ot_algorithm == 'TOD') THEN
    2000         3640 :             WRITE (output_unit, '(A,E14.5,T49,A,I14)') "  eps_taylor     :", settings%eps_taylor, &
    2001         7280 :                "  max_taylor     :", settings%max_taylor
    2002              :          END IF
    2003         3995 :          IF (settings%ot_algorithm == 'REF') THEN
    2004          355 :             WRITE (output_unit, '(A,1X,A,T49,A,I14)') "  ortho_irac     :", settings%ortho_irac, &
    2005          710 :                "  irac_degree    :", settings%irac_degree
    2006          355 :             WRITE (output_unit, '(A,I14,T49,A,E14.5)') "  max_irac       :", settings%max_irac, &
    2007          710 :                "  eps_irac       :", settings%eps_irac
    2008          355 :             WRITE (output_unit, '(A,E14.5,T49,A,E10.3)') "  eps_irac_switch:", settings%eps_irac_switch, &
    2009          710 :                "  eps_irac_quick_exit:", settings%eps_irac_quick_exit
    2010          355 :             WRITE (output_unit, '(A,L2)') "  on_the_fly_loc :", settings%on_the_fly_loc
    2011              :          END IF
    2012         3995 :          WRITE (output_unit, '(A)') "  ----------------------------------- OT ---------------------------------------"
    2013              :          WRITE (UNIT=output_unit, &
    2014              :                 FMT="(/,T3,A,T12,A,T31,A,T39,A,T59,A,T75,A,/,T3,A)") &
    2015         3995 :             "Step", "Update method", "Time", "Convergence", "Total energy", "Change", &
    2016         7990 :             REPEAT("-", 78)
    2017              :       END IF
    2018              : 
    2019         7757 :       CALL timestop(handle)
    2020              : 
    2021         7757 :    END SUBROUTINE ot_readwrite_input
    2022              : 
    2023            0 : END MODULE qs_ot_types
        

Generated by: LCOV version 2.0-1