127 POINTER :: particle_set
129 POINTER :: qs_kind_set
130 TYPE(cp_gauxc_status_type),
INTENT(inout) :: status
133 INTEGER :: gradient_error, unit_nr
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
149 cache%molecule = gauxc_create_molecule( &
152 IF (status%status%code /= 0)
THEN
153 CALL cleanup_after_molecule()
157 cache%basisset = gauxc_create_basisset( &
161 IF (status%status%code /= 0)
THEN
162 CALL cleanup_after_basisset()
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)
172 CALL cp_abort(__location__, &
173 "MODEL_GRADIENT_RUNTIME MPI requires verified GauXC OneDFT gradient support (PR #222).")
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.")
179 CALL cp_abort(__location__, &
180 "MODEL_GRADIENT_RUNTIME MPI is incompatible with FORCE_NUMERICAL_GRADIENT.")
182 CALL cp_abort(__location__,
"Unknown GAUXC%MODEL_GRADIENT_RUNTIME value.")
185 IF (params%use_fd_gradient .AND. .NOT. params%force_fd_gradient .AND. para_env%mepos == 0)
THEN
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.")
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)
201 IF (params%use_self_runtime .OR. .NOT. params%use_gauxc_model)
THEN
206 cache%grid = gauxc_create_grid( &
210 params%radial_quadrature, &
211 params%pruning_scheme, &
212 params%lb_exec_space, &
214 params%device_runtime_fill_fraction, &
217 force_new_runtime=.true.)
223 cache%grid = gauxc_create_grid( &
227 params%radial_quadrature, &
228 params%pruning_scheme, &
229 params%lb_exec_space, &
231 params%device_runtime_fill_fraction, &
233 mpi_comm=para_env%get_handle())
235 IF (status%status%code /= 0)
THEN
236 CALL cleanup_after_grid()
240 cache%integrator = gauxc_create_integrator( &
241 trim(params%xc_fun_name), &
243 params%int_exec_space, &
247 IF (status%status%code /= 0)
THEN
248 CALL cleanup_after_integrator()
252 IF (params%use_gradient_self_runtime)
THEN
255 cache%gradient_grid = gauxc_create_grid( &
259 params%radial_quadrature, &
260 params%pruning_scheme, &
261 params%lb_exec_space, &
263 params%device_runtime_fill_fraction, &
266 force_new_runtime=.true.)
267 IF (status%status%code /= 0)
THEN
268 CALL cleanup_after_gradient_grid()
271 cache%gradient_integrator = gauxc_create_integrator( &
272 trim(params%xc_fun_name), &
273 cache%gradient_grid, &
274 params%int_exec_space, &
278 IF (status%status%code /= 0)
THEN
279 CALL cleanup_after_gradient_integrator()
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)
309 ALLOCATE (cache%last_positions(3, params%natom))
313 DO iatom = 1, params%natom
314 cache%last_positions(:, iatom) = real(particle_set(iatom)%r(:), c_double)
318 cache%mpi_comm = para_env%get_handle()
319 cache%is_init = .true.
324 mark_used(particle_set)
325 mark_used(qs_kind_set)
327 cache%is_init = .false.
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
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
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
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
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
379 SUBROUTINE cleanup_after_molecule()
380 CALL gauxc_destroy_molecule(cache%molecule, status)
381 CALL gauxc_check_status(status)
383 END SUBROUTINE cleanup_after_molecule
388 SUBROUTINE cleanup_final()
389 IF (
ALLOCATED(cache%last_positions))
DEALLOCATE (cache%last_positions)
390 cache%is_init = .false.
391 END SUBROUTINE cleanup_final
448 TYPE(mp_para_env_type),
INTENT(in),
POINTER :: para_env
449 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
450 LOGICAL :: cache_valid
454 REAL(c_double),
PARAMETER :: pos_tol = 1.0e-8_c_double
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
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
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
491 mark_used(particle_set)
494 cache_valid = .false.