LCOV - code coverage report
Current view: top level - src - qs_block_davidson_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:744416f) Lines: 88.5 % 52 46
Test Date: 2026-09-20 02:09:09 Functions: 80.0 % 5 4

            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 module that contains the algorithms to perform an iterative
      10              : !>         diagonalization by the block-Davidson approach
      11              : !>         P. Blaha, et al J. Comp. Physics, 229, (2010), 453-460
      12              : !>         Iterative diagonalization in augmented plane wave based
      13              : !>              methods in electronic structure calculations
      14              : !> \par History
      15              : !>      05.2011 created [MI]
      16              : !> \author MI
      17              : ! **************************************************************************************************
      18              : MODULE qs_block_davidson_types
      19              : 
      20              :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      21              :                                               cp_fm_struct_release,&
      22              :                                               cp_fm_struct_type
      23              :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      24              :                                               cp_fm_release,&
      25              :                                               cp_fm_type
      26              :    USE input_section_types,             ONLY: section_vals_type,&
      27              :                                               section_vals_val_get
      28              :    USE kinds,                           ONLY: dp
      29              : #include "./base/base_uses.f90"
      30              : 
      31              :    IMPLICIT NONE
      32              :    PRIVATE
      33              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_block_davidson_types'
      34              : 
      35              :    PUBLIC :: block_davidson_allocate, block_davidson_deallocate, block_davidson_release, &
      36              :              block_davidson_env_create, davidson_type
      37              : 
      38              :    TYPE davidson_type
      39              :       INTEGER :: max_iter = -1, prec_type = -1, solver_type = -1, niter_new_prec = -1, first_prec = -1
      40              :       LOGICAL :: use_sparse_mos = .FALSE.
      41              :       REAL(KIND=dp) :: conv_percent = -1.0_dp, energy_gap = -1.0_dp, eps_iter = -1.0_dp, &
      42              :                        noise_scale = 100.0_dp
      43              :       ! adaptive-tolerance ratchet state: the inner threshold of the previous
      44              :       ! SCF step, carried across steps so that it may only tighten, and the
      45              :       ! threshold the latest solve actually used (zero: EPS_ADAPT inactive)
      46              :       REAL(KIND=dp) :: eps_iter_prev = HUGE(1.0_dp), eps_iter_used = 0.0_dp
      47              :       TYPE(cp_fm_type), POINTER :: H_block_mat => NULL(), H_block_vec => NULL(), &
      48              :                                    matrix_z => NULL(), matrix_pz => NULL(), S_block_mat => NULL(), W_block_mat => NULL()
      49              :    END TYPE davidson_type
      50              : 
      51              : CONTAINS
      52              : 
      53              : ! **************************************************************************************************
      54              : 
      55              : ! **************************************************************************************************
      56              : !> \brief creates one Davidson environment per solver channel: for Gamma-point
      57              : !>        runs a channel is a spin, for K-point runs it is (ikpoint,ispin)
      58              : !>        following the layout of qs_ot_channel_index.
      59              : !> \param bdav_env ...
      60              : !> \param nchannels number of channels (spins at Gamma, local kpoints*spins with K points)
      61              : !> \param scf_section ...
      62              : ! **************************************************************************************************
      63           38 :    SUBROUTINE block_davidson_env_create(bdav_env, nchannels, scf_section)
      64              : 
      65              :       TYPE(davidson_type), DIMENSION(:), POINTER         :: bdav_env
      66              :       INTEGER, INTENT(IN)                                :: nchannels
      67              :       TYPE(section_vals_type), POINTER                   :: scf_section
      68              : 
      69              :       INTEGER                                            :: ichannel
      70              :       TYPE(davidson_type)                                :: settings
      71              : 
      72            0 :       CPASSERT(.NOT. ASSOCIATED(bdav_env))
      73              :       ! the solver settings are channel independent, so they are read once and
      74              :       ! then copied into every channel
      75              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DAVIDSON%PRECONDITIONER", &
      76           38 :                                 i_val=settings%prec_type)
      77              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DAVIDSON%PRECOND_SOLVER", &
      78           38 :                                 i_val=settings%solver_type)
      79              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DAVIDSON%ENERGY_GAP", &
      80           38 :                                 r_val=settings%energy_gap)
      81              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DAVIDSON%NEW_PREC_EACH", &
      82           38 :                                 i_val=settings%niter_new_prec)
      83              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%MAX_ITER", &
      84           38 :                                 i_val=settings%max_iter)
      85              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%EPS_ITER", &
      86           38 :                                 r_val=settings%eps_iter)
      87              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DAVIDSON%FIRST_PREC", &
      88           38 :                                 i_val=settings%first_prec)
      89              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DAVIDSON%CONV_MOS_PERCENT", &
      90           38 :                                 r_val=settings%conv_percent)
      91              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DAVIDSON%NOISE_SCALE", &
      92           38 :                                 r_val=settings%noise_scale)
      93              :       CALL section_vals_val_get(scf_section, "DIAGONALIZATION%DAVIDSON%SPARSE_MOS", &
      94           38 :                                 l_val=settings%use_sparse_mos)
      95              : 
      96          184 :       ALLOCATE (bdav_env(nchannels))
      97          108 :       DO ichannel = 1, nchannels
      98              :          ! davidson_type has default initializers, so allocation leaves the
      99              :          ! matrix pointers disassociated
     100          108 :          bdav_env(ichannel) = settings
     101              : 
     102              :       END DO
     103              : 
     104           38 :    END SUBROUTINE block_davidson_env_create
     105              : 
     106              : ! **************************************************************************************************
     107              : !> \brief ...
     108              : !> \param bdav_env ...
     109              : !> \param mo_coeff ...
     110              : !> \param nao ...
     111              : !> \param nmo ...
     112              : ! **************************************************************************************************
     113           20 :    SUBROUTINE block_davidson_allocate(bdav_env, mo_coeff, nao, nmo)
     114              : 
     115              :       TYPE(davidson_type)                                :: bdav_env
     116              :       TYPE(cp_fm_type), INTENT(IN)                       :: mo_coeff
     117              :       INTEGER, INTENT(IN)                                :: nao, nmo
     118              : 
     119              :       CHARACTER(len=*), PARAMETER :: routineN = 'block_davidson_allocate'
     120              : 
     121              :       INTEGER                                            :: handle, nmox2
     122              :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct_tmp
     123              : 
     124           20 :       CALL timeset(routineN, handle)
     125           20 :       NULLIFY (fm_struct_tmp)
     126              : 
     127           20 :       nmox2 = 2*nmo
     128              : 
     129              :       CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nao, ncol_global=nmo, &
     130              :                                para_env=mo_coeff%matrix_struct%para_env, &
     131           20 :                                context=mo_coeff%matrix_struct%context)
     132           20 :       NULLIFY (bdav_env%matrix_z, bdav_env%matrix_pz)
     133           20 :       ALLOCATE (bdav_env%matrix_z, bdav_env%matrix_pz)
     134           20 :       CALL cp_fm_create(bdav_env%matrix_z, fm_struct_tmp, name="Z_mat")
     135           20 :       CALL cp_fm_create(bdav_env%matrix_pz, fm_struct_tmp, name="Z_mat")
     136           20 :       CALL cp_fm_struct_release(fm_struct_tmp)
     137              : 
     138           20 :       CALL timestop(handle)
     139              : 
     140           20 :    END SUBROUTINE block_davidson_allocate
     141              : 
     142              : ! **************************************************************************************************
     143              : !> \brief ...
     144              : !> \param bdav_env ...
     145              : ! **************************************************************************************************
     146           50 :    SUBROUTINE block_davidson_deallocate(bdav_env)
     147              : 
     148              :       TYPE(davidson_type), DIMENSION(:), POINTER         :: bdav_env
     149              : 
     150              :       INTEGER                                            :: ichannel, nchannels
     151              : 
     152           50 :       IF (ASSOCIATED(bdav_env)) THEN
     153              : 
     154           50 :          nchannels = SIZE(bdav_env)
     155          140 :          DO ichannel = 1, nchannels
     156              : 
     157              :             ! K-point channels carry settings only (the complex scratch is local
     158              :             ! to generate_extended_space_c), so the pointers may stay disassociated
     159           90 :             IF (ASSOCIATED(bdav_env(ichannel)%matrix_z)) THEN
     160           20 :                CALL cp_fm_release(bdav_env(ichannel)%matrix_z)
     161           20 :                DEALLOCATE (bdav_env(ichannel)%matrix_z)
     162              :             END IF
     163           90 :             IF (ASSOCIATED(bdav_env(ichannel)%matrix_pz)) THEN
     164           20 :                CALL cp_fm_release(bdav_env(ichannel)%matrix_pz)
     165           20 :                DEALLOCATE (bdav_env(ichannel)%matrix_pz)
     166              :             END IF
     167          140 :             NULLIFY (bdav_env(ichannel)%matrix_z, bdav_env(ichannel)%matrix_pz)
     168              : 
     169              :          END DO
     170              : 
     171              :       END IF
     172              : 
     173           50 :    END SUBROUTINE block_davidson_deallocate
     174              : 
     175              : ! **************************************************************************************************
     176              : !> \brief ...
     177              : !> \param bdav_env ...
     178              : ! **************************************************************************************************
     179           38 :    SUBROUTINE block_davidson_release(bdav_env)
     180              : 
     181              :       TYPE(davidson_type), DIMENSION(:), POINTER         :: bdav_env
     182              : 
     183              :       INTEGER                                            :: ispin, nspins
     184              : 
     185           38 :       IF (ASSOCIATED(bdav_env)) THEN
     186              : 
     187           38 :          nspins = SIZE(bdav_env)
     188          108 :          DO ispin = 1, nspins
     189              : 
     190          108 :             IF (ASSOCIATED(bdav_env(ispin)%matrix_z)) THEN
     191            0 :                CALL cp_fm_release(bdav_env(ispin)%matrix_z)
     192            0 :                CALL cp_fm_release(bdav_env(ispin)%matrix_pz)
     193            0 :                DEALLOCATE (bdav_env(ispin)%matrix_z, bdav_env(ispin)%matrix_pz)
     194            0 :                NULLIFY (bdav_env(ispin)%matrix_z, bdav_env(ispin)%matrix_pz)
     195              :             END IF
     196              : 
     197              :          END DO
     198           38 :          DEALLOCATE (bdav_env)
     199              : 
     200              :       END IF
     201              : 
     202           38 :    END SUBROUTINE block_davidson_release
     203              : 
     204            0 : END MODULE qs_block_davidson_types
        

Generated by: LCOV version 2.0-1