QMCPACK
SoaCartesianTensor.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
8 //
9 // File created by: Jeongnim Kim, jeongnim.kim@intel.com, Intel Corp.
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 /*
14  DO NOT MAKE PERMANENT EDITS IN THIS FILE
15  This file is generated from src/Numerics/codegen/gen_cartesian_tensor.py and SoaCartesianTensor.h.in
16 
17  Edit SoaCartesianTensor.h.in, rerun gen_cartesian_tensor.py, and copy the generated file here.
18 */
19 
20 
21 #ifndef QMCPLUSPLUS_SOA_CARTESIAN_TENSOR_H
22 #define QMCPLUSPLUS_SOA_CARTESIAN_TENSOR_H
23 
24 #include <stdexcept>
26 #include "OhmmsPETE/OhmmsArray.h"
28 
29 namespace qmcplusplus
30 {
31 /** CartesianTensor according to Gamess order
32  * @tparam T, value_type, e.g. double
33  *
34  * Original implementation Numerics/CartesianTensor.h
35  * Modified to use SoA for cXYZ and used by SoaAtomicBasisSet
36  * Array ordered as [S,X,Y,Z,XX,YY,ZZ,XY,XZ,YZ,...]
37  * (following Gamess order)
38  */
39 template<class T>
41 {
42 private:
43  using value_type = T;
49 
50  ///maximum angular momentum
51  int Lmax;
52  /// Normalization factors
53  const std::shared_ptr<OffloadVector> norm_factor_ptr_;
54  /// norm_factor reference
56  ///composite V,Gx,Gy,Gz,[L | H00, H01, H02, H11, H12, H12]
57  // {GH000, GH001, GH002, GH011, GH012, GH022, GH111, GH112, GH122, GH222
59 
60 public:
61  /** constructor
62  * @param l_max maximum angular momentum
63  *
64  * Evaluate all the constants and prefactors.
65  */
66  explicit SoaCartesianTensor(const int l_max, bool addsign = false);
67 
68  /// cXYZ accessor
69  auto& getcXYZ() const { return cXYZ; }
70 
71  ///compute Ylm
72  static void evaluate_bare(T x, T y, T z, T* XYZ, int lmax);
73 
74  static void evaluateVGL_impl(T x,
75  T y,
76  T z,
77  T* restrict XYZ,
78  T* restrict gr0,
79  T* restrict gr1,
80  T* restrict gr2,
81  T* restrict lap,
82  int lmax,
83  const T* normfactor,
84  int n_normfac);
85  ///compute Ylm
86  inline void evaluateV(T x, T y, T z, T* XYZ) const
87  {
88  evaluate_bare(x, y, z, XYZ, Lmax);
89  for (size_t i = 0, nl = cXYZ.size(); i < nl; i++)
90  XYZ[i] *= norm_factor_[i];
91  }
92 
93  ///compute Ylm
94  inline void evaluateV(T x, T y, T z, T* XYZ)
95  {
96  evaluate_bare(x, y, z, XYZ, Lmax);
97  for (size_t i = 0, nl = cXYZ.size(); i < nl; i++)
98  XYZ[i] *= norm_factor_[i];
99  }
100 
101  ///compute Ylm
102  inline void evaluateV(T x, T y, T z) { evaluateV(x, y, z, cXYZ.data(0)); }
103 
104  /**
105  * @brief evaluate for multiple electrons and multiple pbc images
106  *
107  * @param [in] xyz electron positions [Nelec, Npbc, 3(x,y,z)]
108  * @param [out] XYZ Cartesian tensor elements [Nelec, Npbc, Nlm]
109  */
110  inline void batched_evaluateV(const OffloadArray3D& xyz, OffloadArray3D& XYZ) const
111  {
112  const size_t nElec = xyz.size(0);
113  const size_t Npbc = xyz.size(1); // number of PBC images
114  assert(xyz.size(2) == 3); // x,y,z
115 
116  assert(XYZ.size(0) == nElec);
117  assert(XYZ.size(1) == Npbc);
118  const size_t Nlm = XYZ.size(2);
119 
120  size_t nR = nElec * Npbc; // total number of positions to evaluate
121 
122  auto* xyz_ptr = xyz.data();
123  auto* XYZ_ptr = XYZ.data();
124  auto* norm_factor__ptr = norm_factor_.data();
125 
126  PRAGMA_OFFLOAD("omp target teams distribute parallel for \
127  map(to:norm_factor__ptr[:Nlm]) \
128  map(to:xyz_ptr[:3*nR], XYZ_ptr[:Nlm*nR])")
129  for (uint32_t ir = 0; ir < nR; ir++)
130  {
131  evaluate_bare(xyz_ptr[0 + 3 * ir], xyz_ptr[1 + 3 * ir], xyz_ptr[2 + 3 * ir], XYZ_ptr + (ir * Nlm), Lmax);
132  for (uint32_t i = 0; i < Nlm; i++)
133  XYZ_ptr[ir * Nlm + i] *= norm_factor__ptr[i];
134  }
135  }
136 
137  /**
138  * @brief evaluate VGL for multiple electrons and multiple pbc images
139  *
140  * when offload is enabled, xyz is assumed to be up to date on the device before entering the function
141  * XYZ_vgl will be up to date on the device (but not host) when this function exits
142  *
143  * @param [in] xyz electron positions [Nelec, Npbc, 3(x,y,z)]
144  * @param [out] XYZ_vgl Cartesian tensor elements [5(v, gx, gy, gz, lapl), Nelec, Npbc, Nlm]
145  */
146  inline void batched_evaluateVGL(const OffloadArray3D& xyz, OffloadArray4D& XYZ_vgl) const
147  {
148  const size_t nElec = xyz.size(0);
149  const size_t Npbc = xyz.size(1); // number of PBC images
150  assert(xyz.size(2) == 3);
151 
152  assert(XYZ_vgl.size(0) == 5);
153  assert(XYZ_vgl.size(1) == nElec);
154  assert(XYZ_vgl.size(2) == Npbc);
155  const size_t Nlm = XYZ_vgl.size(3);
156  assert(norm_factor_.size() == Nlm);
157 
158  size_t nR = nElec * Npbc; // total number of positions to evaluate
159  size_t offset = Nlm * nR; // stride for v/gx/gy/gz/l
160 
161  auto* xyz_ptr = xyz.data();
162  auto* XYZ_vgl_ptr = XYZ_vgl.data();
163  auto* norm_factor__ptr = norm_factor_.data();
164  // TODO: make separate ptrs to start of v/gx/gy/gz/l?
165  // might be more readable?
166  // or just pass one ptr to evaluateVGL and apply stride/offset inside
167 
168  PRAGMA_OFFLOAD("omp target teams distribute parallel for \
169  map(to:norm_factor__ptr[:Nlm]) \
170  map(to: xyz_ptr[:3*nR], XYZ_vgl_ptr[:5*nR*Nlm])")
171  for (uint32_t ir = 0; ir < nR; ir++)
172  {
173  constexpr T czero(0);
174  for (uint32_t i = 0; i < Nlm; i++)
175  {
176  XYZ_vgl_ptr[ir * Nlm + offset * 1 + i] = czero;
177  XYZ_vgl_ptr[ir * Nlm + offset * 2 + i] = czero;
178  XYZ_vgl_ptr[ir * Nlm + offset * 3 + i] = czero;
179  XYZ_vgl_ptr[ir * Nlm + offset * 4 + i] = czero;
180  }
181  evaluateVGL_impl(xyz_ptr[0 + 3 * ir], xyz_ptr[1 + 3 * ir], xyz_ptr[2 + 3 * ir], XYZ_vgl_ptr + (ir * Nlm),
182  XYZ_vgl_ptr + (ir * Nlm + offset * 1), XYZ_vgl_ptr + (ir * Nlm + offset * 2),
183  XYZ_vgl_ptr + (ir * Nlm + offset * 3), XYZ_vgl_ptr + (ir * Nlm + offset * 4), Lmax,
184  norm_factor__ptr, Nlm);
185  }
186  }
187 
188  ///makes a table of \f$ r^l S_l^m \f$ and their gradients up to Lmax.
189  void evaluateVGL(T x, T y, T z);
190 
191  void evaluateVGH(T x, T y, T z);
192 
193  void evaluateVGHGH(T x, T y, T z);
194  ///returns dummy: this is not used
195  inline int index(int l, int m) const { return (l * (l + 1)) + m; }
196 
197  /** return the starting address of the component
198  *
199  * component=0(V), 1(dx), 2(dy), 3(dz), 4(Lap)
200  * See comment at VectorSoAContainer<T,20> cXYZ declaration.
201  */
202  inline const T* operator[](size_t component) const { return cXYZ.data(component); }
203 
204  inline size_t size() const { return cXYZ.size(); }
205 
206  inline int lmax() const { return Lmax; }
207 
208  inline void getABC(int n, int& a, int& b, int& c);
209 
210  int DFactorial(int num) { return (num < 2) ? 1 : num * DFactorial(num - 2); }
211 };
212 
213 template<class T>
214 SoaCartesianTensor<T>::SoaCartesianTensor(const int l_max, bool addsign)
215  : Lmax(l_max), norm_factor_ptr_(std::make_shared<OffloadVector>()), norm_factor_(*norm_factor_ptr_)
216 
217 {
218  if (Lmax > 6)
219  throw std::runtime_error("CartesianTensor can't handle Lmax > 6.\n");
220 
221  int ntot = 0;
222  for (int i = 0; i <= Lmax; i++)
223  ntot += (i + 1) * (i + 2) / 2;
224  cXYZ.resize(ntot);
225  norm_factor_.resize(ntot, 1);
226  int p = 0;
227  int a = 0, b = 0, c = 0;
228  const double pi = 4.0 * std::atan(1.0);
229  for (int l = 0; l <= Lmax; l++)
230  {
231  int n = (l + 1) * (l + 2) / 2;
232  for (int k = 0; k < n; k++)
233  {
234  getABC(p, a, b, c);
235  // factor of (alpha^(l+3/2))^(1/2) goes into the radial function
236  // mmorales: HACK HACK HACK, to avoid modifyng the radial functions,
237  // I add a term to the normalization to cancel the term
238  // coming from the Spherical Harmonics
239  // NormL = pow(2,L+1)*sqrt(2.0/static_cast<real_type>(DFactorial(2*l+1)))*pow(2.0/pi,0.25)
240  double L = static_cast<T>(l);
241  double NormL =
242  std::pow(2, L + 1) * std::sqrt(2.0 / static_cast<double>(DFactorial(2 * l + 1))) * std::pow(2.0 / pi, 0.25);
243  norm_factor_[p++] = static_cast<T>(
244  std::pow(2.0 / pi, 0.75) * std::pow(4.0, 0.5 * (a + b + c)) *
245  std::sqrt(1.0 /
246  static_cast<double>((DFactorial(2 * a - 1) * DFactorial(2 * b - 1) * DFactorial(2 * c - 1)))) /
247  NormL);
248  }
249  }
251 }
252 
253 template<class T>
255 {
256  constexpr T czero(0);
257  cXYZ = czero;
258  evaluateVGL_impl(x, y, z, cXYZ.data(0), cXYZ.data(1), cXYZ.data(2), cXYZ.data(3), cXYZ.data(4), Lmax,
259  norm_factor_.data(), norm_factor_.size());
260 }
261 
262 PRAGMA_OFFLOAD("omp declare target")
263 template<class T>
264 void SoaCartesianTensor<T>::evaluate_bare(T x, T y, T z, T* restrict XYZ, int lmax)
265 {
266  const T x2 = x * x, y2 = y * y, z2 = z * z;
267  const T x3 = x2 * x, y3 = y2 * y, z3 = z2 * z;
268  const T x4 = x3 * x, y4 = y3 * y, z4 = z3 * z;
269  const T x5 = x4 * x, y5 = y4 * y, z5 = z4 * z;
270  switch (lmax)
271  {
272  case 6:
273  XYZ[83] = x2 * y2 * z2; // X2Y2Z2
274  XYZ[82] = x * y2 * z3; // Z3Y2X
275  XYZ[81] = x2 * y * z3; // Z3X2Y
276  XYZ[80] = x * y3 * z2; // Y3Z2X
277  XYZ[79] = x2 * y3 * z; // Y3X2Z
278  XYZ[78] = x3 * y * z2; // X3Z2Y
279  XYZ[77] = x3 * y2 * z; // X3Y2Z
280  XYZ[76] = y3 * z3; // Y3Z3
281  XYZ[75] = x3 * z3; // X3Z3
282  XYZ[74] = x3 * y3; // X3Y3
283  XYZ[73] = x * y * z4; // Z4XY
284  XYZ[72] = x * y4 * z; // Y4XZ
285  XYZ[71] = x4 * y * z; // X4YZ
286  XYZ[70] = y2 * z4; // Z4Y2
287  XYZ[69] = x2 * z4; // Z4X2
288  XYZ[68] = y4 * z2; // Y4Z2
289  XYZ[67] = x2 * y4; // Y4X2
290  XYZ[66] = x4 * z2; // X4Z2
291  XYZ[65] = x4 * y2; // X4Y2
292  XYZ[64] = y * z * z4; // Z5Y
293  XYZ[63] = x * z * z4; // Z5X
294  XYZ[62] = y * y4 * z; // Y5Z
295  XYZ[61] = x * y * y4; // Y5X
296  XYZ[60] = x * x4 * z; // X5Z
297  XYZ[59] = x * x4 * y; // X5Y
298  XYZ[58] = z * z5; // Z6
299  XYZ[57] = y * y5; // Y6
300  XYZ[56] = x * x5; // X6
301  case 5:
302  XYZ[55] = x * y2 * z2; // YYZZX
303  XYZ[54] = x2 * y * z2; // XXZZY
304  XYZ[53] = x2 * y2 * z; // XXYYZ
305  XYZ[52] = x * y * z3; // ZZZXY
306  XYZ[51] = x * y3 * z; // YYYXZ
307  XYZ[50] = x3 * y * z; // XXXYZ
308  XYZ[49] = y2 * z3; // ZZZYY
309  XYZ[48] = x2 * z3; // ZZZXX
310  XYZ[47] = y3 * z2; // YYYZZ
311  XYZ[46] = x2 * y3; // YYYXX
312  XYZ[45] = x3 * z2; // XXXZZ
313  XYZ[44] = x3 * y2; // XXXYY
314  XYZ[43] = y * z4; // ZZZZY
315  XYZ[42] = x * z4; // ZZZZX
316  XYZ[41] = y4 * z; // YYYYZ
317  XYZ[40] = x * y4; // YYYYX
318  XYZ[39] = x4 * z; // XXXXZ
319  XYZ[38] = x4 * y; // XXXXY
320  XYZ[37] = z * z4; // ZZZZZ
321  XYZ[36] = y * y4; // YYYYY
322  XYZ[35] = x * x4; // XXXXX
323  case 4:
324  XYZ[34] = x * y * z2; // ZZXY
325  XYZ[33] = x * y2 * z; // YYXZ
326  XYZ[32] = x2 * y * z; // XXYZ
327  XYZ[31] = y2 * z2; // YYZZ
328  XYZ[30] = x2 * z2; // XXZZ
329  XYZ[29] = x2 * y2; // XXYY
330  XYZ[28] = y * z3; // ZZZY
331  XYZ[27] = x * z3; // ZZZX
332  XYZ[26] = y3 * z; // YYYZ
333  XYZ[25] = x * y3; // YYYX
334  XYZ[24] = x3 * z; // XXXZ
335  XYZ[23] = x3 * y; // XXXY
336  XYZ[22] = z4; // ZZZZ
337  XYZ[21] = y4; // YYYY
338  XYZ[20] = x4; // XXXX
339  case 3:
340  XYZ[19] = x * y * z; // XYZ
341  XYZ[18] = y * z2; // ZZY
342  XYZ[17] = x * z2; // ZZX
343  XYZ[16] = y2 * z; // YYZ
344  XYZ[15] = x * y2; // YYX
345  XYZ[14] = x2 * z; // XXZ
346  XYZ[13] = x2 * y; // XXY
347  XYZ[12] = z3; // ZZZ
348  XYZ[11] = y3; // YYY
349  XYZ[10] = x3; // XXX
350  case 2:
351  XYZ[9] = y * z; // YZ
352  XYZ[8] = x * z; // XZ
353  XYZ[7] = x * y; // XY
354  XYZ[6] = z2; // ZZ
355  XYZ[5] = y2; // YY
356  XYZ[4] = x2; // XX
357  case 1:
358  XYZ[3] = z; // Z
359  XYZ[2] = y; // Y
360  XYZ[1] = x; // X
361  case 0:
362  XYZ[0] = 1; // S
363  }
364 }
365 PRAGMA_OFFLOAD("omp end declare target")
366 
367 
368 PRAGMA_OFFLOAD("omp declare target")
369 template<class T>
370 void SoaCartesianTensor<T>::evaluateVGL_impl(T x,
371  T y,
372  T z,
373  T* restrict XYZ,
374  T* restrict gr0,
375  T* restrict gr1,
376  T* restrict gr2,
377  T* restrict lap,
378  int lmax,
379  const T* normfactor,
380  int n_normfac)
381 {
382  const T x2 = x * x, y2 = y * y, z2 = z * z;
383  const T x3 = x2 * x, y3 = y2 * y, z3 = z2 * z;
384  const T x4 = x3 * x, y4 = y3 * y, z4 = z3 * z;
385  const T x5 = x4 * x, y5 = y4 * y, z5 = z4 * z;
386 
387  switch (lmax)
388  {
389  case 6:
390  XYZ[83] = x2 * y2 * z2; // X2Y2Z2
391  gr0[83] = 2 * x * y2 * z2;
392  gr1[83] = 2 * x2 * y * z2;
393  gr2[83] = 2 * x2 * y2 * z;
394  lap[83] = 2 * x2 * y2 + 2 * x2 * z2 + 2 * y2 * z2;
395  XYZ[82] = x * y2 * z3; // Z3Y2X
396  gr0[82] = y2 * z3;
397  gr1[82] = 2 * x * y * z3;
398  gr2[82] = 3 * x * y2 * z2;
399  lap[82] = 6 * x * y2 * z + 2 * x * z3;
400  XYZ[81] = x2 * y * z3; // Z3X2Y
401  gr0[81] = 2 * x * y * z3;
402  gr1[81] = x2 * z3;
403  gr2[81] = 3 * x2 * y * z2;
404  lap[81] = 6 * x2 * y * z + 2 * y * z3;
405  XYZ[80] = x * y3 * z2; // Y3Z2X
406  gr0[80] = y3 * z2;
407  gr1[80] = 3 * x * y2 * z2;
408  gr2[80] = 2 * x * y3 * z;
409  lap[80] = 6 * x * y * z2 + 2 * x * y3;
410  XYZ[79] = x2 * y3 * z; // Y3X2Z
411  gr0[79] = 2 * x * y3 * z;
412  gr1[79] = 3 * x2 * y2 * z;
413  gr2[79] = x2 * y3;
414  lap[79] = 6 * x2 * y * z + 2 * y3 * z;
415  XYZ[78] = x3 * y * z2; // X3Z2Y
416  gr0[78] = 3 * x2 * y * z2;
417  gr1[78] = x3 * z2;
418  gr2[78] = 2 * x3 * y * z;
419  lap[78] = 6 * x * y * z2 + 2 * x3 * y;
420  XYZ[77] = x3 * y2 * z; // X3Y2Z
421  gr0[77] = 3 * x2 * y2 * z;
422  gr1[77] = 2 * x3 * y * z;
423  gr2[77] = x3 * y2;
424  lap[77] = 6 * x * y2 * z + 2 * x3 * z;
425  XYZ[76] = y3 * z3; // Y3Z3
426  gr1[76] = 3 * y2 * z3;
427  gr2[76] = 3 * y3 * z2;
428  lap[76] = 6 * y * z3 + 6 * y3 * z;
429  XYZ[75] = x3 * z3; // X3Z3
430  gr0[75] = 3 * x2 * z3;
431  gr2[75] = 3 * x3 * z2;
432  lap[75] = 6 * x * z3 + 6 * x3 * z;
433  XYZ[74] = x3 * y3; // X3Y3
434  gr0[74] = 3 * x2 * y3;
435  gr1[74] = 3 * x3 * y2;
436  lap[74] = 6 * x * y3 + 6 * x3 * y;
437  XYZ[73] = x * y * z4; // Z4XY
438  gr0[73] = y * z4;
439  gr1[73] = x * z4;
440  gr2[73] = 4 * x * y * z3;
441  lap[73] = 12 * x * y * z2;
442  XYZ[72] = x * y4 * z; // Y4XZ
443  gr0[72] = y4 * z;
444  gr1[72] = 4 * x * y3 * z;
445  gr2[72] = x * y4;
446  lap[72] = 12 * x * y2 * z;
447  XYZ[71] = x4 * y * z; // X4YZ
448  gr0[71] = 4 * x3 * y * z;
449  gr1[71] = x4 * z;
450  gr2[71] = x4 * y;
451  lap[71] = 12 * x2 * y * z;
452  XYZ[70] = y2 * z4; // Z4Y2
453  gr1[70] = 2 * y * z4;
454  gr2[70] = 4 * y2 * z3;
455  lap[70] = 12 * y2 * z2 + 2 * z4;
456  XYZ[69] = x2 * z4; // Z4X2
457  gr0[69] = 2 * x * z4;
458  gr2[69] = 4 * x2 * z3;
459  lap[69] = 12 * x2 * z2 + 2 * z4;
460  XYZ[68] = y4 * z2; // Y4Z2
461  gr1[68] = 4 * y3 * z2;
462  gr2[68] = 2 * y4 * z;
463  lap[68] = 12 * y2 * z2 + 2 * y4;
464  XYZ[67] = x2 * y4; // Y4X2
465  gr0[67] = 2 * x * y4;
466  gr1[67] = 4 * x2 * y3;
467  lap[67] = 12 * x2 * y2 + 2 * y4;
468  XYZ[66] = x4 * z2; // X4Z2
469  gr0[66] = 4 * x3 * z2;
470  gr2[66] = 2 * x4 * z;
471  lap[66] = 12 * x2 * z2 + 2 * x4;
472  XYZ[65] = x4 * y2; // X4Y2
473  gr0[65] = 4 * x3 * y2;
474  gr1[65] = 2 * x4 * y;
475  lap[65] = 12 * x2 * y2 + 2 * x4;
476  XYZ[64] = y * z * z4; // Z5Y
477  gr1[64] = z * z4;
478  gr2[64] = 5 * y * z4;
479  lap[64] = 20 * y * z3;
480  XYZ[63] = x * z * z4; // Z5X
481  gr0[63] = z * z4;
482  gr2[63] = 5 * x * z4;
483  lap[63] = 20 * x * z3;
484  XYZ[62] = y * y4 * z; // Y5Z
485  gr1[62] = 5 * y4 * z;
486  gr2[62] = y * y4;
487  lap[62] = 20 * y3 * z;
488  XYZ[61] = x * y * y4; // Y5X
489  gr0[61] = y * y4;
490  gr1[61] = 5 * x * y4;
491  lap[61] = 20 * x * y3;
492  XYZ[60] = x * x4 * z; // X5Z
493  gr0[60] = 5 * x4 * z;
494  gr2[60] = x * x4;
495  lap[60] = 20 * x3 * z;
496  XYZ[59] = x * x4 * y; // X5Y
497  gr0[59] = 5 * x4 * y;
498  gr1[59] = x * x4;
499  lap[59] = 20 * x3 * y;
500  XYZ[58] = z * z5; // Z6
501  gr2[58] = 6 * z * z4;
502  lap[58] = 30 * z4;
503  XYZ[57] = y * y5; // Y6
504  gr1[57] = 6 * y * y4;
505  lap[57] = 30 * y4;
506  XYZ[56] = x * x5; // X6
507  gr0[56] = 6 * x * x4;
508  lap[56] = 30 * x4;
509  case 5:
510  XYZ[55] = x * y2 * z2; // YYZZX
511  gr0[55] = y2 * z2;
512  gr1[55] = 2 * x * y * z2;
513  gr2[55] = 2 * x * y2 * z;
514  lap[55] = 2 * x * y2 + 2 * x * z2;
515  XYZ[54] = x2 * y * z2; // XXZZY
516  gr0[54] = 2 * x * y * z2;
517  gr1[54] = x2 * z2;
518  gr2[54] = 2 * x2 * y * z;
519  lap[54] = 2 * x2 * y + 2 * y * z2;
520  XYZ[53] = x2 * y2 * z; // XXYYZ
521  gr0[53] = 2 * x * y2 * z;
522  gr1[53] = 2 * x2 * y * z;
523  gr2[53] = x2 * y2;
524  lap[53] = 2 * x2 * z + 2 * y2 * z;
525  XYZ[52] = x * y * z3; // ZZZXY
526  gr0[52] = y * z3;
527  gr1[52] = x * z3;
528  gr2[52] = 3 * x * y * z2;
529  lap[52] = 6 * x * y * z;
530  XYZ[51] = x * y3 * z; // YYYXZ
531  gr0[51] = y3 * z;
532  gr1[51] = 3 * x * y2 * z;
533  gr2[51] = x * y3;
534  lap[51] = 6 * x * y * z;
535  XYZ[50] = x3 * y * z; // XXXYZ
536  gr0[50] = 3 * x2 * y * z;
537  gr1[50] = x3 * z;
538  gr2[50] = x3 * y;
539  lap[50] = 6 * x * y * z;
540  XYZ[49] = y2 * z3; // ZZZYY
541  gr1[49] = 2 * y * z3;
542  gr2[49] = 3 * y2 * z2;
543  lap[49] = 6 * y2 * z + 2 * z3;
544  XYZ[48] = x2 * z3; // ZZZXX
545  gr0[48] = 2 * x * z3;
546  gr2[48] = 3 * x2 * z2;
547  lap[48] = 6 * x2 * z + 2 * z3;
548  XYZ[47] = y3 * z2; // YYYZZ
549  gr1[47] = 3 * y2 * z2;
550  gr2[47] = 2 * y3 * z;
551  lap[47] = 6 * y * z2 + 2 * y3;
552  XYZ[46] = x2 * y3; // YYYXX
553  gr0[46] = 2 * x * y3;
554  gr1[46] = 3 * x2 * y2;
555  lap[46] = 6 * x2 * y + 2 * y3;
556  XYZ[45] = x3 * z2; // XXXZZ
557  gr0[45] = 3 * x2 * z2;
558  gr2[45] = 2 * x3 * z;
559  lap[45] = 6 * x * z2 + 2 * x3;
560  XYZ[44] = x3 * y2; // XXXYY
561  gr0[44] = 3 * x2 * y2;
562  gr1[44] = 2 * x3 * y;
563  lap[44] = 6 * x * y2 + 2 * x3;
564  XYZ[43] = y * z4; // ZZZZY
565  gr1[43] = z4;
566  gr2[43] = 4 * y * z3;
567  lap[43] = 12 * y * z2;
568  XYZ[42] = x * z4; // ZZZZX
569  gr0[42] = z4;
570  gr2[42] = 4 * x * z3;
571  lap[42] = 12 * x * z2;
572  XYZ[41] = y4 * z; // YYYYZ
573  gr1[41] = 4 * y3 * z;
574  gr2[41] = y4;
575  lap[41] = 12 * y2 * z;
576  XYZ[40] = x * y4; // YYYYX
577  gr0[40] = y4;
578  gr1[40] = 4 * x * y3;
579  lap[40] = 12 * x * y2;
580  XYZ[39] = x4 * z; // XXXXZ
581  gr0[39] = 4 * x3 * z;
582  gr2[39] = x4;
583  lap[39] = 12 * x2 * z;
584  XYZ[38] = x4 * y; // XXXXY
585  gr0[38] = 4 * x3 * y;
586  gr1[38] = x4;
587  lap[38] = 12 * x2 * y;
588  XYZ[37] = z * z4; // ZZZZZ
589  gr2[37] = 5 * z4;
590  lap[37] = 20 * z3;
591  XYZ[36] = y * y4; // YYYYY
592  gr1[36] = 5 * y4;
593  lap[36] = 20 * y3;
594  XYZ[35] = x * x4; // XXXXX
595  gr0[35] = 5 * x4;
596  lap[35] = 20 * x3;
597  case 4:
598  XYZ[34] = x * y * z2; // ZZXY
599  gr0[34] = y * z2;
600  gr1[34] = x * z2;
601  gr2[34] = 2 * x * y * z;
602  lap[34] = 2 * x * y;
603  XYZ[33] = x * y2 * z; // YYXZ
604  gr0[33] = y2 * z;
605  gr1[33] = 2 * x * y * z;
606  gr2[33] = x * y2;
607  lap[33] = 2 * x * z;
608  XYZ[32] = x2 * y * z; // XXYZ
609  gr0[32] = 2 * x * y * z;
610  gr1[32] = x2 * z;
611  gr2[32] = x2 * y;
612  lap[32] = 2 * y * z;
613  XYZ[31] = y2 * z2; // YYZZ
614  gr1[31] = 2 * y * z2;
615  gr2[31] = 2 * y2 * z;
616  lap[31] = 2 * y2 + 2 * z2;
617  XYZ[30] = x2 * z2; // XXZZ
618  gr0[30] = 2 * x * z2;
619  gr2[30] = 2 * x2 * z;
620  lap[30] = 2 * x2 + 2 * z2;
621  XYZ[29] = x2 * y2; // XXYY
622  gr0[29] = 2 * x * y2;
623  gr1[29] = 2 * x2 * y;
624  lap[29] = 2 * x2 + 2 * y2;
625  XYZ[28] = y * z3; // ZZZY
626  gr1[28] = z3;
627  gr2[28] = 3 * y * z2;
628  lap[28] = 6 * y * z;
629  XYZ[27] = x * z3; // ZZZX
630  gr0[27] = z3;
631  gr2[27] = 3 * x * z2;
632  lap[27] = 6 * x * z;
633  XYZ[26] = y3 * z; // YYYZ
634  gr1[26] = 3 * y2 * z;
635  gr2[26] = y3;
636  lap[26] = 6 * y * z;
637  XYZ[25] = x * y3; // YYYX
638  gr0[25] = y3;
639  gr1[25] = 3 * x * y2;
640  lap[25] = 6 * x * y;
641  XYZ[24] = x3 * z; // XXXZ
642  gr0[24] = 3 * x2 * z;
643  gr2[24] = x3;
644  lap[24] = 6 * x * z;
645  XYZ[23] = x3 * y; // XXXY
646  gr0[23] = 3 * x2 * y;
647  gr1[23] = x3;
648  lap[23] = 6 * x * y;
649  XYZ[22] = z4; // ZZZZ
650  gr2[22] = 4 * z3;
651  lap[22] = 12 * z2;
652  XYZ[21] = y4; // YYYY
653  gr1[21] = 4 * y3;
654  lap[21] = 12 * y2;
655  XYZ[20] = x4; // XXXX
656  gr0[20] = 4 * x3;
657  lap[20] = 12 * x2;
658  case 3:
659  XYZ[19] = x * y * z; // XYZ
660  gr0[19] = y * z;
661  gr1[19] = x * z;
662  gr2[19] = x * y;
663  XYZ[18] = y * z2; // ZZY
664  gr1[18] = z2;
665  gr2[18] = 2 * y * z;
666  lap[18] = 2 * y;
667  XYZ[17] = x * z2; // ZZX
668  gr0[17] = z2;
669  gr2[17] = 2 * x * z;
670  lap[17] = 2 * x;
671  XYZ[16] = y2 * z; // YYZ
672  gr1[16] = 2 * y * z;
673  gr2[16] = y2;
674  lap[16] = 2 * z;
675  XYZ[15] = x * y2; // YYX
676  gr0[15] = y2;
677  gr1[15] = 2 * x * y;
678  lap[15] = 2 * x;
679  XYZ[14] = x2 * z; // XXZ
680  gr0[14] = 2 * x * z;
681  gr2[14] = x2;
682  lap[14] = 2 * z;
683  XYZ[13] = x2 * y; // XXY
684  gr0[13] = 2 * x * y;
685  gr1[13] = x2;
686  lap[13] = 2 * y;
687  XYZ[12] = z3; // ZZZ
688  gr2[12] = 3 * z2;
689  lap[12] = 6 * z;
690  XYZ[11] = y3; // YYY
691  gr1[11] = 3 * y2;
692  lap[11] = 6 * y;
693  XYZ[10] = x3; // XXX
694  gr0[10] = 3 * x2;
695  lap[10] = 6 * x;
696  case 2:
697  XYZ[9] = y * z; // YZ
698  gr1[9] = z;
699  gr2[9] = y;
700  XYZ[8] = x * z; // XZ
701  gr0[8] = z;
702  gr2[8] = x;
703  XYZ[7] = x * y; // XY
704  gr0[7] = y;
705  gr1[7] = x;
706  XYZ[6] = z2; // ZZ
707  gr2[6] = 2 * z;
708  lap[6] = 2;
709  XYZ[5] = y2; // YY
710  gr1[5] = 2 * y;
711  lap[5] = 2;
712  XYZ[4] = x2; // XX
713  gr0[4] = 2 * x;
714  lap[4] = 2;
715  case 1:
716  XYZ[3] = z; // Z
717  gr2[3] = 1;
718  XYZ[2] = y; // Y
719  gr1[2] = 1;
720  XYZ[1] = x; // X
721  gr0[1] = 1;
722  case 0:
723  XYZ[0] = 1; // S
724  }
725 
726  for (size_t i = 0; i < n_normfac; i++)
727  {
728  XYZ[i] *= normfactor[i];
729  gr0[i] *= normfactor[i];
730  gr1[i] *= normfactor[i];
731  gr2[i] *= normfactor[i];
732  lap[i] *= normfactor[i];
733  }
734 }
735 PRAGMA_OFFLOAD("omp end declare target")
736 
737 
738 template<class T>
739 void SoaCartesianTensor<T>::evaluateVGH(T x, T y, T z)
740 {
741  constexpr T czero(0);
742  cXYZ = czero;
743 
744  const T x2 = x * x, y2 = y * y, z2 = z * z;
745  const T x3 = x2 * x, y3 = y2 * y, z3 = z2 * z;
746  const T x4 = x3 * x, y4 = y3 * y, z4 = z3 * z;
747  const T x5 = x4 * x, y5 = y4 * y, z5 = z4 * z;
748 
749  T* restrict XYZ = cXYZ.data(0);
750  T* restrict gr0 = cXYZ.data(1);
751  T* restrict gr1 = cXYZ.data(2);
752  T* restrict gr2 = cXYZ.data(3);
753  T* restrict h00 = cXYZ.data(4);
754  T* restrict h01 = cXYZ.data(5);
755  T* restrict h02 = cXYZ.data(6);
756  T* restrict h11 = cXYZ.data(7);
757  T* restrict h12 = cXYZ.data(8);
758  T* restrict h22 = cXYZ.data(9);
759 
760 
761  switch (Lmax)
762  {
763  case 6:
764  XYZ[83] = x2 * y2 * z2; // X2Y2Z2
765  gr0[83] = 2 * x * y2 * z2;
766  gr1[83] = 2 * x2 * y * z2;
767  gr2[83] = 2 * x2 * y2 * z;
768  h00[83] = 2 * y2 * z2;
769  h01[83] = 4 * x * y * z2;
770  h02[83] = 4 * x * y2 * z;
771  h11[83] = 2 * x2 * z2;
772  h12[83] = 4 * x2 * y * z;
773  h22[83] = 2 * x2 * y2;
774  XYZ[82] = x * y2 * z3; // Z3Y2X
775  gr0[82] = y2 * z3;
776  gr1[82] = 2 * x * y * z3;
777  gr2[82] = 3 * x * y2 * z2;
778  h01[82] = 2 * y * z3;
779  h02[82] = 3 * y2 * z2;
780  h11[82] = 2 * x * z3;
781  h12[82] = 6 * x * y * z2;
782  h22[82] = 6 * x * y2 * z;
783  XYZ[81] = x2 * y * z3; // Z3X2Y
784  gr0[81] = 2 * x * y * z3;
785  gr1[81] = x2 * z3;
786  gr2[81] = 3 * x2 * y * z2;
787  h00[81] = 2 * y * z3;
788  h01[81] = 2 * x * z3;
789  h02[81] = 6 * x * y * z2;
790  h12[81] = 3 * x2 * z2;
791  h22[81] = 6 * x2 * y * z;
792  XYZ[80] = x * y3 * z2; // Y3Z2X
793  gr0[80] = y3 * z2;
794  gr1[80] = 3 * x * y2 * z2;
795  gr2[80] = 2 * x * y3 * z;
796  h01[80] = 3 * y2 * z2;
797  h02[80] = 2 * y3 * z;
798  h11[80] = 6 * x * y * z2;
799  h12[80] = 6 * x * y2 * z;
800  h22[80] = 2 * x * y3;
801  XYZ[79] = x2 * y3 * z; // Y3X2Z
802  gr0[79] = 2 * x * y3 * z;
803  gr1[79] = 3 * x2 * y2 * z;
804  gr2[79] = x2 * y3;
805  h00[79] = 2 * y3 * z;
806  h01[79] = 6 * x * y2 * z;
807  h02[79] = 2 * x * y3;
808  h11[79] = 6 * x2 * y * z;
809  h12[79] = 3 * x2 * y2;
810  XYZ[78] = x3 * y * z2; // X3Z2Y
811  gr0[78] = 3 * x2 * y * z2;
812  gr1[78] = x3 * z2;
813  gr2[78] = 2 * x3 * y * z;
814  h00[78] = 6 * x * y * z2;
815  h01[78] = 3 * x2 * z2;
816  h02[78] = 6 * x2 * y * z;
817  h12[78] = 2 * x3 * z;
818  h22[78] = 2 * x3 * y;
819  XYZ[77] = x3 * y2 * z; // X3Y2Z
820  gr0[77] = 3 * x2 * y2 * z;
821  gr1[77] = 2 * x3 * y * z;
822  gr2[77] = x3 * y2;
823  h00[77] = 6 * x * y2 * z;
824  h01[77] = 6 * x2 * y * z;
825  h02[77] = 3 * x2 * y2;
826  h11[77] = 2 * x3 * z;
827  h12[77] = 2 * x3 * y;
828  XYZ[76] = y3 * z3; // Y3Z3
829  gr1[76] = 3 * y2 * z3;
830  gr2[76] = 3 * y3 * z2;
831  h11[76] = 6 * y * z3;
832  h12[76] = 9 * y2 * z2;
833  h22[76] = 6 * y3 * z;
834  XYZ[75] = x3 * z3; // X3Z3
835  gr0[75] = 3 * x2 * z3;
836  gr2[75] = 3 * x3 * z2;
837  h00[75] = 6 * x * z3;
838  h02[75] = 9 * x2 * z2;
839  h22[75] = 6 * x3 * z;
840  XYZ[74] = x3 * y3; // X3Y3
841  gr0[74] = 3 * x2 * y3;
842  gr1[74] = 3 * x3 * y2;
843  h00[74] = 6 * x * y3;
844  h01[74] = 9 * x2 * y2;
845  h11[74] = 6 * x3 * y;
846  XYZ[73] = x * y * z4; // Z4XY
847  gr0[73] = y * z4;
848  gr1[73] = x * z4;
849  gr2[73] = 4 * x * y * z3;
850  h01[73] = z4;
851  h02[73] = 4 * y * z3;
852  h12[73] = 4 * x * z3;
853  h22[73] = 12 * x * y * z2;
854  XYZ[72] = x * y4 * z; // Y4XZ
855  gr0[72] = y4 * z;
856  gr1[72] = 4 * x * y3 * z;
857  gr2[72] = x * y4;
858  h01[72] = 4 * y3 * z;
859  h02[72] = y4;
860  h11[72] = 12 * x * y2 * z;
861  h12[72] = 4 * x * y3;
862  XYZ[71] = x4 * y * z; // X4YZ
863  gr0[71] = 4 * x3 * y * z;
864  gr1[71] = x4 * z;
865  gr2[71] = x4 * y;
866  h00[71] = 12 * x2 * y * z;
867  h01[71] = 4 * x3 * z;
868  h02[71] = 4 * x3 * y;
869  h12[71] = x4;
870  XYZ[70] = y2 * z4; // Z4Y2
871  gr1[70] = 2 * y * z4;
872  gr2[70] = 4 * y2 * z3;
873  h11[70] = 2 * z4;
874  h12[70] = 8 * y * z3;
875  h22[70] = 12 * y2 * z2;
876  XYZ[69] = x2 * z4; // Z4X2
877  gr0[69] = 2 * x * z4;
878  gr2[69] = 4 * x2 * z3;
879  h00[69] = 2 * z4;
880  h02[69] = 8 * x * z3;
881  h22[69] = 12 * x2 * z2;
882  XYZ[68] = y4 * z2; // Y4Z2
883  gr1[68] = 4 * y3 * z2;
884  gr2[68] = 2 * y4 * z;
885  h11[68] = 12 * y2 * z2;
886  h12[68] = 8 * y3 * z;
887  h22[68] = 2 * y4;
888  XYZ[67] = x2 * y4; // Y4X2
889  gr0[67] = 2 * x * y4;
890  gr1[67] = 4 * x2 * y3;
891  h00[67] = 2 * y4;
892  h01[67] = 8 * x * y3;
893  h11[67] = 12 * x2 * y2;
894  XYZ[66] = x4 * z2; // X4Z2
895  gr0[66] = 4 * x3 * z2;
896  gr2[66] = 2 * x4 * z;
897  h00[66] = 12 * x2 * z2;
898  h02[66] = 8 * x3 * z;
899  h22[66] = 2 * x4;
900  XYZ[65] = x4 * y2; // X4Y2
901  gr0[65] = 4 * x3 * y2;
902  gr1[65] = 2 * x4 * y;
903  h00[65] = 12 * x2 * y2;
904  h01[65] = 8 * x3 * y;
905  h11[65] = 2 * x4;
906  XYZ[64] = y * z * z4; // Z5Y
907  gr1[64] = z * z4;
908  gr2[64] = 5 * y * z4;
909  h12[64] = 5 * z4;
910  h22[64] = 20 * y * z3;
911  XYZ[63] = x * z * z4; // Z5X
912  gr0[63] = z * z4;
913  gr2[63] = 5 * x * z4;
914  h02[63] = 5 * z4;
915  h22[63] = 20 * x * z3;
916  XYZ[62] = y * y4 * z; // Y5Z
917  gr1[62] = 5 * y4 * z;
918  gr2[62] = y * y4;
919  h11[62] = 20 * y3 * z;
920  h12[62] = 5 * y4;
921  XYZ[61] = x * y * y4; // Y5X
922  gr0[61] = y * y4;
923  gr1[61] = 5 * x * y4;
924  h01[61] = 5 * y4;
925  h11[61] = 20 * x * y3;
926  XYZ[60] = x * x4 * z; // X5Z
927  gr0[60] = 5 * x4 * z;
928  gr2[60] = x * x4;
929  h00[60] = 20 * x3 * z;
930  h02[60] = 5 * x4;
931  XYZ[59] = x * x4 * y; // X5Y
932  gr0[59] = 5 * x4 * y;
933  gr1[59] = x * x4;
934  h00[59] = 20 * x3 * y;
935  h01[59] = 5 * x4;
936  XYZ[58] = z * z5; // Z6
937  gr2[58] = 6 * z * z4;
938  h22[58] = 30 * z4;
939  XYZ[57] = y * y5; // Y6
940  gr1[57] = 6 * y * y4;
941  h11[57] = 30 * y4;
942  XYZ[56] = x * x5; // X6
943  gr0[56] = 6 * x * x4;
944  h00[56] = 30 * x4;
945  case 5:
946  XYZ[55] = x * y2 * z2; // YYZZX
947  gr0[55] = y2 * z2;
948  gr1[55] = 2 * x * y * z2;
949  gr2[55] = 2 * x * y2 * z;
950  h01[55] = 2 * y * z2;
951  h02[55] = 2 * y2 * z;
952  h11[55] = 2 * x * z2;
953  h12[55] = 4 * x * y * z;
954  h22[55] = 2 * x * y2;
955  XYZ[54] = x2 * y * z2; // XXZZY
956  gr0[54] = 2 * x * y * z2;
957  gr1[54] = x2 * z2;
958  gr2[54] = 2 * x2 * y * z;
959  h00[54] = 2 * y * z2;
960  h01[54] = 2 * x * z2;
961  h02[54] = 4 * x * y * z;
962  h12[54] = 2 * x2 * z;
963  h22[54] = 2 * x2 * y;
964  XYZ[53] = x2 * y2 * z; // XXYYZ
965  gr0[53] = 2 * x * y2 * z;
966  gr1[53] = 2 * x2 * y * z;
967  gr2[53] = x2 * y2;
968  h00[53] = 2 * y2 * z;
969  h01[53] = 4 * x * y * z;
970  h02[53] = 2 * x * y2;
971  h11[53] = 2 * x2 * z;
972  h12[53] = 2 * x2 * y;
973  XYZ[52] = x * y * z3; // ZZZXY
974  gr0[52] = y * z3;
975  gr1[52] = x * z3;
976  gr2[52] = 3 * x * y * z2;
977  h01[52] = z3;
978  h02[52] = 3 * y * z2;
979  h12[52] = 3 * x * z2;
980  h22[52] = 6 * x * y * z;
981  XYZ[51] = x * y3 * z; // YYYXZ
982  gr0[51] = y3 * z;
983  gr1[51] = 3 * x * y2 * z;
984  gr2[51] = x * y3;
985  h01[51] = 3 * y2 * z;
986  h02[51] = y3;
987  h11[51] = 6 * x * y * z;
988  h12[51] = 3 * x * y2;
989  XYZ[50] = x3 * y * z; // XXXYZ
990  gr0[50] = 3 * x2 * y * z;
991  gr1[50] = x3 * z;
992  gr2[50] = x3 * y;
993  h00[50] = 6 * x * y * z;
994  h01[50] = 3 * x2 * z;
995  h02[50] = 3 * x2 * y;
996  h12[50] = x3;
997  XYZ[49] = y2 * z3; // ZZZYY
998  gr1[49] = 2 * y * z3;
999  gr2[49] = 3 * y2 * z2;
1000  h11[49] = 2 * z3;
1001  h12[49] = 6 * y * z2;
1002  h22[49] = 6 * y2 * z;
1003  XYZ[48] = x2 * z3; // ZZZXX
1004  gr0[48] = 2 * x * z3;
1005  gr2[48] = 3 * x2 * z2;
1006  h00[48] = 2 * z3;
1007  h02[48] = 6 * x * z2;
1008  h22[48] = 6 * x2 * z;
1009  XYZ[47] = y3 * z2; // YYYZZ
1010  gr1[47] = 3 * y2 * z2;
1011  gr2[47] = 2 * y3 * z;
1012  h11[47] = 6 * y * z2;
1013  h12[47] = 6 * y2 * z;
1014  h22[47] = 2 * y3;
1015  XYZ[46] = x2 * y3; // YYYXX
1016  gr0[46] = 2 * x * y3;
1017  gr1[46] = 3 * x2 * y2;
1018  h00[46] = 2 * y3;
1019  h01[46] = 6 * x * y2;
1020  h11[46] = 6 * x2 * y;
1021  XYZ[45] = x3 * z2; // XXXZZ
1022  gr0[45] = 3 * x2 * z2;
1023  gr2[45] = 2 * x3 * z;
1024  h00[45] = 6 * x * z2;
1025  h02[45] = 6 * x2 * z;
1026  h22[45] = 2 * x3;
1027  XYZ[44] = x3 * y2; // XXXYY
1028  gr0[44] = 3 * x2 * y2;
1029  gr1[44] = 2 * x3 * y;
1030  h00[44] = 6 * x * y2;
1031  h01[44] = 6 * x2 * y;
1032  h11[44] = 2 * x3;
1033  XYZ[43] = y * z4; // ZZZZY
1034  gr1[43] = z4;
1035  gr2[43] = 4 * y * z3;
1036  h12[43] = 4 * z3;
1037  h22[43] = 12 * y * z2;
1038  XYZ[42] = x * z4; // ZZZZX
1039  gr0[42] = z4;
1040  gr2[42] = 4 * x * z3;
1041  h02[42] = 4 * z3;
1042  h22[42] = 12 * x * z2;
1043  XYZ[41] = y4 * z; // YYYYZ
1044  gr1[41] = 4 * y3 * z;
1045  gr2[41] = y4;
1046  h11[41] = 12 * y2 * z;
1047  h12[41] = 4 * y3;
1048  XYZ[40] = x * y4; // YYYYX
1049  gr0[40] = y4;
1050  gr1[40] = 4 * x * y3;
1051  h01[40] = 4 * y3;
1052  h11[40] = 12 * x * y2;
1053  XYZ[39] = x4 * z; // XXXXZ
1054  gr0[39] = 4 * x3 * z;
1055  gr2[39] = x4;
1056  h00[39] = 12 * x2 * z;
1057  h02[39] = 4 * x3;
1058  XYZ[38] = x4 * y; // XXXXY
1059  gr0[38] = 4 * x3 * y;
1060  gr1[38] = x4;
1061  h00[38] = 12 * x2 * y;
1062  h01[38] = 4 * x3;
1063  XYZ[37] = z * z4; // ZZZZZ
1064  gr2[37] = 5 * z4;
1065  h22[37] = 20 * z3;
1066  XYZ[36] = y * y4; // YYYYY
1067  gr1[36] = 5 * y4;
1068  h11[36] = 20 * y3;
1069  XYZ[35] = x * x4; // XXXXX
1070  gr0[35] = 5 * x4;
1071  h00[35] = 20 * x3;
1072  case 4:
1073  XYZ[34] = x * y * z2; // ZZXY
1074  gr0[34] = y * z2;
1075  gr1[34] = x * z2;
1076  gr2[34] = 2 * x * y * z;
1077  h01[34] = z2;
1078  h02[34] = 2 * y * z;
1079  h12[34] = 2 * x * z;
1080  h22[34] = 2 * x * y;
1081  XYZ[33] = x * y2 * z; // YYXZ
1082  gr0[33] = y2 * z;
1083  gr1[33] = 2 * x * y * z;
1084  gr2[33] = x * y2;
1085  h01[33] = 2 * y * z;
1086  h02[33] = y2;
1087  h11[33] = 2 * x * z;
1088  h12[33] = 2 * x * y;
1089  XYZ[32] = x2 * y * z; // XXYZ
1090  gr0[32] = 2 * x * y * z;
1091  gr1[32] = x2 * z;
1092  gr2[32] = x2 * y;
1093  h00[32] = 2 * y * z;
1094  h01[32] = 2 * x * z;
1095  h02[32] = 2 * x * y;
1096  h12[32] = x2;
1097  XYZ[31] = y2 * z2; // YYZZ
1098  gr1[31] = 2 * y * z2;
1099  gr2[31] = 2 * y2 * z;
1100  h11[31] = 2 * z2;
1101  h12[31] = 4 * y * z;
1102  h22[31] = 2 * y2;
1103  XYZ[30] = x2 * z2; // XXZZ
1104  gr0[30] = 2 * x * z2;
1105  gr2[30] = 2 * x2 * z;
1106  h00[30] = 2 * z2;
1107  h02[30] = 4 * x * z;
1108  h22[30] = 2 * x2;
1109  XYZ[29] = x2 * y2; // XXYY
1110  gr0[29] = 2 * x * y2;
1111  gr1[29] = 2 * x2 * y;
1112  h00[29] = 2 * y2;
1113  h01[29] = 4 * x * y;
1114  h11[29] = 2 * x2;
1115  XYZ[28] = y * z3; // ZZZY
1116  gr1[28] = z3;
1117  gr2[28] = 3 * y * z2;
1118  h12[28] = 3 * z2;
1119  h22[28] = 6 * y * z;
1120  XYZ[27] = x * z3; // ZZZX
1121  gr0[27] = z3;
1122  gr2[27] = 3 * x * z2;
1123  h02[27] = 3 * z2;
1124  h22[27] = 6 * x * z;
1125  XYZ[26] = y3 * z; // YYYZ
1126  gr1[26] = 3 * y2 * z;
1127  gr2[26] = y3;
1128  h11[26] = 6 * y * z;
1129  h12[26] = 3 * y2;
1130  XYZ[25] = x * y3; // YYYX
1131  gr0[25] = y3;
1132  gr1[25] = 3 * x * y2;
1133  h01[25] = 3 * y2;
1134  h11[25] = 6 * x * y;
1135  XYZ[24] = x3 * z; // XXXZ
1136  gr0[24] = 3 * x2 * z;
1137  gr2[24] = x3;
1138  h00[24] = 6 * x * z;
1139  h02[24] = 3 * x2;
1140  XYZ[23] = x3 * y; // XXXY
1141  gr0[23] = 3 * x2 * y;
1142  gr1[23] = x3;
1143  h00[23] = 6 * x * y;
1144  h01[23] = 3 * x2;
1145  XYZ[22] = z4; // ZZZZ
1146  gr2[22] = 4 * z3;
1147  h22[22] = 12 * z2;
1148  XYZ[21] = y4; // YYYY
1149  gr1[21] = 4 * y3;
1150  h11[21] = 12 * y2;
1151  XYZ[20] = x4; // XXXX
1152  gr0[20] = 4 * x3;
1153  h00[20] = 12 * x2;
1154  case 3:
1155  XYZ[19] = x * y * z; // XYZ
1156  gr0[19] = y * z;
1157  gr1[19] = x * z;
1158  gr2[19] = x * y;
1159  h01[19] = z;
1160  h02[19] = y;
1161  h12[19] = x;
1162  XYZ[18] = y * z2; // ZZY
1163  gr1[18] = z2;
1164  gr2[18] = 2 * y * z;
1165  h12[18] = 2 * z;
1166  h22[18] = 2 * y;
1167  XYZ[17] = x * z2; // ZZX
1168  gr0[17] = z2;
1169  gr2[17] = 2 * x * z;
1170  h02[17] = 2 * z;
1171  h22[17] = 2 * x;
1172  XYZ[16] = y2 * z; // YYZ
1173  gr1[16] = 2 * y * z;
1174  gr2[16] = y2;
1175  h11[16] = 2 * z;
1176  h12[16] = 2 * y;
1177  XYZ[15] = x * y2; // YYX
1178  gr0[15] = y2;
1179  gr1[15] = 2 * x * y;
1180  h01[15] = 2 * y;
1181  h11[15] = 2 * x;
1182  XYZ[14] = x2 * z; // XXZ
1183  gr0[14] = 2 * x * z;
1184  gr2[14] = x2;
1185  h00[14] = 2 * z;
1186  h02[14] = 2 * x;
1187  XYZ[13] = x2 * y; // XXY
1188  gr0[13] = 2 * x * y;
1189  gr1[13] = x2;
1190  h00[13] = 2 * y;
1191  h01[13] = 2 * x;
1192  XYZ[12] = z3; // ZZZ
1193  gr2[12] = 3 * z2;
1194  h22[12] = 6 * z;
1195  XYZ[11] = y3; // YYY
1196  gr1[11] = 3 * y2;
1197  h11[11] = 6 * y;
1198  XYZ[10] = x3; // XXX
1199  gr0[10] = 3 * x2;
1200  h00[10] = 6 * x;
1201  case 2:
1202  XYZ[9] = y * z; // YZ
1203  gr1[9] = z;
1204  gr2[9] = y;
1205  h12[9] = 1;
1206  XYZ[8] = x * z; // XZ
1207  gr0[8] = z;
1208  gr2[8] = x;
1209  h02[8] = 1;
1210  XYZ[7] = x * y; // XY
1211  gr0[7] = y;
1212  gr1[7] = x;
1213  h01[7] = 1;
1214  XYZ[6] = z2; // ZZ
1215  gr2[6] = 2 * z;
1216  h22[6] = 2;
1217  XYZ[5] = y2; // YY
1218  gr1[5] = 2 * y;
1219  h11[5] = 2;
1220  XYZ[4] = x2; // XX
1221  gr0[4] = 2 * x;
1222  h00[4] = 2;
1223  case 1:
1224  XYZ[3] = z; // Z
1225  gr2[3] = 1;
1226  XYZ[2] = y; // Y
1227  gr1[2] = 1;
1228  XYZ[1] = x; // X
1229  gr0[1] = 1;
1230  case 0:
1231  XYZ[0] = 1; // S
1232  }
1233 
1234  const size_t ntot = cXYZ.size();
1235  for (size_t i = 0; i < ntot; ++i)
1236  {
1237  XYZ[i] *= norm_factor_[i];
1238  gr0[i] *= norm_factor_[i];
1239  gr1[i] *= norm_factor_[i];
1240  gr2[i] *= norm_factor_[i];
1241  h00[i] *= norm_factor_[i];
1242  h01[i] *= norm_factor_[i];
1243  h02[i] *= norm_factor_[i];
1244  h11[i] *= norm_factor_[i];
1245  h12[i] *= norm_factor_[i];
1246  h22[i] *= norm_factor_[i];
1247  }
1248 }
1249 
1250 
1251 template<class T>
1253 {
1254  constexpr T czero(0);
1255  cXYZ = czero;
1256 
1257  const T x2 = x * x, y2 = y * y, z2 = z * z;
1258  const T x3 = x2 * x, y3 = y2 * y, z3 = z2 * z;
1259  const T x4 = x3 * x, y4 = y3 * y, z4 = z3 * z;
1260  const T x5 = x4 * x, y5 = y4 * y, z5 = z4 * z;
1261 
1262  T* restrict XYZ = cXYZ.data(0);
1263  T* restrict gr0 = cXYZ.data(1);
1264  T* restrict gr1 = cXYZ.data(2);
1265  T* restrict gr2 = cXYZ.data(3);
1266  T* restrict h00 = cXYZ.data(4);
1267  T* restrict h01 = cXYZ.data(5);
1268  T* restrict h02 = cXYZ.data(6);
1269  T* restrict h11 = cXYZ.data(7);
1270  T* restrict h12 = cXYZ.data(8);
1271  T* restrict h22 = cXYZ.data(9);
1272  T* restrict gh000 = cXYZ.data(10);
1273  T* restrict gh001 = cXYZ.data(11);
1274  T* restrict gh002 = cXYZ.data(12);
1275  T* restrict gh011 = cXYZ.data(13);
1276  T* restrict gh012 = cXYZ.data(14);
1277  T* restrict gh022 = cXYZ.data(15);
1278  T* restrict gh111 = cXYZ.data(16);
1279  T* restrict gh112 = cXYZ.data(17);
1280  T* restrict gh122 = cXYZ.data(18);
1281  T* restrict gh222 = cXYZ.data(19);
1282 
1283  switch (Lmax)
1284  {
1285  case 6:
1286  XYZ[83] = x2 * y2 * z2; // X2Y2Z2
1287  gr0[83] = 2 * x * y2 * z2;
1288  gr1[83] = 2 * x2 * y * z2;
1289  gr2[83] = 2 * x2 * y2 * z;
1290  h00[83] = 2 * y2 * z2;
1291  h01[83] = 4 * x * y * z2;
1292  h02[83] = 4 * x * y2 * z;
1293  h11[83] = 2 * x2 * z2;
1294  h12[83] = 4 * x2 * y * z;
1295  h22[83] = 2 * x2 * y2;
1296  gh001[83] = 4 * y * z2;
1297  gh002[83] = 4 * y2 * z;
1298  gh011[83] = 4 * x * z2;
1299  gh012[83] = 8 * x * y * z;
1300  gh022[83] = 4 * x * y2;
1301  gh112[83] = 4 * x2 * z;
1302  gh122[83] = 4 * x2 * y;
1303  XYZ[82] = x * y2 * z3; // Z3Y2X
1304  gr0[82] = y2 * z3;
1305  gr1[82] = 2 * x * y * z3;
1306  gr2[82] = 3 * x * y2 * z2;
1307  h01[82] = 2 * y * z3;
1308  h02[82] = 3 * y2 * z2;
1309  h11[82] = 2 * x * z3;
1310  h12[82] = 6 * x * y * z2;
1311  h22[82] = 6 * x * y2 * z;
1312  gh011[82] = 2 * z3;
1313  gh012[82] = 6 * y * z2;
1314  gh022[82] = 6 * y2 * z;
1315  gh112[82] = 6 * x * z2;
1316  gh122[82] = 12 * x * y * z;
1317  gh222[82] = 6 * x * y2;
1318  XYZ[81] = x2 * y * z3; // Z3X2Y
1319  gr0[81] = 2 * x * y * z3;
1320  gr1[81] = x2 * z3;
1321  gr2[81] = 3 * x2 * y * z2;
1322  h00[81] = 2 * y * z3;
1323  h01[81] = 2 * x * z3;
1324  h02[81] = 6 * x * y * z2;
1325  h12[81] = 3 * x2 * z2;
1326  h22[81] = 6 * x2 * y * z;
1327  gh001[81] = 2 * z3;
1328  gh002[81] = 6 * y * z2;
1329  gh012[81] = 6 * x * z2;
1330  gh022[81] = 12 * x * y * z;
1331  gh122[81] = 6 * x2 * z;
1332  gh222[81] = 6 * x2 * y;
1333  XYZ[80] = x * y3 * z2; // Y3Z2X
1334  gr0[80] = y3 * z2;
1335  gr1[80] = 3 * x * y2 * z2;
1336  gr2[80] = 2 * x * y3 * z;
1337  h01[80] = 3 * y2 * z2;
1338  h02[80] = 2 * y3 * z;
1339  h11[80] = 6 * x * y * z2;
1340  h12[80] = 6 * x * y2 * z;
1341  h22[80] = 2 * x * y3;
1342  gh011[80] = 6 * y * z2;
1343  gh012[80] = 6 * y2 * z;
1344  gh022[80] = 2 * y3;
1345  gh111[80] = 6 * x * z2;
1346  gh112[80] = 12 * x * y * z;
1347  gh122[80] = 6 * x * y2;
1348  XYZ[79] = x2 * y3 * z; // Y3X2Z
1349  gr0[79] = 2 * x * y3 * z;
1350  gr1[79] = 3 * x2 * y2 * z;
1351  gr2[79] = x2 * y3;
1352  h00[79] = 2 * y3 * z;
1353  h01[79] = 6 * x * y2 * z;
1354  h02[79] = 2 * x * y3;
1355  h11[79] = 6 * x2 * y * z;
1356  h12[79] = 3 * x2 * y2;
1357  gh001[79] = 6 * y2 * z;
1358  gh002[79] = 2 * y3;
1359  gh011[79] = 12 * x * y * z;
1360  gh012[79] = 6 * x * y2;
1361  gh111[79] = 6 * x2 * z;
1362  gh112[79] = 6 * x2 * y;
1363  XYZ[78] = x3 * y * z2; // X3Z2Y
1364  gr0[78] = 3 * x2 * y * z2;
1365  gr1[78] = x3 * z2;
1366  gr2[78] = 2 * x3 * y * z;
1367  h00[78] = 6 * x * y * z2;
1368  h01[78] = 3 * x2 * z2;
1369  h02[78] = 6 * x2 * y * z;
1370  h12[78] = 2 * x3 * z;
1371  h22[78] = 2 * x3 * y;
1372  gh000[78] = 6 * y * z2;
1373  gh001[78] = 6 * x * z2;
1374  gh002[78] = 12 * x * y * z;
1375  gh012[78] = 6 * x2 * z;
1376  gh022[78] = 6 * x2 * y;
1377  gh122[78] = 2 * x3;
1378  XYZ[77] = x3 * y2 * z; // X3Y2Z
1379  gr0[77] = 3 * x2 * y2 * z;
1380  gr1[77] = 2 * x3 * y * z;
1381  gr2[77] = x3 * y2;
1382  h00[77] = 6 * x * y2 * z;
1383  h01[77] = 6 * x2 * y * z;
1384  h02[77] = 3 * x2 * y2;
1385  h11[77] = 2 * x3 * z;
1386  h12[77] = 2 * x3 * y;
1387  gh000[77] = 6 * y2 * z;
1388  gh001[77] = 12 * x * y * z;
1389  gh002[77] = 6 * x * y2;
1390  gh011[77] = 6 * x2 * z;
1391  gh012[77] = 6 * x2 * y;
1392  gh112[77] = 2 * x3;
1393  XYZ[76] = y3 * z3; // Y3Z3
1394  gr1[76] = 3 * y2 * z3;
1395  gr2[76] = 3 * y3 * z2;
1396  h11[76] = 6 * y * z3;
1397  h12[76] = 9 * y2 * z2;
1398  h22[76] = 6 * y3 * z;
1399  gh111[76] = 6 * z3;
1400  gh112[76] = 18 * y * z2;
1401  gh122[76] = 18 * y2 * z;
1402  gh222[76] = 6 * y3;
1403  XYZ[75] = x3 * z3; // X3Z3
1404  gr0[75] = 3 * x2 * z3;
1405  gr2[75] = 3 * x3 * z2;
1406  h00[75] = 6 * x * z3;
1407  h02[75] = 9 * x2 * z2;
1408  h22[75] = 6 * x3 * z;
1409  gh000[75] = 6 * z3;
1410  gh002[75] = 18 * x * z2;
1411  gh022[75] = 18 * x2 * z;
1412  gh222[75] = 6 * x3;
1413  XYZ[74] = x3 * y3; // X3Y3
1414  gr0[74] = 3 * x2 * y3;
1415  gr1[74] = 3 * x3 * y2;
1416  h00[74] = 6 * x * y3;
1417  h01[74] = 9 * x2 * y2;
1418  h11[74] = 6 * x3 * y;
1419  gh000[74] = 6 * y3;
1420  gh001[74] = 18 * x * y2;
1421  gh011[74] = 18 * x2 * y;
1422  gh111[74] = 6 * x3;
1423  XYZ[73] = x * y * z4; // Z4XY
1424  gr0[73] = y * z4;
1425  gr1[73] = x * z4;
1426  gr2[73] = 4 * x * y * z3;
1427  h01[73] = z4;
1428  h02[73] = 4 * y * z3;
1429  h12[73] = 4 * x * z3;
1430  h22[73] = 12 * x * y * z2;
1431  gh012[73] = 4 * z3;
1432  gh022[73] = 12 * y * z2;
1433  gh122[73] = 12 * x * z2;
1434  gh222[73] = 24 * x * y * z;
1435  XYZ[72] = x * y4 * z; // Y4XZ
1436  gr0[72] = y4 * z;
1437  gr1[72] = 4 * x * y3 * z;
1438  gr2[72] = x * y4;
1439  h01[72] = 4 * y3 * z;
1440  h02[72] = y4;
1441  h11[72] = 12 * x * y2 * z;
1442  h12[72] = 4 * x * y3;
1443  gh011[72] = 12 * y2 * z;
1444  gh012[72] = 4 * y3;
1445  gh111[72] = 24 * x * y * z;
1446  gh112[72] = 12 * x * y2;
1447  XYZ[71] = x4 * y * z; // X4YZ
1448  gr0[71] = 4 * x3 * y * z;
1449  gr1[71] = x4 * z;
1450  gr2[71] = x4 * y;
1451  h00[71] = 12 * x2 * y * z;
1452  h01[71] = 4 * x3 * z;
1453  h02[71] = 4 * x3 * y;
1454  h12[71] = x4;
1455  gh000[71] = 24 * x * y * z;
1456  gh001[71] = 12 * x2 * z;
1457  gh002[71] = 12 * x2 * y;
1458  gh012[71] = 4 * x3;
1459  XYZ[70] = y2 * z4; // Z4Y2
1460  gr1[70] = 2 * y * z4;
1461  gr2[70] = 4 * y2 * z3;
1462  h11[70] = 2 * z4;
1463  h12[70] = 8 * y * z3;
1464  h22[70] = 12 * y2 * z2;
1465  gh112[70] = 8 * z3;
1466  gh122[70] = 24 * y * z2;
1467  gh222[70] = 24 * y2 * z;
1468  XYZ[69] = x2 * z4; // Z4X2
1469  gr0[69] = 2 * x * z4;
1470  gr2[69] = 4 * x2 * z3;
1471  h00[69] = 2 * z4;
1472  h02[69] = 8 * x * z3;
1473  h22[69] = 12 * x2 * z2;
1474  gh002[69] = 8 * z3;
1475  gh022[69] = 24 * x * z2;
1476  gh222[69] = 24 * x2 * z;
1477  XYZ[68] = y4 * z2; // Y4Z2
1478  gr1[68] = 4 * y3 * z2;
1479  gr2[68] = 2 * y4 * z;
1480  h11[68] = 12 * y2 * z2;
1481  h12[68] = 8 * y3 * z;
1482  h22[68] = 2 * y4;
1483  gh111[68] = 24 * y * z2;
1484  gh112[68] = 24 * y2 * z;
1485  gh122[68] = 8 * y3;
1486  XYZ[67] = x2 * y4; // Y4X2
1487  gr0[67] = 2 * x * y4;
1488  gr1[67] = 4 * x2 * y3;
1489  h00[67] = 2 * y4;
1490  h01[67] = 8 * x * y3;
1491  h11[67] = 12 * x2 * y2;
1492  gh001[67] = 8 * y3;
1493  gh011[67] = 24 * x * y2;
1494  gh111[67] = 24 * x2 * y;
1495  XYZ[66] = x4 * z2; // X4Z2
1496  gr0[66] = 4 * x3 * z2;
1497  gr2[66] = 2 * x4 * z;
1498  h00[66] = 12 * x2 * z2;
1499  h02[66] = 8 * x3 * z;
1500  h22[66] = 2 * x4;
1501  gh000[66] = 24 * x * z2;
1502  gh002[66] = 24 * x2 * z;
1503  gh022[66] = 8 * x3;
1504  XYZ[65] = x4 * y2; // X4Y2
1505  gr0[65] = 4 * x3 * y2;
1506  gr1[65] = 2 * x4 * y;
1507  h00[65] = 12 * x2 * y2;
1508  h01[65] = 8 * x3 * y;
1509  h11[65] = 2 * x4;
1510  gh000[65] = 24 * x * y2;
1511  gh001[65] = 24 * x2 * y;
1512  gh011[65] = 8 * x3;
1513  XYZ[64] = y * z * z4; // Z5Y
1514  gr1[64] = z * z4;
1515  gr2[64] = 5 * y * z4;
1516  h12[64] = 5 * z4;
1517  h22[64] = 20 * y * z3;
1518  gh122[64] = 20 * z3;
1519  gh222[64] = 60 * y * z2;
1520  XYZ[63] = x * z * z4; // Z5X
1521  gr0[63] = z * z4;
1522  gr2[63] = 5 * x * z4;
1523  h02[63] = 5 * z4;
1524  h22[63] = 20 * x * z3;
1525  gh022[63] = 20 * z3;
1526  gh222[63] = 60 * x * z2;
1527  XYZ[62] = y * y4 * z; // Y5Z
1528  gr1[62] = 5 * y4 * z;
1529  gr2[62] = y * y4;
1530  h11[62] = 20 * y3 * z;
1531  h12[62] = 5 * y4;
1532  gh111[62] = 60 * y2 * z;
1533  gh112[62] = 20 * y3;
1534  XYZ[61] = x * y * y4; // Y5X
1535  gr0[61] = y * y4;
1536  gr1[61] = 5 * x * y4;
1537  h01[61] = 5 * y4;
1538  h11[61] = 20 * x * y3;
1539  gh011[61] = 20 * y3;
1540  gh111[61] = 60 * x * y2;
1541  XYZ[60] = x * x4 * z; // X5Z
1542  gr0[60] = 5 * x4 * z;
1543  gr2[60] = x * x4;
1544  h00[60] = 20 * x3 * z;
1545  h02[60] = 5 * x4;
1546  gh000[60] = 60 * x2 * z;
1547  gh002[60] = 20 * x3;
1548  XYZ[59] = x * x4 * y; // X5Y
1549  gr0[59] = 5 * x4 * y;
1550  gr1[59] = x * x4;
1551  h00[59] = 20 * x3 * y;
1552  h01[59] = 5 * x4;
1553  gh000[59] = 60 * x2 * y;
1554  gh001[59] = 20 * x3;
1555  XYZ[58] = z * z5; // Z6
1556  gr2[58] = 6 * z * z4;
1557  h22[58] = 30 * z4;
1558  gh222[58] = 120 * z3;
1559  XYZ[57] = y * y5; // Y6
1560  gr1[57] = 6 * y * y4;
1561  h11[57] = 30 * y4;
1562  gh111[57] = 120 * y3;
1563  XYZ[56] = x * x5; // X6
1564  gr0[56] = 6 * x * x4;
1565  h00[56] = 30 * x4;
1566  gh000[56] = 120 * x3;
1567  case 5:
1568  XYZ[55] = x * y2 * z2; // YYZZX
1569  gr0[55] = y2 * z2;
1570  gr1[55] = 2 * x * y * z2;
1571  gr2[55] = 2 * x * y2 * z;
1572  h01[55] = 2 * y * z2;
1573  h02[55] = 2 * y2 * z;
1574  h11[55] = 2 * x * z2;
1575  h12[55] = 4 * x * y * z;
1576  h22[55] = 2 * x * y2;
1577  gh011[55] = 2 * z2;
1578  gh012[55] = 4 * y * z;
1579  gh022[55] = 2 * y2;
1580  gh112[55] = 4 * x * z;
1581  gh122[55] = 4 * x * y;
1582  XYZ[54] = x2 * y * z2; // XXZZY
1583  gr0[54] = 2 * x * y * z2;
1584  gr1[54] = x2 * z2;
1585  gr2[54] = 2 * x2 * y * z;
1586  h00[54] = 2 * y * z2;
1587  h01[54] = 2 * x * z2;
1588  h02[54] = 4 * x * y * z;
1589  h12[54] = 2 * x2 * z;
1590  h22[54] = 2 * x2 * y;
1591  gh001[54] = 2 * z2;
1592  gh002[54] = 4 * y * z;
1593  gh012[54] = 4 * x * z;
1594  gh022[54] = 4 * x * y;
1595  gh122[54] = 2 * x2;
1596  XYZ[53] = x2 * y2 * z; // XXYYZ
1597  gr0[53] = 2 * x * y2 * z;
1598  gr1[53] = 2 * x2 * y * z;
1599  gr2[53] = x2 * y2;
1600  h00[53] = 2 * y2 * z;
1601  h01[53] = 4 * x * y * z;
1602  h02[53] = 2 * x * y2;
1603  h11[53] = 2 * x2 * z;
1604  h12[53] = 2 * x2 * y;
1605  gh001[53] = 4 * y * z;
1606  gh002[53] = 2 * y2;
1607  gh011[53] = 4 * x * z;
1608  gh012[53] = 4 * x * y;
1609  gh112[53] = 2 * x2;
1610  XYZ[52] = x * y * z3; // ZZZXY
1611  gr0[52] = y * z3;
1612  gr1[52] = x * z3;
1613  gr2[52] = 3 * x * y * z2;
1614  h01[52] = z3;
1615  h02[52] = 3 * y * z2;
1616  h12[52] = 3 * x * z2;
1617  h22[52] = 6 * x * y * z;
1618  gh012[52] = 3 * z2;
1619  gh022[52] = 6 * y * z;
1620  gh122[52] = 6 * x * z;
1621  gh222[52] = 6 * x * y;
1622  XYZ[51] = x * y3 * z; // YYYXZ
1623  gr0[51] = y3 * z;
1624  gr1[51] = 3 * x * y2 * z;
1625  gr2[51] = x * y3;
1626  h01[51] = 3 * y2 * z;
1627  h02[51] = y3;
1628  h11[51] = 6 * x * y * z;
1629  h12[51] = 3 * x * y2;
1630  gh011[51] = 6 * y * z;
1631  gh012[51] = 3 * y2;
1632  gh111[51] = 6 * x * z;
1633  gh112[51] = 6 * x * y;
1634  XYZ[50] = x3 * y * z; // XXXYZ
1635  gr0[50] = 3 * x2 * y * z;
1636  gr1[50] = x3 * z;
1637  gr2[50] = x3 * y;
1638  h00[50] = 6 * x * y * z;
1639  h01[50] = 3 * x2 * z;
1640  h02[50] = 3 * x2 * y;
1641  h12[50] = x3;
1642  gh000[50] = 6 * y * z;
1643  gh001[50] = 6 * x * z;
1644  gh002[50] = 6 * x * y;
1645  gh012[50] = 3 * x2;
1646  XYZ[49] = y2 * z3; // ZZZYY
1647  gr1[49] = 2 * y * z3;
1648  gr2[49] = 3 * y2 * z2;
1649  h11[49] = 2 * z3;
1650  h12[49] = 6 * y * z2;
1651  h22[49] = 6 * y2 * z;
1652  gh112[49] = 6 * z2;
1653  gh122[49] = 12 * y * z;
1654  gh222[49] = 6 * y2;
1655  XYZ[48] = x2 * z3; // ZZZXX
1656  gr0[48] = 2 * x * z3;
1657  gr2[48] = 3 * x2 * z2;
1658  h00[48] = 2 * z3;
1659  h02[48] = 6 * x * z2;
1660  h22[48] = 6 * x2 * z;
1661  gh002[48] = 6 * z2;
1662  gh022[48] = 12 * x * z;
1663  gh222[48] = 6 * x2;
1664  XYZ[47] = y3 * z2; // YYYZZ
1665  gr1[47] = 3 * y2 * z2;
1666  gr2[47] = 2 * y3 * z;
1667  h11[47] = 6 * y * z2;
1668  h12[47] = 6 * y2 * z;
1669  h22[47] = 2 * y3;
1670  gh111[47] = 6 * z2;
1671  gh112[47] = 12 * y * z;
1672  gh122[47] = 6 * y2;
1673  XYZ[46] = x2 * y3; // YYYXX
1674  gr0[46] = 2 * x * y3;
1675  gr1[46] = 3 * x2 * y2;
1676  h00[46] = 2 * y3;
1677  h01[46] = 6 * x * y2;
1678  h11[46] = 6 * x2 * y;
1679  gh001[46] = 6 * y2;
1680  gh011[46] = 12 * x * y;
1681  gh111[46] = 6 * x2;
1682  XYZ[45] = x3 * z2; // XXXZZ
1683  gr0[45] = 3 * x2 * z2;
1684  gr2[45] = 2 * x3 * z;
1685  h00[45] = 6 * x * z2;
1686  h02[45] = 6 * x2 * z;
1687  h22[45] = 2 * x3;
1688  gh000[45] = 6 * z2;
1689  gh002[45] = 12 * x * z;
1690  gh022[45] = 6 * x2;
1691  XYZ[44] = x3 * y2; // XXXYY
1692  gr0[44] = 3 * x2 * y2;
1693  gr1[44] = 2 * x3 * y;
1694  h00[44] = 6 * x * y2;
1695  h01[44] = 6 * x2 * y;
1696  h11[44] = 2 * x3;
1697  gh000[44] = 6 * y2;
1698  gh001[44] = 12 * x * y;
1699  gh011[44] = 6 * x2;
1700  XYZ[43] = y * z4; // ZZZZY
1701  gr1[43] = z4;
1702  gr2[43] = 4 * y * z3;
1703  h12[43] = 4 * z3;
1704  h22[43] = 12 * y * z2;
1705  gh122[43] = 12 * z2;
1706  gh222[43] = 24 * y * z;
1707  XYZ[42] = x * z4; // ZZZZX
1708  gr0[42] = z4;
1709  gr2[42] = 4 * x * z3;
1710  h02[42] = 4 * z3;
1711  h22[42] = 12 * x * z2;
1712  gh022[42] = 12 * z2;
1713  gh222[42] = 24 * x * z;
1714  XYZ[41] = y4 * z; // YYYYZ
1715  gr1[41] = 4 * y3 * z;
1716  gr2[41] = y4;
1717  h11[41] = 12 * y2 * z;
1718  h12[41] = 4 * y3;
1719  gh111[41] = 24 * y * z;
1720  gh112[41] = 12 * y2;
1721  XYZ[40] = x * y4; // YYYYX
1722  gr0[40] = y4;
1723  gr1[40] = 4 * x * y3;
1724  h01[40] = 4 * y3;
1725  h11[40] = 12 * x * y2;
1726  gh011[40] = 12 * y2;
1727  gh111[40] = 24 * x * y;
1728  XYZ[39] = x4 * z; // XXXXZ
1729  gr0[39] = 4 * x3 * z;
1730  gr2[39] = x4;
1731  h00[39] = 12 * x2 * z;
1732  h02[39] = 4 * x3;
1733  gh000[39] = 24 * x * z;
1734  gh002[39] = 12 * x2;
1735  XYZ[38] = x4 * y; // XXXXY
1736  gr0[38] = 4 * x3 * y;
1737  gr1[38] = x4;
1738  h00[38] = 12 * x2 * y;
1739  h01[38] = 4 * x3;
1740  gh000[38] = 24 * x * y;
1741  gh001[38] = 12 * x2;
1742  XYZ[37] = z * z4; // ZZZZZ
1743  gr2[37] = 5 * z4;
1744  h22[37] = 20 * z3;
1745  gh222[37] = 60 * z2;
1746  XYZ[36] = y * y4; // YYYYY
1747  gr1[36] = 5 * y4;
1748  h11[36] = 20 * y3;
1749  gh111[36] = 60 * y2;
1750  XYZ[35] = x * x4; // XXXXX
1751  gr0[35] = 5 * x4;
1752  h00[35] = 20 * x3;
1753  gh000[35] = 60 * x2;
1754  case 4:
1755  XYZ[34] = x * y * z2; // ZZXY
1756  gr0[34] = y * z2;
1757  gr1[34] = x * z2;
1758  gr2[34] = 2 * x * y * z;
1759  h01[34] = z2;
1760  h02[34] = 2 * y * z;
1761  h12[34] = 2 * x * z;
1762  h22[34] = 2 * x * y;
1763  gh012[34] = 2 * z;
1764  gh022[34] = 2 * y;
1765  gh122[34] = 2 * x;
1766  XYZ[33] = x * y2 * z; // YYXZ
1767  gr0[33] = y2 * z;
1768  gr1[33] = 2 * x * y * z;
1769  gr2[33] = x * y2;
1770  h01[33] = 2 * y * z;
1771  h02[33] = y2;
1772  h11[33] = 2 * x * z;
1773  h12[33] = 2 * x * y;
1774  gh011[33] = 2 * z;
1775  gh012[33] = 2 * y;
1776  gh112[33] = 2 * x;
1777  XYZ[32] = x2 * y * z; // XXYZ
1778  gr0[32] = 2 * x * y * z;
1779  gr1[32] = x2 * z;
1780  gr2[32] = x2 * y;
1781  h00[32] = 2 * y * z;
1782  h01[32] = 2 * x * z;
1783  h02[32] = 2 * x * y;
1784  h12[32] = x2;
1785  gh001[32] = 2 * z;
1786  gh002[32] = 2 * y;
1787  gh012[32] = 2 * x;
1788  XYZ[31] = y2 * z2; // YYZZ
1789  gr1[31] = 2 * y * z2;
1790  gr2[31] = 2 * y2 * z;
1791  h11[31] = 2 * z2;
1792  h12[31] = 4 * y * z;
1793  h22[31] = 2 * y2;
1794  gh112[31] = 4 * z;
1795  gh122[31] = 4 * y;
1796  XYZ[30] = x2 * z2; // XXZZ
1797  gr0[30] = 2 * x * z2;
1798  gr2[30] = 2 * x2 * z;
1799  h00[30] = 2 * z2;
1800  h02[30] = 4 * x * z;
1801  h22[30] = 2 * x2;
1802  gh002[30] = 4 * z;
1803  gh022[30] = 4 * x;
1804  XYZ[29] = x2 * y2; // XXYY
1805  gr0[29] = 2 * x * y2;
1806  gr1[29] = 2 * x2 * y;
1807  h00[29] = 2 * y2;
1808  h01[29] = 4 * x * y;
1809  h11[29] = 2 * x2;
1810  gh001[29] = 4 * y;
1811  gh011[29] = 4 * x;
1812  XYZ[28] = y * z3; // ZZZY
1813  gr1[28] = z3;
1814  gr2[28] = 3 * y * z2;
1815  h12[28] = 3 * z2;
1816  h22[28] = 6 * y * z;
1817  gh122[28] = 6 * z;
1818  gh222[28] = 6 * y;
1819  XYZ[27] = x * z3; // ZZZX
1820  gr0[27] = z3;
1821  gr2[27] = 3 * x * z2;
1822  h02[27] = 3 * z2;
1823  h22[27] = 6 * x * z;
1824  gh022[27] = 6 * z;
1825  gh222[27] = 6 * x;
1826  XYZ[26] = y3 * z; // YYYZ
1827  gr1[26] = 3 * y2 * z;
1828  gr2[26] = y3;
1829  h11[26] = 6 * y * z;
1830  h12[26] = 3 * y2;
1831  gh111[26] = 6 * z;
1832  gh112[26] = 6 * y;
1833  XYZ[25] = x * y3; // YYYX
1834  gr0[25] = y3;
1835  gr1[25] = 3 * x * y2;
1836  h01[25] = 3 * y2;
1837  h11[25] = 6 * x * y;
1838  gh011[25] = 6 * y;
1839  gh111[25] = 6 * x;
1840  XYZ[24] = x3 * z; // XXXZ
1841  gr0[24] = 3 * x2 * z;
1842  gr2[24] = x3;
1843  h00[24] = 6 * x * z;
1844  h02[24] = 3 * x2;
1845  gh000[24] = 6 * z;
1846  gh002[24] = 6 * x;
1847  XYZ[23] = x3 * y; // XXXY
1848  gr0[23] = 3 * x2 * y;
1849  gr1[23] = x3;
1850  h00[23] = 6 * x * y;
1851  h01[23] = 3 * x2;
1852  gh000[23] = 6 * y;
1853  gh001[23] = 6 * x;
1854  XYZ[22] = z4; // ZZZZ
1855  gr2[22] = 4 * z3;
1856  h22[22] = 12 * z2;
1857  gh222[22] = 24 * z;
1858  XYZ[21] = y4; // YYYY
1859  gr1[21] = 4 * y3;
1860  h11[21] = 12 * y2;
1861  gh111[21] = 24 * y;
1862  XYZ[20] = x4; // XXXX
1863  gr0[20] = 4 * x3;
1864  h00[20] = 12 * x2;
1865  gh000[20] = 24 * x;
1866  case 3:
1867  XYZ[19] = x * y * z; // XYZ
1868  gr0[19] = y * z;
1869  gr1[19] = x * z;
1870  gr2[19] = x * y;
1871  h01[19] = z;
1872  h02[19] = y;
1873  h12[19] = x;
1874  gh012[19] = 1;
1875  XYZ[18] = y * z2; // ZZY
1876  gr1[18] = z2;
1877  gr2[18] = 2 * y * z;
1878  h12[18] = 2 * z;
1879  h22[18] = 2 * y;
1880  gh122[18] = 2;
1881  XYZ[17] = x * z2; // ZZX
1882  gr0[17] = z2;
1883  gr2[17] = 2 * x * z;
1884  h02[17] = 2 * z;
1885  h22[17] = 2 * x;
1886  gh022[17] = 2;
1887  XYZ[16] = y2 * z; // YYZ
1888  gr1[16] = 2 * y * z;
1889  gr2[16] = y2;
1890  h11[16] = 2 * z;
1891  h12[16] = 2 * y;
1892  gh112[16] = 2;
1893  XYZ[15] = x * y2; // YYX
1894  gr0[15] = y2;
1895  gr1[15] = 2 * x * y;
1896  h01[15] = 2 * y;
1897  h11[15] = 2 * x;
1898  gh011[15] = 2;
1899  XYZ[14] = x2 * z; // XXZ
1900  gr0[14] = 2 * x * z;
1901  gr2[14] = x2;
1902  h00[14] = 2 * z;
1903  h02[14] = 2 * x;
1904  gh002[14] = 2;
1905  XYZ[13] = x2 * y; // XXY
1906  gr0[13] = 2 * x * y;
1907  gr1[13] = x2;
1908  h00[13] = 2 * y;
1909  h01[13] = 2 * x;
1910  gh001[13] = 2;
1911  XYZ[12] = z3; // ZZZ
1912  gr2[12] = 3 * z2;
1913  h22[12] = 6 * z;
1914  gh222[12] = 6;
1915  XYZ[11] = y3; // YYY
1916  gr1[11] = 3 * y2;
1917  h11[11] = 6 * y;
1918  gh111[11] = 6;
1919  XYZ[10] = x3; // XXX
1920  gr0[10] = 3 * x2;
1921  h00[10] = 6 * x;
1922  gh000[10] = 6;
1923  case 2:
1924  XYZ[9] = y * z; // YZ
1925  gr1[9] = z;
1926  gr2[9] = y;
1927  h12[9] = 1;
1928  XYZ[8] = x * z; // XZ
1929  gr0[8] = z;
1930  gr2[8] = x;
1931  h02[8] = 1;
1932  XYZ[7] = x * y; // XY
1933  gr0[7] = y;
1934  gr1[7] = x;
1935  h01[7] = 1;
1936  XYZ[6] = z2; // ZZ
1937  gr2[6] = 2 * z;
1938  h22[6] = 2;
1939  XYZ[5] = y2; // YY
1940  gr1[5] = 2 * y;
1941  h11[5] = 2;
1942  XYZ[4] = x2; // XX
1943  gr0[4] = 2 * x;
1944  h00[4] = 2;
1945  case 1:
1946  XYZ[3] = z; // Z
1947  gr2[3] = 1;
1948  XYZ[2] = y; // Y
1949  gr1[2] = 1;
1950  XYZ[1] = x; // X
1951  gr0[1] = 1;
1952  case 0:
1953  XYZ[0] = 1; // S
1954  }
1955 
1956  const size_t ntot = cXYZ.size();
1957  for (size_t i = 0; i < ntot; ++i)
1958  {
1959  XYZ[i] *= norm_factor_[i];
1960  gr0[i] *= norm_factor_[i];
1961  gr1[i] *= norm_factor_[i];
1962  gr2[i] *= norm_factor_[i];
1963  h00[i] *= norm_factor_[i];
1964  h01[i] *= norm_factor_[i];
1965  h02[i] *= norm_factor_[i];
1966  h11[i] *= norm_factor_[i];
1967  h12[i] *= norm_factor_[i];
1968  h22[i] *= norm_factor_[i];
1969  gh000[i] *= norm_factor_[i];
1970  gh001[i] *= norm_factor_[i];
1971  gh002[i] *= norm_factor_[i];
1972  gh011[i] *= norm_factor_[i];
1973  gh012[i] *= norm_factor_[i];
1974  gh022[i] *= norm_factor_[i];
1975  gh111[i] *= norm_factor_[i];
1976  gh112[i] *= norm_factor_[i];
1977  gh122[i] *= norm_factor_[i];
1978  gh222[i] *= norm_factor_[i];
1979  }
1980 }
1981 
1982 // generated from read_order.py
1983 template<class T>
1984 void SoaCartesianTensor<T>::getABC(int n, int& a, int& b, int& c)
1985 {
1986  // following Gamess notation
1987  switch (n)
1988  {
1989  // S
1990  case 0: // S
1991  a = 0;
1992  b = 0;
1993  c = 0;
1994  break;
1995  // P
1996  case 1: // X
1997  a = 1;
1998  b = 0;
1999  c = 0;
2000  break;
2001  case 2: // Y
2002  a = 0;
2003  b = 1;
2004  c = 0;
2005  break;
2006  case 3: // Z
2007  a = 0;
2008  b = 0;
2009  c = 1;
2010  break;
2011  // D
2012  case 4: // XX
2013  a = 2;
2014  b = 0;
2015  c = 0;
2016  break;
2017  case 5: // YY
2018  a = 0;
2019  b = 2;
2020  c = 0;
2021  break;
2022  case 6: // ZZ
2023  a = 0;
2024  b = 0;
2025  c = 2;
2026  break;
2027  case 7: // XY
2028  a = 1;
2029  b = 1;
2030  c = 0;
2031  break;
2032  case 8: // XZ
2033  a = 1;
2034  b = 0;
2035  c = 1;
2036  break;
2037  case 9: // YZ
2038  a = 0;
2039  b = 1;
2040  c = 1;
2041  break;
2042  // F
2043  case 10: // XXX
2044  a = 3;
2045  b = 0;
2046  c = 0;
2047  break;
2048  case 11: // YYY
2049  a = 0;
2050  b = 3;
2051  c = 0;
2052  break;
2053  case 12: // ZZZ
2054  a = 0;
2055  b = 0;
2056  c = 3;
2057  break;
2058  case 13: // XXY
2059  a = 2;
2060  b = 1;
2061  c = 0;
2062  break;
2063  case 14: // XXZ
2064  a = 2;
2065  b = 0;
2066  c = 1;
2067  break;
2068  case 15: // YYX
2069  a = 1;
2070  b = 2;
2071  c = 0;
2072  break;
2073  case 16: // YYZ
2074  a = 0;
2075  b = 2;
2076  c = 1;
2077  break;
2078  case 17: // ZZX
2079  a = 1;
2080  b = 0;
2081  c = 2;
2082  break;
2083  case 18: // ZZY
2084  a = 0;
2085  b = 1;
2086  c = 2;
2087  break;
2088  case 19: // XYZ
2089  a = 1;
2090  b = 1;
2091  c = 1;
2092  break;
2093  // G
2094  case 20: // XXXX
2095  a = 4;
2096  b = 0;
2097  c = 0;
2098  break;
2099  case 21: // YYYY
2100  a = 0;
2101  b = 4;
2102  c = 0;
2103  break;
2104  case 22: // ZZZZ
2105  a = 0;
2106  b = 0;
2107  c = 4;
2108  break;
2109  case 23: // XXXY
2110  a = 3;
2111  b = 1;
2112  c = 0;
2113  break;
2114  case 24: // XXXZ
2115  a = 3;
2116  b = 0;
2117  c = 1;
2118  break;
2119  case 25: // YYYX
2120  a = 1;
2121  b = 3;
2122  c = 0;
2123  break;
2124  case 26: // YYYZ
2125  a = 0;
2126  b = 3;
2127  c = 1;
2128  break;
2129  case 27: // ZZZX
2130  a = 1;
2131  b = 0;
2132  c = 3;
2133  break;
2134  case 28: // ZZZY
2135  a = 0;
2136  b = 1;
2137  c = 3;
2138  break;
2139  case 29: // XXYY
2140  a = 2;
2141  b = 2;
2142  c = 0;
2143  break;
2144  case 30: // XXZZ
2145  a = 2;
2146  b = 0;
2147  c = 2;
2148  break;
2149  case 31: // YYZZ
2150  a = 0;
2151  b = 2;
2152  c = 2;
2153  break;
2154  case 32: // XXYZ
2155  a = 2;
2156  b = 1;
2157  c = 1;
2158  break;
2159  case 33: // YYXZ
2160  a = 1;
2161  b = 2;
2162  c = 1;
2163  break;
2164  case 34: // ZZXY
2165  a = 1;
2166  b = 1;
2167  c = 2;
2168  break;
2169  // H
2170  case 35: // XXXXX
2171  a = 5;
2172  b = 0;
2173  c = 0;
2174  break;
2175  case 36: // YYYYY
2176  a = 0;
2177  b = 5;
2178  c = 0;
2179  break;
2180  case 37: // ZZZZZ
2181  a = 0;
2182  b = 0;
2183  c = 5;
2184  break;
2185  case 38: // XXXXY
2186  a = 4;
2187  b = 1;
2188  c = 0;
2189  break;
2190  case 39: // XXXXZ
2191  a = 4;
2192  b = 0;
2193  c = 1;
2194  break;
2195  case 40: // YYYYX
2196  a = 1;
2197  b = 4;
2198  c = 0;
2199  break;
2200  case 41: // YYYYZ
2201  a = 0;
2202  b = 4;
2203  c = 1;
2204  break;
2205  case 42: // ZZZZX
2206  a = 1;
2207  b = 0;
2208  c = 4;
2209  break;
2210  case 43: // ZZZZY
2211  a = 0;
2212  b = 1;
2213  c = 4;
2214  break;
2215  case 44: // XXXYY
2216  a = 3;
2217  b = 2;
2218  c = 0;
2219  break;
2220  case 45: // XXXZZ
2221  a = 3;
2222  b = 0;
2223  c = 2;
2224  break;
2225  case 46: // YYYXX
2226  a = 2;
2227  b = 3;
2228  c = 0;
2229  break;
2230  case 47: // YYYZZ
2231  a = 0;
2232  b = 3;
2233  c = 2;
2234  break;
2235  case 48: // ZZZXX
2236  a = 2;
2237  b = 0;
2238  c = 3;
2239  break;
2240  case 49: // ZZZYY
2241  a = 0;
2242  b = 2;
2243  c = 3;
2244  break;
2245  case 50: // XXXYZ
2246  a = 3;
2247  b = 1;
2248  c = 1;
2249  break;
2250  case 51: // YYYXZ
2251  a = 1;
2252  b = 3;
2253  c = 1;
2254  break;
2255  case 52: // ZZZXY
2256  a = 1;
2257  b = 1;
2258  c = 3;
2259  break;
2260  case 53: // XXYYZ
2261  a = 2;
2262  b = 2;
2263  c = 1;
2264  break;
2265  case 54: // XXZZY
2266  a = 2;
2267  b = 1;
2268  c = 2;
2269  break;
2270  case 55: // YYZZX
2271  a = 1;
2272  b = 2;
2273  c = 2;
2274  break;
2275  // I
2276  case 56: // X6
2277  a = 6;
2278  b = 0;
2279  c = 0;
2280  break;
2281  case 57: // Y6
2282  a = 0;
2283  b = 6;
2284  c = 0;
2285  break;
2286  case 58: // Z6
2287  a = 0;
2288  b = 0;
2289  c = 6;
2290  break;
2291  case 59: // X5Y
2292  a = 5;
2293  b = 1;
2294  c = 0;
2295  break;
2296  case 60: // X5Z
2297  a = 5;
2298  b = 0;
2299  c = 1;
2300  break;
2301  case 61: // Y5X
2302  a = 1;
2303  b = 5;
2304  c = 0;
2305  break;
2306  case 62: // Y5Z
2307  a = 0;
2308  b = 5;
2309  c = 1;
2310  break;
2311  case 63: // Z5X
2312  a = 1;
2313  b = 0;
2314  c = 5;
2315  break;
2316  case 64: // Z5Y
2317  a = 0;
2318  b = 1;
2319  c = 5;
2320  break;
2321  case 65: // X4Y2
2322  a = 4;
2323  b = 2;
2324  c = 0;
2325  break;
2326  case 66: // X4Z2
2327  a = 4;
2328  b = 0;
2329  c = 2;
2330  break;
2331  case 67: // Y4X2
2332  a = 2;
2333  b = 4;
2334  c = 0;
2335  break;
2336  case 68: // Y4Z2
2337  a = 0;
2338  b = 4;
2339  c = 2;
2340  break;
2341  case 69: // Z4X2
2342  a = 2;
2343  b = 0;
2344  c = 4;
2345  break;
2346  case 70: // Z4Y2
2347  a = 0;
2348  b = 2;
2349  c = 4;
2350  break;
2351  case 71: // X4YZ
2352  a = 4;
2353  b = 1;
2354  c = 1;
2355  break;
2356  case 72: // Y4XZ
2357  a = 1;
2358  b = 4;
2359  c = 1;
2360  break;
2361  case 73: // Z4XY
2362  a = 1;
2363  b = 1;
2364  c = 4;
2365  break;
2366  case 74: // X3Y3
2367  a = 3;
2368  b = 3;
2369  c = 0;
2370  break;
2371  case 75: // X3Z3
2372  a = 3;
2373  b = 0;
2374  c = 3;
2375  break;
2376  case 76: // Y3Z3
2377  a = 0;
2378  b = 3;
2379  c = 3;
2380  break;
2381  case 77: // X3Y2Z
2382  a = 3;
2383  b = 2;
2384  c = 1;
2385  break;
2386  case 78: // X3Z2Y
2387  a = 3;
2388  b = 1;
2389  c = 2;
2390  break;
2391  case 79: // Y3X2Z
2392  a = 2;
2393  b = 3;
2394  c = 1;
2395  break;
2396  case 80: // Y3Z2X
2397  a = 1;
2398  b = 3;
2399  c = 2;
2400  break;
2401  case 81: // Z3X2Y
2402  a = 2;
2403  b = 1;
2404  c = 3;
2405  break;
2406  case 82: // Z3Y2X
2407  a = 1;
2408  b = 2;
2409  c = 3;
2410  break;
2411  case 83: // X2Y2Z2
2412  a = 2;
2413  b = 2;
2414  c = 2;
2415  break;
2416 
2417  default:
2418  throw std::runtime_error("CartesianTensor::getABC() - Incorrect index.\n");
2419  }
2420 }
2421 
2422 } //namespace qmcplusplus
2423 #endif
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
void evaluateV(T x, T y, T z, T *XYZ)
compute Ylm
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
OffloadVector & norm_factor_
norm_factor reference
void getABC(int n, int &a, int &b, int &c)
int Lmax
maximum angular momentum
constexpr std::complex< float > czero
Definition: BLAS.hpp:51
const double pi
Definition: Standard.h:56
Type_t * data()
Definition: OhmmsArray.h:87
Soa Container for D-dim vectors.
static void evaluateVGL_impl(T x, T y, T z, T *restrict XYZ, T *restrict gr0, T *restrict gr1, T *restrict gr2, T *restrict lap, int lmax, const T *normfactor, int n_normfac)
const T * operator[](size_t component) const
return the starting address of the component
MakeReturn< BinaryNode< FnPow, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t pow(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
const std::shared_ptr< OffloadVector > norm_factor_ptr_
Normalization factors.
size_type size() const
return the current size
Definition: OhmmsVector.h:162
MakeReturn< UnaryNode< FnArcTan, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t atan(const Vector< T1, C1 > &l)
void evaluateV(T x, T y, T z)
compute Ylm
int index(int l, int m) const
returns dummy: this is not used
size_t size() const
Definition: OhmmsArray.h:57
void evaluateV(T x, T y, T z, T *XYZ) const
compute Ylm
auto & getcXYZ() const
cXYZ accessor
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
void batched_evaluateV(const OffloadArray3D &xyz, OffloadArray3D &XYZ) const
evaluate for multiple electrons and multiple pbc images
void updateTo(size_type size=0, std::ptrdiff_t offset=0)
Definition: OhmmsVector.h:263
void resize(size_type n)
resize myData
A D-dimensional Array class based on PETE.
Definition: OhmmsArray.h:25
size_type size() const
return the physical size
CartesianTensor according to Gamess order.
SoaCartesianTensor(const int l_max, bool addsign=false)
constructor
VectorSoaContainer< T, 20 > cXYZ
composite V,Gx,Gy,Gz,[L | H00, H01, H02, H11, H12, H12]
void evaluateVGL(T x, T y, T z)
makes a table of and their gradients up to Lmax.
void batched_evaluateVGL(const OffloadArray3D &xyz, OffloadArray4D &XYZ_vgl) const
evaluate VGL for multiple electrons and multiple pbc images
static void evaluate_bare(T x, T y, T z, T *XYZ, int lmax)
compute Ylm