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 : ! **************************************************************************************************
9 : !> \brief Module with functions to handle derivative descriptors.
10 : !> derivative description are strings have the following form
11 : !> "rhorhorhoa" which means that it is a forth order
12 : !> derivative, twice with respect to rho, once with respect to rhoa
13 : !> and once with respect to drhoa.
14 : !> Possible derivatives are:
15 : !> - rho: total density
16 : !> - norm_drho: norm of the gradient of the total density
17 : !> - rhoa, rhob: alpha and beta spin density (with LSD)
18 : !> - norm_drhoa, norm_drhob: norm of the gradient of the alpha and beta
19 : !> spin density
20 : !> - tau: the local kinetic part
21 : !> - taua, taub: the kinetic part of the different spins
22 : !> \note
23 : !> add drhox, drhoy, drhoz, drhoax,...?
24 : !> \author thomas & fawzi
25 : ! **************************************************************************************************
26 : MODULE xc_derivative_desc
27 :
28 : USE util, ONLY: sort
29 : #include "../base/base_uses.f90"
30 :
31 : IMPLICIT NONE
32 :
33 : PRIVATE
34 :
35 : INTEGER, PARAMETER, PUBLIC :: &
36 : deriv_rho = 1, &
37 : deriv_rhoa = 2, &
38 : deriv_rhob = 3, &
39 : deriv_norm_drho = 4, &
40 : deriv_norm_drhoa = 5, &
41 : deriv_norm_drhob = 6, &
42 : deriv_tau = 7, &
43 : deriv_tau_a = 8, &
44 : deriv_tau_b = 9, &
45 : deriv_laplace_rho = 10, &
46 : deriv_laplace_rhoa = 11, &
47 : deriv_laplace_rhob = 12, &
48 : ! Reduced gradients gamma_ij = grad rho_i . grad rho_j. These are the
49 : ! variables LibXC itself differentiates with respect to (its sigma), and
50 : ! unlike norm_drho they leave the chain rule free of 1/|grad rho| factors.
51 : deriv_gamma = 13, &
52 : deriv_gamma_aa = 14, &
53 : deriv_gamma_ab = 15, &
54 : deriv_gamma_bb = 16
55 :
56 : INTEGER, PARAMETER :: MAX_LABEL_LENGTH = 12
57 :
58 : LOGICAL, PARAMETER :: debug_this_module = .FALSE.
59 :
60 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_derivative_desc'
61 :
62 : PUBLIC :: desc_to_id, id_to_desc, create_split_desc, standardize_desc
63 :
64 : CONTAINS
65 :
66 : ! **************************************************************************************************
67 : !> \brief ...
68 : !> \param desc ...
69 : !> \return ...
70 : ! **************************************************************************************************
71 0 : FUNCTION desc_to_id(desc) RESULT(id)
72 : CHARACTER(LEN=*), INTENT(IN) :: desc
73 : INTEGER :: id
74 :
75 0 : SELECT CASE (TRIM(desc))
76 : CASE ("rho")
77 0 : id = deriv_rho
78 : CASE ("rhoa")
79 0 : id = deriv_rhoa
80 : CASE ("rhob")
81 0 : id = deriv_rhob
82 : CASE ("norm_drho")
83 0 : id = deriv_norm_drho
84 : CASE ("norm_drhoa")
85 0 : id = deriv_norm_drhoa
86 : CASE ("norm_drhob")
87 0 : id = deriv_norm_drhob
88 : CASE ("tau")
89 0 : id = deriv_tau
90 : CASE ("tau_a")
91 0 : id = deriv_tau_a
92 : CASE ("tau_b")
93 0 : id = deriv_tau_b
94 : CASE ("laplace_rho")
95 0 : id = deriv_laplace_rho
96 : CASE ("laplace_rhoa")
97 0 : id = deriv_laplace_rhoa
98 : CASE ("laplace_rhob")
99 0 : id = deriv_laplace_rhob
100 : CASE ("gamma")
101 0 : id = deriv_gamma
102 : CASE ("gamma_aa")
103 0 : id = deriv_gamma_aa
104 : CASE ("gamma_ab")
105 0 : id = deriv_gamma_ab
106 : CASE ("gamma_bb")
107 0 : id = deriv_gamma_bb
108 : CASE DEFAULT
109 0 : CPABORT("Unknown derivative variable: "//desc)
110 : END SELECT
111 :
112 0 : END FUNCTION desc_to_id
113 :
114 : ! **************************************************************************************************
115 : !> \brief ...
116 : !> \param id ...
117 : !> \return ...
118 : ! **************************************************************************************************
119 0 : FUNCTION id_to_desc(id) RESULT(desc)
120 : INTEGER, INTENT(IN) :: id
121 : CHARACTER(LEN=MAX_LABEL_LENGTH) :: desc
122 :
123 0 : SELECT CASE (id)
124 : CASE (deriv_rho)
125 0 : desc = "rho"
126 : CASE (deriv_rhoa)
127 0 : desc = "rhoa"
128 : CASE (deriv_rhob)
129 0 : desc = "rhob"
130 : CASE (deriv_norm_drho)
131 0 : desc = "norm_drho"
132 : CASE (deriv_norm_drhoa)
133 0 : desc = "norm_drhoa"
134 : CASE (deriv_norm_drhob)
135 0 : desc = "norm_drhob"
136 : CASE (deriv_tau)
137 0 : desc = "tau"
138 : CASE (deriv_tau_a)
139 0 : desc = "tau_a"
140 : CASE (deriv_tau_b)
141 0 : desc = "tau_b"
142 : CASE (deriv_laplace_rho)
143 0 : desc = "laplace_rho"
144 : CASE (deriv_laplace_rhoa)
145 0 : desc = "laplace_rhoa"
146 : CASE (deriv_laplace_rhob)
147 0 : desc = "laplace_rhob"
148 : CASE (deriv_gamma)
149 0 : desc = "gamma"
150 : CASE (deriv_gamma_aa)
151 0 : desc = "gamma_aa"
152 : CASE (deriv_gamma_ab)
153 0 : desc = "gamma_ab"
154 : CASE (deriv_gamma_bb)
155 0 : desc = "gamma_bb"
156 : CASE DEFAULT
157 0 : CPABORT("Unknown derivative id!")
158 : END SELECT
159 :
160 0 : END FUNCTION id_to_desc
161 :
162 : ! **************************************************************************************************
163 : !> \brief ...
164 : !> \param desc ...
165 : !> \param split_desc ...
166 : ! **************************************************************************************************
167 721737 : SUBROUTINE create_split_desc(desc, split_desc)
168 : INTEGER, DIMENSION(:), INTENT(IN) :: desc
169 : INTEGER, DIMENSION(:), POINTER :: split_desc
170 :
171 721737 : INTEGER, ALLOCATABLE, DIMENSION(:) :: indices
172 :
173 1938717 : ALLOCATE (split_desc(SIZE(desc)))
174 721737 : IF (SIZE(desc) > 0) THEN
175 990486 : ALLOCATE (indices(SIZE(desc)))
176 1042046 : split_desc = desc
177 495243 : CALL sort(split_desc, SIZE(desc), indices)
178 495243 : DEALLOCATE (indices)
179 : END IF
180 :
181 721737 : END SUBROUTINE create_split_desc
182 :
183 : ! **************************************************************************************************
184 : !> \brief ...
185 : !> \param desc ...
186 : !> \param split_desc ...
187 : ! **************************************************************************************************
188 3218007 : SUBROUTINE standardize_desc(desc, split_desc)
189 : INTEGER, DIMENSION(:), INTENT(IN) :: desc
190 : INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(OUT) :: split_desc
191 :
192 3218007 : INTEGER, ALLOCATABLE, DIMENSION(:) :: indices
193 :
194 9085364 : ALLOCATE (split_desc(SIZE(desc)))
195 3218007 : IF (SIZE(desc) > 0) THEN
196 5298700 : ALLOCATE (indices(SIZE(desc)))
197 6554516 : split_desc(:) = desc
198 2649350 : CALL sort(split_desc, SIZE(desc), indices)
199 2649350 : DEALLOCATE (indices)
200 : END IF
201 :
202 3218007 : END SUBROUTINE standardize_desc
203 :
204 : END MODULE xc_derivative_desc
|