(git:374b731)
Loading...
Searching...
No Matches
grid_hip_process_vab.h
Go to the documentation of this file.
1/*----------------------------------------------------------------------------*/
2/* CP2K: A general program to perform molecular dynamics simulations */
3/* Copyright 2000-2024 CP2K developers group <https://cp2k.org> */
4/* */
5/* SPDX-License-Identifier: BSD-3-Clause */
6/*----------------------------------------------------------------------------*/
7
8/*
9 * NOTE : derived from the reference and GPU backends
10 * Authors :
11 - Dr Mathieu Taillefumier (ETH Zurich / CSCS)
12 - Advanced Micro Devices, Inc.
13*/
14
15#ifndef GRID_HIP_PROCESS_VAB_H
16#define GRID_HIP_PROCESS_VAB_H
17
19
20/* taken from ../common/grid_process_vab.h but added template parameter */
21namespace rocm_backend {
22/*******************************************************************************
23 * \brief Returns matrix element cab[idx(b)][idx(a)].
24 * \author Ole Schuett
25 ******************************************************************************/
26template <typename T>
27__device__ __inline__ T get_term(const orbital &a, const orbital &b,
28 const int n, const T *cab) {
29 return cab[idx(b) * n + idx(a)];
30}
31
32/*******************************************************************************
33 * \brief Returns i'th component of force on atom a for compute_tau=false.
34 * \author Ole Schuett
35 ******************************************************************************/
36template <typename T>
37__device__ __inline__ T get_force_a_normal(const orbital &a, const orbital &b,
38 const int i, const T zeta,
39 const int n, const T *cab) {
40 const T aip1 = get_term(up(i, a), b, n, cab);
41 const T aim1 = get_term(down(i, a), b, n, cab);
42 return 2.0 * zeta * aip1 - a.l[i] * aim1;
43}
44
45/*******************************************************************************
46 * \brief Returns i'th component of force on atom a.
47 * \author Ole Schuett
48 ******************************************************************************/
49template <bool compute_tau, typename T>
50__device__ __inline__ double
51get_force_a(const orbital &a, const orbital &b, const int i, const T zeta,
52 const T zetb, const int n, const T *cab) {
53 if (!compute_tau) {
54 return get_force_a_normal(a, b, i, zeta, n, cab);
55 } else {
56 T force = 0.0;
57 for (int k = 0; k < 3; k++) {
58 auto a_up = up(k, a);
59 auto a_down = down(k, a);
60 auto b_up = up(k, b);
61 auto b_down = down(k, b);
62 force += 0.5 * a.l[k] * b.l[k] *
63 get_force_a_normal(a_down, b_down, i, zeta, n, cab);
64 force -=
65 zeta * b.l[k] * get_force_a_normal(a_up, b_down, i, zeta, n, cab);
66 force -=
67 a.l[k] * zetb * get_force_a_normal(a_down, b_up, i, zeta, n, cab);
68 force +=
69 2.0 * zeta * zetb * get_force_a_normal(a_up, b_up, i, zeta, n, cab);
70 }
71 return force;
72 }
73}
74
75/*******************************************************************************
76 * \brief Returns i'th component of force on atom b for compute_tau=false.
77 * \author Ole Schuett
78 ******************************************************************************/
79template <typename T>
80__device__ __inline__ double
81get_force_b_normal(const orbital &a, const orbital &b, const int i,
82 const T zetb, const T rab[3], const int n, const T *cab) {
83 const T axpm0 = get_term(a, b, n, cab);
84 const T aip1 = get_term(up(i, a), b, n, cab);
85 const T bim1 = get_term(a, down(i, b), n, cab);
86 return 2.0 * zetb * (aip1 - rab[i] * axpm0) - b.l[i] * bim1;
87}
88
89/*******************************************************************************
90 * \brief Returns i'th component of force on atom b.
91 * \author Ole Schuett
92 ******************************************************************************/
93template <bool compute_tau, typename T>
94__device__ __inline__ T get_force_b(const orbital &a, const orbital &b,
95 const int i, const T zeta, const T zetb,
96 const T rab[3], const int n, const T *cab) {
97 if (!compute_tau) {
98 return get_force_b_normal(a, b, i, zetb, rab, n, cab);
99 } else {
100 T force = 0.0;
101 for (int k = 0; k < 3; k++) {
102 const auto a_up = up(k, a);
103 const auto a_down = down(k, a);
104 const auto b_up = up(k, b);
105 const auto b_down = down(k, b);
106 force += 0.5 * a.l[k] * b.l[k] *
107 get_force_b_normal(a_down, b_down, i, zetb, rab, n, cab);
108 force -= zeta * b.l[k] *
109 get_force_b_normal(a_up, b_down, i, zetb, rab, n, cab);
110 force -= a.l[k] * zetb *
111 get_force_b_normal(a_down, b_up, i, zetb, rab, n, cab);
112 force += 2.0 * zeta * zetb *
113 get_force_b_normal(a_up, b_up, i, zetb, rab, n, cab);
114 }
115 return force;
116 }
117}
118
119/*******************************************************************************
120 * \brief Returns element i,j of virial on atom a for compute_tau=false.
121 * \author Ole Schuett
122 ******************************************************************************/
123template <typename T>
124__device__ __inline__ double
125get_virial_a_normal(const orbital &a, const orbital &b, const int i,
126 const int j, const T zeta, const int n, const T *cab) {
127 return 2.0 * zeta * get_term(up(i, up(j, a)), b, n, cab) -
128 a.l[j] * get_term(up(i, down(j, a)), b, n, cab);
129}
130
131/*******************************************************************************
132 * \brief Returns element i,j of virial on atom a.
133 * \author Ole Schuett
134 ******************************************************************************/
135template <bool compute_tau, typename T>
136__device__ __inline__ T get_virial_a(const orbital &a, const orbital &b,
137 const int i, const int j, const T zeta,
138 const T zetb, const int n, const T *cab) {
139
140 if (!compute_tau) {
141 return get_virial_a_normal(a, b, i, j, zeta, n, cab);
142 } else {
143 T virial = 0.0;
144 for (int k = 0; k < 3; k++) {
145 const auto a_up = up(k, a);
146 const auto a_down = down(k, a);
147 const auto b_up = up(k, b);
148 const auto b_down = down(k, b);
149 virial += 0.5 * a.l[k] * b.l[k] *
150 get_virial_a_normal(a_down, b_down, i, j, zeta, n, cab);
151 virial -=
152 zeta * b.l[k] * get_virial_a_normal(a_up, b_down, i, j, zeta, n, cab);
153 virial -=
154 a.l[k] * zetb * get_virial_a_normal(a_down, b_up, i, j, zeta, n, cab);
155 virial += 2.0 * zeta * zetb *
156 get_virial_a_normal(a_up, b_up, i, j, zeta, n, cab);
157 }
158 return virial;
159 }
160}
161
162/*******************************************************************************
163 * \brief Returns element i,j of virial on atom b for compute_tau=false.
164 * \author Ole Schuett
165 ******************************************************************************/
166template <typename T>
167__device__ __inline__ double
168get_virial_b_normal(const orbital &a, const orbital &b, const int i,
169 const int j, const T zetb, const T rab[3], const int n,
170 const T *cab) {
171
172 return 2.0 * zetb *
173 (get_term(up(i, up(j, a)), b, n, cab) -
174 get_term(up(i, a), b, n, cab) * rab[j] -
175 get_term(up(j, a), b, n, cab) * rab[i] +
176 get_term(a, b, n, cab) * rab[j] * rab[i]) -
177 b.l[j] * get_term(a, up(i, down(j, b)), n, cab);
178}
179
180/*******************************************************************************
181 * \brief Returns element i,j of virial on atom b.
182 * \author Ole Schuett
183 ******************************************************************************/
184template <bool compute_tau, typename T>
185__device__ __inline__ double
186get_virial_b(const orbital &a, const orbital &b, const int i, const int j,
187 const T zeta, const T zetb, const T rab[3], const int n,
188 const T *cab) {
189
190 if (!compute_tau) {
191 return get_virial_b_normal(a, b, i, j, zetb, rab, n, cab);
192 } else {
193 T virial = 0.0;
194 for (int k = 0; k < 3; k++) {
195 const auto a_up = up(k, a);
196 const auto a_down = down(k, a);
197 const auto b_up = up(k, b);
198 const auto b_down = down(k, b);
199 virial += 0.5 * a.l[k] * b.l[k] *
200 get_virial_b_normal(a_down, b_down, i, j, zetb, rab, n, cab);
201 virial -= zeta * b.l[k] *
202 get_virial_b_normal(a_up, b_down, i, j, zetb, rab, n, cab);
203 virial -= a.l[k] * zetb *
204 get_virial_b_normal(a_down, b_up, i, j, zetb, rab, n, cab);
205 virial += 2.0 * zeta * zetb *
206 get_virial_b_normal(a_up, b_up, i, j, zetb, rab, n, cab);
207 }
208 return virial;
209 }
210}
211
212/*******************************************************************************
213 * \brief Returns element i,j of hab matrix.
214 * \author Ole Schuett
215 ******************************************************************************/
216template <bool compute_tau, typename T>
217__device__ __inline__ T get_hab(const orbital &a, const orbital &b,
218 const T zeta, const T zetb, const int n,
219 const T *cab) {
220 if (!compute_tau) {
221 return get_term(a, b, n, cab);
222 } else {
223 T hab = 0.0;
224 for (int k = 0; k < 3; k++) {
225 const auto a_up = up(k, a);
226 const auto a_down = down(k, a);
227 const auto b_up = up(k, b);
228 const auto b_down = down(k, b);
229 hab += 0.5 * a.l[k] * b.l[k] * get_term(a_down, b_down, n, cab);
230 hab -= zeta * b.l[k] * get_term(a_up, b_down, n, cab);
231 hab -= a.l[k] * zetb * get_term(a_down, b_up, n, cab);
232 hab += 2.0 * zeta * zetb * get_term(a_up, b_up, n, cab);
233 }
234 return hab;
235 }
236}
237
238/*******************************************************************************
239 * \brief Returns difference in angular momentum range for given flags.
240 ******************************************************************************/
241inline ldiffs_value process_get_ldiffs(bool calculate_forces,
242 bool calculate_virial,
243 bool compute_tau) {
244 ldiffs_value ldiffs;
245
246 ldiffs.la_max_diff = 0;
247 ldiffs.lb_max_diff = 0;
248 ldiffs.la_min_diff = 0;
249 ldiffs.lb_min_diff = 0;
250
251 if (calculate_forces || calculate_virial) {
252 ldiffs.la_max_diff += 1; // for deriv. of gaussian, unimportant which one
253 ldiffs.la_min_diff -= 1;
254 ldiffs.lb_min_diff -= 1;
255 }
256
257 if (calculate_virial) {
258 ldiffs.la_max_diff += 1;
259 ldiffs.lb_max_diff += 1;
260 }
261
262 if (compute_tau) {
263 ldiffs.la_max_diff += 1;
264 ldiffs.lb_max_diff += 1;
265 ldiffs.la_min_diff -= 1;
266 ldiffs.lb_min_diff -= 1;
267 }
268
269 return ldiffs;
270}
271}; // namespace rocm_backend
272#endif
static void const int const int i
__device__ __inline__ double get_virial_a_normal(const orbital &a, const orbital &b, const int i, const int j, const T zeta, const int n, const T *cab)
Returns element i,j of virial on atom a for compute_tau=false.
__device__ __inline__ double get_virial_b(const orbital &a, const orbital &b, const int i, const int j, const T zeta, const T zetb, const T rab[3], const int n, const T *cab)
Returns element i,j of virial on atom b.
__device__ __inline__ double get_force_b_normal(const orbital &a, const orbital &b, const int i, const T zetb, const T rab[3], const int n, const T *cab)
Returns i'th component of force on atom b for compute_tau=false.
__device__ __inline__ T get_virial_a(const orbital &a, const orbital &b, const int i, const int j, const T zeta, const T zetb, const int n, const T *cab)
Returns element i,j of virial on atom a.
ldiffs_value process_get_ldiffs(bool calculate_forces, bool calculate_virial, bool compute_tau)
Returns difference in angular momentum range for given flags.
__device__ __inline__ double get_virial_b_normal(const orbital &a, const orbital &b, const int i, const int j, const T zetb, const T rab[3], const int n, const T *cab)
Returns element i,j of virial on atom b for compute_tau=false.
__inline__ __device__ orbital down(const int i, const orbital &a)
Decrease i'th component of given orbital angular momentum.
__device__ __inline__ T get_hab(const orbital &a, const orbital &b, const T zeta, const T zetb, const int n, const T *cab)
Returns element i,j of hab matrix.
__device__ __inline__ double get_force_a(const orbital &a, const orbital &b, const int i, const T zeta, const T zetb, const int n, const T *cab)
Returns i'th component of force on atom a.
__device__ __inline__ T get_force_a_normal(const orbital &a, const orbital &b, const int i, const T zeta, const int n, const T *cab)
Returns i'th component of force on atom a for compute_tau=false.
__inline__ __device__ int idx(const orbital a)
Return coset index of given orbital angular momentum.
__device__ __inline__ orbital up(const int i, const orbital &a)
Increase i'th component of given orbital angular momentum.
__device__ __inline__ T get_term(const orbital &a, const orbital &b, const int n, const T *cab)
Returns matrix element cab[idx(b)][idx(a)].
__device__ __inline__ T get_force_b(const orbital &a, const orbital &b, const int i, const T zeta, const T zetb, const T rab[3], const int n, const T *cab)
Returns i'th component of force on atom b.
Differences in angular momentum.
Orbital angular momentum.