(git:33f85d8)
Loading...
Searching...
No Matches
pexsi_types.F
Go to the documentation of this file.
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
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,&
30 USE kinds, ONLY: dp
31 USE message_passing, ONLY: mp_comm_type,&
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
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! **************************************************************************************************
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(__LIBPEXSI)
94 TYPE(cp_pexsi_options) :: options
95#else
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
114CONTAINS
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 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 logger => cp_get_default_logger()
138 IF (logger%para_env%is_source()) THEN
139 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
140 ELSE
141 unit_nr = -1
142 END IF
143
144 CALL timeset(routinen, handle)
145
146 CALL cite_reference(lin2009)
147 CALL cite_reference(lin2013)
148
149 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 .OR. (pexsi_env%num_ranks_per_pole .EQ. 0)) THEN
156 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 DO WHILE (mod(numnodes, pexsi_env%num_ranks_per_pole) .NE. 0)
163 pexsi_env%num_ranks_per_pole = pexsi_env%num_ranks_per_pole + 1
164 END DO
165
166 CALL cp_pexsi_get_options(pexsi_env%options, npsymbfact=npsymbfact)
167 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 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 pexsi_env%mp_dims = 0
174 CALL mp_dims_create(pexsi_env%num_ranks_per_pole, pexsi_env%mp_dims)
175
176 ! allocations with nspin
177 pexsi_env%nspin = nspin
178 ALLOCATE (pexsi_env%kTS(nspin))
179 pexsi_env%kTS(:) = 0.0_dp
180 ALLOCATE (pexsi_env%max_ev_vector(nspin))
181 ALLOCATE (pexsi_env%matrix_w(nspin))
182 DO ispin = 1, pexsi_env%nspin
183 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 pexsi_env%mp_dims(2), mynode)
189 END associate
190
191 pexsi_env%do_adaptive_tol_nel = .false.
192
193 ! Print PEXSI infos
194 IF (unit_nr > 0) CALL print_pexsi_info(pexsi_env, unit_nr)
195
196 CALL timestop(handle)
197 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 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 CALL timeset(routinen, handle)
214 CALL cp_pexsi_plan_finalize(pexsi_env%plan)
215 DEALLOCATE (pexsi_env%kTS)
216 DEALLOCATE (pexsi_env%max_ev_vector)
217 DO ispin = 1, pexsi_env%nspin
218 DEALLOCATE (pexsi_env%matrix_w(ispin)%matrix)
219 END DO
220 DEALLOCATE (pexsi_env%matrix_w)
221 CALL timestop(handle)
222 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 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 CALL timeset(routinen, handle)
250
251 SELECT CASE (direction)
252 CASE (cp2k_to_pexsi)
253 scaling = 2.0_dp
254 CASE (pexsi_to_cp2k)
255 scaling = 0.5_dp
256 END SELECT
257
258 IF (PRESENT(numelectron)) numelectron = scaling*numelectron
259 IF (PRESENT(matrix_p)) CALL dbcsr_scale(matrix_p, scaling)
260 IF (PRESENT(matrix_w)) CALL dbcsr_scale(matrix_w%matrix, scaling)
261 IF (PRESENT(kts)) kts = scaling*kts
262
263 CALL timestop(handle)
264 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 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 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 npsymbfact=npsymbfact)
288
289 WRITE (unit_nr, '(/A)') " PEXSI| Initialized with parameters"
290 WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI| Electronic temperature", temperature
291 WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI| Spectral gap", gap
292 WRITE (unit_nr, '(A,T61,I20)') " PEXSI| Number of poles", numpole
293 WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI| Target tolerance in number of electrons", &
294 pexsi_env%tol_nel_target
295 WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI| Convergence tolerance for inertia counting in mu", &
296 muinertiatolerance
297 WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI| Restart tolerance for inertia counting in mu", &
298 mupexsisafeguard
299 WRITE (unit_nr, '(A,T61,E20.3)') " PEXSI| Expansion of mu interval for inertia counting", &
300 muinertiaexpansion
301
302 WRITE (unit_nr, '(/A)') " PEXSI| Parallelization scheme"
303 WRITE (unit_nr, '(A,T61,I20)') " PEXSI| Number of poles processed in parallel", &
304 numnodes/pexsi_env%num_ranks_per_pole
305 WRITE (unit_nr, '(A,T61,I20)') " PEXSI| Number of processors per pole", &
306 pexsi_env%num_ranks_per_pole
307 WRITE (unit_nr, '(A,T71,I5,T76,I5)') " PEXSI| Process grid dimensions", &
308 pexsi_env%mp_dims(1), pexsi_env%mp_dims(2)
309 SELECT CASE (ordering)
310 CASE (0)
311 WRITE (unit_nr, '(A,T61,A20)') " PEXSI| Ordering strategy", "parallel"
312 CASE (1)
313 WRITE (unit_nr, '(A,T61,A20)') " PEXSI| Ordering strategy", "sequential"
314 CASE (2)
315 WRITE (unit_nr, '(A,T61,A20)') " PEXSI| Ordering strategy", "multiple minimum degree"
316 END SELECT
317 SELECT CASE (rowordering)
318 CASE (0)
319 WRITE (unit_nr, '(A,T61,A20)') " PEXSI| Row permutation strategy", "no row permutation"
320 CASE (1)
321 WRITE (unit_nr, '(A,T61,A20)') " PEXSI| Row permutation strategy", "make diagonal entry larger than off diagonal"
322 END SELECT
323 IF (ordering .EQ. 0) WRITE (unit_nr, '(A,T61,I20/)') &
324 " PEXSI| Number of processors for symbolic factorization", npsymbfact
325
326 END SUBROUTINE print_pexsi_info
327END MODULE pexsi_types
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public lin2009
integer, save, public lin2013
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
subroutine, public mp_dims_create(nodes, dims)
wrapper to MPI_Dims_create
Interface to the PEXSI library, providing wrappers for all PEXSI routines that are called inside CP2K...
subroutine, public cp_pexsi_set_options(pexsi_options, temperature, gap, deltae, numpole, isinertiacount, maxpexsiiter, mumin0, mumax0, mu0, muinertiatolerance, muinertiaexpansion, mupexsisafeguard, numelectronpexsitolerance, matrixtype, issymbolicfactorize, ordering, rowordering, npsymbfact, verbosity)
Set PEXSI internal options.
subroutine, public cp_pexsi_get_options(pexsi_options, temperature, gap, deltae, numpole, isinertiacount, maxpexsiiter, mumin0, mumax0, mu0, muinertiatolerance, muinertiaexpansion, mupexsisafeguard, numelectronpexsitolerance, matrixtype, issymbolicfactorize, ordering, rowordering, npsymbfact, verbosity)
Access PEXSI internal options.
subroutine, public cp_pexsi_plan_finalize(plan)
...
integer(kind=c_intptr_t) function, public cp_pexsi_plan_initialize(comm, numprocrow, numproccol, outputfileindex)
...
Environment storing all data that is needed in order to call the DFT driver of the PEXSI library with...
Definition pexsi_types.F:18
subroutine, public convert_nspin_cp2k_pexsi(direction, numelectron, matrix_p, matrix_w, kts)
Scale various quantities with factors of 2. This converts spin restricted DFT calculations (PEXSI) to...
integer, parameter, public cp2k_to_pexsi
Definition pexsi_types.F:48
subroutine, public lib_pexsi_init(pexsi_env, mp_group, nspin)
Initialize PEXSI.
integer, parameter, public pexsi_to_cp2k
Definition pexsi_types.F:48
subroutine, public lib_pexsi_finalize(pexsi_env)
Release all PEXSI data.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
All PEXSI related data.
Definition pexsi_types.F:87