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 : MODULE xc_gauxc_gradient_policy
9 : IMPLICIT NONE
10 : PRIVATE
11 :
12 : #if defined(__GAUXC) && defined(__GAUXC_ONEDFT_GRADIENT_FIX)
13 : LOGICAL, PARAMETER :: gauxc_has_onedft_gradient_fix = .TRUE.
14 : #else
15 : LOGICAL, PARAMETER :: gauxc_has_onedft_gradient_fix = .FALSE.
16 : #endif
17 :
18 : PUBLIC :: gauxc_has_onedft_gradient_fix, gauxc_resolve_gradient_policy
19 :
20 : CONTAINS
21 :
22 : ! **************************************************************************************************
23 : !> \brief Select molecular XC gradients without changing the energy/VXC runtime.
24 : !> \param need_gradient Whether forces or a molecular virial are requested
25 : !> \param gapw_method Whether the calculation uses GAPW or GAPW_XC
26 : !> \param max_l Largest angular momentum in the basis
27 : !> \param is_model Whether a OneDFT model is used
28 : !> \param nranks Size of the force-evaluation communicator
29 : !> \param energy_self Whether energy/VXC uses replicated rank-local runtimes
30 : !> \param runtime Requested AUTO, SELF or MPI gradient runtime
31 : !> \param force_fd Force finite differences for diagnostics
32 : !> \param use_fd Selected finite-difference route
33 : !> \param use_mpi Selected distributed analytical route
34 : !> \param use_self Whether a separate rank-local gradient runtime is required
35 : !> \param error Zero on success; nonzero for an unsupported explicit request
36 : ! **************************************************************************************************
37 82 : PURE SUBROUTINE gauxc_resolve_gradient_policy(need_gradient, gapw_method, max_l, is_model, nranks, &
38 : energy_self, runtime, force_fd, use_fd, use_mpi, use_self, error)
39 : LOGICAL, INTENT(IN) :: need_gradient, gapw_method
40 : INTEGER, INTENT(IN) :: max_l
41 : LOGICAL, INTENT(IN) :: is_model
42 : INTEGER, INTENT(IN) :: nranks
43 : LOGICAL, INTENT(IN) :: energy_self
44 : CHARACTER(LEN=*), INTENT(IN) :: runtime
45 : LOGICAL, INTENT(IN) :: force_fd
46 : LOGICAL, INTENT(OUT) :: use_fd, use_mpi, use_self
47 : INTEGER, INTENT(OUT) :: error
48 :
49 82 : use_fd = .FALSE.
50 82 : use_mpi = .FALSE.
51 82 : use_self = .FALSE.
52 82 : error = 0
53 82 : IF (.NOT. need_gradient) RETURN
54 :
55 : ! PR #222 fixes OneDFT, not the separate conventional-functional path.
56 : use_fd = force_fd .OR. (gapw_method .AND. max_l > 3 .AND. &
57 14 : .NOT. (is_model .AND. gauxc_has_onedft_gradient_fix))
58 14 : IF (.NOT. is_model .OR. nranks <= 1) RETURN
59 :
60 2 : SELECT CASE (runtime)
61 : CASE ("AUTO")
62 2 : use_mpi = gauxc_has_onedft_gradient_fix .AND. .NOT. energy_self .AND. .NOT. use_fd
63 4 : use_self = .NOT. energy_self .AND. .NOT. use_mpi .AND. .NOT. use_fd
64 : CASE ("SELF")
65 6 : use_self = .NOT. energy_self .AND. .NOT. use_fd
66 : CASE ("MPI")
67 0 : IF (.NOT. gauxc_has_onedft_gradient_fix) THEN
68 : error = 1
69 0 : ELSE IF (energy_self) THEN
70 0 : error = 2
71 0 : ELSE IF (use_fd) THEN
72 0 : error = 3
73 : ELSE
74 0 : use_mpi = .TRUE.
75 : END IF
76 : CASE DEFAULT
77 8 : error = 4
78 : END SELECT
79 : END SUBROUTINE gauxc_resolve_gradient_policy
80 :
81 : END MODULE xc_gauxc_gradient_policy
|