(git:08825b9)
Loading...
Searching...
No Matches
xc_gauxc_cache.F
Go to the documentation of this file.
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#ifdef __GAUXC
9#include "gauxc/gauxc_config.f"
10#endif
11
13
15 USE iso_c_binding, ONLY: c_double
16 USE kinds, ONLY: default_path_length,&
18 USE message_passing, ONLY: mp_comm_self,&
23 USE xc_gauxc_interface, ONLY: &
24 cp_gauxc_basisset_type, cp_gauxc_grid_type, cp_gauxc_integrator_type, &
25 cp_gauxc_molecule_type, cp_gauxc_status_type, gauxc_check_status, gauxc_create_basisset, &
26 gauxc_create_grid, gauxc_create_integrator, gauxc_create_molecule, gauxc_destroy_basisset, &
27 gauxc_destroy_grid, gauxc_destroy_integrator, gauxc_destroy_molecule
28#include "../base/base_uses.f90"
29
30 IMPLICIT NONE
31 PRIVATE
32
34 INTEGER :: natom = -1
35 INTEGER :: nspins = -1
36 INTEGER :: batch_size = -1
37 REAL(c_double) :: device_runtime_fill_fraction = 0.0_c_double
38 CHARACTER(LEN=default_string_length) :: xc_fun_name = ""
39 CHARACTER(LEN=default_string_length) :: grid_type = ""
40 CHARACTER(LEN=default_string_length) :: radial_quadrature = ""
41 CHARACTER(LEN=default_string_length) :: pruning_scheme = ""
42 CHARACTER(LEN=default_string_length) :: lb_exec_space = ""
43 CHARACTER(LEN=default_string_length) :: int_exec_space = ""
44 CHARACTER(LEN=default_path_length) :: model_eval_name = ""
45 CHARACTER(len=default_string_length) :: lwd_kernel = ""
46 CHARACTER(len=default_string_length) :: gradient_runtime = "AUTO"
47 LOGICAL :: need_xc_gradient = .false.
48 LOGICAL :: gapw_method = .false.
49 LOGICAL :: force_fd_gradient = .false.
50 LOGICAL :: use_mpi_runtime = .false.
51 LOGICAL :: use_gradient_mpi_runtime = .false.
52 LOGICAL :: use_self_runtime = .false.
53 LOGICAL :: use_gradient_self_runtime = .false.
54 LOGICAL :: use_fd_gradient = .false.
55 LOGICAL :: use_gauxc_model = .false.
57
59 TYPE(cp_gauxc_molecule_type) :: molecule = cp_gauxc_molecule_type()
60 TYPE(cp_gauxc_basisset_type) :: basisset = cp_gauxc_basisset_type()
61 TYPE(cp_gauxc_grid_type) :: grid = cp_gauxc_grid_type()
62 TYPE(cp_gauxc_grid_type) :: gradient_grid = cp_gauxc_grid_type()
63 TYPE(cp_gauxc_integrator_type) :: integrator = cp_gauxc_integrator_type()
64 TYPE(cp_gauxc_integrator_type) :: gradient_integrator = cp_gauxc_integrator_type()
65 INTEGER :: mpi_comm = -1
66 LOGICAL :: is_init = .false.
67 REAL(c_double), DIMENSION(:, :), ALLOCATABLE :: last_positions
68 CONTAINS
69
70 PROCEDURE, PUBLIC :: needs_gradient_grid => gauxc_cache_type_needs_gradient_grid
71 PROCEDURE, PUBLIC :: max_l => gauxc_cache_type_max_l
72 END TYPE cp_gauxc_cache_type
73
74 PUBLIC :: &
79
80CONTAINS
81
82! **************************************************************************************************
83!> \brief ...
84!> \param this ...
85!> \return ...
86! **************************************************************************************************
87 FUNCTION gauxc_cache_type_needs_gradient_grid(this) RESULT(res)
88 class(cp_gauxc_cache_type) :: this
89 LOGICAL :: res
90
91 res = this%use_gradient_self_runtime
93
94! **************************************************************************************************
95!> \brief ...
96!> \param this ...
97!> \return ...
98! **************************************************************************************************
99 FUNCTION gauxc_cache_type_max_l(this) RESULT(res)
100 class(cp_gauxc_cache_type) :: this
101 INTEGER :: res
102
103 res = this%basisset%max_l
104 END FUNCTION gauxc_cache_type_max_l
105
106! **************************************************************************************************
107!> \brief ...
108!> \param cache ...
109!> \param params ...
110!> \param para_env ...
111!> \param particle_set ...
112!> \param qs_kind_set ...
113!> \param status ...
114! **************************************************************************************************
115 SUBROUTINE gauxc_cache_init( &
116 cache, &
117 params, &
118 para_env, &
119 particle_set, &
120 qs_kind_set, &
121 status)
122
123 TYPE(cp_gauxc_cache_type), INTENT(inout) :: cache
124 TYPE(cp_gauxc_cache_params), INTENT(inout) :: params
125 TYPE(mp_para_env_type), INTENT(in), POINTER :: para_env
126 TYPE(particle_type), DIMENSION(:), INTENT(in), &
127 POINTER :: particle_set
128 TYPE(qs_kind_type), DIMENSION(:), INTENT(in), &
129 POINTER :: qs_kind_set
130 TYPE(cp_gauxc_status_type), INTENT(inout) :: status
131
132#ifdef __GAUXC
133 INTEGER :: gradient_error, unit_nr
134
136 cache, &
137 params, &
138 para_env, &
139 particle_set)) THEN
140 params%use_fd_gradient = cache%use_fd_gradient
141 params%use_gradient_mpi_runtime = cache%use_gradient_mpi_runtime
142 params%use_gradient_self_runtime = cache%use_gradient_self_runtime
143 status%status%code = 0
144 RETURN
145 END IF
146
147 CALL gauxc_cache_release(cache)
148
149 cache%molecule = gauxc_create_molecule( &
150 particle_set, &
151 status)
152 IF (status%status%code /= 0) THEN
153 CALL cleanup_after_molecule()
154 RETURN
155 END IF
156
157 cache%basisset = gauxc_create_basisset( &
158 qs_kind_set, &
159 particle_set, &
160 status)
161 IF (status%status%code /= 0) THEN
162 CALL cleanup_after_basisset()
163 RETURN
164 END IF
165
167 params%need_xc_gradient, params%gapw_method, cache%max_l(), params%use_gauxc_model, para_env%num_pe, &
168 params%use_self_runtime, trim(params%gradient_runtime), params%force_fd_gradient, &
169 params%use_fd_gradient, params%use_gradient_mpi_runtime, params%use_gradient_self_runtime, gradient_error)
170 SELECT CASE (gradient_error)
171 CASE (1)
172 CALL cp_abort(__location__, &
173 "MODEL_GRADIENT_RUNTIME MPI requires verified GauXC OneDFT gradient support (PR #222).")
174 CASE (2)
175 CALL cp_abort(__location__, &
176 "MODEL_GRADIENT_RUNTIME MPI requires an MPI energy/VXC runtime. "// &
177 "Use AUTO/SELF to retain the open-shell replicated-runtime safeguard.")
178 CASE (3)
179 CALL cp_abort(__location__, &
180 "MODEL_GRADIENT_RUNTIME MPI is incompatible with FORCE_NUMERICAL_GRADIENT.")
181 CASE (4)
182 CALL cp_abort(__location__, "Unknown GAUXC%MODEL_GRADIENT_RUNTIME value.")
183 END SELECT
184
185 IF (params%use_fd_gradient .AND. .NOT. params%force_fd_gradient .AND. para_env%mepos == 0) THEN
186 CALL cp_warn( &
187 __location__, &
188 "Using finite-difference GauXC XC gradients for METHOD GAPW/GAPW_XC with "// &
189 "basis functions beyond f shells. Analytical high-l gradients have not been "// &
190 "enabled for this GauXC installation and functional path.")
191 END IF
192 IF (params%need_xc_gradient .AND. para_env%mepos == 0) THEN
194 IF (unit_nr > 0) THEN
195 WRITE (unit_nr, '(A,A)') " GAUXC| Molecular XC gradient method: ", &
196 trim(merge("FD ", "ANALYTICAL", params%use_fd_gradient))
197 WRITE (unit_nr, '(A,A)') " GAUXC| Molecular XC gradient runtime: ", &
198 merge("MPI ", "SELF", params%use_gradient_mpi_runtime)
199 END IF
200 END IF
201 IF (params%use_self_runtime .OR. .NOT. params%use_gauxc_model) THEN
202 ! SKALA currently needs a replicated molecular runtime for reproducible
203 ! open-shell densities across CP2K MPI ranks.
204 ! Conventional GauXC also uses a replicated runtime here: CP2K has
205 ! already allreduced the dense AO density matrix on every rank.
206 cache%grid = gauxc_create_grid( &
207 cache%molecule, &
208 cache%basisset, &
209 params%grid_type, &
210 params%radial_quadrature, &
211 params%pruning_scheme, &
212 params%lb_exec_space, &
213 params%batch_size, &
214 params%device_runtime_fill_fraction, &
215 status, &
216 mpi_comm=mp_comm_self%get_handle(), &
217 force_new_runtime=.true.)
218 ELSE
219 ! Use the QS force-evaluation communicator rather than GauXC's global
220 ! runtime. In mixed CDFT the diabatic states can be built on disjoint
221 ! MPI subgroups; using the global communicator would make GauXC wait
222 ! for ranks that are working on another state.
223 cache%grid = gauxc_create_grid( &
224 cache%molecule, &
225 cache%basisset, &
226 params%grid_type, &
227 params%radial_quadrature, &
228 params%pruning_scheme, &
229 params%lb_exec_space, &
230 params%batch_size, &
231 params%device_runtime_fill_fraction, &
232 status, &
233 mpi_comm=para_env%get_handle())
234 END IF
235 IF (status%status%code /= 0) THEN
236 CALL cleanup_after_grid()
237 RETURN
238 END IF
239
240 cache%integrator = gauxc_create_integrator( &
241 trim(params%xc_fun_name), &
242 cache%grid, &
243 params%int_exec_space, &
244 params%lwd_kernel, &
245 params%nspins, &
246 status)
247 IF (status%status%code /= 0) THEN
248 CALL cleanup_after_integrator()
249 RETURN
250 END IF
251
252 IF (params%use_gradient_self_runtime) THEN
253 ! Retain the energy/VXC runtime when SELF is requested or the external
254 ! GauXC installation has not advertised corrected distributed gradients.
255 cache%gradient_grid = gauxc_create_grid( &
256 cache%molecule, &
257 cache%basisset, &
258 params%grid_type, &
259 params%radial_quadrature, &
260 params%pruning_scheme, &
261 params%lb_exec_space, &
262 params%batch_size, &
263 params%device_runtime_fill_fraction, &
264 status, &
265 mpi_comm=mp_comm_self%get_handle(), &
266 force_new_runtime=.true.)
267 IF (status%status%code /= 0) THEN
268 CALL cleanup_after_gradient_grid()
269 RETURN
270 END IF
271 cache%gradient_integrator = gauxc_create_integrator( &
272 trim(params%xc_fun_name), &
273 cache%gradient_grid, &
274 params%int_exec_space, &
275 params%lwd_kernel, &
276 params%nspins, &
277 status)
278 IF (status%status%code /= 0) THEN
279 CALL cleanup_after_gradient_integrator()
280 RETURN
281 END IF
282 END IF
283
284 cache%natom = params%natom
285 cache%nspins = params%nspins
286 cache%batch_size = params%batch_size
287 cache%device_runtime_fill_fraction = real(params%device_runtime_fill_fraction, c_double)
288 cache%xc_fun_name = trim(params%xc_fun_name)
289 cache%grid_type = trim(params%grid_type)
290 cache%radial_quadrature = trim(params%radial_quadrature)
291 cache%pruning_scheme = trim(params%pruning_scheme)
292 cache%lb_exec_space = trim(params%lb_exec_space)
293 cache%int_exec_space = trim(params%int_exec_space)
294 cache%model_eval_name = trim(params%model_eval_name)
295 cache%lwd_kernel = trim(params%lwd_kernel)
296 cache%gradient_runtime = params%gradient_runtime
297 cache%need_xc_gradient = params%need_xc_gradient
298 cache%gapw_method = params%gapw_method
299 cache%force_fd_gradient = params%force_fd_gradient
300 cache%use_gauxc_model = params%use_gauxc_model
301 cache%use_gradient_mpi_runtime = params%use_gradient_mpi_runtime
302 cache%use_mpi_runtime = params%use_mpi_runtime
303 cache%use_gradient_self_runtime = params%use_gradient_self_runtime
304 cache%use_self_runtime = params%use_self_runtime
305 cache%use_fd_gradient = params%use_fd_gradient
306 IF (ALLOCATED(cache%last_positions)) THEN
307 DEALLOCATE (cache%last_positions)
308 END IF
309 ALLOCATE (cache%last_positions(3, params%natom))
310
311 block
312 INTEGER :: iatom
313 DO iatom = 1, params%natom
314 cache%last_positions(:, iatom) = real(particle_set(iatom)%r(:), c_double)
315 END DO
316 END block
317
318 cache%mpi_comm = para_env%get_handle()
319 cache%is_init = .true.
320
321#else
322 mark_used(params)
323 mark_used(para_env)
324 mark_used(particle_set)
325 mark_used(qs_kind_set)
326 mark_used(status)
327 cache%is_init = .false.
328#endif
329
330 CONTAINS
331! **************************************************************************************************
332!> \brief ...
333! **************************************************************************************************
334 SUBROUTINE cleanup_after_gradient_integrator()
335 CALL gauxc_destroy_integrator(cache%gradient_integrator, status)
336 CALL gauxc_check_status(status)
337 CALL cleanup_after_gradient_grid()
338 END SUBROUTINE cleanup_after_gradient_integrator
339
340! **************************************************************************************************
341!> \brief ...
342! **************************************************************************************************
343 SUBROUTINE cleanup_after_gradient_grid()
344 CALL gauxc_destroy_grid(cache%gradient_grid, status)
345 CALL gauxc_check_status(status)
346 CALL cleanup_after_integrator()
347 END SUBROUTINE cleanup_after_gradient_grid
348
349! **************************************************************************************************
350!> \brief ...
351! **************************************************************************************************
352 SUBROUTINE cleanup_after_integrator()
353 CALL gauxc_destroy_integrator(cache%integrator, status)
354 CALL gauxc_check_status(status)
355 CALL cleanup_after_grid()
356 END SUBROUTINE cleanup_after_integrator
357
358! **************************************************************************************************
359!> \brief ...
360! **************************************************************************************************
361 SUBROUTINE cleanup_after_grid()
362 CALL gauxc_destroy_grid(cache%grid, status)
363 CALL gauxc_check_status(status)
364 CALL cleanup_after_basisset()
365 END SUBROUTINE cleanup_after_grid
366
367! **************************************************************************************************
368!> \brief ...
369! **************************************************************************************************
370 SUBROUTINE cleanup_after_basisset()
371 CALL gauxc_destroy_basisset(cache%basisset, status)
372 CALL gauxc_check_status(status)
373 CALL cleanup_after_molecule()
374 END SUBROUTINE cleanup_after_basisset
375
376! **************************************************************************************************
377!> \brief ...
378! **************************************************************************************************
379 SUBROUTINE cleanup_after_molecule()
380 CALL gauxc_destroy_molecule(cache%molecule, status)
381 CALL gauxc_check_status(status)
382 CALL cleanup_final()
383 END SUBROUTINE cleanup_after_molecule
384
385! **************************************************************************************************
386!> \brief ...
387! **************************************************************************************************
388 SUBROUTINE cleanup_final()
389 IF (ALLOCATED(cache%last_positions)) DEALLOCATE (cache%last_positions)
390 cache%is_init = .false.
391 END SUBROUTINE cleanup_final
392
393 END SUBROUTINE gauxc_cache_init
394
395! **************************************************************************************************
396!> \brief Release all GauXC objects in a cache and deallocate arrays
397!> \param cache ...
398! **************************************************************************************************
399 SUBROUTINE gauxc_cache_release(cache)
400 TYPE(cp_gauxc_cache_type), INTENT(INOUT) :: cache
401
402#ifdef __GAUXC
403 TYPE(cp_gauxc_status_type) :: status
404
405 IF (cache%is_init) THEN
406 IF (cache%needs_gradient_grid()) THEN
407 CALL gauxc_destroy_integrator(cache%gradient_integrator, status)
408 CALL gauxc_check_status(status)
409 CALL gauxc_destroy_grid(cache%gradient_grid, status)
410 CALL gauxc_check_status(status)
411 END IF
412 CALL gauxc_destroy_integrator(cache%integrator, status)
413 CALL gauxc_check_status(status)
414 CALL gauxc_destroy_grid(cache%grid, status)
415 CALL gauxc_check_status(status)
416 CALL gauxc_destroy_basisset(cache%basisset, status)
417 CALL gauxc_check_status(status)
418 CALL gauxc_destroy_molecule(cache%molecule, status)
419 CALL gauxc_check_status(status)
420 END IF
421 IF (ALLOCATED(cache%last_positions)) DEALLOCATE (cache%last_positions)
422 cache%is_init = .false.
423#else
424 mark_used(cache)
425 IF (ALLOCATED(cache%last_positions)) DEALLOCATE (cache%last_positions)
426 cache%is_init = .false.
427#endif
428 END SUBROUTINE gauxc_cache_release
429
430! **************************************************************************************************
431!> \brief Check if the GauXC cache is valid for the given parameters
432!> \param cache ...
433!> \param params ...
434!> \param para_env ...
435!> \param particle_set ...
436!> \return ...
437!> \retval cache_valid ...
438! **************************************************************************************************
440 cache, &
441 params, &
442 para_env, &
443 particle_set) &
444 result(cache_valid)
445
446 TYPE(cp_gauxc_cache_type), INTENT(IN) :: cache
447 TYPE(cp_gauxc_cache_params), INTENT(in) :: params
448 TYPE(mp_para_env_type), INTENT(in), POINTER :: para_env
449 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
450 LOGICAL :: cache_valid
451
452#ifdef __GAUXC
453 INTEGER :: iatom
454 REAL(c_double), PARAMETER :: pos_tol = 1.0e-8_c_double
455
456 cache_valid = .false.
457 IF (.NOT. cache%is_init) RETURN
458 IF (cache%natom /= params%natom) RETURN
459 IF (cache%nspins /= params%nspins) RETURN
460 IF (cache%batch_size /= params%batch_size) RETURN
461 IF (abs(cache%device_runtime_fill_fraction - real(params%device_runtime_fill_fraction, c_double)) > &
462 1.0e-10_c_double) RETURN
463 IF (trim(cache%xc_fun_name) /= trim(params%xc_fun_name)) RETURN
464 IF (trim(cache%grid_type) /= trim(params%grid_type)) RETURN
465 IF (trim(cache%radial_quadrature) /= trim(params%radial_quadrature)) RETURN
466 IF (trim(cache%pruning_scheme) /= trim(params%pruning_scheme)) RETURN
467 IF (trim(cache%lb_exec_space) /= trim(params%lb_exec_space)) RETURN
468 IF (trim(cache%int_exec_space) /= trim(params%int_exec_space)) RETURN
469 IF (trim(cache%model_eval_name) /= trim(params%model_eval_name)) RETURN
470 IF (trim(cache%lwd_kernel) /= trim(params%lwd_kernel)) RETURN
471 IF (cache%use_self_runtime .NEQV. params%use_self_runtime) RETURN
472 IF (cache%use_mpi_runtime .NEQV. params%use_mpi_runtime) RETURN
473
474 ! Compare requests, not flags resolved from the basis during initialization.
475 IF (cache%gradient_runtime /= params%gradient_runtime) RETURN
476 IF (cache%need_xc_gradient .NEQV. params%need_xc_gradient) RETURN
477 IF (cache%gapw_method .NEQV. params%gapw_method) RETURN
478 IF (cache%force_fd_gradient .NEQV. params%force_fd_gradient) RETURN
479 IF (cache%use_gauxc_model .NEQV. params%use_gauxc_model) RETURN
480 IF (cache%mpi_comm /= para_env%get_handle()) RETURN
481
482 IF (.NOT. ALLOCATED(cache%last_positions)) RETURN
483 IF (SIZE(cache%last_positions, 2) /= params%natom) RETURN
484 DO iatom = 1, params%natom
485 IF (any(abs(cache%last_positions(:, iatom) - &
486 REAL(particle_set(iatom)%r(:), c_double)) > pos_tol)) return
487 END DO
488 cache_valid = .true.
489#else
490 mark_used(cache)
491 mark_used(particle_set)
492 mark_used(params)
493 mark_used(para_env)
494 cache_valid = .false.
495#endif
496 END FUNCTION gauxc_cache_is_valid
497
498END MODULE xc_gauxc_cache
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
Provides integrator routines (velocity verlet) for all the ensemble types.
Definition integrator.F:26
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
Interface to the message passing library MPI.
type(mp_comm_type), parameter, public mp_comm_self
Define the data structure for the particle information.
Define the quickstep kind type and their sub types.
subroutine, public gauxc_cache_init(cache, params, para_env, particle_set, qs_kind_set, status)
...
logical function gauxc_cache_type_needs_gradient_grid(this)
...
logical function, public gauxc_cache_is_valid(cache, params, para_env, particle_set)
Check if the GauXC cache is valid for the given parameters.
subroutine, public gauxc_cache_release(cache)
Release all GauXC objects in a cache and deallocate arrays.
pure subroutine, public gauxc_resolve_gradient_policy(need_gradient, gapw_method, max_l, is_model, nranks, energy_self, runtime, force_fd, use_fd, use_mpi, use_self, error)
Select molecular XC gradients without changing the energy/VXC runtime.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.