LCOV - code coverage report
Current view: top level - src - qs_diis.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 93.0 % 426 396
Test Date: 2025-07-25 12:55:17 Functions: 100.0 % 14 14

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

Generated by: LCOV version 2.0-1