LCOV - code coverage report
Current view: top level - src - dm_ls_scf.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:9e7f125) Lines: 441 476 92.6 %
Date: 2025-05-16 07:28:05 Functions: 12 12 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Routines for a linear scaling quickstep SCF run based on the density
      10             : !>        matrix
      11             : !> \par History
      12             : !>       2010.10 created [Joost VandeVondele]
      13             : !> \author Joost VandeVondele
      14             : ! **************************************************************************************************
      15             : MODULE dm_ls_scf
      16             :    USE arnoldi_api,                     ONLY: arnoldi_extremal
      17             :    USE bibliography,                    ONLY: Kolafa2004,&
      18             :                                               Kuhne2007,&
      19             :                                               cite_reference
      20             :    USE cp_control_types,                ONLY: dft_control_type
      21             :    USE cp_dbcsr_api,                    ONLY: &
      22             :         dbcsr_add, dbcsr_binary_read, dbcsr_binary_write, dbcsr_copy, dbcsr_create, &
      23             :         dbcsr_distribution_type, dbcsr_filter, dbcsr_get_info, dbcsr_get_occupation, &
      24             :         dbcsr_multiply, dbcsr_p_type, dbcsr_release, dbcsr_scale, dbcsr_set, dbcsr_type, &
      25             :         dbcsr_type_no_symmetry
      26             :    USE cp_dbcsr_contrib,                ONLY: dbcsr_checksum
      27             :    USE cp_external_control,             ONLY: external_control
      28             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      29             :                                               cp_logger_get_default_unit_nr,&
      30             :                                               cp_logger_type
      31             :    USE dm_ls_chebyshev,                 ONLY: compute_chebyshev
      32             :    USE dm_ls_scf_create,                ONLY: ls_scf_create
      33             :    USE dm_ls_scf_curvy,                 ONLY: deallocate_curvy_data,&
      34             :                                               dm_ls_curvy_optimization
      35             :    USE dm_ls_scf_methods,               ONLY: apply_matrix_preconditioner,&
      36             :                                               compute_homo_lumo,&
      37             :                                               density_matrix_sign,&
      38             :                                               density_matrix_sign_fixed_mu,&
      39             :                                               density_matrix_tc2,&
      40             :                                               density_matrix_trs4,&
      41             :                                               ls_scf_init_matrix_S
      42             :    USE dm_ls_scf_qs,                    ONLY: &
      43             :         ls_nonscf_energy, ls_nonscf_ks, ls_scf_dm_to_ks, ls_scf_init_qs, ls_scf_qs_atomic_guess, &
      44             :         matrix_ls_create, matrix_ls_to_qs, matrix_qs_to_ls, rho_mixing_ls_init
      45             :    USE dm_ls_scf_types,                 ONLY: ls_scf_env_type
      46             :    USE ec_env_types,                    ONLY: energy_correction_type
      47             :    USE input_constants,                 ONLY: ls_cluster_atomic,&
      48             :                                               ls_scf_pexsi,&
      49             :                                               ls_scf_sign,&
      50             :                                               ls_scf_tc2,&
      51             :                                               ls_scf_trs4,&
      52             :                                               transport_transmission
      53             :    USE input_section_types,             ONLY: section_vals_type
      54             :    USE iterate_matrix,                  ONLY: purify_mcweeny
      55             :    USE kinds,                           ONLY: default_path_length,&
      56             :                                               default_string_length,&
      57             :                                               dp
      58             :    USE machine,                         ONLY: m_flush,&
      59             :                                               m_walltime
      60             :    USE mathlib,                         ONLY: binomial
      61             :    USE molecule_types,                  ONLY: molecule_type
      62             :    USE pao_main,                        ONLY: pao_optimization_end,&
      63             :                                               pao_optimization_start,&
      64             :                                               pao_post_scf,&
      65             :                                               pao_update
      66             :    USE pexsi_methods,                   ONLY: density_matrix_pexsi,&
      67             :                                               pexsi_finalize_scf,&
      68             :                                               pexsi_init_scf,&
      69             :                                               pexsi_set_convergence_tolerance,&
      70             :                                               pexsi_to_qs
      71             :    USE qs_diis,                         ONLY: qs_diis_b_clear_sparse,&
      72             :                                               qs_diis_b_create_sparse,&
      73             :                                               qs_diis_b_step_4lscf
      74             :    USE qs_diis_types,                   ONLY: qs_diis_b_release_sparse,&
      75             :                                               qs_diis_buffer_type_sparse
      76             :    USE qs_environment_types,            ONLY: get_qs_env,&
      77             :                                               qs_environment_type
      78             :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      79             :    USE qs_nonscf_utils,                 ONLY: qs_nonscf_print_summary
      80             :    USE qs_scf_post_gpw,                 ONLY: qs_scf_post_moments,&
      81             :                                               write_mo_free_results
      82             :    USE qs_scf_post_tb,                  ONLY: scf_post_calculation_tb
      83             :    USE transport,                       ONLY: external_scf_method,&
      84             :                                               transport_initialize
      85             :    USE transport_env_types,             ONLY: transport_env_type
      86             : #include "./base/base_uses.f90"
      87             : 
      88             :    IMPLICIT NONE
      89             : 
      90             :    PRIVATE
      91             : 
      92             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'dm_ls_scf'
      93             : 
      94             :    PUBLIC :: calculate_w_matrix_ls, ls_scf, post_scf_sparsities
      95             : 
      96             : CONTAINS
      97             : 
      98             : ! **************************************************************************************************
      99             : !> \brief perform an linear scaling scf procedure: entry point
     100             : !>
     101             : !> \param qs_env ...
     102             : !> \param nonscf ...
     103             : !> \par History
     104             : !>       2010.10 created [Joost VandeVondele]
     105             : !> \author Joost VandeVondele
     106             : ! **************************************************************************************************
     107         664 :    SUBROUTINE ls_scf(qs_env, nonscf)
     108             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     109             :       LOGICAL, INTENT(IN), OPTIONAL                      :: nonscf
     110             : 
     111             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ls_scf'
     112             : 
     113             :       INTEGER                                            :: handle
     114             :       LOGICAL                                            :: do_scf, pao_is_done
     115             :       TYPE(ls_scf_env_type), POINTER                     :: ls_scf_env
     116             : 
     117         664 :       CALL timeset(routineN, handle)
     118         664 :       do_scf = .TRUE.
     119         664 :       IF (PRESENT(nonscf)) do_scf = .NOT. nonscf
     120             : 
     121             :       ! Moved here from qs_environment to remove dependencies
     122         664 :       CALL ls_scf_create(qs_env)
     123         664 :       CALL get_qs_env(qs_env, ls_scf_env=ls_scf_env)
     124             : 
     125         664 :       IF (do_scf) THEN
     126         598 :          CALL pao_optimization_start(qs_env, ls_scf_env)
     127         598 :          pao_is_done = .FALSE.
     128        1414 :          DO WHILE (.NOT. pao_is_done)
     129         816 :             CALL ls_scf_init_scf(qs_env, ls_scf_env, .FALSE.)
     130         816 :             CALL pao_update(qs_env, ls_scf_env, pao_is_done)
     131         816 :             CALL ls_scf_main(qs_env, ls_scf_env, .FALSE.)
     132         816 :             CALL pao_post_scf(qs_env, ls_scf_env, pao_is_done)
     133         816 :             CALL ls_scf_post(qs_env, ls_scf_env)
     134             :          END DO
     135         598 :          CALL pao_optimization_end(ls_scf_env)
     136             :       ELSE
     137          66 :          CALL ls_scf_init_scf(qs_env, ls_scf_env, .TRUE.)
     138          66 :          CALL ls_scf_main(qs_env, ls_scf_env, .TRUE.)
     139          66 :          CALL ls_scf_post(qs_env, ls_scf_env)
     140             :       END IF
     141             : 
     142         664 :       CALL timestop(handle)
     143             : 
     144         664 :    END SUBROUTINE ls_scf
     145             : 
     146             : ! **************************************************************************************************
     147             : !> \brief initialization needed for scf
     148             : !> \param qs_env ...
     149             : !> \param ls_scf_env ...
     150             : !> \param nonscf ...
     151             : !> \par History
     152             : !>       2010.10 created [Joost VandeVondele]
     153             : !> \author Joost VandeVondele
     154             : ! **************************************************************************************************
     155         882 :    SUBROUTINE ls_scf_init_scf(qs_env, ls_scf_env, nonscf)
     156             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     157             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
     158             :       LOGICAL, INTENT(IN)                                :: nonscf
     159             : 
     160             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ls_scf_init_scf'
     161             : 
     162             :       INTEGER                                            :: handle, ispin, nspin, unit_nr
     163             :       TYPE(cp_logger_type), POINTER                      :: logger
     164         882 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s, matrix_w
     165             :       TYPE(dft_control_type), POINTER                    :: dft_control
     166         882 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     167             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     168             :       TYPE(section_vals_type), POINTER                   :: input
     169             : 
     170         882 :       CALL timeset(routineN, handle)
     171             : 
     172             :       ! get a useful output_unit
     173         882 :       logger => cp_get_default_logger()
     174         882 :       IF (logger%para_env%is_source()) THEN
     175         441 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     176             :       ELSE
     177             :          unit_nr = -1
     178             :       END IF
     179             : 
     180             :       ! get basic quantities from the qs_env
     181             :       CALL get_qs_env(qs_env, nelectron_total=ls_scf_env%nelectron_total, &
     182             :                       matrix_s=matrix_s, &
     183             :                       matrix_w=matrix_w, &
     184             :                       ks_env=ks_env, &
     185             :                       dft_control=dft_control, &
     186             :                       molecule_set=molecule_set, &
     187             :                       input=input, &
     188             :                       has_unit_metric=ls_scf_env%has_unit_metric, &
     189             :                       para_env=ls_scf_env%para_env, &
     190         882 :                       nelectron_spin=ls_scf_env%nelectron_spin)
     191             : 
     192             :       ! needs forces ? There might be a better way to flag this
     193         882 :       ls_scf_env%calculate_forces = ASSOCIATED(matrix_w)
     194             : 
     195             :       ! some basic initialization of the QS side of things
     196         882 :       CALL ls_scf_init_qs(qs_env)
     197             : 
     198             :       ! create the matrix template for use in the ls procedures
     199             :       CALL matrix_ls_create(matrix_ls=ls_scf_env%matrix_s, matrix_qs=matrix_s(1)%matrix, &
     200         882 :                             ls_mstruct=ls_scf_env%ls_mstruct)
     201             : 
     202         882 :       nspin = ls_scf_env%nspins
     203         882 :       IF (ALLOCATED(ls_scf_env%matrix_p)) THEN
     204        1098 :          DO ispin = 1, SIZE(ls_scf_env%matrix_p)
     205        1098 :             CALL dbcsr_release(ls_scf_env%matrix_p(ispin))
     206             :          END DO
     207             :       ELSE
     208        1358 :          ALLOCATE (ls_scf_env%matrix_p(nspin))
     209             :       END IF
     210             : 
     211        1784 :       DO ispin = 1, nspin
     212             :          CALL dbcsr_create(ls_scf_env%matrix_p(ispin), template=ls_scf_env%matrix_s, &
     213        1784 :                            matrix_type=dbcsr_type_no_symmetry)
     214             :       END DO
     215             : 
     216        3548 :       ALLOCATE (ls_scf_env%matrix_ks(nspin))
     217        1784 :       DO ispin = 1, nspin
     218             :          CALL dbcsr_create(ls_scf_env%matrix_ks(ispin), template=ls_scf_env%matrix_s, &
     219        1784 :                            matrix_type=dbcsr_type_no_symmetry)
     220             :       END DO
     221             : 
     222             :       ! set up matrix S, and needed functions of S
     223         882 :       CALL ls_scf_init_matrix_s(matrix_s(1)%matrix, ls_scf_env)
     224             : 
     225             :       ! get the initial guess for the SCF
     226         882 :       CALL ls_scf_initial_guess(qs_env, ls_scf_env, nonscf)
     227             : 
     228         882 :       IF (ls_scf_env%do_rho_mixing) THEN
     229           0 :          CALL rho_mixing_ls_init(qs_env, ls_scf_env)
     230             :       END IF
     231             : 
     232         882 :       IF (ls_scf_env%do_pexsi) THEN
     233           0 :          CALL pexsi_init_scf(ks_env, ls_scf_env%pexsi, matrix_s(1)%matrix)
     234             :       END IF
     235             : 
     236         882 :       IF (qs_env%do_transport) THEN
     237           0 :          CALL transport_initialize(ks_env, qs_env%transport_env, matrix_s(1)%matrix)
     238             :       END IF
     239             : 
     240         882 :       CALL timestop(handle)
     241             : 
     242         882 :    END SUBROUTINE ls_scf_init_scf
     243             : 
     244             : ! **************************************************************************************************
     245             : !> \brief deal with the scf initial guess
     246             : !> \param qs_env ...
     247             : !> \param ls_scf_env ...
     248             : !> \param nonscf ...
     249             : !> \par History
     250             : !>       2012.11 created [Joost VandeVondele]
     251             : !> \author Joost VandeVondele
     252             : ! **************************************************************************************************
     253        1252 :    SUBROUTINE ls_scf_initial_guess(qs_env, ls_scf_env, nonscf)
     254             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     255             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
     256             :       LOGICAL, INTENT(IN)                                :: nonscf
     257             : 
     258             :       CHARACTER(len=*), PARAMETER :: routineN = 'ls_scf_initial_guess'
     259             :       INTEGER, PARAMETER                                 :: aspc_guess = 2, atomic_guess = 1, &
     260             :                                                             restart_guess = 3
     261             : 
     262             :       CHARACTER(LEN=default_path_length)                 :: file_name, project_name
     263             :       INTEGER                                            :: handle, iaspc, initial_guess_type, &
     264             :                                                             ispin, istore, naspc, unit_nr
     265             :       REAL(KIND=dp)                                      :: alpha, cs_pos
     266             :       TYPE(cp_logger_type), POINTER                      :: logger
     267             :       TYPE(dbcsr_distribution_type)                      :: dist
     268             :       TYPE(dbcsr_type)                                   :: matrix_tmp1
     269             : 
     270         512 :       IF (ls_scf_env%do_pao) RETURN ! pao has its own initial guess
     271             : 
     272         370 :       CALL timeset(routineN, handle)
     273             : 
     274             :       ! get a useful output_unit
     275         370 :       logger => cp_get_default_logger()
     276         370 :       IF (logger%para_env%is_source()) THEN
     277         185 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     278             :       ELSE
     279             :          unit_nr = -1
     280             :       END IF
     281             : 
     282         185 :       IF (unit_nr > 0) WRITE (unit_nr, '()')
     283             :       ! if there is no history go for the atomic guess, otherwise extrapolate the dm history
     284         370 :       IF (ls_scf_env%scf_history%istore == 0) THEN
     285         244 :          IF (ls_scf_env%restart_read) THEN
     286             :             initial_guess_type = restart_guess
     287             :          ELSE
     288             :             initial_guess_type = atomic_guess
     289             :          END IF
     290             :       ELSE
     291             :          initial_guess_type = aspc_guess
     292             :       END IF
     293             : 
     294             :       ! how to get the initial guess
     295             :       SELECT CASE (initial_guess_type)
     296             :       CASE (atomic_guess)
     297         240 :          CALL ls_scf_qs_atomic_guess(qs_env, ls_scf_env, ls_scf_env%energy_init, nonscf)
     298         240 :          IF (unit_nr > 0) WRITE (unit_nr, '()')
     299             :       CASE (restart_guess)
     300           4 :          project_name = logger%iter_info%project_name
     301           8 :          DO ispin = 1, SIZE(ls_scf_env%matrix_p)
     302           4 :             WRITE (file_name, '(A,I0,A)') TRIM(project_name)//"_LS_DM_SPIN_", ispin, "_RESTART.dm"
     303           4 :             CALL dbcsr_get_info(ls_scf_env%matrix_p(1), distribution=dist)
     304           4 :             CALL dbcsr_binary_read(file_name, distribution=dist, matrix_new=ls_scf_env%matrix_p(ispin))
     305           4 :             cs_pos = dbcsr_checksum(ls_scf_env%matrix_p(ispin), pos=.TRUE.)
     306          12 :             IF (unit_nr > 0) THEN
     307           2 :                WRITE (unit_nr, '(T2,A,E20.8)') "Read restart DM "//TRIM(file_name)//" with checksum: ", cs_pos
     308             :             END IF
     309             :          END DO
     310             : 
     311             :          ! directly go to computing the corresponding energy and ks matrix
     312           4 :          IF (nonscf) THEN
     313           0 :             CALL ls_nonscf_ks(qs_env, ls_scf_env, ls_scf_env%energy_init)
     314             :          ELSE
     315           4 :             CALL ls_scf_dm_to_ks(qs_env, ls_scf_env, ls_scf_env%energy_init, iscf=0)
     316             :          END IF
     317             :       CASE (aspc_guess)
     318         126 :          CALL cite_reference(Kolafa2004)
     319         126 :          CALL cite_reference(Kuhne2007)
     320         126 :          naspc = MIN(ls_scf_env%scf_history%istore, ls_scf_env%scf_history%nstore)
     321         258 :          DO ispin = 1, SIZE(ls_scf_env%matrix_p)
     322             :             ! actual extrapolation
     323         132 :             CALL dbcsr_set(ls_scf_env%matrix_p(ispin), 0.0_dp)
     324         624 :             DO iaspc = 1, naspc
     325             :                alpha = (-1.0_dp)**(iaspc + 1)*REAL(iaspc, KIND=dp)* &
     326         366 :                        binomial(2*naspc, naspc - iaspc)/binomial(2*naspc - 2, naspc - 1)
     327         366 :                istore = MOD(ls_scf_env%scf_history%istore - iaspc, ls_scf_env%scf_history%nstore) + 1
     328         498 :                CALL dbcsr_add(ls_scf_env%matrix_p(ispin), ls_scf_env%scf_history%matrix(ispin, istore), 1.0_dp, alpha)
     329             :             END DO
     330             :          END DO
     331             :       END SELECT
     332             : 
     333             :       ! which cases need getting purified and non-orthogonal ?
     334         126 :       SELECT CASE (initial_guess_type)
     335             :       CASE (atomic_guess, restart_guess)
     336             :          ! do nothing
     337             :       CASE (aspc_guess)
     338             :          ! purification can't be done on the pexsi matrix, which is not necessarily idempotent,
     339             :          ! and not stored in an ortho basis form
     340         126 :          IF (.NOT. (ls_scf_env%do_pexsi)) THEN
     341         258 :             DO ispin = 1, SIZE(ls_scf_env%matrix_p)
     342             :                ! linear combination of P's is not idempotent. A bit of McWeeny is needed to ensure it is again
     343         132 :                IF (SIZE(ls_scf_env%matrix_p) == 1) CALL dbcsr_scale(ls_scf_env%matrix_p(ispin), 0.5_dp)
     344             :                ! to ensure that noisy blocks do not build up during MD (in particular with curvy) filter that guess a bit more
     345         132 :                CALL dbcsr_filter(ls_scf_env%matrix_p(ispin), ls_scf_env%eps_filter**(2.0_dp/3.0_dp))
     346         132 :                CALL purify_mcweeny(ls_scf_env%matrix_p(ispin:ispin), ls_scf_env%eps_filter, 3)
     347         132 :                IF (SIZE(ls_scf_env%matrix_p) == 1) CALL dbcsr_scale(ls_scf_env%matrix_p(ispin), 2.0_dp)
     348             : 
     349         258 :                IF (ls_scf_env%use_s_sqrt) THEN
     350             :                   ! need to get P in the non-orthogonal basis if it was stored differently
     351             :                   CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, &
     352         132 :                                     matrix_type=dbcsr_type_no_symmetry)
     353             :                   CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_p(ispin), &
     354         132 :                                       0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
     355             :                   CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt_inv, &
     356             :                                       0.0_dp, ls_scf_env%matrix_p(ispin), &
     357         132 :                                       filter_eps=ls_scf_env%eps_filter)
     358         132 :                   CALL dbcsr_release(matrix_tmp1)
     359             : 
     360         132 :                   IF (ls_scf_env%has_s_preconditioner) THEN
     361             :                      CALL apply_matrix_preconditioner(ls_scf_env%matrix_p(ispin), "forward", &
     362         126 :                                                       ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
     363             :                   END IF
     364             :                END IF
     365             :             END DO
     366             :          END IF
     367             : 
     368             :          ! compute corresponding energy and ks matrix
     369         496 :          IF (nonscf) THEN
     370          60 :             CALL ls_nonscf_ks(qs_env, ls_scf_env, ls_scf_env%energy_init)
     371             :          ELSE
     372          66 :             CALL ls_scf_dm_to_ks(qs_env, ls_scf_env, ls_scf_env%energy_init, iscf=0)
     373             :          END IF
     374             :       END SELECT
     375             : 
     376         370 :       IF (unit_nr > 0) THEN
     377         185 :          WRITE (unit_nr, '(T2,A,F20.9)') "Energy with the initial guess:", ls_scf_env%energy_init
     378         185 :          WRITE (unit_nr, '()')
     379             :       END IF
     380             : 
     381         370 :       CALL timestop(handle)
     382             : 
     383         882 :    END SUBROUTINE ls_scf_initial_guess
     384             : 
     385             : ! **************************************************************************************************
     386             : !> \brief store a history of matrices for later use in ls_scf_initial_guess
     387             : !> \param ls_scf_env ...
     388             : !> \par History
     389             : !>       2012.11 created [Joost VandeVondele]
     390             : !> \author Joost VandeVondele
     391             : ! **************************************************************************************************
     392         370 :    SUBROUTINE ls_scf_store_result(ls_scf_env)
     393             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
     394             : 
     395             :       CHARACTER(len=*), PARAMETER :: routineN = 'ls_scf_store_result'
     396             : 
     397             :       CHARACTER(LEN=default_path_length)                 :: file_name, project_name
     398             :       INTEGER                                            :: handle, ispin, istore, unit_nr
     399             :       REAL(KIND=dp)                                      :: cs_pos
     400             :       TYPE(cp_logger_type), POINTER                      :: logger
     401             :       TYPE(dbcsr_type)                                   :: matrix_tmp1
     402             : 
     403         370 :       CALL timeset(routineN, handle)
     404             : 
     405             :       ! get a useful output_unit
     406         370 :       logger => cp_get_default_logger()
     407         370 :       IF (logger%para_env%is_source()) THEN
     408         185 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     409             :       ELSE
     410             :          unit_nr = -1
     411             :       END IF
     412             : 
     413         370 :       IF (ls_scf_env%restart_write) THEN
     414          12 :          DO ispin = 1, SIZE(ls_scf_env%matrix_p)
     415           6 :             project_name = logger%iter_info%project_name
     416           6 :             WRITE (file_name, '(A,I0,A)') TRIM(project_name)//"_LS_DM_SPIN_", ispin, "_RESTART.dm"
     417           6 :             cs_pos = dbcsr_checksum(ls_scf_env%matrix_p(ispin), pos=.TRUE.)
     418           6 :             IF (unit_nr > 0) THEN
     419           3 :                WRITE (unit_nr, '(T2,A,E20.8)') "Writing restart DM "//TRIM(file_name)//" with checksum: ", cs_pos
     420             :             END IF
     421           6 :             IF (ls_scf_env%do_transport .OR. ls_scf_env%do_pexsi) THEN
     422           0 :                IF (unit_nr > 0) THEN
     423           0 :                   WRITE (unit_nr, '(T6,A)') "The restart DM "//TRIM(file_name)//" has the sparsity of S, therefore,"
     424           0 :                   WRITE (unit_nr, '(T6,A)') "not compatible with methods that require a full DM! "
     425             :                END IF
     426             :             END IF
     427          12 :             CALL dbcsr_binary_write(ls_scf_env%matrix_p(ispin), file_name)
     428             :          END DO
     429             :       END IF
     430             : 
     431         370 :       IF (ls_scf_env%scf_history%nstore > 0) THEN
     432         362 :          ls_scf_env%scf_history%istore = ls_scf_env%scf_history%istore + 1
     433         744 :          DO ispin = 1, SIZE(ls_scf_env%matrix_p)
     434         382 :             istore = MOD(ls_scf_env%scf_history%istore - 1, ls_scf_env%scf_history%nstore) + 1
     435         382 :             CALL dbcsr_copy(ls_scf_env%scf_history%matrix(ispin, istore), ls_scf_env%matrix_p(ispin))
     436             : 
     437             :             ! if we have the sqrt around, we use it to go to the orthogonal basis
     438         744 :             IF (ls_scf_env%use_s_sqrt) THEN
     439             :                ! usually sqrt(S) * P * sqrt(S) should be available, or could be stored at least,
     440             :                ! so that the next multiplications could be saved.
     441             :                CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, &
     442         378 :                                  matrix_type=dbcsr_type_no_symmetry)
     443             : 
     444         378 :                IF (ls_scf_env%has_s_preconditioner) THEN
     445             :                   CALL apply_matrix_preconditioner(ls_scf_env%scf_history%matrix(ispin, istore), "backward", &
     446         332 :                                                    ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
     447             :                END IF
     448             :                CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt, ls_scf_env%scf_history%matrix(ispin, istore), &
     449         378 :                                    0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
     450             :                CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt, &
     451             :                                    0.0_dp, ls_scf_env%scf_history%matrix(ispin, istore), &
     452         378 :                                    filter_eps=ls_scf_env%eps_filter)
     453         378 :                CALL dbcsr_release(matrix_tmp1)
     454             :             END IF
     455             : 
     456             :          END DO
     457             :       END IF
     458             : 
     459         370 :       CALL timestop(handle)
     460             : 
     461         370 :    END SUBROUTINE ls_scf_store_result
     462             : 
     463             : ! **************************************************************************************************
     464             : !> \brief Main SCF routine. Can we keep it clean ?
     465             : !> \param qs_env ...
     466             : !> \param ls_scf_env ...
     467             : !> \param nonscf ...
     468             : !> \par History
     469             : !>       2010.10 created [Joost VandeVondele]
     470             : !> \author Joost VandeVondele
     471             : ! **************************************************************************************************
     472         882 :    SUBROUTINE ls_scf_main(qs_env, ls_scf_env, nonscf)
     473             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     474             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
     475             :       LOGICAL, INTENT(IN), OPTIONAL                      :: nonscf
     476             : 
     477             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ls_scf_main'
     478             : 
     479             :       INTEGER                                            :: handle, iscf, ispin, &
     480             :                                                             nelectron_spin_real, nmixing, nspin, &
     481             :                                                             unit_nr
     482             :       LOGICAL :: check_convergence, diis_step, do_transport, extra_scf, maxscf_reached, &
     483             :          scf_converged, should_stop, transm_maxscf_reached, transm_scf_converged
     484             :       REAL(KIND=dp)                                      :: energy_diff, energy_new, energy_old, &
     485             :                                                             eps_diis, t1, t2, tdiag
     486             :       TYPE(cp_logger_type), POINTER                      :: logger
     487         882 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks, matrix_s
     488         882 :       TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:)        :: matrix_ks_deviation, matrix_mixing_old
     489             :       TYPE(energy_correction_type), POINTER              :: ec_env
     490             :       TYPE(qs_diis_buffer_type_sparse), POINTER          :: diis_buffer
     491             :       TYPE(transport_env_type), POINTER                  :: transport_env
     492             : 
     493         882 :       CALL timeset(routineN, handle)
     494             : 
     495             :       ! get a useful output_unit
     496         882 :       logger => cp_get_default_logger()
     497         882 :       IF (logger%para_env%is_source()) THEN
     498         441 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     499             :       ELSE
     500         441 :          unit_nr = -1
     501             :       END IF
     502             : 
     503         882 :       nspin = ls_scf_env%nspins
     504             : 
     505             :       ! old quantities, useful for mixing
     506        5332 :       ALLOCATE (matrix_mixing_old(nspin), matrix_ks_deviation(nspin))
     507        1784 :       DO ispin = 1, nspin
     508         902 :          CALL dbcsr_create(matrix_mixing_old(ispin), template=ls_scf_env%matrix_ks(ispin))
     509             : 
     510         902 :          CALL dbcsr_create(matrix_ks_deviation(ispin), template=ls_scf_env%matrix_ks(ispin))
     511        1784 :          CALL dbcsr_set(matrix_ks_deviation(ispin), 0.0_dp)
     512             :       END DO
     513        2646 :       ls_scf_env%homo_spin(:) = 0.0_dp
     514        2646 :       ls_scf_env%lumo_spin(:) = 0.0_dp
     515             : 
     516         882 :       transm_scf_converged = .FALSE.
     517         882 :       transm_maxscf_reached = .FALSE.
     518             : 
     519         882 :       energy_old = 0.0_dp
     520         882 :       IF (ls_scf_env%scf_history%istore > 0) energy_old = ls_scf_env%energy_init
     521         882 :       check_convergence = .TRUE.
     522         882 :       iscf = 0
     523         882 :       IF (ls_scf_env%ls_diis) THEN
     524           4 :          diis_step = .FALSE.
     525           4 :          eps_diis = ls_scf_env%eps_diis
     526           4 :          nmixing = ls_scf_env%nmixing
     527             :          NULLIFY (diis_buffer)
     528           4 :          ALLOCATE (diis_buffer)
     529             :          CALL qs_diis_b_create_sparse(diis_buffer, &
     530           4 :                                       nbuffer=ls_scf_env%max_diis)
     531           4 :          CALL qs_diis_b_clear_sparse(diis_buffer)
     532           4 :          CALL get_qs_env(qs_env, matrix_s=matrix_s)
     533             :       END IF
     534             : 
     535         882 :       CALL get_qs_env(qs_env, transport_env=transport_env, do_transport=do_transport)
     536             : 
     537             :       ! the real SCF loop
     538        2878 :       DO
     539             : 
     540             :          ! check on max SCF or timing/exit
     541        2878 :          CALL external_control(should_stop, "SCF", start_time=qs_env%start_time, target_time=qs_env%target_time)
     542        2878 :          IF (do_transport) THEN
     543           0 :             maxscf_reached = should_stop .OR. iscf >= ls_scf_env%max_scf
     544             :             ! one extra scf step for post-processing in transmission calculations
     545           0 :             IF (transport_env%params%method .EQ. transport_transmission) THEN
     546           0 :                IF (transm_maxscf_reached) THEN
     547           0 :                   IF (unit_nr > 0) WRITE (unit_nr, '(T2,A)') "SCF not converged! "
     548             :                   EXIT
     549             :                END IF
     550             :                transm_maxscf_reached = maxscf_reached
     551             :             ELSE
     552           0 :                IF (maxscf_reached) THEN
     553           0 :                   IF (unit_nr > 0) WRITE (unit_nr, '(T2,A)') "SCF not converged! "
     554             :                   EXIT
     555             :                END IF
     556             :             END IF
     557             :          ELSE
     558        2878 :             IF (should_stop .OR. iscf >= ls_scf_env%max_scf) THEN
     559          46 :                IF (unit_nr > 0) WRITE (unit_nr, '(T2,A)') "SCF not converged! "
     560             :                ! Skip Harris functional calculation if ground-state is NOT converged
     561          46 :                IF (qs_env%energy_correction) THEN
     562           0 :                   CALL get_qs_env(qs_env, ec_env=ec_env)
     563           0 :                   IF (ec_env%skip_ec) ec_env%do_skip = .TRUE.
     564             :                END IF
     565             :                EXIT
     566             :             END IF
     567             :          END IF
     568             : 
     569        2832 :          t1 = m_walltime()
     570        2832 :          iscf = iscf + 1
     571             : 
     572             :          ! first get a copy of the current KS matrix
     573        2832 :          CALL get_qs_env(qs_env, matrix_ks=matrix_ks)
     574        5884 :          DO ispin = 1, nspin
     575             :             CALL matrix_qs_to_ls(ls_scf_env%matrix_ks(ispin), matrix_ks(ispin)%matrix, &
     576        3052 :                                  ls_scf_env%ls_mstruct, covariant=.TRUE.)
     577        3052 :             IF (ls_scf_env%has_s_preconditioner) THEN
     578             :                CALL apply_matrix_preconditioner(ls_scf_env%matrix_ks(ispin), "forward", &
     579        1302 :                                                 ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
     580             :             END IF
     581        5884 :             CALL dbcsr_filter(ls_scf_env%matrix_ks(ispin), ls_scf_env%eps_filter)
     582             :          END DO
     583             :          ! run curvy steps if required. Needs an idempotent DM (either perification or restart)
     584        2832 :          IF ((iscf > 1 .OR. ls_scf_env%scf_history%istore > 0) .AND. ls_scf_env%curvy_steps) THEN
     585          90 :             CALL dm_ls_curvy_optimization(ls_scf_env, energy_old, check_convergence)
     586             :          ELSE
     587             :             ! turn the KS matrix in a density matrix
     588        5692 :             DO ispin = 1, nspin
     589        2950 :                IF (nonscf) THEN
     590          66 :                   CALL dbcsr_copy(matrix_mixing_old(ispin), ls_scf_env%matrix_ks(ispin))
     591        2884 :                ELSEIF (ls_scf_env%do_rho_mixing) THEN
     592           0 :                   CALL dbcsr_copy(matrix_mixing_old(ispin), ls_scf_env%matrix_ks(ispin))
     593             :                ELSE
     594        2884 :                   IF (iscf == 1) THEN
     595             :                      ! initialize the mixing matrix with the current state if needed
     596         826 :                      CALL dbcsr_copy(matrix_mixing_old(ispin), ls_scf_env%matrix_ks(ispin))
     597             :                   ELSE
     598        2058 :                      IF (ls_scf_env%ls_diis) THEN ! ------- IF-DIIS+MIX--- START
     599          28 :                         IF (diis_step .AND. (iscf - 1) .GE. ls_scf_env%iter_ini_diis) THEN
     600          22 :                            IF (unit_nr > 0) THEN
     601             :                               WRITE (unit_nr, '(A61)') &
     602          11 :                                  '*************************************************************'
     603             :                               WRITE (unit_nr, '(A50,2(I3,A1),L1,A1)') &
     604          11 :                                  " Using DIIS mixed KS:  (iscf,INI_DIIS,DIIS_STEP)=(", &
     605          22 :                                  iscf, ",", ls_scf_env%iter_ini_diis, ",", diis_step, ")"
     606             :                               WRITE (unit_nr, '(A52)') &
     607          11 :                                  " KS_nw= DIIS-Linear-Combination-Previous KS matrices"
     608             :                               WRITE (unit_nr, '(61A)') &
     609          11 :                                  "*************************************************************"
     610             :                            END IF
     611             :                            CALL dbcsr_copy(matrix_mixing_old(ispin), & ! out
     612          22 :                                            ls_scf_env%matrix_ks(ispin)) ! in
     613             :                         ELSE
     614           6 :                            IF (unit_nr > 0) THEN
     615             :                               WRITE (unit_nr, '(A57)') &
     616           3 :                                  "*********************************************************"
     617             :                               WRITE (unit_nr, '(A23,F5.3,A25,I3)') &
     618           3 :                                  " Using MIXING_FRACTION=", ls_scf_env%mixing_fraction, &
     619           6 :                                  " to mix KS matrix:  iscf=", iscf
     620             :                               WRITE (unit_nr, '(A7,F5.3,A6,F5.3,A7)') &
     621           3 :                                  " KS_nw=", ls_scf_env%mixing_fraction, "*KS + ", &
     622           6 :                                  1.0_dp - ls_scf_env%mixing_fraction, "*KS_old"
     623             :                               WRITE (unit_nr, '(A57)') &
     624           3 :                                  "*********************************************************"
     625             :                            END IF
     626             :                            ! perform the mixing of ks matrices
     627             :                            CALL dbcsr_add(matrix_mixing_old(ispin), &
     628             :                                           ls_scf_env%matrix_ks(ispin), &
     629             :                                           1.0_dp - ls_scf_env%mixing_fraction, &
     630           6 :                                           ls_scf_env%mixing_fraction)
     631             :                         END IF
     632             :                      ELSE ! otherwise
     633        2030 :                         IF (unit_nr > 0) THEN
     634             :                            WRITE (unit_nr, '(A57)') &
     635        1015 :                               "*********************************************************"
     636             :                            WRITE (unit_nr, '(A23,F5.3,A25,I3)') &
     637        1015 :                               " Using MIXING_FRACTION=", ls_scf_env%mixing_fraction, &
     638        2030 :                               " to mix KS matrix:  iscf=", iscf
     639             :                            WRITE (unit_nr, '(A7,F5.3,A6,F5.3,A7)') &
     640        1015 :                               " KS_nw=", ls_scf_env%mixing_fraction, "*KS + ", &
     641        2030 :                               1.0_dp - ls_scf_env%mixing_fraction, "*KS_old"
     642             :                            WRITE (unit_nr, '(A57)') &
     643        1015 :                               "*********************************************************"
     644             :                         END IF
     645             :                         ! perform the mixing of ks matrices
     646             :                         CALL dbcsr_add(matrix_mixing_old(ispin), &
     647             :                                        ls_scf_env%matrix_ks(ispin), &
     648             :                                        1.0_dp - ls_scf_env%mixing_fraction, &
     649        2030 :                                        ls_scf_env%mixing_fraction)
     650             :                      END IF ! ------- IF-DIIS+MIX--- END
     651             :                   END IF
     652             :                END IF
     653             : 
     654             :                ! compute the density matrix that matches it
     655             :                ! we need the proper number of states
     656        2950 :                nelectron_spin_real = ls_scf_env%nelectron_spin(ispin)
     657        2950 :                IF (ls_scf_env%nspins == 1) nelectron_spin_real = nelectron_spin_real/2
     658             : 
     659        2950 :                IF (do_transport) THEN
     660           0 :                   IF (ls_scf_env%has_s_preconditioner) &
     661           0 :                      CPABORT("NOT YET IMPLEMENTED with S preconditioner. ")
     662           0 :                   IF (ls_scf_env%ls_mstruct%cluster_type .NE. ls_cluster_atomic) &
     663           0 :                      CPABORT("NOT YET IMPLEMENTED with molecular clustering. ")
     664             : 
     665           0 :                   extra_scf = maxscf_reached .OR. scf_converged
     666             :                   ! get the current Kohn-Sham matrix (ks) and return matrix_p evaluated using an external C routine
     667             :                   CALL external_scf_method(transport_env, ls_scf_env%matrix_s, matrix_mixing_old(ispin), &
     668             :                                            ls_scf_env%matrix_p(ispin), nelectron_spin_real, ls_scf_env%natoms, &
     669           0 :                                            energy_diff, iscf, extra_scf)
     670             : 
     671             :                ELSE
     672        3858 :                   SELECT CASE (ls_scf_env%purification_method)
     673             :                   CASE (ls_scf_sign)
     674             :                      CALL density_matrix_sign(ls_scf_env%matrix_p(ispin), ls_scf_env%mu_spin(ispin), ls_scf_env%fixed_mu, &
     675             :                                               ls_scf_env%sign_method, ls_scf_env%sign_order, matrix_mixing_old(ispin), &
     676             :                                               ls_scf_env%matrix_s, ls_scf_env%matrix_s_inv, nelectron_spin_real, &
     677             :                                               ls_scf_env%eps_filter, ls_scf_env%sign_symmetric, ls_scf_env%submatrix_sign_method, &
     678         908 :                                               ls_scf_env%matrix_s_sqrt_inv)
     679             :                   CASE (ls_scf_tc2)
     680             :                      CALL density_matrix_tc2(ls_scf_env%matrix_p(ispin), matrix_mixing_old(ispin), ls_scf_env%matrix_s_sqrt_inv, &
     681             :                                              nelectron_spin_real, ls_scf_env%eps_filter, ls_scf_env%homo_spin(ispin), &
     682             :                                              ls_scf_env%lumo_spin(ispin), non_monotonic=ls_scf_env%non_monotonic, &
     683             :                                              eps_lanczos=ls_scf_env%eps_lanczos, max_iter_lanczos=ls_scf_env%max_iter_lanczos, &
     684         118 :                                              iounit=-1)
     685             :                   CASE (ls_scf_trs4)
     686             :                      CALL density_matrix_trs4(ls_scf_env%matrix_p(ispin), matrix_mixing_old(ispin), ls_scf_env%matrix_s_sqrt_inv, &
     687             :                                               nelectron_spin_real, ls_scf_env%eps_filter, ls_scf_env%homo_spin(ispin), &
     688             :                                               ls_scf_env%lumo_spin(ispin), ls_scf_env%mu_spin(ispin), &
     689             :                                               dynamic_threshold=ls_scf_env%dynamic_threshold, &
     690             :                                               matrix_ks_deviation=matrix_ks_deviation(ispin), &
     691             :                                               eps_lanczos=ls_scf_env%eps_lanczos, max_iter_lanczos=ls_scf_env%max_iter_lanczos, &
     692        1924 :                                               iounit=-1)
     693             :                   CASE (ls_scf_pexsi)
     694           0 :                      IF (ls_scf_env%has_s_preconditioner) &
     695           0 :                         CPABORT("S preconditioning not implemented in combination with the PEXSI library. ")
     696           0 :                      IF (ls_scf_env%ls_mstruct%cluster_type .NE. ls_cluster_atomic) &
     697             :                         CALL cp_abort(__LOCATION__, &
     698           0 :                                       "Molecular clustering not implemented in combination with the PEXSI library. ")
     699             :                      CALL density_matrix_pexsi(ls_scf_env%pexsi, ls_scf_env%matrix_p(ispin), ls_scf_env%pexsi%matrix_w(ispin), &
     700             :                                                ls_scf_env%pexsi%kTS(ispin), matrix_mixing_old(ispin), ls_scf_env%matrix_s, &
     701        2950 :                                                nelectron_spin_real, ls_scf_env%mu_spin(ispin), iscf, ispin)
     702             :                   END SELECT
     703             :                END IF
     704             : 
     705        2950 :                IF (ls_scf_env%has_s_preconditioner) THEN
     706             :                   CALL apply_matrix_preconditioner(ls_scf_env%matrix_p(ispin), "forward", &
     707        1302 :                                                    ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
     708             :                END IF
     709        2950 :                CALL dbcsr_filter(ls_scf_env%matrix_p(ispin), ls_scf_env%eps_filter)
     710             : 
     711        5692 :                IF (ls_scf_env%nspins == 1) CALL dbcsr_scale(ls_scf_env%matrix_p(ispin), 2.0_dp)
     712             : 
     713             :             END DO
     714             :          END IF
     715             : 
     716             :          ! compute the corresponding new energy KS matrix and new energy
     717        2832 :          IF (nonscf) THEN
     718          66 :             CALL ls_nonscf_energy(qs_env, ls_scf_env)
     719             :          ELSE
     720        2766 :             CALL ls_scf_dm_to_ks(qs_env, ls_scf_env, energy_new, iscf)
     721             :          END IF
     722             : 
     723        2832 :          IF (ls_scf_env%do_pexsi) THEN
     724           0 :             CALL pexsi_to_qs(ls_scf_env, qs_env, kTS=ls_scf_env%pexsi%kTS)
     725             :          END IF
     726             : 
     727        2832 :          t2 = m_walltime()
     728        2832 :          IF (nonscf) THEN
     729          66 :             tdiag = t2 - t1
     730          66 :             CALL qs_nonscf_print_summary(qs_env, tdiag, ls_scf_env%nelectron_total, unit_nr)
     731          66 :             EXIT
     732             :          ELSE
     733             :             ! report current SCF loop
     734        2766 :             energy_diff = energy_new - energy_old
     735        2766 :             energy_old = energy_new
     736        2766 :             IF (unit_nr > 0) THEN
     737        1383 :                WRITE (unit_nr, *)
     738        1383 :                WRITE (unit_nr, '(T2,A,I6,F20.9,F20.9,F12.6)') "SCF", iscf, energy_new, energy_diff, t2 - t1
     739        1383 :                WRITE (unit_nr, *)
     740        1383 :                CALL m_flush(unit_nr)
     741             :             END IF
     742             :          END IF
     743             : 
     744        2766 :          IF (do_transport) THEN
     745           0 :             scf_converged = check_convergence .AND. ABS(energy_diff) < ls_scf_env%eps_scf*ls_scf_env%nelectron_total
     746             :             ! one extra scf step for post-processing in transmission calculations
     747           0 :             IF (transport_env%params%method .EQ. transport_transmission) THEN
     748           0 :                IF (transm_scf_converged) EXIT
     749             :                transm_scf_converged = scf_converged
     750             :             ELSE
     751           0 :                IF (scf_converged) THEN
     752           0 :                   IF (unit_nr > 0) WRITE (unit_nr, '(/,T2,A,I5,A/)') "SCF run converged in ", iscf, " steps."
     753             :                   EXIT
     754             :                END IF
     755             :             END IF
     756             :          ELSE
     757             :             ! exit criterion on the energy only for the time being
     758        2766 :             IF (check_convergence .AND. ABS(energy_diff) < ls_scf_env%eps_scf*ls_scf_env%nelectron_total) THEN
     759         770 :                IF (unit_nr > 0) WRITE (unit_nr, '(/,T2,A,I5,A/)') "SCF run converged in ", iscf, " steps."
     760             :                ! Skip Harris functional calculation if ground-state is NOT converged
     761         770 :                IF (qs_env%energy_correction) THEN
     762          20 :                   CALL get_qs_env(qs_env, ec_env=ec_env)
     763          20 :                   IF (ec_env%skip_ec) ec_env%do_skip = .FALSE.
     764             :                END IF
     765             :                EXIT
     766             :             END IF
     767             :          END IF
     768             : 
     769        1996 :          IF (ls_scf_env%ls_diis) THEN
     770             : ! diis_buffer, buffer with 1) Kohn-Sham history matrix,
     771             : !                          2) KS error history matrix (f=KPS-SPK),
     772             : !                          3) B matrix (for finding DIIS weighting coefficients)
     773             :             CALL qs_diis_b_step_4lscf(diis_buffer, qs_env, ls_scf_env, unit_nr, &
     774             :                                       iscf, diis_step, eps_diis, nmixing, matrix_s(1)%matrix, &
     775          18 :                                       ls_scf_env%eps_filter)
     776             :          END IF
     777             : 
     778        1996 :          IF (ls_scf_env%do_pexsi) THEN
     779             :             CALL pexsi_set_convergence_tolerance(ls_scf_env%pexsi, energy_diff, &
     780             :                                                  ls_scf_env%eps_scf*ls_scf_env%nelectron_total, &
     781             :                                                  ! initialize in second scf step of first SCF cycle:
     782             :                                                  (iscf .EQ. 2) .AND. (ls_scf_env%scf_history%istore .EQ. 0), &
     783           0 :                                                  check_convergence)
     784             :          END IF
     785             : 
     786             :       END DO
     787             : 
     788             :       ! free storage
     789         882 :       IF (ls_scf_env%ls_diis) THEN
     790           4 :          CALL qs_diis_b_release_sparse(diis_buffer)
     791           4 :          DEALLOCATE (diis_buffer)
     792             :       END IF
     793        1784 :       DO ispin = 1, nspin
     794         902 :          CALL dbcsr_release(matrix_mixing_old(ispin))
     795        1784 :          CALL dbcsr_release(matrix_ks_deviation(ispin))
     796             :       END DO
     797         882 :       DEALLOCATE (matrix_mixing_old, matrix_ks_deviation)
     798             : 
     799         882 :       CALL timestop(handle)
     800             : 
     801         882 :    END SUBROUTINE ls_scf_main
     802             : 
     803             : ! **************************************************************************************************
     804             : !> \brief after SCF we have a density matrix, and the self consistent KS matrix
     805             : !>        analyze its properties.
     806             : !> \param qs_env ...
     807             : !> \param ls_scf_env ...
     808             : !> \par History
     809             : !>       2010.10 created [Joost VandeVondele]
     810             : !> \author Joost VandeVondele
     811             : ! **************************************************************************************************
     812         882 :    SUBROUTINE ls_scf_post(qs_env, ls_scf_env)
     813             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     814             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
     815             : 
     816             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ls_scf_post'
     817             : 
     818             :       INTEGER                                            :: handle, ispin, unit_nr
     819             :       REAL(KIND=dp)                                      :: occ
     820             :       TYPE(cp_logger_type), POINTER                      :: logger
     821         882 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_w
     822             :       TYPE(dft_control_type), POINTER                    :: dft_control
     823             : 
     824         882 :       CALL timeset(routineN, handle)
     825             : 
     826         882 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     827             : 
     828             :       ! get a useful output_unit
     829         882 :       logger => cp_get_default_logger()
     830         882 :       IF (logger%para_env%is_source()) THEN
     831         441 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     832             :       ELSE
     833         441 :          unit_nr = -1
     834             :       END IF
     835             : 
     836             :       ! store the matrix for a next scf run
     837         882 :       IF (.NOT. ls_scf_env%do_pao) &
     838         370 :          CALL ls_scf_store_result(ls_scf_env)
     839             : 
     840             :       ! write homo and lumo energy and occupation (if not already part of the output)
     841         882 :       IF (ls_scf_env%curvy_steps) THEN
     842          18 :          CALL post_scf_homo_lumo(ls_scf_env)
     843             : 
     844             :          ! always report P occ
     845          18 :          IF (unit_nr > 0) WRITE (unit_nr, *) ""
     846          38 :          DO ispin = 1, ls_scf_env%nspins
     847          20 :             occ = dbcsr_get_occupation(ls_scf_env%matrix_p(ispin))
     848          38 :             IF (unit_nr > 0) WRITE (unit_nr, '(T2,A,F20.12)') "Density matrix (P) occupation ", occ
     849             :          END DO
     850             :       END IF
     851             : 
     852             :       ! compute the matrix_w if associated
     853         882 :       IF (ls_scf_env%calculate_forces) THEN
     854         170 :          CALL get_qs_env(qs_env, matrix_w=matrix_w)
     855         170 :          CPASSERT(ASSOCIATED(matrix_w))
     856         170 :          IF (ls_scf_env%do_pexsi) THEN
     857           0 :             CALL pexsi_to_qs(ls_scf_env, qs_env, matrix_w=ls_scf_env%pexsi%matrix_w)
     858             :          ELSE
     859         170 :             CALL calculate_w_matrix_ls(matrix_w, ls_scf_env)
     860             :          END IF
     861             :       END IF
     862             : 
     863             :       ! compute properties
     864             : 
     865         882 :       IF (ls_scf_env%perform_mu_scan) CALL post_scf_mu_scan(ls_scf_env)
     866             : 
     867         882 :       IF (ls_scf_env%report_all_sparsities) CALL post_scf_sparsities(ls_scf_env)
     868             : 
     869         882 :       IF (dft_control%qs_control%dftb) THEN
     870          44 :          CALL scf_post_calculation_tb(qs_env, "DFTB", .TRUE.)
     871         838 :       ELSE IF (dft_control%qs_control%xtb) THEN
     872          86 :          CALL scf_post_calculation_tb(qs_env, "xTB", .TRUE.)
     873             :       ELSE
     874         752 :          CALL write_mo_free_results(qs_env)
     875             :       END IF
     876             : 
     877         882 :       IF (ls_scf_env%chebyshev%compute_chebyshev) CALL compute_chebyshev(qs_env, ls_scf_env)
     878             : 
     879         882 :       IF (.TRUE.) CALL post_scf_experiment()
     880             : 
     881         882 :       IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb) THEN
     882             :          !
     883             :       ELSE
     884         752 :          CALL qs_scf_post_moments(qs_env%input, logger, qs_env, unit_nr)
     885             :       END IF
     886             : 
     887             :       ! clean up used data
     888             : 
     889         882 :       CALL dbcsr_release(ls_scf_env%matrix_s)
     890         882 :       CALL deallocate_curvy_data(ls_scf_env%curvy_data)
     891             : 
     892         882 :       IF (ls_scf_env%has_s_preconditioner) THEN
     893         326 :          CALL dbcsr_release(ls_scf_env%matrix_bs_sqrt)
     894         326 :          CALL dbcsr_release(ls_scf_env%matrix_bs_sqrt_inv)
     895             :       END IF
     896             : 
     897         882 :       IF (ls_scf_env%needs_s_inv) THEN
     898         880 :          CALL dbcsr_release(ls_scf_env%matrix_s_inv)
     899             :       END IF
     900             : 
     901         882 :       IF (ls_scf_env%use_s_sqrt) THEN
     902         878 :          CALL dbcsr_release(ls_scf_env%matrix_s_sqrt)
     903         878 :          CALL dbcsr_release(ls_scf_env%matrix_s_sqrt_inv)
     904             :       END IF
     905             : 
     906        1784 :       DO ispin = 1, SIZE(ls_scf_env%matrix_ks)
     907        1784 :          CALL dbcsr_release(ls_scf_env%matrix_ks(ispin))
     908             :       END DO
     909         882 :       DEALLOCATE (ls_scf_env%matrix_ks)
     910             : 
     911         882 :       IF (ls_scf_env%do_pexsi) &
     912           0 :          CALL pexsi_finalize_scf(ls_scf_env%pexsi, ls_scf_env%mu_spin)
     913             : 
     914         882 :       CALL timestop(handle)
     915             : 
     916         882 :    END SUBROUTINE ls_scf_post
     917             : 
     918             : ! **************************************************************************************************
     919             : !> \brief Compute the HOMO LUMO energies post SCF
     920             : !> \param ls_scf_env ...
     921             : !> \par History
     922             : !>       2013.06 created [Joost VandeVondele]
     923             : !> \author Joost VandeVondele
     924             : ! **************************************************************************************************
     925          18 :    SUBROUTINE post_scf_homo_lumo(ls_scf_env)
     926             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
     927             : 
     928             :       CHARACTER(len=*), PARAMETER :: routineN = 'post_scf_homo_lumo'
     929             : 
     930             :       INTEGER                                            :: handle, ispin, nspin, unit_nr
     931             :       LOGICAL                                            :: converged
     932             :       REAL(KIND=dp)                                      :: eps_max, eps_min, homo, lumo
     933             :       TYPE(cp_logger_type), POINTER                      :: logger
     934             :       TYPE(dbcsr_type)                                   :: matrix_k, matrix_p, matrix_tmp
     935             : 
     936          18 :       CALL timeset(routineN, handle)
     937             : 
     938             :       ! get a useful output_unit
     939          18 :       logger => cp_get_default_logger()
     940          18 :       IF (logger%para_env%is_source()) THEN
     941           9 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     942             :       ELSE
     943           9 :          unit_nr = -1
     944             :       END IF
     945             : 
     946          18 :       IF (unit_nr > 0) WRITE (unit_nr, '(T2,A)') ""
     947             : 
     948             :       ! TODO: remove these limitations
     949          18 :       CPASSERT(.NOT. ls_scf_env%has_s_preconditioner)
     950          18 :       CPASSERT(ls_scf_env%use_s_sqrt)
     951             : 
     952          18 :       nspin = ls_scf_env%nspins
     953             : 
     954          18 :       CALL dbcsr_create(matrix_p, template=ls_scf_env%matrix_p(1), matrix_type=dbcsr_type_no_symmetry)
     955             : 
     956          18 :       CALL dbcsr_create(matrix_k, template=ls_scf_env%matrix_p(1), matrix_type=dbcsr_type_no_symmetry)
     957             : 
     958          18 :       CALL dbcsr_create(matrix_tmp, template=ls_scf_env%matrix_p(1), matrix_type=dbcsr_type_no_symmetry)
     959             : 
     960          38 :       DO ispin = 1, nspin
     961             :          ! ortho basis ks
     962             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_ks(ispin), &
     963          20 :                              0.0_dp, matrix_tmp, filter_eps=ls_scf_env%eps_filter)
     964             :          CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp, ls_scf_env%matrix_s_sqrt_inv, &
     965          20 :                              0.0_dp, matrix_k, filter_eps=ls_scf_env%eps_filter)
     966             : 
     967             :          ! extremal eigenvalues ks
     968             :          CALL arnoldi_extremal(matrix_k, eps_max, eps_min, max_iter=ls_scf_env%max_iter_lanczos, &
     969          20 :                                threshold=ls_scf_env%eps_lanczos, converged=converged)
     970             : 
     971             :          ! ortho basis p
     972             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt, ls_scf_env%matrix_p(ispin), &
     973          20 :                              0.0_dp, matrix_tmp, filter_eps=ls_scf_env%eps_filter)
     974             :          CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp, ls_scf_env%matrix_s_sqrt, &
     975          20 :                              0.0_dp, matrix_p, filter_eps=ls_scf_env%eps_filter)
     976          20 :          IF (nspin == 1) CALL dbcsr_scale(matrix_p, 0.5_dp)
     977             : 
     978             :          ! go compute homo lumo
     979             :          CALL compute_homo_lumo(matrix_k, matrix_p, eps_min, eps_max, ls_scf_env%eps_filter, &
     980          58 :                                 ls_scf_env%max_iter_lanczos, ls_scf_env%eps_lanczos, homo, lumo, unit_nr)
     981             : 
     982             :       END DO
     983             : 
     984          18 :       CALL dbcsr_release(matrix_p)
     985          18 :       CALL dbcsr_release(matrix_k)
     986          18 :       CALL dbcsr_release(matrix_tmp)
     987             : 
     988          18 :       CALL timestop(handle)
     989             : 
     990          18 :    END SUBROUTINE post_scf_homo_lumo
     991             : 
     992             : ! **************************************************************************************************
     993             : !> \brief Compute the density matrix for various values of the chemical potential
     994             : !> \param ls_scf_env ...
     995             : !> \par History
     996             : !>       2010.10 created [Joost VandeVondele]
     997             : !> \author Joost VandeVondele
     998             : ! **************************************************************************************************
     999           2 :    SUBROUTINE post_scf_mu_scan(ls_scf_env)
    1000             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
    1001             : 
    1002             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'post_scf_mu_scan'
    1003             : 
    1004             :       INTEGER                                            :: handle, imu, ispin, nelectron_spin_real, &
    1005             :                                                             nmu, nspin, unit_nr
    1006             :       REAL(KIND=dp)                                      :: mu, t1, t2, trace
    1007             :       TYPE(cp_logger_type), POINTER                      :: logger
    1008             :       TYPE(dbcsr_type)                                   :: matrix_p
    1009             : 
    1010           2 :       CALL timeset(routineN, handle)
    1011             : 
    1012             :       ! get a useful output_unit
    1013           2 :       logger => cp_get_default_logger()
    1014           2 :       IF (logger%para_env%is_source()) THEN
    1015           1 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1016             :       ELSE
    1017             :          unit_nr = -1
    1018             :       END IF
    1019             : 
    1020           2 :       nspin = ls_scf_env%nspins
    1021             : 
    1022           2 :       CALL dbcsr_create(matrix_p, template=ls_scf_env%matrix_p(1))
    1023             : 
    1024           2 :       nmu = 10
    1025          24 :       DO imu = 0, nmu
    1026             : 
    1027          22 :          t1 = m_walltime()
    1028             : 
    1029          22 :          mu = -0.4_dp + imu*(0.1_dp + 0.4_dp)/nmu
    1030             : 
    1031          22 :          IF (unit_nr > 0) WRITE (unit_nr, *) "------- starting with mu ", mu
    1032             : 
    1033          44 :          DO ispin = 1, nspin
    1034             :             ! we need the proper number of states
    1035          22 :             nelectron_spin_real = ls_scf_env%nelectron_spin(ispin)
    1036          22 :             IF (ls_scf_env%nspins == 1) nelectron_spin_real = nelectron_spin_real/2
    1037             : 
    1038             :             CALL density_matrix_sign_fixed_mu(matrix_p, trace, mu, ls_scf_env%sign_method, &
    1039             :                                               ls_scf_env%sign_order, ls_scf_env%matrix_ks(ispin), &
    1040             :                                               ls_scf_env%matrix_s, ls_scf_env%matrix_s_inv, &
    1041             :                                               ls_scf_env%eps_filter, ls_scf_env%sign_symmetric, &
    1042          44 :                                               ls_scf_env%submatrix_sign_method, ls_scf_env%matrix_s_sqrt_inv)
    1043             :          END DO
    1044             : 
    1045          22 :          t2 = m_walltime()
    1046             : 
    1047          24 :          IF (unit_nr > 0) WRITE (unit_nr, *) " obtained ", mu, trace, t2 - t1
    1048             : 
    1049             :       END DO
    1050             : 
    1051           2 :       CALL dbcsr_release(matrix_p)
    1052             : 
    1053           2 :       CALL timestop(handle)
    1054             : 
    1055           2 :    END SUBROUTINE post_scf_mu_scan
    1056             : 
    1057             : ! **************************************************************************************************
    1058             : !> \brief Report on the sparsities of various interesting matrices.
    1059             : !>
    1060             : !> \param ls_scf_env ...
    1061             : !> \par History
    1062             : !>       2010.10 created [Joost VandeVondele]
    1063             : !> \author Joost VandeVondele
    1064             : ! **************************************************************************************************
    1065         180 :    SUBROUTINE post_scf_sparsities(ls_scf_env)
    1066             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
    1067             : 
    1068             :       CHARACTER(len=*), PARAMETER :: routineN = 'post_scf_sparsities'
    1069             : 
    1070             :       CHARACTER(LEN=default_string_length)               :: title
    1071             :       INTEGER                                            :: handle, ispin, nspin, unit_nr
    1072             :       TYPE(cp_logger_type), POINTER                      :: logger
    1073             :       TYPE(dbcsr_type)                                   :: matrix_tmp1, matrix_tmp2
    1074             : 
    1075         180 :       CALL timeset(routineN, handle)
    1076             : 
    1077             :       ! get a useful output_unit
    1078         180 :       logger => cp_get_default_logger()
    1079         180 :       IF (logger%para_env%is_source()) THEN
    1080          90 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1081             :       ELSE
    1082          90 :          unit_nr = -1
    1083             :       END IF
    1084             : 
    1085         180 :       nspin = ls_scf_env%nspins
    1086             : 
    1087         180 :       IF (unit_nr > 0) THEN
    1088          90 :          WRITE (unit_nr, '()')
    1089          90 :          WRITE (unit_nr, '(T2,A,E17.3)') "Sparsity reports for eps_filter: ", ls_scf_env%eps_filter
    1090          90 :          WRITE (unit_nr, '()')
    1091             :       END IF
    1092             : 
    1093             :       CALL report_matrix_sparsity(ls_scf_env%matrix_s, unit_nr, "overlap matrix (S)", &
    1094         180 :                                   ls_scf_env%eps_filter)
    1095             : 
    1096         368 :       DO ispin = 1, nspin
    1097         188 :          WRITE (title, '(A,I3)') "Kohn-Sham matrix (H) for spin ", ispin
    1098             :          CALL report_matrix_sparsity(ls_scf_env%matrix_ks(ispin), unit_nr, title, &
    1099         368 :                                      ls_scf_env%eps_filter)
    1100             :       END DO
    1101             : 
    1102         180 :       CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
    1103         180 :       CALL dbcsr_create(matrix_tmp2, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
    1104             : 
    1105         368 :       DO ispin = 1, nspin
    1106         188 :          WRITE (title, '(A,I3)') "Density matrix (P) for spin ", ispin
    1107             :          CALL report_matrix_sparsity(ls_scf_env%matrix_p(ispin), unit_nr, title, &
    1108         188 :                                      ls_scf_env%eps_filter)
    1109             : 
    1110             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s, ls_scf_env%matrix_p(ispin), &
    1111         188 :                              0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
    1112             : 
    1113         188 :          WRITE (title, '(A,I3,A)') "S * P(", ispin, ")"
    1114         188 :          CALL report_matrix_sparsity(matrix_tmp1, unit_nr, title, ls_scf_env%eps_filter)
    1115             : 
    1116             :          CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s, &
    1117         188 :                              0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
    1118         188 :          WRITE (title, '(A,I3,A)') "S * P(", ispin, ") * S"
    1119         368 :          CALL report_matrix_sparsity(matrix_tmp2, unit_nr, title, ls_scf_env%eps_filter)
    1120             :       END DO
    1121             : 
    1122         180 :       IF (ls_scf_env%needs_s_inv) THEN
    1123             :          CALL report_matrix_sparsity(ls_scf_env%matrix_s_inv, unit_nr, "inv(S)", &
    1124         180 :                                      ls_scf_env%eps_filter)
    1125         368 :          DO ispin = 1, nspin
    1126             :             CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_inv, ls_scf_env%matrix_ks(ispin), &
    1127         188 :                                 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
    1128             : 
    1129         188 :             WRITE (title, '(A,I3,A)') "inv(S) * H(", ispin, ")"
    1130         368 :             CALL report_matrix_sparsity(matrix_tmp1, unit_nr, title, ls_scf_env%eps_filter)
    1131             :          END DO
    1132             :       END IF
    1133             : 
    1134         180 :       IF (ls_scf_env%use_s_sqrt) THEN
    1135             : 
    1136             :          CALL report_matrix_sparsity(ls_scf_env%matrix_s_sqrt, unit_nr, "sqrt(S)", &
    1137         178 :                                      ls_scf_env%eps_filter)
    1138             :          CALL report_matrix_sparsity(ls_scf_env%matrix_s_sqrt_inv, unit_nr, "inv(sqrt(S))", &
    1139         178 :                                      ls_scf_env%eps_filter)
    1140             : 
    1141         364 :          DO ispin = 1, nspin
    1142             :             CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_ks(ispin), &
    1143         186 :                                 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
    1144             :             CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt_inv, &
    1145         186 :                                 0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
    1146         186 :             WRITE (title, '(A,I3,A)') "inv(sqrt(S)) * H(", ispin, ") * inv(sqrt(S))"
    1147         364 :             CALL report_matrix_sparsity(matrix_tmp2, unit_nr, title, ls_scf_env%eps_filter)
    1148             :          END DO
    1149             : 
    1150         364 :          DO ispin = 1, nspin
    1151             :             CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt, ls_scf_env%matrix_p(ispin), &
    1152         186 :                                 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
    1153             :             CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt, &
    1154         186 :                                 0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
    1155         186 :             WRITE (title, '(A,I3,A)') "sqrt(S) * P(", ispin, ") * sqrt(S)"
    1156         364 :             CALL report_matrix_sparsity(matrix_tmp2, unit_nr, title, ls_scf_env%eps_filter)
    1157             :          END DO
    1158             : 
    1159             :       END IF
    1160             : 
    1161         180 :       CALL dbcsr_release(matrix_tmp1)
    1162         180 :       CALL dbcsr_release(matrix_tmp2)
    1163             : 
    1164         180 :       CALL timestop(handle)
    1165             : 
    1166         180 :    END SUBROUTINE post_scf_sparsities
    1167             : 
    1168             : ! **************************************************************************************************
    1169             : !> \brief Helper routine to report on the sparsity of a single matrix,
    1170             : !>        for several filtering values
    1171             : !> \param matrix ...
    1172             : !> \param unit_nr ...
    1173             : !> \param title ...
    1174             : !> \param eps ...
    1175             : !> \par History
    1176             : !>       2010.10 created [Joost VandeVondele]
    1177             : !> \author Joost VandeVondele
    1178             : ! **************************************************************************************************
    1179        2028 :    SUBROUTINE report_matrix_sparsity(matrix, unit_nr, title, eps)
    1180             :       TYPE(dbcsr_type)                                   :: matrix
    1181             :       INTEGER                                            :: unit_nr
    1182             :       CHARACTER(LEN=*)                                   :: title
    1183             :       REAL(KIND=dp)                                      :: eps
    1184             : 
    1185             :       CHARACTER(len=*), PARAMETER :: routineN = 'report_matrix_sparsity'
    1186             : 
    1187             :       INTEGER                                            :: handle
    1188             :       REAL(KIND=dp)                                      :: eps_local, occ
    1189             :       TYPE(dbcsr_type)                                   :: matrix_tmp
    1190             : 
    1191        2028 :       CALL timeset(routineN, handle)
    1192        2028 :       CALL dbcsr_create(matrix_tmp, template=matrix, name=TRIM(title))
    1193        2028 :       CALL dbcsr_copy(matrix_tmp, matrix, name=TRIM(title))
    1194             : 
    1195        2028 :       IF (unit_nr > 0) THEN
    1196        1014 :          WRITE (unit_nr, '(T2,A)') "Sparsity for : "//TRIM(title)
    1197             :       END IF
    1198             : 
    1199        2028 :       eps_local = MAX(eps, 10E-14_dp)
    1200       14796 :       DO
    1201       16824 :          IF (eps_local > 1.1_dp) EXIT
    1202       14796 :          CALL dbcsr_filter(matrix_tmp, eps_local)
    1203       14796 :          occ = dbcsr_get_occupation(matrix_tmp)
    1204       14796 :          IF (unit_nr > 0) WRITE (unit_nr, '(T2,F16.12,A3,F16.12)') eps_local, " : ", occ
    1205       14796 :          eps_local = eps_local*10
    1206             :       END DO
    1207             : 
    1208        2028 :       CALL dbcsr_release(matrix_tmp)
    1209             : 
    1210        2028 :       CALL timestop(handle)
    1211             : 
    1212        2028 :    END SUBROUTINE report_matrix_sparsity
    1213             : 
    1214             : ! **************************************************************************************************
    1215             : !> \brief Compute matrix_w as needed for the forces
    1216             : !> \param matrix_w ...
    1217             : !> \param ls_scf_env ...
    1218             : !> \par History
    1219             : !>       2010.11 created [Joost VandeVondele]
    1220             : !> \author Joost VandeVondele
    1221             : ! **************************************************************************************************
    1222         200 :    SUBROUTINE calculate_w_matrix_ls(matrix_w, ls_scf_env)
    1223             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_w
    1224             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
    1225             : 
    1226             :       CHARACTER(len=*), PARAMETER :: routineN = 'calculate_w_matrix_ls'
    1227             : 
    1228             :       INTEGER                                            :: handle, ispin
    1229             :       REAL(KIND=dp)                                      :: scaling
    1230             :       TYPE(dbcsr_type)                                   :: matrix_tmp1, matrix_tmp2, matrix_tmp3
    1231             : 
    1232         200 :       CALL timeset(routineN, handle)
    1233             : 
    1234         200 :       CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
    1235         200 :       CALL dbcsr_create(matrix_tmp2, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
    1236         200 :       CALL dbcsr_create(matrix_tmp3, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
    1237             : 
    1238         200 :       IF (ls_scf_env%nspins == 1) THEN
    1239         192 :          scaling = 0.5_dp
    1240             :       ELSE
    1241           8 :          scaling = 1.0_dp
    1242             :       END IF
    1243             : 
    1244         408 :       DO ispin = 1, ls_scf_env%nspins
    1245             : 
    1246         208 :          CALL dbcsr_copy(matrix_tmp3, ls_scf_env%matrix_ks(ispin))
    1247         208 :          IF (ls_scf_env%has_s_preconditioner) THEN
    1248             :             CALL apply_matrix_preconditioner(matrix_tmp3, "backward", &
    1249         136 :                                              ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
    1250             :          END IF
    1251         208 :          CALL dbcsr_filter(matrix_tmp3, ls_scf_env%eps_filter)
    1252             : 
    1253             :          CALL dbcsr_multiply("N", "N", scaling, ls_scf_env%matrix_p(ispin), matrix_tmp3, &
    1254         208 :                              0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
    1255             :          CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_p(ispin), &
    1256         208 :                              0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
    1257         408 :          CALL matrix_ls_to_qs(matrix_w(ispin)%matrix, matrix_tmp2, ls_scf_env%ls_mstruct, covariant=.FALSE.)
    1258             :       END DO
    1259             : 
    1260         200 :       CALL dbcsr_release(matrix_tmp1)
    1261         200 :       CALL dbcsr_release(matrix_tmp2)
    1262         200 :       CALL dbcsr_release(matrix_tmp3)
    1263             : 
    1264         200 :       CALL timestop(handle)
    1265             : 
    1266         200 :    END SUBROUTINE calculate_w_matrix_ls
    1267             : 
    1268             : ! **************************************************************************************************
    1269             : !> \brief a place for quick experiments
    1270             : !> \par History
    1271             : !>       2010.11 created [Joost VandeVondele]
    1272             : !> \author Joost VandeVondele
    1273             : ! **************************************************************************************************
    1274         882 :    SUBROUTINE post_scf_experiment()
    1275             : 
    1276             :       CHARACTER(len=*), PARAMETER :: routineN = 'post_scf_experiment'
    1277             : 
    1278             :       INTEGER                                            :: handle, unit_nr
    1279             :       TYPE(cp_logger_type), POINTER                      :: logger
    1280             : 
    1281         882 :       CALL timeset(routineN, handle)
    1282             : 
    1283             :       ! get a useful output_unit
    1284         882 :       logger => cp_get_default_logger()
    1285         882 :       IF (logger%para_env%is_source()) THEN
    1286         441 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
    1287             :       ELSE
    1288             :          unit_nr = -1
    1289             :       END IF
    1290             : 
    1291         882 :       CALL timestop(handle)
    1292         882 :    END SUBROUTINE post_scf_experiment
    1293             : 
    1294             : END MODULE dm_ls_scf

Generated by: LCOV version 1.15