LCOV - code coverage report
Current view: top level - src - qs_scf_loop_utils.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:1f285aa) Lines: 177 191 92.7 %
Date: 2024-04-23 06:49:27 Functions: 11 11 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             : !> \brief Utility routines for qs_scf
       9             : ! **************************************************************************************************
      10             : MODULE qs_scf_loop_utils
      11             :    USE cp_control_types,                ONLY: dft_control_type
      12             :    USE cp_external_control,             ONLY: external_control
      13             :    USE cp_log_handling,                 ONLY: cp_to_string
      14             :    USE dbcsr_api,                       ONLY: dbcsr_copy,&
      15             :                                               dbcsr_get_info,&
      16             :                                               dbcsr_p_type,&
      17             :                                               dbcsr_type
      18             :    USE input_section_types,             ONLY: section_vals_type
      19             :    USE kinds,                           ONLY: default_string_length,&
      20             :                                               dp
      21             :    USE kpoint_types,                    ONLY: kpoint_type
      22             :    USE message_passing,                 ONLY: mp_para_env_type
      23             :    USE qs_density_matrices,             ONLY: calculate_density_matrix
      24             :    USE qs_density_mixing_types,         ONLY: broyden_mixing_nr,&
      25             :                                               direct_mixing_nr,&
      26             :                                               gspace_mixing_nr,&
      27             :                                               multisecant_mixing_nr,&
      28             :                                               no_mixing_nr,&
      29             :                                               pulay_mixing_nr
      30             :    USE qs_energy_types,                 ONLY: qs_energy_type
      31             :    USE qs_environment_types,            ONLY: get_qs_env,&
      32             :                                               qs_environment_type
      33             :    USE qs_fb_env_methods,               ONLY: fb_env_do_diag
      34             :    USE qs_gspace_mixing,                ONLY: gspace_mixing
      35             :    USE qs_ks_types,                     ONLY: qs_ks_did_change,&
      36             :                                               qs_ks_env_type
      37             :    USE qs_mixing_utils,                 ONLY: self_consistency_check
      38             :    USE qs_mo_occupation,                ONLY: set_mo_occupation
      39             :    USE qs_mo_types,                     ONLY: mo_set_type
      40             :    USE qs_mom_methods,                  ONLY: do_mom_diag
      41             :    USE qs_ot_scf,                       ONLY: ot_scf_destroy,&
      42             :                                               ot_scf_mini
      43             :    USE qs_outer_scf,                    ONLY: outer_loop_gradient
      44             :    USE qs_rho_methods,                  ONLY: qs_rho_update_rho
      45             :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      46             :                                               qs_rho_type
      47             :    USE qs_scf_diagonalization,          ONLY: do_block_davidson_diag,&
      48             :                                               do_block_krylov_diag,&
      49             :                                               do_general_diag,&
      50             :                                               do_general_diag_kp,&
      51             :                                               do_ot_diag,&
      52             :                                               do_roks_diag,&
      53             :                                               do_scf_diag_subspace,&
      54             :                                               do_special_diag
      55             :    USE qs_scf_methods,                  ONLY: scf_env_density_mixing
      56             :    USE qs_scf_output,                   ONLY: qs_scf_print_summary
      57             :    USE qs_scf_types,                    ONLY: block_davidson_diag_method_nr,&
      58             :                                               block_krylov_diag_method_nr,&
      59             :                                               filter_matrix_diag_method_nr,&
      60             :                                               general_diag_method_nr,&
      61             :                                               ot_diag_method_nr,&
      62             :                                               ot_method_nr,&
      63             :                                               qs_scf_env_type,&
      64             :                                               special_diag_method_nr
      65             :    USE scf_control_types,               ONLY: scf_control_type,&
      66             :                                               smear_type
      67             : #include "./base/base_uses.f90"
      68             : 
      69             :    IMPLICIT NONE
      70             : 
      71             :    PRIVATE
      72             : 
      73             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_loop_utils'
      74             : 
      75             :    PUBLIC :: qs_scf_set_loop_flags, &
      76             :              qs_scf_new_mos, qs_scf_new_mos_kp, &
      77             :              qs_scf_density_mixing, qs_scf_check_inner_exit, &
      78             :              qs_scf_check_outer_exit, qs_scf_inner_finalize, qs_scf_rho_update
      79             : 
      80             : CONTAINS
      81             : 
      82             : ! **************************************************************************************************
      83             : !> \brief computes properties for a given hamiltonian using the current wfn
      84             : !> \param scf_env ...
      85             : !> \param diis_step ...
      86             : !> \param energy_only ...
      87             : !> \param just_energy ...
      88             : !> \param exit_inner_loop ...
      89             : ! **************************************************************************************************
      90       18706 :    SUBROUTINE qs_scf_set_loop_flags(scf_env, diis_step, &
      91             :                                     energy_only, just_energy, exit_inner_loop)
      92             : 
      93             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
      94             :       LOGICAL                                            :: diis_step, energy_only, just_energy, &
      95             :                                                             exit_inner_loop
      96             : 
      97             : ! Some flags needed to be set at the beginning of the loop
      98             : 
      99       18706 :       diis_step = .FALSE.
     100       18706 :       energy_only = .FALSE.
     101       18706 :       just_energy = .FALSE.
     102             : 
     103             :       ! SCF loop, optimisation of the wfn coefficients
     104             :       ! qs_env%rho%rho_r and qs_env%rho%rho_g should be up to date here
     105             : 
     106       18706 :       scf_env%iter_count = 0
     107       18706 :       exit_inner_loop = .FALSE.
     108             : 
     109       18706 :    END SUBROUTINE qs_scf_set_loop_flags
     110             : 
     111             : ! **************************************************************************************************
     112             : !> \brief takes known energy and derivatives and produces new wfns
     113             : !>        and or density matrix
     114             : !> \param qs_env ...
     115             : !> \param scf_env ...
     116             : !> \param scf_control ...
     117             : !> \param scf_section ...
     118             : !> \param diis_step ...
     119             : !> \param energy_only ...
     120             : ! **************************************************************************************************
     121      145147 :    SUBROUTINE qs_scf_new_mos(qs_env, scf_env, scf_control, scf_section, diis_step, &
     122             :                              energy_only)
     123             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     124             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     125             :       TYPE(scf_control_type), POINTER                    :: scf_control
     126             :       TYPE(section_vals_type), POINTER                   :: scf_section
     127             :       LOGICAL                                            :: diis_step, energy_only
     128             : 
     129             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'qs_scf_new_mos'
     130             : 
     131             :       INTEGER                                            :: handle, ispin
     132             :       LOGICAL                                            :: has_unit_metric, skip_diag_sub
     133      145147 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks, matrix_s
     134             :       TYPE(dft_control_type), POINTER                    :: dft_control
     135      145147 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
     136             :       TYPE(qs_energy_type), POINTER                      :: energy
     137             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     138             :       TYPE(qs_rho_type), POINTER                         :: rho
     139             : 
     140      145147 :       CALL timeset(routineN, handle)
     141             : 
     142      145147 :       NULLIFY (energy, ks_env, matrix_ks, matrix_s, rho, mos, dft_control)
     143             : 
     144             :       CALL get_qs_env(qs_env=qs_env, &
     145             :                       matrix_s=matrix_s, energy=energy, &
     146             :                       ks_env=ks_env, &
     147             :                       matrix_ks=matrix_ks, rho=rho, mos=mos, &
     148             :                       dft_control=dft_control, &
     149      145147 :                       has_unit_metric=has_unit_metric)
     150      145147 :       scf_env%iter_param = 0.0_dp
     151             : 
     152             :       ! transfer total_zeff_corr from qs_env to scf_env only if
     153             :       ! correct_el_density_dip is switched on [SGh]
     154      145147 :       IF (dft_control%correct_el_density_dip) THEN
     155          40 :          scf_env%sum_zeff_corr = qs_env%total_zeff_corr
     156          40 :          IF (ABS(qs_env%total_zeff_corr) > 0.0_dp) THEN
     157          40 :             IF (scf_env%method /= general_diag_method_nr) THEN
     158             :                CALL cp_abort(__LOCATION__, &
     159             :                              "Please use ALGORITHM STANDARD in "// &
     160             :                              "SCF%DIAGONALIZATION if "// &
     161             :                              "CORE_CORRECTION /= 0.0 and "// &
     162           0 :                              "SURFACE_DIPOLE_CORRECTION TRUE ")
     163          40 :             ELSEIF (dft_control%roks) THEN
     164             :                CALL cp_abort(__LOCATION__, &
     165             :                              "Combination of "// &
     166             :                              "CORE_CORRECTION /= 0.0 and "// &
     167             :                              "SURFACE_DIPOLE_CORRECTION TRUE "// &
     168           0 :                              "is not implemented with ROKS")
     169          40 :             ELSEIF (scf_control%diagonalization%mom) THEN
     170             :                CALL cp_abort(__LOCATION__, &
     171             :                              "Combination of "// &
     172             :                              "CORE_CORRECTION /= 0.0 and "// &
     173             :                              "SURFACE_DIPOLE_CORRECTION TRUE "// &
     174           0 :                              "is not implemented with SCF%MOM")
     175             :             END IF
     176             :          END IF
     177             :       END IF
     178             : 
     179      145147 :       SELECT CASE (scf_env%method)
     180             :       CASE DEFAULT
     181             :          CALL cp_abort(__LOCATION__, &
     182             :                        "unknown scf method: "// &
     183           0 :                        cp_to_string(scf_env%method))
     184             : 
     185             :          ! *************************************************************************
     186             :          ! Filter matrix diagonalisation: ugly implementation at this point of time
     187             :          ! *************************************************************************
     188             :       CASE (filter_matrix_diag_method_nr)
     189             : 
     190          80 :          IF (ABS(qs_env%total_zeff_corr) > 0.0_dp) THEN
     191             :             CALL cp_abort(__LOCATION__, &
     192             :                           "CORE_CORRECTION /= 0.0 plus SURFACE_DIPOLE_CORRECTION TRUE "// &
     193           0 :                           "requires SCF%DIAGONALIZATION: ALGORITHM STANDARD")
     194             :          END IF
     195             :          CALL fb_env_do_diag(scf_env%filter_matrix_env, qs_env, &
     196          80 :                              matrix_ks, matrix_s, scf_section, diis_step)
     197             : 
     198             :          ! Diagonlization in non orthonormal case
     199             :       CASE (general_diag_method_nr)
     200       62547 :          IF (dft_control%roks) THEN
     201             :             CALL do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
     202             :                               scf_control, scf_section, diis_step, &
     203         528 :                               has_unit_metric)
     204             :          ELSE
     205       62019 :             IF (scf_control%diagonalization%mom) THEN
     206             :                CALL do_mom_diag(scf_env, mos, matrix_ks, &
     207             :                                 matrix_s, scf_control, scf_section, &
     208         324 :                                 diis_step)
     209             :             ELSE
     210             :                CALL do_general_diag(scf_env, mos, matrix_ks, &
     211             :                                     matrix_s, scf_control, scf_section, &
     212       61695 :                                     diis_step)
     213             :             END IF
     214       62019 :             IF (scf_control%do_diag_sub) THEN
     215             :                skip_diag_sub = (scf_env%subspace_env%eps_diag_sub > 0.0_dp) .AND. &
     216          10 :                                (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%subspace_env%eps_diag_sub)
     217             :                IF (.NOT. skip_diag_sub) THEN
     218             :                   CALL do_scf_diag_subspace(qs_env, scf_env, scf_env%subspace_env, mos, rho, &
     219          10 :                                             ks_env, scf_section, scf_control)
     220             :                END IF
     221             :             END IF
     222             :          END IF
     223             :          ! Diagonlization in orthonormal case
     224             :       CASE (special_diag_method_nr)
     225       18410 :          IF (dft_control%roks) THEN
     226             :             CALL do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
     227             :                               scf_control, scf_section, diis_step, &
     228         512 :                               has_unit_metric)
     229             :          ELSE
     230             :             CALL do_special_diag(scf_env, mos, matrix_ks, &
     231             :                                  scf_control, scf_section, &
     232       17898 :                                  diis_step)
     233             :          END IF
     234             :          ! OT diagonlization
     235             :       CASE (ot_diag_method_nr)
     236             :          CALL do_ot_diag(scf_env, mos, matrix_ks, matrix_s, &
     237          64 :                          scf_control, scf_section, diis_step)
     238             :          ! Block Krylov diagonlization
     239             :       CASE (block_krylov_diag_method_nr)
     240          40 :          IF ((scf_env%krylov_space%eps_std_diag > 0.0_dp) .AND. &
     241             :              (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%krylov_space%eps_std_diag)) THEN
     242           2 :             IF (scf_env%krylov_space%always_check_conv) THEN
     243             :                CALL do_block_krylov_diag(scf_env, mos, matrix_ks, &
     244           0 :                                          scf_control, scf_section, check_moconv_only=.TRUE.)
     245             :             END IF
     246             :             CALL do_general_diag(scf_env, mos, matrix_ks, &
     247           2 :                                  matrix_s, scf_control, scf_section, diis_step)
     248             :          ELSE
     249             :             CALL do_block_krylov_diag(scf_env, mos, matrix_ks, &
     250          38 :                                       scf_control, scf_section)
     251             :          END IF
     252          40 :          IF (scf_control%do_diag_sub) THEN
     253             :             skip_diag_sub = (scf_env%subspace_env%eps_diag_sub > 0.0_dp) .AND. &
     254           0 :                             (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%subspace_env%eps_diag_sub)
     255             :             IF (.NOT. skip_diag_sub) THEN
     256             :                CALL do_scf_diag_subspace(qs_env, scf_env, scf_env%subspace_env, mos, rho, &
     257           0 :                                          ks_env, scf_section, scf_control)
     258             :             END IF
     259             :          END IF
     260             :          ! Block Davidson diagonlization
     261             :       CASE (block_davidson_diag_method_nr)
     262             :          CALL do_block_davidson_diag(qs_env, scf_env, mos, matrix_ks, matrix_s, scf_control, &
     263          84 :                                      scf_section, .FALSE.)
     264             :          ! OT without diagonlization. Needs special treatment for SCP runs
     265             :       CASE (ot_method_nr)
     266             :          CALL qs_scf_loop_do_ot(qs_env, scf_env, scf_control%smear, mos, rho, &
     267             :                                 qs_env%mo_derivs, energy%total, &
     268      145147 :                                 matrix_s, energy_only=energy_only, has_unit_metric=has_unit_metric)
     269             :       END SELECT
     270             : 
     271      145147 :       energy%kTS = 0.0_dp
     272      145147 :       energy%efermi = 0.0_dp
     273      145147 :       CALL get_qs_env(qs_env, mos=mos)
     274      311474 :       DO ispin = 1, SIZE(mos)
     275      166327 :          energy%kTS = energy%kTS + mos(ispin)%kTS
     276      311474 :          energy%efermi = energy%efermi + mos(ispin)%mu
     277             :       END DO
     278      145147 :       energy%efermi = energy%efermi/REAL(SIZE(mos), KIND=dp)
     279             : 
     280      145147 :       CALL timestop(handle)
     281             : 
     282      145147 :    END SUBROUTINE qs_scf_new_mos
     283             : 
     284             : ! **************************************************************************************************
     285             : !> \brief Updates MOs and density matrix using diagonalization
     286             : !>        Kpoint code
     287             : !> \param qs_env ...
     288             : !> \param scf_env ...
     289             : !> \param scf_control ...
     290             : !> \param diis_step ...
     291             : ! **************************************************************************************************
     292        5320 :    SUBROUTINE qs_scf_new_mos_kp(qs_env, scf_env, scf_control, diis_step)
     293             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     294             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     295             :       TYPE(scf_control_type), POINTER                    :: scf_control
     296             :       LOGICAL                                            :: diis_step
     297             : 
     298             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'qs_scf_new_mos_kp'
     299             : 
     300             :       INTEGER                                            :: handle, ispin
     301             :       LOGICAL                                            :: has_unit_metric
     302             :       REAL(dp)                                           :: diis_error
     303        5320 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks, matrix_s
     304             :       TYPE(dft_control_type), POINTER                    :: dft_control
     305             :       TYPE(kpoint_type), POINTER                         :: kpoints
     306        5320 :       TYPE(mo_set_type), DIMENSION(:, :), POINTER        :: mos
     307             :       TYPE(qs_energy_type), POINTER                      :: energy
     308             : 
     309        5320 :       CALL timeset(routineN, handle)
     310             : 
     311        5320 :       NULLIFY (dft_control, kpoints, matrix_ks, matrix_s)
     312             : 
     313        5320 :       CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, kpoints=kpoints)
     314        5320 :       scf_env%iter_param = 0.0_dp
     315             : 
     316        5320 :       IF (dft_control%roks) &
     317           0 :          CPABORT("KP code: ROKS method not available: ")
     318             : 
     319        5320 :       SELECT CASE (scf_env%method)
     320             :       CASE DEFAULT
     321             :          CALL cp_abort(__LOCATION__, &
     322             :                        "KP code: Unknown scf method: "// &
     323           0 :                        cp_to_string(scf_env%method))
     324             :       CASE (general_diag_method_nr)
     325             :          ! Diagonlization in non orthonormal case
     326        5320 :          CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s)
     327             :          CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, .TRUE., &
     328        5320 :                                  diis_step, diis_error, qs_env)
     329        5320 :          IF (diis_step) THEN
     330        2372 :             scf_env%iter_param = diis_error
     331        2372 :             scf_env%iter_method = "DIIS/Diag."
     332             :          ELSE
     333        2948 :             IF (scf_env%mixing_method == 0) THEN
     334           0 :                scf_env%iter_method = "NoMix/Diag."
     335        2948 :             ELSE IF (scf_env%mixing_method == 1) THEN
     336        2372 :                scf_env%iter_param = scf_env%p_mix_alpha
     337        2372 :                scf_env%iter_method = "P_Mix/Diag."
     338         576 :             ELSEIF (scf_env%mixing_method > 1) THEN
     339         576 :                scf_env%iter_param = scf_env%mixing_store%alpha
     340         576 :                scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Diag."
     341             :             END IF
     342             :          END IF
     343             :       CASE (special_diag_method_nr)
     344           0 :          CALL get_qs_env(qs_env=qs_env, has_unit_metric=has_unit_metric)
     345           0 :          CPASSERT(has_unit_metric)
     346             :          ! Diagonlization in orthonormal case
     347             :          CALL cp_abort(__LOCATION__, &
     348             :                        "KP code: Scf method not available: "// &
     349           0 :                        cp_to_string(scf_env%method))
     350             :       CASE (ot_diag_method_nr, &
     351             :             block_krylov_diag_method_nr, &
     352             :             block_davidson_diag_method_nr, &
     353             :             ot_method_nr)
     354             :          CALL cp_abort(__LOCATION__, &
     355             :                        "KP code: Scf method not available: "// &
     356        5320 :                        cp_to_string(scf_env%method))
     357             :       END SELECT
     358             : 
     359        5320 :       CALL get_qs_env(qs_env=qs_env, energy=energy)
     360        5320 :       energy%kTS = 0.0_dp
     361        5320 :       energy%efermi = 0.0_dp
     362        5320 :       mos => kpoints%kp_env(1)%kpoint_env%mos
     363       11176 :       DO ispin = 1, SIZE(mos, 2)
     364        5856 :          energy%kTS = energy%kTS + mos(1, ispin)%kTS
     365       11176 :          energy%efermi = energy%efermi + mos(1, ispin)%mu
     366             :       END DO
     367        5320 :       energy%efermi = energy%efermi/REAL(SIZE(mos, 2), KIND=dp)
     368             : 
     369        5320 :       CALL timestop(handle)
     370             : 
     371        5320 :    END SUBROUTINE qs_scf_new_mos_kp
     372             : 
     373             : ! **************************************************************************************************
     374             : !> \brief the inner loop of scf, specific to using to the orbital transformation method
     375             : !>       basically, in goes the ks matrix out goes a new p matrix
     376             : !> \param qs_env ...
     377             : !> \param scf_env ...
     378             : !> \param smear ...
     379             : !> \param mos ...
     380             : !> \param rho ...
     381             : !> \param mo_derivs ...
     382             : !> \param total_energy ...
     383             : !> \param matrix_s ...
     384             : !> \param energy_only ...
     385             : !> \param has_unit_metric ...
     386             : !> \par History
     387             : !>      03.2006 created [Joost VandeVondele]
     388             : !>      2013    moved from qs_scf [Florian Schiffmann]
     389             : ! **************************************************************************************************
     390       63922 :    SUBROUTINE qs_scf_loop_do_ot(qs_env, scf_env, smear, mos, rho, mo_derivs, total_energy, &
     391             :                                 matrix_s, energy_only, has_unit_metric)
     392             : 
     393             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     394             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     395             :       TYPE(smear_type), POINTER                          :: smear
     396             :       TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT)     :: mos
     397             :       TYPE(qs_rho_type), POINTER                         :: rho
     398             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: mo_derivs
     399             :       REAL(KIND=dp), INTENT(IN)                          :: total_energy
     400             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     401             :       LOGICAL, INTENT(INOUT)                             :: energy_only
     402             :       LOGICAL, INTENT(IN)                                :: has_unit_metric
     403             : 
     404             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'qs_scf_loop_do_ot'
     405             : 
     406             :       INTEGER                                            :: handle, ispin
     407       63922 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: rho_ao
     408             :       TYPE(dbcsr_type), POINTER                          :: orthogonality_metric
     409             : 
     410       63922 :       CALL timeset(routineN, handle)
     411       63922 :       NULLIFY (rho_ao)
     412             : 
     413       63922 :       CALL qs_rho_get(rho, rho_ao=rho_ao)
     414             : 
     415       63922 :       IF (has_unit_metric) THEN
     416       18084 :          NULLIFY (orthogonality_metric)
     417             :       ELSE
     418       45838 :          orthogonality_metric => matrix_s(1)%matrix
     419             :       END IF
     420             : 
     421             :       ! in case of LSD the first spin qs_ot_env will drive the minimization
     422             :       ! in the case of a restricted calculation, it will make sure the spin orbitals are equal
     423             : 
     424             :       CALL ot_scf_mini(mos, mo_derivs, smear, orthogonality_metric, &
     425             :                        total_energy, energy_only, scf_env%iter_delta, &
     426       63922 :                        scf_env%qs_ot_env)
     427             : 
     428      138388 :       DO ispin = 1, SIZE(mos)
     429      138388 :          CALL set_mo_occupation(mo_set=mos(ispin), smear=smear)
     430             :       END DO
     431             : 
     432      138388 :       DO ispin = 1, SIZE(mos)
     433             :          CALL calculate_density_matrix(mos(ispin), &
     434             :                                        rho_ao(ispin)%matrix, &
     435      138388 :                                        use_dbcsr=.TRUE.)
     436             :       END DO
     437             : 
     438       63922 :       scf_env%iter_method = scf_env%qs_ot_env(1)%OT_METHOD_FULL
     439       63922 :       scf_env%iter_param = scf_env%qs_ot_env(1)%ds_min
     440       63922 :       qs_env%broyden_adaptive_sigma = scf_env%qs_ot_env(1)%broyden_adaptive_sigma
     441             : 
     442       63922 :       CALL timestop(handle)
     443             : 
     444       63922 :    END SUBROUTINE qs_scf_loop_do_ot
     445             : 
     446             : ! **************************************************************************************************
     447             : !> \brief Performs the requested density mixing if any needed
     448             : !> \param scf_env   Holds SCF environment information
     449             : !> \param rho       All data for the electron density
     450             : !> \param para_env  Parallel environment
     451             : !> \param diis_step Did we do a DIIS step?
     452             : ! **************************************************************************************************
     453      150467 :    SUBROUTINE qs_scf_density_mixing(scf_env, rho, para_env, diis_step)
     454             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     455             :       TYPE(qs_rho_type), POINTER                         :: rho
     456             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     457             :       LOGICAL                                            :: diis_step
     458             : 
     459      150467 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: rho_ao_kp
     460             : 
     461      150467 :       NULLIFY (rho_ao_kp)
     462             : 
     463      150467 :       CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
     464             : 
     465      235302 :       SELECT CASE (scf_env%mixing_method)
     466             :       CASE (direct_mixing_nr)
     467             :          CALL scf_env_density_mixing(scf_env%p_mix_new, &
     468             :                                      scf_env%mixing_store, rho_ao_kp, para_env, scf_env%iter_delta, scf_env%iter_count, &
     469       84835 :                                      diis=diis_step)
     470             :       CASE (gspace_mixing_nr, pulay_mixing_nr, broyden_mixing_nr, &
     471             :             multisecant_mixing_nr)
     472             :          ! Compute the difference p_out-p_in
     473             :          CALL self_consistency_check(rho_ao_kp, scf_env%p_delta, para_env, scf_env%p_mix_new, &
     474        1710 :                                      delta=scf_env%iter_delta)
     475             :       CASE (no_mixing_nr)
     476             :       CASE DEFAULT
     477             :          CALL cp_abort(__LOCATION__, &
     478             :                        "unknown scf mixing method: "// &
     479      150467 :                        cp_to_string(scf_env%mixing_method))
     480             :       END SELECT
     481             : 
     482      150467 :    END SUBROUTINE qs_scf_density_mixing
     483             : 
     484             : ! **************************************************************************************************
     485             : !> \brief checks whether exit conditions for outer loop are satisfied
     486             : !> \param qs_env ...
     487             : !> \param scf_env ...
     488             : !> \param scf_control ...
     489             : !> \param should_stop ...
     490             : !> \param outer_loop_converged ...
     491             : !> \param exit_outer_loop ...
     492             : ! **************************************************************************************************
     493       19218 :    SUBROUTINE qs_scf_check_outer_exit(qs_env, scf_env, scf_control, should_stop, &
     494             :                                       outer_loop_converged, exit_outer_loop)
     495             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     496             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     497             :       TYPE(scf_control_type), POINTER                    :: scf_control
     498             :       LOGICAL                                            :: should_stop, outer_loop_converged, &
     499             :                                                             exit_outer_loop
     500             : 
     501             :       REAL(KIND=dp)                                      :: outer_loop_eps
     502             : 
     503       19218 :       outer_loop_converged = .TRUE.
     504       19218 :       IF (scf_control%outer_scf%have_scf) THEN
     505             :          ! We have an outer SCF loop...
     506        5622 :          scf_env%outer_scf%iter_count = scf_env%outer_scf%iter_count + 1
     507        5622 :          outer_loop_converged = .FALSE.
     508             : 
     509        5622 :          CALL outer_loop_gradient(qs_env, scf_env)
     510             :          ! Multiple constraints: get largest deviation
     511       16952 :          outer_loop_eps = SQRT(MAXVAL(scf_env%outer_scf%gradient(:, scf_env%outer_scf%iter_count)**2))
     512             : 
     513        5622 :          IF (outer_loop_eps < scf_control%outer_scf%eps_scf) outer_loop_converged = .TRUE.
     514             :       END IF
     515             : 
     516             :       exit_outer_loop = should_stop .OR. outer_loop_converged .OR. &
     517       19218 :                         scf_env%outer_scf%iter_count > scf_control%outer_scf%max_scf
     518             : 
     519       19218 :    END SUBROUTINE qs_scf_check_outer_exit
     520             : 
     521             : ! **************************************************************************************************
     522             : !> \brief checks whether exit conditions for inner loop are satisfied
     523             : !> \param qs_env ...
     524             : !> \param scf_env ...
     525             : !> \param scf_control ...
     526             : !> \param should_stop ...
     527             : !> \param exit_inner_loop ...
     528             : !> \param inner_loop_converged ...
     529             : !> \param output_unit ...
     530             : ! **************************************************************************************************
     531      150467 :    SUBROUTINE qs_scf_check_inner_exit(qs_env, scf_env, scf_control, should_stop, &
     532             :                                       exit_inner_loop, inner_loop_converged, output_unit)
     533             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     534             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     535             :       TYPE(scf_control_type), POINTER                    :: scf_control
     536             :       LOGICAL                                            :: should_stop, exit_inner_loop, &
     537             :                                                             inner_loop_converged
     538             :       INTEGER                                            :: output_unit
     539             : 
     540      150467 :       inner_loop_converged = .FALSE.
     541      150467 :       exit_inner_loop = .FALSE.
     542             : 
     543             :       CALL external_control(should_stop, "SCF", target_time=qs_env%target_time, &
     544      150467 :                             start_time=qs_env%start_time)
     545      150467 :       IF (scf_env%iter_delta < scf_control%eps_scf) THEN
     546       15739 :          IF (output_unit > 0) THEN
     547             :             WRITE (UNIT=output_unit, FMT="(/,T3,A,I5,A/)") &
     548        8053 :                "*** SCF run converged in ", scf_env%iter_count, " steps ***"
     549             :          END IF
     550       15739 :          inner_loop_converged = .TRUE.
     551       15739 :          exit_inner_loop = .TRUE.
     552      134728 :       ELSE IF (should_stop .OR. scf_env%iter_count >= scf_control%max_scf) THEN
     553        2967 :          inner_loop_converged = .FALSE.
     554        2967 :          exit_inner_loop = .TRUE.
     555        2967 :          IF (output_unit > 0) THEN
     556             :             WRITE (UNIT=output_unit, FMT="(/,T3,A,I5,A/)") &
     557        1490 :                "Leaving inner SCF loop after reaching ", scf_env%iter_count, " steps."
     558             :          END IF
     559             :       END IF
     560             : 
     561      150467 :    END SUBROUTINE qs_scf_check_inner_exit
     562             : 
     563             : ! **************************************************************************************************
     564             : !> \brief undoing density mixing. Important upon convergence
     565             : !> \param scf_env ...
     566             : !> \param rho ...
     567             : !> \param dft_control ...
     568             : !> \param para_env ...
     569             : !> \param diis_step ...
     570             : ! **************************************************************************************************
     571       18706 :    SUBROUTINE qs_scf_undo_mixing(scf_env, rho, dft_control, para_env, diis_step)
     572             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     573             :       TYPE(qs_rho_type), POINTER                         :: rho
     574             :       TYPE(dft_control_type), POINTER                    :: dft_control
     575             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     576             :       LOGICAL                                            :: diis_step
     577             : 
     578             :       CHARACTER(len=default_string_length)               :: name
     579             :       INTEGER                                            :: ic, ispin, nc
     580       18706 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: rho_ao_kp
     581             : 
     582       18706 :       NULLIFY (rho_ao_kp)
     583             : 
     584       18706 :       IF (scf_env%mixing_method > 0) THEN
     585       12060 :          CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
     586       12060 :          nc = SIZE(scf_env%p_mix_new, 2)
     587       23894 :          SELECT CASE (scf_env%mixing_method)
     588             :          CASE (direct_mixing_nr)
     589             :             CALL scf_env_density_mixing(scf_env%p_mix_new, scf_env%mixing_store, &
     590             :                                         rho_ao_kp, para_env, scf_env%iter_delta, &
     591             :                                         scf_env%iter_count, diis=diis_step, &
     592       11834 :                                         invert=.TRUE.)
     593       68428 :             DO ic = 1, nc
     594      136204 :                DO ispin = 1, dft_control%nspins
     595       67776 :                   CALL dbcsr_get_info(rho_ao_kp(ispin, ic)%matrix, name=name) ! keep the name
     596      124370 :                   CALL dbcsr_copy(rho_ao_kp(ispin, ic)%matrix, scf_env%p_mix_new(ispin, ic)%matrix, name=name)
     597             :                END DO
     598             :             END DO
     599             :          CASE (gspace_mixing_nr, pulay_mixing_nr, broyden_mixing_nr, &
     600             :                multisecant_mixing_nr)
     601       26648 :             DO ic = 1, nc
     602       28980 :                DO ispin = 1, dft_control%nspins
     603       14392 :                   CALL dbcsr_get_info(rho_ao_kp(ispin, ic)%matrix, name=name) ! keep the name
     604       28754 :                   CALL dbcsr_copy(rho_ao_kp(ispin, ic)%matrix, scf_env%p_mix_new(ispin, ic)%matrix, name=name)
     605             :                END DO
     606             :             END DO
     607             :          END SELECT
     608             :       END IF
     609       18706 :    END SUBROUTINE qs_scf_undo_mixing
     610             : 
     611             : ! **************************************************************************************************
     612             : !> \brief Performs the updates rho (takes care of mixing as well)
     613             : !> \param rho ...
     614             : !> \param qs_env ...
     615             : !> \param scf_env ...
     616             : !> \param ks_env ...
     617             : !> \param mix_rho ...
     618             : ! **************************************************************************************************
     619      150467 :    SUBROUTINE qs_scf_rho_update(rho, qs_env, scf_env, ks_env, mix_rho)
     620             :       TYPE(qs_rho_type), POINTER                         :: rho
     621             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     622             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     623             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     624             :       LOGICAL, INTENT(IN)                                :: mix_rho
     625             : 
     626             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     627             : 
     628      150467 :       NULLIFY (para_env)
     629      150467 :       CALL get_qs_env(qs_env, para_env=para_env)
     630             :       ! ** update qs_env%rho
     631      150467 :       CALL qs_rho_update_rho(rho, qs_env=qs_env)
     632             :       ! ** Density mixing through density matrix or on the reciprocal space grid (exclusive)
     633      150467 :       IF (mix_rho) THEN
     634             :          CALL gspace_mixing(qs_env, scf_env%mixing_method, scf_env%mixing_store, rho, &
     635        1484 :                             para_env, scf_env%iter_count)
     636             : 
     637             :       END IF
     638      150467 :       CALL qs_ks_did_change(ks_env, rho_changed=.TRUE.)
     639             : 
     640      150467 :    END SUBROUTINE qs_scf_rho_update
     641             : 
     642             : ! **************************************************************************************************
     643             : !> \brief Performs the necessary steps before leaving innner scf loop
     644             : !> \param scf_env ...
     645             : !> \param qs_env ...
     646             : !> \param diis_step ...
     647             : !> \param output_unit ...
     648             : ! **************************************************************************************************
     649       18706 :    SUBROUTINE qs_scf_inner_finalize(scf_env, qs_env, diis_step, output_unit)
     650             :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     651             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     652             :       LOGICAL                                            :: diis_step
     653             :       INTEGER, INTENT(IN)                                :: output_unit
     654             : 
     655             :       LOGICAL                                            :: do_kpoints
     656             :       TYPE(dft_control_type), POINTER                    :: dft_control
     657             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     658             :       TYPE(qs_energy_type), POINTER                      :: energy
     659             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     660             :       TYPE(qs_rho_type), POINTER                         :: rho
     661             : 
     662       18706 :       NULLIFY (energy, rho, dft_control, ks_env)
     663             : 
     664             :       CALL get_qs_env(qs_env=qs_env, energy=energy, ks_env=ks_env, &
     665             :                       rho=rho, dft_control=dft_control, para_env=para_env, &
     666       18706 :                       do_kpoints=do_kpoints)
     667             : 
     668       18706 :       CALL cleanup_scf_loop(scf_env)
     669             : 
     670             :       ! now, print out energies and charges corresponding to the obtained wfn
     671             :       ! (this actually is not 100% consistent at this point)!
     672       18706 :       CALL qs_scf_print_summary(output_unit, qs_env)
     673             : 
     674       18706 :       CALL qs_scf_undo_mixing(scf_env, rho, dft_control, para_env, diis_step)
     675             : 
     676             :       !   *** update rspace rho since the mo changed
     677             :       !   *** this might not always be needed (i.e. no post calculation / no forces )
     678             :       !   *** but guarantees that rho and wfn are consistent at this point
     679       18706 :       CALL qs_scf_rho_update(rho, qs_env, scf_env, ks_env, mix_rho=.FALSE.)
     680             : 
     681       18706 :    END SUBROUTINE qs_scf_inner_finalize
     682             : 
     683             : ! **************************************************************************************************
     684             : !> \brief perform cleanup operations at the end of an scf loop
     685             : !> \param scf_env ...
     686             : !> \par History
     687             : !>      03.2006 created [Joost VandeVondele]
     688             : ! **************************************************************************************************
     689       18706 :    SUBROUTINE cleanup_scf_loop(scf_env)
     690             :       TYPE(qs_scf_env_type), INTENT(INOUT)               :: scf_env
     691             : 
     692             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'cleanup_scf_loop'
     693             : 
     694             :       INTEGER                                            :: handle, ispin
     695             : 
     696       18706 :       CALL timeset(routineN, handle)
     697             : 
     698       25352 :       SELECT CASE (scf_env%method)
     699             :       CASE (ot_method_nr)
     700       14553 :          DO ispin = 1, SIZE(scf_env%qs_ot_env)
     701       14553 :             CALL ot_scf_destroy(scf_env%qs_ot_env(ispin))
     702             :          END DO
     703        6646 :          DEALLOCATE (scf_env%qs_ot_env)
     704             :       CASE (ot_diag_method_nr)
     705             :          !
     706             :       CASE (general_diag_method_nr)
     707             :          !
     708             :       CASE (special_diag_method_nr)
     709             :          !
     710             :       CASE (block_krylov_diag_method_nr, block_davidson_diag_method_nr)
     711             :          !
     712             :       CASE (filter_matrix_diag_method_nr)
     713             :          !
     714             :       CASE DEFAULT
     715             :          CALL cp_abort(__LOCATION__, &
     716             :                        "unknown scf method method:"// &
     717       18706 :                        cp_to_string(scf_env%method))
     718             :       END SELECT
     719             : 
     720       18706 :       CALL timestop(handle)
     721             : 
     722       18706 :    END SUBROUTINE cleanup_scf_loop
     723             : 
     724             : END MODULE qs_scf_loop_utils

Generated by: LCOV version 1.15