LCOV - code coverage report
Current view: top level - src - dm_ls_scf.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 449 475 94.5 %
Date: 2024-11-21 06:45:46 Functions: 12 12 100.0 %

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

Generated by: LCOV version 1.15