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

Generated by: LCOV version 2.0-1