LCOV - code coverage report
Current view: top level - src - qs_diis.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 92.3 % 440 406
Test Date: 2026-10-15 00:55:44 Functions: 100.0 % 14 14

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

Generated by: LCOV version 2.0-1