(git:1f285aa)
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 */
21 namespace rocm_backend {
22 /*******************************************************************************
23  * \brief Returns matrix element cab[idx(b)][idx(a)].
24  * \author Ole Schuett
25  ******************************************************************************/
26 template <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  ******************************************************************************/
36 template <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  ******************************************************************************/
49 template <bool compute_tau, typename T>
50 __device__ __inline__ double
51 get_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  ******************************************************************************/
79 template <typename T>
80 __device__ __inline__ double
81 get_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  ******************************************************************************/
93 template <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  ******************************************************************************/
123 template <typename T>
124 __device__ __inline__ double
125 get_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  ******************************************************************************/
135 template <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  ******************************************************************************/
166 template <typename T>
167 __device__ __inline__ double
168 get_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  ******************************************************************************/
184 template <bool compute_tau, typename T>
185 __device__ __inline__ double
186 get_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  ******************************************************************************/
216 template <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  ******************************************************************************/
241 inline 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
real(dp), dimension(3) a
Definition: ai_eri_debug.F:31
real(dp), dimension(3) b
Definition: ai_eri_debug.F:31
__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.