LCOV - code coverage report
Current view: top level - src - qs_diis.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:15a58fb) Lines: 396 426 93.0 %
Date: 2025-02-18 08:24:35 Functions: 14 14 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Apply the direct inversion in the iterative subspace (DIIS) of Pulay
      10             : !>      in the framework of an SCF iteration for convergence acceleration
      11             : !> \par Literature
      12             : !>      - P. Pulay, Chem. Phys. Lett. 73, 393 (1980)
      13             : !>      - P. Pulay, J. Comput. Chem. 3, 556 (1982)
      14             : !> \par History
      15             : !>      - Changed to BLACS matrix usage (08.06.2001,MK)
      16             : !>      - rewritten to include LSD (1st attempt) (01.2003, Joost VandeVondele)
      17             : !>      - DIIS for ROKS (05.04.06,MK)
      18             : !>      - DIIS for k-points (04.2023, Augustin Bussy)
      19             : !> \author Matthias Krack (28.06.2000)
      20             : ! **************************************************************************************************
      21             : MODULE qs_diis
      22             :    USE cp_cfm_basic_linalg,             ONLY: cp_cfm_trace
      23             :    USE cp_cfm_types,                    ONLY: cp_cfm_create,&
      24             :                                               cp_cfm_get_info,&
      25             :                                               cp_cfm_release,&
      26             :                                               cp_cfm_to_cfm,&
      27             :                                               cp_cfm_to_fm,&
      28             :                                               cp_cfm_type,&
      29             :                                               cp_fm_to_cfm
      30             :    USE cp_dbcsr_api,                    ONLY: &
      31             :         dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_dot, dbcsr_multiply, dbcsr_p_type, &
      32             :         dbcsr_release, dbcsr_set, dbcsr_transposed, dbcsr_type
      33             :    USE cp_dbcsr_contrib,                ONLY: dbcsr_maxabs
      34             :    USE cp_dbcsr_operations,             ONLY: copy_dbcsr_to_fm
      35             :    USE cp_fm_basic_linalg,              ONLY: cp_fm_column_scale,&
      36             :                                               cp_fm_scale,&
      37             :                                               cp_fm_scale_and_add,&
      38             :                                               cp_fm_symm,&
      39             :                                               cp_fm_trace
      40             :    USE cp_fm_struct,                    ONLY: cp_fm_struct_type
      41             :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      42             :                                               cp_fm_get_info,&
      43             :                                               cp_fm_maxabsval,&
      44             :                                               cp_fm_release,&
      45             :                                               cp_fm_set_all,&
      46             :                                               cp_fm_to_fm,&
      47             :                                               cp_fm_type
      48             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      49             :                                               cp_logger_type,&
      50             :                                               cp_to_string
      51             :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      52             :                                               cp_print_key_unit_nr
      53             :    USE dm_ls_scf_types,                 ONLY: ls_scf_env_type
      54             :    USE input_section_types,             ONLY: section_vals_type
      55             :    USE kinds,                           ONLY: default_string_length,&
      56             :                                               dp
      57             :    USE mathlib,                         ONLY: diag_complex,&
      58             :                                               diamat_all
      59             :    USE message_passing,                 ONLY: mp_para_env_type
      60             :    USE parallel_gemm_api,               ONLY: parallel_gemm
      61             :    USE qs_diis_types,                   ONLY: qs_diis_buffer_type,&
      62             :                                               qs_diis_buffer_type_kp,&
      63             :                                               qs_diis_buffer_type_sparse
      64             :    USE qs_environment_types,            ONLY: get_qs_env,&
      65             :                                               qs_environment_type
      66             :    USE qs_mo_types,                     ONLY: get_mo_set,&
      67             :                                               mo_set_type
      68             :    USE string_utilities,                ONLY: compress
      69             : #include "./base/base_uses.f90"
      70             : 
      71             :    IMPLICIT NONE
      72             : 
      73             :    PRIVATE
      74             : 
      75             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_diis'
      76             : 
      77             :    ! Public subroutines
      78             : 
      79             :    PUBLIC :: qs_diis_b_clear, &
      80             :              qs_diis_b_create, &
      81             :              qs_diis_b_step
      82             :    PUBLIC :: qs_diis_b_clear_sparse, &
      83             :              qs_diis_b_create_sparse, &
      84             :              qs_diis_b_step_4lscf
      85             :    PUBLIC :: qs_diis_b_clear_kp, &
      86             :              qs_diis_b_create_kp, &
      87             :              qs_diis_b_step_kp, &
      88             :              qs_diis_b_calc_err_kp, &
      89             :              qs_diis_b_info_kp
      90             : 
      91             : CONTAINS
      92             : 
      93             : ! **************************************************************************************************
      94             : !> \brief Allocates an SCF DIIS buffer
      95             : !> \param diis_buffer the buffer to create
      96             : !> \param nbuffer ...
      97             : !> \par History
      98             : !>      02.2003 created [fawzi]
      99             : !> \author fawzi
     100             : ! **************************************************************************************************
     101        3950 :    SUBROUTINE qs_diis_b_create(diis_buffer, nbuffer)
     102             : 
     103             :       TYPE(qs_diis_buffer_type), INTENT(OUT)             :: diis_buffer
     104             :       INTEGER, INTENT(in)                                :: nbuffer
     105             : 
     106             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_diis_b_create'
     107             : 
     108             :       INTEGER                                            :: handle
     109             : 
     110             : ! -------------------------------------------------------------------------
     111             : 
     112        3950 :       CALL timeset(routineN, handle)
     113             : 
     114        3950 :       NULLIFY (diis_buffer%b_matrix)
     115        3950 :       NULLIFY (diis_buffer%error)
     116        3950 :       NULLIFY (diis_buffer%param)
     117        3950 :       diis_buffer%nbuffer = nbuffer
     118        3950 :       diis_buffer%ncall = 0
     119             : 
     120        3950 :       CALL timestop(handle)
     121             : 
     122        3950 :    END SUBROUTINE qs_diis_b_create
     123             : 
     124             : ! **************************************************************************************************
     125             : !> \brief Allocate and initialize a DIIS buffer for nao*nao parameter
     126             : !>      variables and with a buffer size of nbuffer.
     127             : !> \param diis_buffer the buffer to initialize
     128             : !> \param matrix_struct the structure for the matrix of the buffer
     129             : !> \param nspin ...
     130             : !> \param scf_section ...
     131             : !> \par History
     132             : !>      - Creation (07.05.2001, Matthias Krack)
     133             : !>      - Changed to BLACS matrix usage (08.06.2001,MK)
     134             : !>      - DIIS for ROKS (05.04.06,MK)
     135             : !> \author Matthias Krack
     136             : !> \note
     137             : !>      check to allocate matrixes only when needed, using a linked list?
     138             : ! **************************************************************************************************
     139       70855 :    SUBROUTINE qs_diis_b_check_i_alloc(diis_buffer, matrix_struct, nspin, &
     140             :                                       scf_section)
     141             : 
     142             :       TYPE(qs_diis_buffer_type), INTENT(INOUT)           :: diis_buffer
     143             :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
     144             :       INTEGER, INTENT(IN)                                :: nspin
     145             :       TYPE(section_vals_type), POINTER                   :: scf_section
     146             : 
     147             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_diis_b_check_i_alloc'
     148             : 
     149             :       INTEGER                                            :: handle, ibuffer, ispin, nbuffer, &
     150             :                                                             output_unit
     151             :       TYPE(cp_logger_type), POINTER                      :: logger
     152             : 
     153             : ! -------------------------------------------------------------------------
     154             : 
     155       70855 :       CALL timeset(routineN, handle)
     156             : 
     157       70855 :       logger => cp_get_default_logger()
     158             : 
     159       70855 :       nbuffer = diis_buffer%nbuffer
     160             : 
     161       70855 :       IF (.NOT. ASSOCIATED(diis_buffer%error)) THEN
     162       29962 :          ALLOCATE (diis_buffer%error(nbuffer, nspin))
     163             : 
     164        6590 :          DO ispin = 1, nspin
     165       20998 :             DO ibuffer = 1, nbuffer
     166             :                CALL cp_fm_create(diis_buffer%error(ibuffer, ispin), &
     167             :                                  name="qs_diis_b%error("// &
     168             :                                  TRIM(ADJUSTL(cp_to_string(ibuffer)))//","// &
     169             :                                  TRIM(ADJUSTL(cp_to_string(ibuffer)))//")", &
     170       18010 :                                  matrix_struct=matrix_struct)
     171             :             END DO
     172             :          END DO
     173             :       END IF
     174             : 
     175       70855 :       IF (.NOT. ASSOCIATED(diis_buffer%param)) THEN
     176       29962 :          ALLOCATE (diis_buffer%param(nbuffer, nspin))
     177             : 
     178        6590 :          DO ispin = 1, nspin
     179       20998 :             DO ibuffer = 1, nbuffer
     180             :                CALL cp_fm_create(diis_buffer%param(ibuffer, ispin), &
     181             :                                  name="qs_diis_b%param("// &
     182             :                                  TRIM(ADJUSTL(cp_to_string(ibuffer)))//","// &
     183             :                                  TRIM(ADJUSTL(cp_to_string(ibuffer)))//")", &
     184       18010 :                                  matrix_struct=matrix_struct)
     185             :             END DO
     186             :          END DO
     187             :       END IF
     188             : 
     189       70855 :       IF (.NOT. ASSOCIATED(diis_buffer%b_matrix)) THEN
     190       14940 :          ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
     191       92628 :          diis_buffer%b_matrix = 0.0_dp
     192             :          output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
     193        2988 :                                             extension=".scfLog")
     194        2988 :          IF (output_unit > 0) THEN
     195             :             WRITE (UNIT=output_unit, FMT="(/,T9,A)") &
     196           9 :                "DIIS | The SCF DIIS buffer was allocated and initialized"
     197             :          END IF
     198             :          CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
     199        2988 :                                            "PRINT%DIIS_INFO")
     200             :       END IF
     201             : 
     202       70855 :       CALL timestop(handle)
     203             : 
     204       70855 :    END SUBROUTINE qs_diis_b_check_i_alloc
     205             : 
     206             : ! **************************************************************************************************
     207             : !> \brief Update the SCF DIIS buffer, and if appropriate does a diis step.
     208             : !> \param diis_buffer ...
     209             : !> \param mo_array ...
     210             : !> \param kc ...
     211             : !> \param sc ...
     212             : !> \param delta ...
     213             : !> \param error_max ...
     214             : !> \param diis_step ...
     215             : !> \param eps_diis ...
     216             : !> \param nmixing ...
     217             : !> \param s_matrix ...
     218             : !> \param scf_section ...
     219             : !> \param roks ...
     220             : !> \par History
     221             : !>      - Creation (07.05.2001, Matthias Krack)
     222             : !>      - Changed to BLACS matrix usage (08.06.2001, MK)
     223             : !>      - 03.2003 rewamped [fawzi]
     224             : !>      - Adapted for high-spin ROKS (08.04.06,MK)
     225             : !> \author Matthias Krack
     226             : ! **************************************************************************************************
     227       70855 :    SUBROUTINE qs_diis_b_step(diis_buffer, mo_array, kc, sc, delta, error_max, &
     228             :                              diis_step, eps_diis, nmixing, s_matrix, scf_section, roks)
     229             : 
     230             :       TYPE(qs_diis_buffer_type), POINTER                 :: diis_buffer
     231             :       TYPE(mo_set_type), DIMENSION(:), INTENT(IN)        :: mo_array
     232             :       TYPE(cp_fm_type), DIMENSION(:), POINTER            :: kc
     233             :       TYPE(cp_fm_type), INTENT(IN)                       :: sc
     234             :       REAL(KIND=dp), INTENT(IN)                          :: delta
     235             :       REAL(KIND=dp), INTENT(OUT)                         :: error_max
     236             :       LOGICAL, INTENT(OUT)                               :: diis_step
     237             :       REAL(KIND=dp), INTENT(IN)                          :: eps_diis
     238             :       INTEGER, INTENT(IN), OPTIONAL                      :: nmixing
     239             :       TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
     240             :          POINTER                                         :: s_matrix
     241             :       TYPE(section_vals_type), POINTER                   :: scf_section
     242             :       LOGICAL, INTENT(IN), OPTIONAL                      :: roks
     243             : 
     244             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'qs_diis_b_step'
     245             :       REAL(KIND=dp), PARAMETER :: eigenvalue_threshold = 1.0E-12_dp
     246             : 
     247             :       CHARACTER(LEN=2*default_string_length)             :: message
     248             :       INTEGER                                            :: handle, homo, ib, imo, ispin, jb, &
     249             :                                                             my_nmixing, nao, nb, nb1, nmo, nspin, &
     250             :                                                             output_unit
     251             :       LOGICAL                                            :: eigenvectors_discarded, my_roks
     252             :       REAL(KIND=dp)                                      :: maxocc, tmp
     253       70855 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: ev, occ
     254       70855 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: occa, occb
     255       70855 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: a, b
     256             :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
     257             :       TYPE(cp_fm_type), POINTER                          :: c, new_errors, old_errors, parameters
     258             :       TYPE(cp_logger_type), POINTER                      :: logger
     259             : 
     260             : ! -------------------------------------------------------------------------
     261             : 
     262       70855 :       CALL timeset(routineN, handle)
     263             : 
     264       70855 :       nspin = SIZE(mo_array)
     265       70855 :       diis_step = .FALSE.
     266             : 
     267       70855 :       IF (PRESENT(roks)) THEN
     268         934 :          my_roks = .TRUE.
     269         934 :          nspin = 1
     270             :       ELSE
     271             :          my_roks = .FALSE.
     272             :       END IF
     273             : 
     274       70855 :       my_nmixing = 2
     275       70855 :       IF (PRESENT(nmixing)) my_nmixing = nmixing
     276             : 
     277       70855 :       NULLIFY (c, new_errors, old_errors, parameters, matrix_struct, a, b, occa, occb)
     278       70855 :       logger => cp_get_default_logger()
     279             : 
     280             :       ! Quick return, if no DIIS is requested
     281             : 
     282       70855 :       IF (diis_buffer%nbuffer < 1) THEN
     283           0 :          CALL timestop(handle)
     284             :          RETURN
     285             :       END IF
     286             : 
     287             :       CALL cp_fm_get_info(kc(1), &
     288       70855 :                           matrix_struct=matrix_struct)
     289             :       CALL qs_diis_b_check_i_alloc(diis_buffer, &
     290             :                                    matrix_struct=matrix_struct, &
     291             :                                    nspin=nspin, &
     292       70855 :                                    scf_section=scf_section)
     293             : 
     294       70855 :       error_max = 0.0_dp
     295             : 
     296       70855 :       ib = MODULO(diis_buffer%ncall, diis_buffer%nbuffer) + 1
     297       70855 :       diis_buffer%ncall = diis_buffer%ncall + 1
     298       70855 :       nb = MIN(diis_buffer%ncall, diis_buffer%nbuffer)
     299             : 
     300      150754 :       DO ispin = 1, nspin
     301             : 
     302             :          CALL get_mo_set(mo_set=mo_array(ispin), &
     303             :                          nao=nao, &
     304             :                          nmo=nmo, &
     305             :                          homo=homo, &
     306             :                          mo_coeff=c, &
     307             :                          occupation_numbers=occa, &
     308       79899 :                          maxocc=maxocc)
     309             : 
     310       79899 :          new_errors => diis_buffer%error(ib, ispin)
     311       79899 :          parameters => diis_buffer%param(ib, ispin)
     312             : 
     313             :          ! Copy the Kohn-Sham matrix K to the DIIS buffer
     314             : 
     315       79899 :          CALL cp_fm_to_fm(kc(ispin), parameters)
     316             : 
     317       79899 :          IF (my_roks) THEN
     318             : 
     319        2802 :             ALLOCATE (occ(nmo))
     320             : 
     321             :             CALL get_mo_set(mo_set=mo_array(2), &
     322         934 :                             occupation_numbers=occb)
     323             : 
     324       15120 :             DO imo = 1, nmo
     325       15120 :                occ(imo) = SQRT(occa(imo) + occb(imo))
     326             :             END DO
     327             : 
     328         934 :             CALL cp_fm_to_fm(c, sc)
     329         934 :             CALL cp_fm_column_scale(sc, occ(1:homo))
     330             : 
     331             :             ! KC <- K*C
     332         934 :             CALL cp_fm_symm("L", "U", nao, homo, 1.0_dp, parameters, sc, 0.0_dp, kc(ispin))
     333             : 
     334         934 :             IF (PRESENT(s_matrix)) THEN
     335         484 :                CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors)
     336             :                ! SC <- S*C
     337         484 :                CALL cp_fm_symm("L", "U", nao, homo, 1.0_dp, new_errors, c, 0.0_dp, sc)
     338         484 :                CALL cp_fm_column_scale(sc, occ(1:homo))
     339             :             END IF
     340             : 
     341             :             ! new_errors <- KC*(SC)^T - (SC)*(KC)^T = K*P*S - S*P*K
     342             :             ! or for an orthogonal basis
     343             :             ! new_errors <- KC*C^T - C*(KC)^T = K*P - P*K with S = I
     344         934 :             CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
     345         934 :             CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
     346             : 
     347         934 :             DEALLOCATE (occ)
     348             : 
     349             :          ELSE
     350             : 
     351             :             ! KC <- K*C
     352       78965 :             CALL cp_fm_symm("L", "U", nao, homo, maxocc, parameters, c, 0.0_dp, kc(ispin))
     353             : 
     354       78965 :             IF (PRESENT(s_matrix)) THEN
     355             :                ! I guess that this copy can be avoided for LSD
     356       62959 :                CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors)
     357             :                ! sc <- S*C
     358       62959 :                CALL cp_fm_symm("L", "U", nao, homo, 2.0_dp, new_errors, c, 0.0_dp, sc)
     359             :                ! new_errors <- KC*(SC)^T - (SC)*(KC)^T = K*P*S - S*P*K
     360       62959 :                CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
     361       62959 :                CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
     362             :             ELSE
     363             :                ! new_errors <- KC*(C)^T - C*(KC)^T = K*P - P*K
     364       16006 :                CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, c, kc(ispin), 0.0_dp, new_errors)
     365       16006 :                CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, kc(ispin), c, -1.0_dp, new_errors)
     366             :             END IF
     367             : 
     368             :          END IF
     369             : 
     370       79899 :          CALL cp_fm_maxabsval(new_errors, tmp)
     371      230653 :          error_max = MAX(error_max, tmp)
     372             : 
     373             :       END DO
     374             : 
     375             :       ! Check, if a DIIS step is appropriate
     376             : 
     377       70855 :       diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
     378             : 
     379             :       output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
     380       70855 :                                          extension=".scfLog")
     381       70855 :       IF (output_unit > 0) THEN
     382             :          WRITE (UNIT=output_unit, FMT="(/,T9,A,I4,/,(T9,A,ES12.3))") &
     383         104 :             "DIIS | Current SCF DIIS buffer size:         ", nb, &
     384         104 :             "DIIS | Maximum SCF DIIS error vector element:", error_max, &
     385         104 :             "DIIS | Current SCF convergence:              ", delta, &
     386         208 :             "DIIS | Threshold value for a DIIS step:      ", eps_diis
     387         104 :          IF (error_max < eps_diis) THEN
     388             :             WRITE (UNIT=output_unit, FMT="(T9,A)") &
     389         102 :                "DIIS | => The SCF DIIS buffer will be updated"
     390             :          ELSE
     391             :             WRITE (UNIT=output_unit, FMT="(T9,A)") &
     392           2 :                "DIIS | => No update of the SCF DIIS buffer"
     393             :          END IF
     394         104 :          IF (diis_step .AND. (error_max < eps_diis)) THEN
     395             :             WRITE (UNIT=output_unit, FMT="(T9,A,/)") &
     396          62 :                "DIIS | => A SCF DIIS step will be performed"
     397             :          ELSE
     398             :             WRITE (UNIT=output_unit, FMT="(T9,A,/)") &
     399          42 :                "DIIS | => No SCF DIIS step will be performed"
     400             :          END IF
     401             :       END IF
     402             : 
     403             :       ! Update the SCF DIIS buffer
     404             : 
     405       70855 :       IF (error_max < eps_diis) THEN
     406             : 
     407       68145 :          b => diis_buffer%b_matrix
     408             : 
     409      286097 :          DO jb = 1, nb
     410      217952 :             b(jb, ib) = 0.0_dp
     411      464730 :             DO ispin = 1, nspin
     412      246778 :                old_errors => diis_buffer%error(jb, ispin)
     413      246778 :                new_errors => diis_buffer%error(ib, ispin)
     414      246778 :                CALL cp_fm_trace(old_errors, new_errors, tmp)
     415      464730 :                b(jb, ib) = b(jb, ib) + tmp
     416             :             END DO
     417      286097 :             b(ib, jb) = b(jb, ib)
     418             :          END DO
     419             : 
     420             :       ELSE
     421             : 
     422        2710 :          diis_step = .FALSE.
     423             : 
     424             :       END IF
     425             : 
     426             :       ! Perform DIIS step
     427             : 
     428       70855 :       IF (diis_step) THEN
     429             : 
     430       49911 :          nb1 = nb + 1
     431             : 
     432      199644 :          ALLOCATE (a(nb1, nb1))
     433      149733 :          ALLOCATE (b(nb1, nb1))
     434      149733 :          ALLOCATE (ev(nb1))
     435             : 
     436             :          ! Set up the linear DIIS equation system
     437             : 
     438     1737991 :          b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
     439             : 
     440      228539 :          b(1:nb, nb1) = -1.0_dp
     441      228539 :          b(nb1, 1:nb) = -1.0_dp
     442       49911 :          b(nb1, nb1) = 0.0_dp
     443             : 
     444             :          ! Solve the linear DIIS equation system
     445             : 
     446      278450 :          ev(1:nb1) = 0.0_dp
     447       49911 :          CALL diamat_all(b(1:nb1, 1:nb1), ev(1:nb1))
     448             : 
     449     2652147 :          a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
     450             : 
     451       49911 :          eigenvectors_discarded = .FALSE.
     452             : 
     453      278450 :          DO jb = 1, nb1
     454      278450 :             IF (ABS(ev(jb)) < eigenvalue_threshold) THEN
     455       25290 :                IF (output_unit > 0) THEN
     456           5 :                   IF (.NOT. eigenvectors_discarded) THEN
     457             :                      WRITE (UNIT=output_unit, FMT="(T9,A)") &
     458           5 :                         "DIIS | Checking eigenvalues of the DIIS error matrix"
     459             :                   END IF
     460             :                   WRITE (UNIT=message, FMT="(T9,A,I6,A,ES10.1,A,ES10.1)") &
     461           5 :                      "DIIS | Eigenvalue ", jb, " = ", ev(jb), " is smaller than "// &
     462          10 :                      "threshold ", eigenvalue_threshold
     463           5 :                   CALL compress(message)
     464           5 :                   WRITE (UNIT=output_unit, FMT="(T9,A)") TRIM(message)
     465           5 :                   eigenvectors_discarded = .TRUE.
     466             :                END IF
     467      147474 :                a(1:nb1, jb) = 0.0_dp
     468             :             ELSE
     469     1153644 :                a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
     470             :             END IF
     471             :          END DO
     472             : 
     473       49911 :          IF ((output_unit > 0) .AND. eigenvectors_discarded) THEN
     474             :             WRITE (UNIT=output_unit, FMT="(T9,A,/)") &
     475           5 :                "DIIS | The corresponding eigenvectors were discarded"
     476             :          END IF
     477             : 
     478     1301118 :          ev(1:nb) = MATMUL(a(1:nb, 1:nb1), b(nb1, 1:nb1))
     479             : 
     480             :          ! Update Kohn-Sham matrix
     481             : 
     482      106178 :          DO ispin = 1, nspin
     483       56267 :             CALL cp_fm_set_all(kc(ispin), 0.0_dp)
     484      308614 :             DO jb = 1, nb
     485      202436 :                parameters => diis_buffer%param(jb, ispin)
     486      258703 :                CALL cp_fm_scale_and_add(1.0_dp, kc(ispin), -ev(jb), parameters)
     487             :             END DO
     488             :          END DO
     489             : 
     490       49911 :          DEALLOCATE (a)
     491       49911 :          DEALLOCATE (b)
     492       49911 :          DEALLOCATE (ev)
     493             : 
     494             :       ELSE
     495             : 
     496       44576 :          DO ispin = 1, nspin
     497       23632 :             parameters => diis_buffer%param(ib, ispin)
     498       44576 :             CALL cp_fm_to_fm(parameters, kc(ispin))
     499             :          END DO
     500             : 
     501             :       END IF
     502             : 
     503             :       CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
     504       70855 :                                         "PRINT%DIIS_INFO")
     505             : 
     506       70855 :       CALL timestop(handle)
     507             : 
     508      141710 :    END SUBROUTINE qs_diis_b_step
     509             : 
     510             : ! **************************************************************************************************
     511             : !> \brief clears the buffer
     512             : !> \param diis_buffer the buffer to clear
     513             : !> \par History
     514             : !>      02.2003 created [fawzi]
     515             : !> \author fawzi
     516             : ! **************************************************************************************************
     517       12938 :    PURE SUBROUTINE qs_diis_b_clear(diis_buffer)
     518             : 
     519             :       TYPE(qs_diis_buffer_type), INTENT(INOUT)           :: diis_buffer
     520             : 
     521       12938 :       diis_buffer%ncall = 0
     522             : 
     523       12938 :    END SUBROUTINE qs_diis_b_clear
     524             : 
     525             : ! **************************************************************************************************
     526             : !> \brief Update the SCF DIIS buffer in linear scaling SCF (LS-SCF),
     527             : !>        and if appropriate does a diis step.
     528             : !> \param diis_buffer ...
     529             : !> \param qs_env ...
     530             : !> \param ls_scf_env ...
     531             : !> \param unit_nr ...
     532             : !> \param iscf ...
     533             : !> \param diis_step ...
     534             : !> \param eps_diis ...
     535             : !> \param nmixing ...
     536             : !> \param s_matrix ...
     537             : !> \param threshold ...
     538             : !> \par History
     539             : !>      - Adapted for LS-SCF (10-11-14) from qs_diis_b_step
     540             : !> \author Fredy W. Aquino
     541             : ! **************************************************************************************************
     542             : 
     543          18 :    SUBROUTINE qs_diis_b_step_4lscf(diis_buffer, qs_env, ls_scf_env, unit_nr, iscf, &
     544             :                                    diis_step, eps_diis, nmixing, s_matrix, threshold)
     545             : ! Note.- Input: ls_scf_env%matrix_p(ispin) , Density Matrix
     546             : !               matrix_ks (from qs_env)    , Kohn-Sham Matrix  (IN/OUT)
     547             : 
     548             :       TYPE(qs_diis_buffer_type_sparse), POINTER          :: diis_buffer
     549             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     550             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
     551             :       INTEGER, INTENT(IN)                                :: unit_nr, iscf
     552             :       LOGICAL, INTENT(OUT)                               :: diis_step
     553             :       REAL(KIND=dp), INTENT(IN)                          :: eps_diis
     554             :       INTEGER, INTENT(IN), OPTIONAL                      :: nmixing
     555             :       TYPE(dbcsr_type), OPTIONAL                         :: s_matrix
     556             :       REAL(KIND=dp), INTENT(IN)                          :: threshold
     557             : 
     558             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_diis_b_step_4lscf'
     559             :       REAL(KIND=dp), PARAMETER :: eigenvalue_threshold = 1.0E-12_dp
     560             : 
     561             :       INTEGER                                            :: handle, ib, ispin, jb, my_nmixing, nb, &
     562             :                                                             nb1, nspin
     563             :       REAL(KIND=dp)                                      :: error_max, tmp
     564          18 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: ev
     565          18 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: a, b
     566             :       TYPE(cp_logger_type), POINTER                      :: logger
     567          18 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks
     568             :       TYPE(dbcsr_type)                                   :: matrix_KSerr_t, matrix_tmp
     569             :       TYPE(dbcsr_type), POINTER                          :: new_errors, old_errors, parameters
     570             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     571             : 
     572          18 :       CALL timeset(routineN, handle)
     573          18 :       nspin = ls_scf_env%nspins
     574          18 :       diis_step = .FALSE.
     575          18 :       my_nmixing = 2
     576          18 :       IF (PRESENT(nmixing)) my_nmixing = nmixing
     577          18 :       NULLIFY (new_errors, old_errors, parameters, a, b)
     578          18 :       logger => cp_get_default_logger()
     579             :       ! Quick return, if no DIIS is requested
     580          18 :       IF (diis_buffer%nbuffer < 1) THEN
     581           0 :          CALL timestop(handle)
     582             :          RETURN
     583             :       END IF
     584             : 
     585             : ! Getting current Kohn-Sham matrix from qs_env
     586             :       CALL get_qs_env(qs_env, &
     587             :                       para_env=para_env, &
     588          18 :                       matrix_ks=matrix_ks)
     589             :       CALL qs_diis_b_check_i_alloc_sparse( &
     590             :          diis_buffer, &
     591             :          ls_scf_env, &
     592          18 :          nspin)
     593          18 :       error_max = 0.0_dp
     594             : 
     595          18 :       ib = MODULO(diis_buffer%ncall, diis_buffer%nbuffer) + 1
     596          18 :       diis_buffer%ncall = diis_buffer%ncall + 1
     597          18 :       nb = MIN(diis_buffer%ncall, diis_buffer%nbuffer)
     598             : ! Create scratch arrays
     599             :       CALL dbcsr_create(matrix_tmp, &
     600             :                         template=ls_scf_env%matrix_ks(1), &
     601          18 :                         matrix_type='N')
     602          18 :       CALL dbcsr_set(matrix_tmp, 0.0_dp) ! reset matrix
     603             :       CALL dbcsr_create(matrix_KSerr_t, &
     604             :                         template=ls_scf_env%matrix_ks(1), &
     605          18 :                         matrix_type='N')
     606          18 :       CALL dbcsr_set(matrix_KSerr_t, 0.0_dp) ! reset matrix
     607             : 
     608          46 :       DO ispin = 1, nspin ! ------ Loop-ispin----START
     609             : 
     610          28 :          new_errors => diis_buffer%error(ib, ispin)%matrix
     611          28 :          parameters => diis_buffer%param(ib, ispin)%matrix
     612             :          ! Copy the Kohn-Sham matrix K to the DIIS buffer
     613             :          CALL dbcsr_copy(parameters, & ! out
     614          28 :                          matrix_ks(ispin)%matrix) ! in
     615             : 
     616          28 :          IF (PRESENT(s_matrix)) THEN ! if-s_matrix ---------- START
     617             : ! Calculate Kohn-Sham error (non-orthogonal)= K*P*S-(K*P*S)^T
     618             : ! matrix_tmp = P*S
     619             :             CALL dbcsr_multiply("N", "N", &
     620             :                                 1.0_dp, ls_scf_env%matrix_p(ispin), &
     621             :                                 s_matrix, &
     622             :                                 0.0_dp, matrix_tmp, &
     623          28 :                                 filter_eps=threshold)
     624             : ! new_errors= K*P*S
     625             :             CALL dbcsr_multiply("N", "N", &
     626             :                                 1.0_dp, matrix_ks(ispin)%matrix, &
     627             :                                 matrix_tmp, &
     628             :                                 0.0_dp, new_errors, &
     629          28 :                                 filter_eps=threshold)
     630             : ! matrix_KSerr_t= transpose(K*P*S)
     631             :             CALL dbcsr_transposed(matrix_KSerr_t, &
     632          28 :                                   new_errors)
     633             : ! new_errors=K*P*S-transpose(K*P*S)
     634             :             CALL dbcsr_add(new_errors, &
     635             :                            matrix_KSerr_t, &
     636          28 :                            1.0_dp, -1.0_dp)
     637             :          ELSE ! if-s_matrix ---------- MID
     638             : ! Calculate Kohn-Sham error (orthogonal)= K*P - P*K
     639             : ! new_errors=K*P
     640             :             CALL dbcsr_multiply("N", "N", &
     641             :                                 1.0_dp, matrix_ks(ispin)%matrix, &
     642             :                                 ls_scf_env%matrix_p(ispin), &
     643             :                                 0.0_dp, new_errors, &
     644           0 :                                 filter_eps=threshold)
     645             : ! matrix_KSerr_t= transpose(K*P)
     646             :             CALL dbcsr_transposed(matrix_KSerr_t, &
     647           0 :                                   new_errors)
     648             : ! new_errors=K*P-transpose(K*P)
     649             :             CALL dbcsr_add(new_errors, &
     650             :                            matrix_KSerr_t, &
     651           0 :                            1.0_dp, -1.0_dp)
     652             :          END IF ! if-s_matrix ---------- END
     653             : 
     654          28 :          tmp = dbcsr_maxabs(new_errors)
     655          46 :          error_max = MAX(error_max, tmp)
     656             : 
     657             :       END DO ! ------ Loop-ispin----END
     658             : 
     659             :       ! Check, if a DIIS step is appropriate
     660             : 
     661          18 :       diis_step = (diis_buffer%ncall >= my_nmixing)
     662             : 
     663          18 :       IF (unit_nr > 0) THEN
     664             :          WRITE (unit_nr, '(A29,I3,A3,4(I3,A1))') &
     665           9 :             "DIIS: (ncall,nbuffer,ib,nb)=(", iscf, ")=(", &
     666          18 :             diis_buffer%ncall, ",", diis_buffer%nbuffer, ",", ib, ",", nb, ")"
     667             :          WRITE (unit_nr, '(A57,I3,A3,L1,A1,F10.8,A1,F4.2,A1,L1,A1)') &
     668           9 :             "DIIS: (diis_step,error_max,eps_diis,error_max<eps_diis)=(", &
     669           9 :             iscf, ")=(", diis_step, ",", error_max, ",", eps_diis, ",", &
     670          18 :             (error_max < eps_diis), ")"
     671             :          WRITE (unit_nr, '(A75)') &
     672           9 :             "DIIS: diis_step=T : Perform DIIS  error_max<eps_diis=T : Update DIIS buffer"
     673             :       END IF
     674             : 
     675             :       ! Update the SCF DIIS buffer
     676          18 :       IF (error_max < eps_diis) THEN
     677          18 :          b => diis_buffer%b_matrix
     678          66 :          DO jb = 1, nb
     679          48 :             b(jb, ib) = 0.0_dp
     680         124 :             DO ispin = 1, nspin
     681          76 :                old_errors => diis_buffer%error(jb, ispin)%matrix
     682          76 :                new_errors => diis_buffer%error(ib, ispin)%matrix
     683             :                CALL dbcsr_dot(old_errors, &
     684             :                               new_errors, &
     685          76 :                               tmp) ! out : < f_i | f_j >
     686         124 :                b(jb, ib) = b(jb, ib) + tmp
     687             :             END DO ! end-loop-ispin
     688          66 :             b(ib, jb) = b(jb, ib)
     689             :          END DO ! end-loop-jb
     690             :       ELSE
     691           0 :          diis_step = .FALSE.
     692             :       END IF
     693             : 
     694             :       ! Perform DIIS step
     695          18 :       IF (diis_step) THEN
     696          14 :          nb1 = nb + 1
     697          56 :          ALLOCATE (a(nb1, nb1))
     698          42 :          ALLOCATE (b(nb1, nb1))
     699          42 :          ALLOCATE (ev(nb1))
     700             :          ! Set up the linear DIIS equation system
     701         398 :          b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
     702          58 :          b(1:nb, nb1) = -1.0_dp
     703          58 :          b(nb1, 1:nb) = -1.0_dp
     704          14 :          b(nb1, nb1) = 0.0_dp
     705             :          ! Solve the linear DIIS equation system
     706          14 :          CALL diamat_all(b(1:nb1, 1:nb1), ev(1:nb1))
     707         630 :          a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
     708          72 :          DO jb = 1, nb1
     709          72 :             IF (ABS(ev(jb)) < eigenvalue_threshold) THEN
     710           0 :                a(1:nb1, jb) = 0.0_dp
     711             :             ELSE
     712         308 :                a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
     713             :             END IF
     714             :          END DO ! end-loop-jb
     715             : 
     716         308 :          ev(1:nb) = MATMUL(a(1:nb, 1:nb1), b(nb1, 1:nb1))
     717             : 
     718             :          ! Update Kohn-Sham matrix
     719          14 :          IF (iscf .GE. ls_scf_env%iter_ini_diis) THEN ! if-iscf-to-updateKS------ START
     720             : 
     721          14 :             IF (unit_nr > 0) THEN
     722           7 :                WRITE (unit_nr, '(A40,I3)') 'DIIS: Updating Kohn-Sham matrix at iscf=', iscf
     723             :             END IF
     724             : 
     725          36 :             DO ispin = 1, nspin
     726             :                CALL dbcsr_set(matrix_ks(ispin)%matrix, & ! reset matrix
     727          22 :                               0.0_dp)
     728         106 :                DO jb = 1, nb
     729          70 :                   parameters => diis_buffer%param(jb, ispin)%matrix
     730             :                   CALL dbcsr_add(matrix_ks(ispin)%matrix, parameters, &
     731          92 :                                  1.0_dp, -ev(jb))
     732             :                END DO ! end-loop-jb
     733             :             END DO ! end-loop-ispin
     734             :          END IF ! if-iscf-to-updateKS------ END
     735             : 
     736          14 :          DEALLOCATE (a)
     737          14 :          DEALLOCATE (b)
     738          14 :          DEALLOCATE (ev)
     739             : 
     740             :       ELSE
     741          10 :          DO ispin = 1, nspin
     742           6 :             parameters => diis_buffer%param(ib, ispin)%matrix
     743             :             CALL dbcsr_copy(parameters, & ! out
     744          10 :                             matrix_ks(ispin)%matrix) ! in
     745             :          END DO ! end-loop-ispin
     746             :       END IF
     747          18 :       CALL dbcsr_release(matrix_tmp)
     748          18 :       CALL dbcsr_release(matrix_KSerr_t)
     749          18 :       CALL timestop(handle)
     750             : 
     751          18 :    END SUBROUTINE qs_diis_b_step_4lscf
     752             : 
     753             : ! **************************************************************************************************
     754             : !> \brief Allocate and initialize a DIIS buffer with a buffer size of nbuffer.
     755             : !> \param diis_buffer the buffer to initialize
     756             : !> \param ls_scf_env ...
     757             : !> \param nspin ...
     758             : !> \par History
     759             : !>      - Adapted from qs_diis_b_check_i_alloc for sparse matrices and
     760             : !>        used in LS-SCF module (ls_scf_main) (10-11-14)
     761             : !> \author Fredy W. Aquino
     762             : !> \note
     763             : !>      check to allocate matrices only when needed
     764             : ! **************************************************************************************************
     765             : 
     766          18 :    SUBROUTINE qs_diis_b_check_i_alloc_sparse(diis_buffer, ls_scf_env, &
     767             :                                              nspin)
     768             : 
     769             :       TYPE(qs_diis_buffer_type_sparse), INTENT(INOUT)    :: diis_buffer
     770             :       TYPE(ls_scf_env_type)                              :: ls_scf_env
     771             :       INTEGER, INTENT(IN)                                :: nspin
     772             : 
     773             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_diis_b_check_i_alloc_sparse'
     774             : 
     775             :       INTEGER                                            :: handle, ibuffer, ispin, nbuffer
     776             :       TYPE(cp_logger_type), POINTER                      :: logger
     777             : 
     778             : ! -------------------------------------------------------------------------
     779             : 
     780          18 :       CALL timeset(routineN, handle)
     781             : 
     782          18 :       logger => cp_get_default_logger()
     783             : 
     784          18 :       nbuffer = diis_buffer%nbuffer
     785             : 
     786          18 :       IF (.NOT. ASSOCIATED(diis_buffer%error)) THEN
     787          46 :          ALLOCATE (diis_buffer%error(nbuffer, nspin))
     788             : 
     789          10 :          DO ispin = 1, nspin
     790          34 :             DO ibuffer = 1, nbuffer
     791          24 :                ALLOCATE (diis_buffer%error(ibuffer, ispin)%matrix)
     792             : 
     793             :                CALL dbcsr_create(diis_buffer%error(ibuffer, ispin)%matrix, &
     794             :                                  template=ls_scf_env%matrix_ks(1), &
     795          30 :                                  matrix_type='N')
     796             :             END DO
     797             :          END DO
     798             :       END IF
     799             : 
     800          18 :       IF (.NOT. ASSOCIATED(diis_buffer%param)) THEN
     801          46 :          ALLOCATE (diis_buffer%param(nbuffer, nspin))
     802             : 
     803          10 :          DO ispin = 1, nspin
     804          34 :             DO ibuffer = 1, nbuffer
     805          24 :                ALLOCATE (diis_buffer%param(ibuffer, ispin)%matrix)
     806             :                CALL dbcsr_create(diis_buffer%param(ibuffer, ispin)%matrix, &
     807             :                                  template=ls_scf_env%matrix_ks(1), &
     808          30 :                                  matrix_type='N')
     809             :             END DO
     810             :          END DO
     811             :       END IF
     812             : 
     813          18 :       IF (.NOT. ASSOCIATED(diis_buffer%b_matrix)) THEN
     814          16 :          ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
     815             : 
     816         124 :          diis_buffer%b_matrix = 0.0_dp
     817             :       END IF
     818             : 
     819          18 :       CALL timestop(handle)
     820             : 
     821          18 :    END SUBROUTINE qs_diis_b_check_i_alloc_sparse
     822             : 
     823             : ! **************************************************************************************************
     824             : !> \brief clears the DIIS buffer in LS-SCF calculation
     825             : !> \param diis_buffer the buffer to clear
     826             : !> \par History
     827             : !>      10-11-14 created [FA] modified from qs_diis_b_clear
     828             : !> \author Fredy W. Aquino
     829             : ! **************************************************************************************************
     830             : 
     831           4 :    PURE SUBROUTINE qs_diis_b_clear_sparse(diis_buffer)
     832             : 
     833             :       TYPE(qs_diis_buffer_type_sparse), INTENT(INOUT)    :: diis_buffer
     834             : 
     835           4 :       diis_buffer%ncall = 0
     836             : 
     837           4 :    END SUBROUTINE qs_diis_b_clear_sparse
     838             : 
     839             : ! **************************************************************************************************
     840             : !> \brief Allocates an SCF DIIS buffer for LS-SCF calculation
     841             : !> \param diis_buffer the buffer to create
     842             : !> \param nbuffer ...
     843             : !> \par History
     844             : !>      10-11-14 created [FA] modified from qs_diis_b_create
     845             : !> \author Fredy W. Aquino
     846             : ! **************************************************************************************************
     847           4 :    PURE SUBROUTINE qs_diis_b_create_sparse(diis_buffer, nbuffer)
     848             : 
     849             :       TYPE(qs_diis_buffer_type_sparse), INTENT(OUT)      :: diis_buffer
     850             :       INTEGER, INTENT(in)                                :: nbuffer
     851             : 
     852             :       NULLIFY (diis_buffer%b_matrix)
     853             :       NULLIFY (diis_buffer%error)
     854             :       NULLIFY (diis_buffer%param)
     855           4 :       diis_buffer%nbuffer = nbuffer
     856           4 :       diis_buffer%ncall = 0
     857             : 
     858           4 :    END SUBROUTINE qs_diis_b_create_sparse
     859             : 
     860             : ! **************************************************************************************************
     861             : !> \brief Allocates an SCF DIIS buffer for k-points
     862             : !> \param diis_buffer the buffer to create
     863             : !> \param nbuffer ...
     864             : ! **************************************************************************************************
     865         134 :    SUBROUTINE qs_diis_b_create_kp(diis_buffer, nbuffer)
     866             : 
     867             :       TYPE(qs_diis_buffer_type_kp), INTENT(OUT)          :: diis_buffer
     868             :       INTEGER, INTENT(in)                                :: nbuffer
     869             : 
     870             :       NULLIFY (diis_buffer%b_matrix)
     871             :       NULLIFY (diis_buffer%error)
     872             :       NULLIFY (diis_buffer%param)
     873             :       NULLIFY (diis_buffer%smat)
     874         134 :       diis_buffer%nbuffer = nbuffer
     875         134 :       diis_buffer%ncall = 0
     876             : 
     877         134 :    END SUBROUTINE qs_diis_b_create_kp
     878             : 
     879             : ! **************************************************************************************************
     880             : !> \brief Allocate and initialize a DIIS buffer for nao*nao parameter
     881             : !>      variables and with a buffer size of nbuffer, in the k-point case
     882             : !> \param diis_buffer the buffer to initialize
     883             : !> \param matrix_struct the structure for the matrix of the buffer note: this is in the kp subgroup
     884             : !> \param nspin ...
     885             : !> \param nkp ...
     886             : !> \param scf_section ...
     887             : ! **************************************************************************************************
     888        9596 :    SUBROUTINE qs_diis_b_check_i_alloc_kp(diis_buffer, matrix_struct, nspin, nkp, scf_section)
     889             : 
     890             :       TYPE(qs_diis_buffer_type_kp), INTENT(INOUT)        :: diis_buffer
     891             :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
     892             :       INTEGER, INTENT(IN)                                :: nspin, nkp
     893             :       TYPE(section_vals_type), POINTER                   :: scf_section
     894             : 
     895             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_diis_b_check_i_alloc_kp'
     896             : 
     897             :       INTEGER                                            :: handle, ibuffer, ikp, ispin, nbuffer, &
     898             :                                                             output_unit
     899             :       TYPE(cp_logger_type), POINTER                      :: logger
     900             : 
     901             : ! -------------------------------------------------------------------------
     902             : 
     903        9596 :       CALL timeset(routineN, handle)
     904             : 
     905        9596 :       logger => cp_get_default_logger()
     906             : 
     907        9596 :       nbuffer = diis_buffer%nbuffer
     908             : 
     909        9596 :       IF (.NOT. ASSOCIATED(diis_buffer%error)) THEN
     910        4128 :          ALLOCATE (diis_buffer%error(nbuffer, nspin, nkp))
     911             : 
     912         596 :          DO ikp = 1, nkp
     913        1224 :             DO ispin = 1, nspin
     914        3638 :                DO ibuffer = 1, nbuffer
     915             :                   CALL cp_cfm_create(diis_buffer%error(ibuffer, ispin, ikp), &
     916             :                                      name="qs_diis_b%error("// &
     917             :                                      TRIM(ADJUSTL(cp_to_string(ibuffer)))//","// &
     918             :                                      TRIM(ADJUSTL(cp_to_string(ibuffer)))//")", &
     919        3140 :                                      matrix_struct=matrix_struct)
     920             :                END DO
     921             :             END DO
     922             :          END DO
     923             :       END IF
     924             : 
     925        9596 :       IF (.NOT. ASSOCIATED(diis_buffer%param)) THEN
     926        4128 :          ALLOCATE (diis_buffer%param(nbuffer, nspin, nkp))
     927             : 
     928         596 :          DO ikp = 1, nkp
     929        1224 :             DO ispin = 1, nspin
     930        3638 :                DO ibuffer = 1, nbuffer
     931             :                   CALL cp_cfm_create(diis_buffer%param(ibuffer, ispin, ikp), &
     932             :                                      name="qs_diis_b%param("// &
     933             :                                      TRIM(ADJUSTL(cp_to_string(ibuffer)))//","// &
     934             :                                      TRIM(ADJUSTL(cp_to_string(ibuffer)))//")", &
     935        3140 :                                      matrix_struct=matrix_struct)
     936             :                END DO
     937             :             END DO
     938             :          END DO
     939             :       END IF
     940             : 
     941        9596 :       IF (.NOT. ASSOCIATED(diis_buffer%smat)) THEN
     942         792 :          ALLOCATE (diis_buffer%smat(nkp))
     943         596 :          DO ikp = 1, nkp
     944             :             CALL cp_cfm_create(diis_buffer%smat(ikp), &
     945             :                                name="kp_cfm_smat("// &
     946             :                                TRIM(ADJUSTL(cp_to_string(ibuffer)))//","// &
     947             :                                TRIM(ADJUSTL(cp_to_string(ibuffer)))//")", &
     948         596 :                                matrix_struct=matrix_struct)
     949             :          END DO
     950             :       END IF
     951             : 
     952        9596 :       IF (.NOT. ASSOCIATED(diis_buffer%b_matrix)) THEN
     953         490 :          ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
     954        3038 :          diis_buffer%b_matrix = 0.0_dp
     955             :          output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
     956          98 :                                             extension=".scfLog")
     957          98 :          IF (output_unit > 0) THEN
     958             :             WRITE (UNIT=output_unit, FMT="(/,T9,A)") &
     959           0 :                "DIIS | The SCF DIIS buffer was allocated and initialized"
     960             :          END IF
     961             :          CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
     962          98 :                                            "PRINT%DIIS_INFO")
     963             :       END IF
     964             : 
     965        9596 :       CALL timestop(handle)
     966             : 
     967        9596 :    END SUBROUTINE qs_diis_b_check_i_alloc_kp
     968             : 
     969             : ! **************************************************************************************************
     970             : !> \brief clears the buffer
     971             : !> \param diis_buffer the buffer to clear
     972             : ! **************************************************************************************************
     973         862 :    PURE SUBROUTINE qs_diis_b_clear_kp(diis_buffer)
     974             : 
     975             :       TYPE(qs_diis_buffer_type_kp), INTENT(INOUT)        :: diis_buffer
     976             : 
     977         862 :       diis_buffer%ncall = 0
     978             : 
     979         862 :    END SUBROUTINE qs_diis_b_clear_kp
     980             : 
     981             : ! **************************************************************************************************
     982             : !> \brief Update info about the current buffer step ib and the current number of buffers nb
     983             : !> \param diis_buffer ...
     984             : !> \param ib ...
     985             : !> \param nb ...
     986             : ! **************************************************************************************************
     987        3968 :    SUBROUTINE qs_diis_b_info_kp(diis_buffer, ib, nb)
     988             :       TYPE(qs_diis_buffer_type_kp), POINTER              :: diis_buffer
     989             :       INTEGER, INTENT(OUT)                               :: ib, nb
     990             : 
     991        3968 :       ib = MODULO(diis_buffer%ncall, diis_buffer%nbuffer) + 1
     992        3968 :       diis_buffer%ncall = diis_buffer%ncall + 1
     993        3968 :       nb = MIN(diis_buffer%ncall, diis_buffer%nbuffer)
     994             : 
     995        3968 :    END SUBROUTINE qs_diis_b_info_kp
     996             : 
     997             : ! **************************************************************************************************
     998             : !> \brief Calculate and store the error for a given k-point
     999             : !> \param diis_buffer ...
    1000             : !> \param ib ...
    1001             : !> \param mos ...
    1002             : !> \param kc ...
    1003             : !> \param sc ...
    1004             : !> \param ispin ...
    1005             : !> \param ikp ...
    1006             : !> \param nkp_local ...
    1007             : !> \param scf_section ...
    1008             : !> \note We assume that we always have an overlap matrix and complex matrices
    1009             : !> TODO: do we need to pass the kp weight for the back Fourier transform?
    1010             : ! **************************************************************************************************
    1011       28788 :    SUBROUTINE qs_diis_b_calc_err_kp(diis_buffer, ib, mos, kc, sc, ispin, ikp, nkp_local, scf_section)
    1012             :       TYPE(qs_diis_buffer_type_kp), POINTER              :: diis_buffer
    1013             :       INTEGER, INTENT(IN)                                :: ib
    1014             :       TYPE(mo_set_type), DIMENSION(:, :), POINTER        :: mos
    1015             :       TYPE(cp_cfm_type), INTENT(INOUT)                   :: kc, sc
    1016             :       INTEGER, INTENT(IN)                                :: ispin, ikp, nkp_local
    1017             :       TYPE(section_vals_type), POINTER                   :: scf_section
    1018             : 
    1019             :       CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_diis_b_calc_err_kp'
    1020             : 
    1021             :       INTEGER                                            :: handle, homo, nao, nmo, nspin
    1022             :       REAL(dp)                                           :: maxocc
    1023             :       TYPE(cp_cfm_type)                                  :: cmos
    1024             :       TYPE(cp_cfm_type), POINTER                         :: new_errors, parameters, smat
    1025             :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
    1026             :       TYPE(cp_fm_type), POINTER                          :: imos, rmos
    1027             : 
    1028        9596 :       NULLIFY (matrix_struct, imos, rmos, parameters, new_errors, smat)
    1029             : 
    1030        9596 :       CALL timeset(routineN, handle)
    1031             : 
    1032             :       !Calculate the error for this given k-point, store the KS matrix as well as the ovlp matrix
    1033             :       !All of this happens within the kp subgroups
    1034             : 
    1035             :       ! Quick return, if no DIIS is requested
    1036        9596 :       IF (diis_buffer%nbuffer < 1) THEN
    1037           0 :          CALL timestop(handle)
    1038           0 :          RETURN
    1039             :       END IF
    1040        9596 :       nspin = SIZE(mos, 2)
    1041             : 
    1042        9596 :       CALL cp_cfm_get_info(kc, matrix_struct=matrix_struct)
    1043             :       CALL qs_diis_b_check_i_alloc_kp(diis_buffer, &
    1044             :                                       matrix_struct=matrix_struct, &
    1045             :                                       nspin=nspin, nkp=nkp_local, &
    1046        9596 :                                       scf_section=scf_section)
    1047             : 
    1048             :       !We calculate: e(ikp) = F(ikp)*P(ikp)*S(ikp) - S(ikp)*P(ikp)*F(ikp)
    1049        9596 :       CALL get_mo_set(mos(1, ispin), nao=nao, nmo=nmo, homo=homo, mo_coeff=rmos, maxocc=maxocc)
    1050        9596 :       CALL get_mo_set(mos(2, ispin), mo_coeff=imos)
    1051        9596 :       NULLIFY (matrix_struct)
    1052        9596 :       CALL cp_fm_get_info(rmos, matrix_struct=matrix_struct)
    1053        9596 :       CALL cp_cfm_create(cmos, matrix_struct)
    1054        9596 :       CALL cp_fm_to_cfm(rmos, imos, cmos)
    1055             : 
    1056        9596 :       new_errors => diis_buffer%error(ib, ispin, ikp)
    1057        9596 :       parameters => diis_buffer%param(ib, ispin, ikp)
    1058        9596 :       smat => diis_buffer%smat(ikp)
    1059             : 
    1060             :       !copy the KS and overlap matrices to the DIIS buffer
    1061        9596 :       CALL cp_cfm_to_cfm(kc, parameters)
    1062        9596 :       CALL cp_cfm_to_cfm(sc, smat)
    1063             : 
    1064             :       ! KC <- K*C
    1065        9596 :       CALL parallel_gemm("N", "N", nao, homo, nao, CMPLX(maxocc, KIND=dp), parameters, cmos, (0.0_dp, 0.0_dp), kc)
    1066             :       ! SC <- S*C
    1067        9596 :       CALL parallel_gemm("N", "N", nao, homo, nao, (2.0_dp, 0.0_dp), smat, cmos, (0.0_dp, 0.0_dp), sc)
    1068             : 
    1069             :       ! new_errors <- KC*(SC)^T - (SC)*(KC)^T = K*P*S - S*P*K
    1070        9596 :       CALL parallel_gemm("N", "T", nao, nao, homo, (1.0_dp, 0.0_dp), sc, kc, (0.0_dp, 0.0_dp), new_errors)
    1071        9596 :       CALL parallel_gemm("N", "T", nao, nao, homo, (1.0_dp, 0.0_dp), kc, sc, (-1.0_dp, 0.0_dp), new_errors)
    1072             : 
    1073             :       !clean-up
    1074        9596 :       CALL cp_cfm_release(cmos)
    1075             : 
    1076        9596 :       CALL timestop(handle)
    1077             : 
    1078        9596 :    END SUBROUTINE qs_diis_b_calc_err_kp
    1079             : 
    1080             : ! **************************************************************************************************
    1081             : !> \brief Update the SCF DIIS buffer, and if appropriate does a diis step, for k-points
    1082             : !> \param diis_buffer ...
    1083             : !> \param coeffs ...
    1084             : !> \param ib ...
    1085             : !> \param nb ...
    1086             : !> \param delta ...
    1087             : !> \param error_max ...
    1088             : !> \param diis_step ...
    1089             : !> \param eps_diis ...
    1090             : !> \param nspin ...
    1091             : !> \param nkp ...
    1092             : !> \param nkp_local ...
    1093             : !> \param nmixing ...
    1094             : !> \param scf_section ...
    1095             : !> \param para_env ...
    1096             : ! **************************************************************************************************
    1097        3968 :    SUBROUTINE qs_diis_b_step_kp(diis_buffer, coeffs, ib, nb, delta, error_max, diis_step, eps_diis, &
    1098             :                                 nspin, nkp, nkp_local, nmixing, scf_section, para_env)
    1099             : 
    1100             :       TYPE(qs_diis_buffer_type_kp), POINTER              :: diis_buffer
    1101             :       COMPLEX(KIND=dp), DIMENSION(:), INTENT(INOUT)      :: coeffs
    1102             :       INTEGER, INTENT(IN)                                :: ib, nb
    1103             :       REAL(KIND=dp), INTENT(IN)                          :: delta
    1104             :       REAL(KIND=dp), INTENT(OUT)                         :: error_max
    1105             :       LOGICAL, INTENT(OUT)                               :: diis_step
    1106             :       REAL(KIND=dp), INTENT(IN)                          :: eps_diis
    1107             :       INTEGER, INTENT(IN)                                :: nspin, nkp, nkp_local
    1108             :       INTEGER, INTENT(IN), OPTIONAL                      :: nmixing
    1109             :       TYPE(section_vals_type), POINTER                   :: scf_section
    1110             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1111             : 
    1112             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'qs_diis_b_step_kp'
    1113             :       REAL(KIND=dp), PARAMETER :: eigenvalue_threshold = 1.0E-12_dp
    1114             : 
    1115             :       CHARACTER(LEN=2*default_string_length)             :: message
    1116             :       COMPLEX(KIND=dp)                                   :: tmp
    1117        3968 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :)     :: a, b
    1118             :       INTEGER                                            :: handle, ikp, ispin, jb, my_nmixing, nb1, &
    1119             :                                                             output_unit
    1120             :       LOGICAL                                            :: eigenvectors_discarded
    1121        3968 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: ev
    1122             :       TYPE(cp_cfm_type)                                  :: old_errors
    1123             :       TYPE(cp_cfm_type), POINTER                         :: new_errors
    1124             :       TYPE(cp_fm_struct_type), POINTER                   :: matrix_struct
    1125             :       TYPE(cp_fm_type)                                   :: ierr, rerr
    1126             :       TYPE(cp_logger_type), POINTER                      :: logger
    1127             : 
    1128        3968 :       NULLIFY (matrix_struct, new_errors, logger)
    1129             : 
    1130        3968 :       CALL timeset(routineN, handle)
    1131             : 
    1132        3968 :       diis_step = .FALSE.
    1133             : 
    1134        3968 :       my_nmixing = 2
    1135        3968 :       IF (PRESENT(nmixing)) my_nmixing = nmixing
    1136             : 
    1137        3968 :       logger => cp_get_default_logger()
    1138             : 
    1139             :       ! Quick return, if no DIIS is requested
    1140        3968 :       IF (diis_buffer%nbuffer < 1) THEN
    1141           0 :          CALL timestop(handle)
    1142           0 :          RETURN
    1143             :       END IF
    1144             : 
    1145             :       ! Check, if a DIIS step is appropriate
    1146        3968 :       diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
    1147             : 
    1148             :       ! Calculate the DIIS buffer, and update it if max_error < eps_diis
    1149        3968 :       CALL cp_cfm_get_info(diis_buffer%error(ib, 1, 1), matrix_struct=matrix_struct)
    1150        3968 :       CALL cp_fm_create(ierr, matrix_struct)
    1151        3968 :       CALL cp_fm_create(rerr, matrix_struct)
    1152        3968 :       CALL cp_cfm_create(old_errors, matrix_struct)
    1153       15872 :       ALLOCATE (b(nb, nb))
    1154       60952 :       b = 0.0_dp
    1155       16470 :       DO jb = 1, nb
    1156       36902 :          DO ikp = 1, nkp_local
    1157       64494 :             DO ispin = 1, nspin
    1158       27592 :                new_errors => diis_buffer%error(ib, ispin, ikp)
    1159       27592 :                CALL cp_cfm_to_fm(diis_buffer%error(jb, ispin, ikp), rerr, ierr)
    1160       27592 :                CALL cp_fm_scale(-1.0_dp, ierr)
    1161       27592 :                CALL cp_fm_to_cfm(rerr, ierr, old_errors)
    1162       27592 :                CALL cp_cfm_trace(old_errors, new_errors, tmp)
    1163       51992 :                b(jb, ib) = b(jb, ib) + 1.0_dp/REAL(nkp, dp)*tmp
    1164             :             END DO
    1165             :          END DO
    1166       16470 :          b(ib, jb) = CONJG(b(jb, ib))
    1167             :       END DO
    1168        3968 :       CALL cp_fm_release(ierr)
    1169        3968 :       CALL cp_fm_release(rerr)
    1170        3968 :       CALL cp_cfm_release(old_errors)
    1171        3968 :       CALL para_env%sum(b)
    1172             : 
    1173        3968 :       error_max = SQRT(REAL(b(ib, ib))**2 + AIMAG(b(ib, ib))**2)
    1174             : 
    1175             :       output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
    1176        3968 :                                          extension=".scfLog")
    1177        3968 :       IF (output_unit > 0) THEN
    1178             :          WRITE (UNIT=output_unit, FMT="(/,T9,A,I4,/,(T9,A,ES12.3))") &
    1179           0 :             "DIIS | Current SCF DIIS buffer size:         ", nb, &
    1180           0 :             "DIIS | Maximum SCF DIIS error at last step:  ", error_max, &
    1181           0 :             "DIIS | Current SCF convergence:              ", delta, &
    1182           0 :             "DIIS | Threshold value for a DIIS step:      ", eps_diis
    1183           0 :          IF (error_max < eps_diis) THEN
    1184             :             WRITE (UNIT=output_unit, FMT="(T9,A)") &
    1185           0 :                "DIIS | => The SCF DIIS buffer will be updated"
    1186             :          ELSE
    1187             :             WRITE (UNIT=output_unit, FMT="(T9,A)") &
    1188           0 :                "DIIS | => No update of the SCF DIIS buffer"
    1189             :          END IF
    1190           0 :          IF (diis_step .AND. (error_max < eps_diis)) THEN
    1191             :             WRITE (UNIT=output_unit, FMT="(T9,A,/)") &
    1192           0 :                "DIIS | => A SCF DIIS step will be performed"
    1193             :          ELSE
    1194             :             WRITE (UNIT=output_unit, FMT="(T9,A,/)") &
    1195           0 :                "DIIS | => No SCF DIIS step will be performed"
    1196             :          END IF
    1197             :       END IF
    1198             : 
    1199             :       ! Update the SCF DIIS buffer
    1200        3968 :       IF (error_max < eps_diis) THEN
    1201       16200 :          DO jb = 1, nb
    1202       12356 :             diis_buffer%b_matrix(ib, jb) = b(ib, jb)
    1203       16200 :             diis_buffer%b_matrix(jb, ib) = b(jb, ib)
    1204             :          END DO
    1205             :       ELSE
    1206             : 
    1207         124 :          diis_step = .FALSE.
    1208             :       END IF
    1209        3968 :       DEALLOCATE (b)
    1210             : 
    1211             :       ! Perform DIIS step
    1212        3968 :       IF (diis_step) THEN
    1213             : 
    1214        2436 :          nb1 = nb + 1
    1215             : 
    1216        9744 :          ALLOCATE (a(nb1, nb1))
    1217        7308 :          ALLOCATE (b(nb1, nb1))
    1218        7308 :          ALLOCATE (ev(nb1))
    1219             : 
    1220             :          ! Set up the linear DIIS equation system
    1221       44980 :          b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
    1222             : 
    1223       11338 :          b(1:nb, nb1) = -1.0_dp
    1224       11338 :          b(nb1, 1:nb) = -1.0_dp
    1225        2436 :          b(nb1, nb1) = 0.0_dp
    1226             : 
    1227             :          ! Solve the linear DIIS equation system
    1228       13774 :          ev(1:nb1) = 0.0_dp !eigenvalues
    1229       67656 :          a(1:nb1, 1:nb1) = 0.0_dp !eigenvectors
    1230        2436 :          CALL diag_complex(b(1:nb1, 1:nb1), a(1:nb1, 1:nb1), ev(1:nb1))
    1231       67656 :          b(1:nb1, 1:nb1) = a(1:nb1, 1:nb1)
    1232             : 
    1233        2436 :          eigenvectors_discarded = .FALSE.
    1234             : 
    1235       13774 :          DO jb = 1, nb1
    1236       13774 :             IF (ABS(ev(jb)) < eigenvalue_threshold) THEN
    1237        1552 :                IF (output_unit > 0) THEN
    1238           0 :                   IF (.NOT. eigenvectors_discarded) THEN
    1239             :                      WRITE (UNIT=output_unit, FMT="(T9,A)") &
    1240           0 :                         "DIIS | Checking eigenvalues of the DIIS error matrix"
    1241             :                   END IF
    1242             :                   WRITE (UNIT=message, FMT="(T9,A,I6,A,ES10.1,A,ES10.1)") &
    1243           0 :                      "DIIS | Eigenvalue ", jb, " = ", ev(jb), " is smaller than "// &
    1244           0 :                      "threshold ", eigenvalue_threshold
    1245           0 :                   CALL compress(message)
    1246           0 :                   WRITE (UNIT=output_unit, FMT="(T9,A)") TRIM(message)
    1247           0 :                   eigenvectors_discarded = .TRUE.
    1248             :                END IF
    1249        9126 :                a(1:nb1, jb) = 0.0_dp
    1250             :             ELSE
    1251       56094 :                a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
    1252             :             END IF
    1253             :          END DO
    1254             : 
    1255        2436 :          IF ((output_unit > 0) .AND. eigenvectors_discarded) THEN
    1256             :             WRITE (UNIT=output_unit, FMT="(T9,A,/)") &
    1257           0 :                "DIIS | The corresponding eigenvectors were discarded"
    1258             :          END IF
    1259             : 
    1260       78994 :          coeffs(1:nb) = -MATMUL(a(1:nb, 1:nb1), CONJG(b(nb1, 1:nb1)))
    1261             :       ELSE
    1262             : 
    1263        5132 :          coeffs(:) = 0.0_dp
    1264        1532 :          coeffs(ib) = 1.0_dp
    1265             :       END IF
    1266             : 
    1267             :       CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
    1268        3968 :                                         "PRINT%DIIS_INFO")
    1269             : 
    1270        3968 :       CALL timestop(handle)
    1271             : 
    1272       11904 :    END SUBROUTINE qs_diis_b_step_kp
    1273        2436 : END MODULE qs_diis

Generated by: LCOV version 1.15