LCOV - code coverage report
Current view: top level - src - pexsi_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 0.0 % 84 0
Test Date: 2025-07-25 12:55:17 Functions: 0.0 % 5 0

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Environment storing all data that is needed in order to call the DFT
      10              : !>        driver of the PEXSI library with data from the linear scaling quickstep
      11              : !>        SCF environment, mainly parameters and intermediate data for the matrix
      12              : !>        conversion between DBCSR and CSR format.
      13              : !> \par History
      14              : !>       2014.11 created [Patrick Seewald]
      15              : !> \author Patrick Seewald
      16              : ! **************************************************************************************************
      17              : 
      18              : MODULE pexsi_types
      19              :    USE ISO_C_BINDING,                   ONLY: C_INTPTR_T
      20              :    USE bibliography,                    ONLY: Lin2009,&
      21              :                                               Lin2013,&
      22              :                                               cite_reference
      23              :    USE cp_dbcsr_api,                    ONLY: dbcsr_csr_type,&
      24              :                                               dbcsr_p_type,&
      25              :                                               dbcsr_scale,&
      26              :                                               dbcsr_type
      27              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      28              :                                               cp_logger_get_default_unit_nr,&
      29              :                                               cp_logger_type
      30              :    USE kinds,                           ONLY: dp
      31              :    USE message_passing,                 ONLY: mp_comm_type,&
      32              :                                               mp_dims_create
      33              :    USE pexsi_interface,                 ONLY: cp_pexsi_get_options,&
      34              :                                               cp_pexsi_options,&
      35              :                                               cp_pexsi_plan_finalize,&
      36              :                                               cp_pexsi_plan_initialize,&
      37              :                                               cp_pexsi_set_options
      38              : #include "./base/base_uses.f90"
      39              : 
      40              :    IMPLICIT NONE
      41              : 
      42              :    PRIVATE
      43              : 
      44              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pexsi_types'
      45              : 
      46              :    LOGICAL, PARAMETER, PRIVATE          :: careful_mod = .FALSE.
      47              : 
      48              :    INTEGER, PARAMETER, PUBLIC           :: cp2k_to_pexsi = 1, pexsi_to_cp2k = 2
      49              : 
      50              :    PUBLIC :: lib_pexsi_env, lib_pexsi_init, lib_pexsi_finalize, &
      51              :              convert_nspin_cp2k_pexsi
      52              : 
      53              : ! **************************************************************************************************
      54              : !> \brief All PEXSI related data
      55              : !> \param options                       PEXSI options
      56              : !> \param plan                          PEXSI plan
      57              : !> \param mp_group                      message-passing group ID
      58              : !> \param mp_dims                       dimensions of the MPI cartesian grid used
      59              : !>                                      for PEXSI
      60              : !> \param num_ranks_per_pole            number of MPI ranks per pole in PEXSI
      61              : !> \param kTS                           entropic energy contribution
      62              : !> \param matrix_w                      energy-weighted density matrix as needed
      63              : !>                                      for the forces
      64              : !> \param csr_mat                       intermediate matrices in CSR format
      65              : !> \param dbcsr_template_matrix_sym     Symmetric template matrix fixing DBCSR
      66              : !>                                      sparsity pattern
      67              : !> \param dbcsr_template_matrix_nonsym  Nonsymmetric template matrix fixing
      68              : !>                                      DBCSR sparsity pattern
      69              : !> \param csr_sparsity                  DBCSR matrix defining CSR sparsity
      70              : !> \param csr_screening                 whether distance screening should be
      71              : !>                                      applied to CSR matrices
      72              : !> \param max_ev_vector                 eigenvector corresponding to the largest
      73              : !>                                      energy eigenvalue,
      74              : !>                                      returned by the Arnoldi method used to
      75              : !>                                      determine the spectral radius deltaE
      76              : !> \param nspin                         number of spins
      77              : !> \param do_adaptive_tol_nel           Whether or not to use adaptive threshold
      78              : !>                                      for PEXSI convergence
      79              : !> \param adaptive_nel_alpha            constants for adaptive thresholding
      80              : !> \param adaptive_nel_beta             ...
      81              : !> \param tol_nel_initial               Initial convergence threshold (in number of electrons)
      82              : !> \param tol_nel_target                Target convergence threshold (in number of electrons)
      83              : !> \par History
      84              : !>      11.2014 created [Patrick Seewald]
      85              : !> \author Patrick Seewald
      86              : ! **************************************************************************************************
      87              :    TYPE lib_pexsi_env
      88              :       TYPE(dbcsr_type)                         :: dbcsr_template_matrix_sym = dbcsr_type(), &
      89              :                                                   dbcsr_template_matrix_nonsym = dbcsr_type()
      90              :       TYPE(dbcsr_csr_type)                     :: csr_mat_p = dbcsr_csr_type(), csr_mat_ks = dbcsr_csr_type(), &
      91              :                                                   csr_mat_s = dbcsr_csr_type(), csr_mat_E = dbcsr_csr_type(), &
      92              :                                                   csr_mat_F = dbcsr_csr_type()
      93              : #if defined(__PEXSI)
      94              :       TYPE(cp_pexsi_options)                   :: options
      95              : #else
      96              :       TYPE(cp_pexsi_options)                   :: options = cp_pexsi_options()
      97              : #endif
      98              :       REAL(KIND=dp), DIMENSION(:), POINTER     :: kTS => NULL()
      99              :       TYPE(dbcsr_p_type), DIMENSION(:), &
     100              :          POINTER                               :: matrix_w => NULL()
     101              :       INTEGER(KIND=C_INTPTR_T)                 :: plan = 0_C_INTPTR_T
     102              :       INTEGER                                  :: nspin = -1, num_ranks_per_pole = -1
     103              :       TYPE(mp_comm_type)                       :: mp_group = mp_comm_type()
     104              :       TYPE(dbcsr_type), DIMENSION(:), &
     105              :          POINTER                               :: max_ev_vector => NULL()
     106              :       TYPE(dbcsr_type)                         :: csr_sparsity = dbcsr_type()
     107              :       INTEGER, DIMENSION(2)                    :: mp_dims = -1
     108              : 
     109              :       LOGICAL                                  :: csr_screening = .FALSE., do_adaptive_tol_nel = .FALSE.
     110              :       REAL(KIND=dp)                            :: adaptive_nel_alpha = -1.0_dp, adaptive_nel_beta = -1.0_dp, &
     111              :                                                   tol_nel_initial = -1.0_dp, tol_nel_target = -1.0_dp
     112              :    END TYPE lib_pexsi_env
     113              : 
     114              : CONTAINS
     115              : 
     116              : ! **************************************************************************************************
     117              : !> \brief Initialize PEXSI
     118              : !> \param pexsi_env All data needed by PEXSI
     119              : !> \param mp_group message-passing group ID
     120              : !> \param nspin number of spins
     121              : !> \par History
     122              : !>      11.2014 created [Patrick Seewald]
     123              : !> \author Patrick Seewald
     124              : ! **************************************************************************************************
     125            0 :    SUBROUTINE lib_pexsi_init(pexsi_env, mp_group, nspin)
     126              :       TYPE(lib_pexsi_env), INTENT(INOUT)                 :: pexsi_env
     127              : 
     128              :       CLASS(mp_comm_type), INTENT(IN)                     :: mp_group
     129              :       INTEGER, INTENT(IN)                                :: nspin
     130              : 
     131              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'lib_pexsi_init'
     132              : 
     133              :       INTEGER                                            :: handle, ispin, npSymbFact, &
     134              :                                                             unit_nr
     135              :       TYPE(cp_logger_type), POINTER                      :: logger
     136              : 
     137            0 :       logger => cp_get_default_logger()
     138            0 :       IF (logger%para_env%is_source()) THEN
     139            0 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     140              :       ELSE
     141            0 :          unit_nr = -1
     142              :       END IF
     143              : 
     144            0 :       CALL timeset(routineN, handle)
     145              : 
     146            0 :       CALL cite_reference(Lin2009)
     147            0 :       CALL cite_reference(Lin2013)
     148              : 
     149            0 :       pexsi_env%mp_group = mp_group
     150              :       ASSOCIATE (numnodes => pexsi_env%mp_group%num_pe, mynode => pexsi_env%mp_group%mepos)
     151              : 
     152              :          ! Use all nodes available per pole by default or if the user tries to use
     153              :          ! more nodes than MPI size
     154              :          IF ((pexsi_env%num_ranks_per_pole .GT. numnodes) &
     155            0 :              .OR. (pexsi_env%num_ranks_per_pole .EQ. 0)) THEN
     156            0 :             pexsi_env%num_ranks_per_pole = numnodes
     157              :          END IF
     158              : 
     159              :          ! Find num_ranks_per_pole from user input MIN_RANKS_PER_POLE s.t. num_ranks_per_pole
     160              :          ! is the smallest number greater or equal to min_ranks_per_pole that divides
     161              :          ! MPI size without remainder.
     162            0 :          DO WHILE (MOD(numnodes, pexsi_env%num_ranks_per_pole) .NE. 0)
     163            0 :             pexsi_env%num_ranks_per_pole = pexsi_env%num_ranks_per_pole + 1
     164              :          END DO
     165              : 
     166            0 :          CALL cp_pexsi_get_options(pexsi_env%options, npSymbFact=npSymbFact)
     167            0 :          IF ((npSymbFact .GT. pexsi_env%num_ranks_per_pole) .OR. (npSymbFact .EQ. 0)) THEN
     168              :             ! Use maximum possible number of ranks for symbolic factorization
     169            0 :             CALL cp_pexsi_set_options(pexsi_env%options, npSymbFact=pexsi_env%num_ranks_per_pole)
     170              :          END IF
     171              : 
     172              :          ! Create dimensions for MPI cartesian grid for PEXSI
     173            0 :          pexsi_env%mp_dims = 0
     174            0 :          CALL mp_dims_create(pexsi_env%num_ranks_per_pole, pexsi_env%mp_dims)
     175              : 
     176              :          ! allocations with nspin
     177            0 :          pexsi_env%nspin = nspin
     178            0 :          ALLOCATE (pexsi_env%kTS(nspin))
     179            0 :          pexsi_env%kTS(:) = 0.0_dp
     180            0 :          ALLOCATE (pexsi_env%max_ev_vector(nspin))
     181            0 :          ALLOCATE (pexsi_env%matrix_w(nspin))
     182            0 :          DO ispin = 1, pexsi_env%nspin
     183            0 :             ALLOCATE (pexsi_env%matrix_w(ispin)%matrix)
     184              :          END DO
     185              : 
     186              :          ! Initialize PEXSI
     187              :          pexsi_env%plan = cp_pexsi_plan_initialize(pexsi_env%mp_group, pexsi_env%mp_dims(1), &
     188            0 :                                                    pexsi_env%mp_dims(2), mynode)
     189              :       END ASSOCIATE
     190              : 
     191            0 :       pexsi_env%do_adaptive_tol_nel = .FALSE.
     192              : 
     193              :       ! Print PEXSI infos
     194            0 :       IF (unit_nr > 0) CALL print_pexsi_info(pexsi_env, unit_nr)
     195              : 
     196            0 :       CALL timestop(handle)
     197            0 :    END SUBROUTINE lib_pexsi_init
     198              : 
     199              : ! **************************************************************************************************
     200              : !> \brief Release all PEXSI data
     201              : !> \param pexsi_env ...
     202              : !> \par History
     203              : !>      11.2014 created [Patrick Seewald]
     204              : !> \author Patrick Seewald
     205              : ! **************************************************************************************************
     206            0 :    SUBROUTINE lib_pexsi_finalize(pexsi_env)
     207              :       TYPE(lib_pexsi_env), INTENT(INOUT)                 :: pexsi_env
     208              : 
     209              :       CHARACTER(len=*), PARAMETER :: routineN = 'lib_pexsi_finalize'
     210              : 
     211              :       INTEGER                                            :: handle, ispin
     212              : 
     213            0 :       CALL timeset(routineN, handle)
     214            0 :       CALL cp_pexsi_plan_finalize(pexsi_env%plan)
     215            0 :       DEALLOCATE (pexsi_env%kTS)
     216            0 :       DEALLOCATE (pexsi_env%max_ev_vector)
     217            0 :       DO ispin = 1, pexsi_env%nspin
     218            0 :          DEALLOCATE (pexsi_env%matrix_w(ispin)%matrix)
     219              :       END DO
     220            0 :       DEALLOCATE (pexsi_env%matrix_w)
     221            0 :       CALL timestop(handle)
     222            0 :    END SUBROUTINE lib_pexsi_finalize
     223              : 
     224              : ! **************************************************************************************************
     225              : !> \brief Scale various quantities with factors of 2. This converts spin restricted
     226              : !>        DFT calculations (PEXSI) to the unrestricted case (as is the case where
     227              : !>        the density matrix method is called in the linear scaling code).
     228              : !> \param[in] direction ...
     229              : !> \param[in,out] numElectron ...
     230              : !> \param matrix_p ...
     231              : !> \param matrix_w ...
     232              : !> \param kTS ...
     233              : !> \par History
     234              : !>      01.2015 created [Patrick Seewald]
     235              : !> \author Patrick Seewald
     236              : ! **************************************************************************************************
     237            0 :    SUBROUTINE convert_nspin_cp2k_pexsi(direction, numElectron, matrix_p, matrix_w, kTS)
     238              :       INTEGER, INTENT(IN)                                :: direction
     239              :       REAL(KIND=dp), INTENT(INOUT), OPTIONAL             :: numElectron
     240              :       TYPE(dbcsr_type), INTENT(INOUT), OPTIONAL          :: matrix_p
     241              :       TYPE(dbcsr_p_type), INTENT(INOUT), OPTIONAL        :: matrix_w
     242              :       REAL(KIND=dp), INTENT(INOUT), OPTIONAL             :: kTS
     243              : 
     244              :       CHARACTER(len=*), PARAMETER :: routineN = 'convert_nspin_cp2k_pexsi'
     245              : 
     246              :       INTEGER                                            :: handle
     247              :       REAL(KIND=dp)                                      :: scaling
     248              : 
     249            0 :       CALL timeset(routineN, handle)
     250              : 
     251            0 :       SELECT CASE (direction)
     252              :       CASE (cp2k_to_pexsi)
     253            0 :          scaling = 2.0_dp
     254              :       CASE (pexsi_to_cp2k)
     255            0 :          scaling = 0.5_dp
     256              :       END SELECT
     257              : 
     258            0 :       IF (PRESENT(numElectron)) numElectron = scaling*numElectron
     259            0 :       IF (PRESENT(matrix_p)) CALL dbcsr_scale(matrix_p, scaling)
     260            0 :       IF (PRESENT(matrix_w)) CALL dbcsr_scale(matrix_w%matrix, scaling)
     261            0 :       IF (PRESENT(kTS)) kTS = scaling*kTS
     262              : 
     263            0 :       CALL timestop(handle)
     264            0 :    END SUBROUTINE convert_nspin_cp2k_pexsi
     265              : 
     266              : ! **************************************************************************************************
     267              : !> \brief Print relevant options of PEXSI
     268              : !> \param pexsi_env ...
     269              : !> \param unit_nr ...
     270              : ! **************************************************************************************************
     271            0 :    SUBROUTINE print_pexsi_info(pexsi_env, unit_nr)
     272              :       TYPE(lib_pexsi_env), INTENT(IN)                    :: pexsi_env
     273              :       INTEGER, INTENT(IN)                                :: unit_nr
     274              : 
     275              :       INTEGER                                            :: npSymbFact, numnodes, numPole, ordering, &
     276              :                                                             rowOrdering
     277              :       REAL(KIND=dp)                                      :: gap, muInertiaExpansion, &
     278              :                                                             muInertiaTolerance, muMax0, muMin0, &
     279              :                                                             muPEXSISafeGuard, temperature
     280              : 
     281            0 :       numnodes = pexsi_env%mp_group%num_pe
     282              : 
     283              :       CALL cp_pexsi_get_options(pexsi_env%options, temperature=temperature, gap=gap, &
     284              :                                 numPole=numPole, muMin0=muMin0, muMax0=muMax0, muInertiaTolerance= &
     285              :                                 muInertiaTolerance, muInertiaExpansion=muInertiaExpansion, &
     286              :                                 muPEXSISafeGuard=muPEXSISafeGuard, ordering=ordering, rowOrdering=rowOrdering, &
     287            0 :                                 npSymbFact=npSymbFact)
     288              : 
     289            0 :       WRITE (unit_nr, '(/A)') " PEXSI| Initialized with parameters"
     290            0 :       WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI|   Electronic temperature", temperature
     291            0 :       WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI|   Spectral gap", gap
     292            0 :       WRITE (unit_nr, '(A,T61,I20)') " PEXSI|   Number of poles", numPole
     293            0 :       WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI|   Target tolerance in number of electrons", &
     294            0 :          pexsi_env%tol_nel_target
     295            0 :       WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI|   Convergence tolerance for inertia counting in mu", &
     296            0 :          muInertiaTolerance
     297            0 :       WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI|   Restart tolerance for inertia counting in mu", &
     298            0 :          muPEXSISafeGuard
     299            0 :       WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI|   Expansion of mu interval for inertia counting", &
     300            0 :          muInertiaExpansion
     301              : 
     302            0 :       WRITE (unit_nr, '(/A)') " PEXSI| Parallelization scheme"
     303            0 :       WRITE (unit_nr, '(A,T61,I20)') " PEXSI|   Number of poles processed in parallel", &
     304            0 :          numnodes/pexsi_env%num_ranks_per_pole
     305            0 :       WRITE (unit_nr, '(A,T61,I20)') " PEXSI|   Number of processors per pole", &
     306            0 :          pexsi_env%num_ranks_per_pole
     307            0 :       WRITE (unit_nr, '(A,T71,I5,T76,I5)') " PEXSI|   Process grid dimensions", &
     308            0 :          pexsi_env%mp_dims(1), pexsi_env%mp_dims(2)
     309            0 :       SELECT CASE (ordering)
     310              :       CASE (0)
     311            0 :          WRITE (unit_nr, '(A,T61,A20)') " PEXSI|   Ordering strategy", "parallel"
     312              :       CASE (1)
     313            0 :          WRITE (unit_nr, '(A,T61,A20)') " PEXSI|   Ordering strategy", "sequential"
     314              :       CASE (2)
     315            0 :          WRITE (unit_nr, '(A,T61,A20)') " PEXSI|   Ordering strategy", "multiple minimum degree"
     316              :       END SELECT
     317            0 :       SELECT CASE (rowOrdering)
     318              :       CASE (0)
     319            0 :          WRITE (unit_nr, '(A,T61,A20)') " PEXSI|   Row permutation strategy", "no row permutation"
     320              :       CASE (1)
     321            0 :          WRITE (unit_nr, '(A,T61,A20)') " PEXSI|   Row permutation strategy", "make diagonal entry larger than off diagonal"
     322              :       END SELECT
     323            0 :       IF (ordering .EQ. 0) WRITE (unit_nr, '(A,T61,I20/)') &
     324            0 :          " PEXSI|   Number of processors for symbolic factorization", npSymbFact
     325              : 
     326            0 :    END SUBROUTINE print_pexsi_info
     327            0 : END MODULE pexsi_types
        

Generated by: LCOV version 2.0-1