GADGET-4
ewaldtensors.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * \copyright This file is part of the GADGET4 N-body/SPH code developed
3  * \copyright by Volker Springel. Copyright (C) 2014-2020 by Volker Springel
4  * \copyright (vspringel@mpa-garching.mpg.de) and all contributing authors.
5  *******************************************************************************/
6 
12 #ifndef GRAVITY_EWALDTENSORS_H
13 #define GRAVITY_EWALDTENSORS_H
14 
15 #include "../data/symtensors.h"
16 
17 // derivative tensors for Ewald correction - they have few independent elements due to cubic symmetry
18 
19 template <typename T>
21 {
22  public:
23  T x0;
24 
25  // constructor
27 
28  // constructor
29  ewaldtensor0(const T x) { x0 = x; }
30 
31  inline ewaldtensor0 &operator+=(const ewaldtensor0 &right)
32  {
33  x0 += right.x0;
34 
35  return *this;
36  }
37 };
38 
39 template <typename T>
41 {
42  public:
43  T XX;
44 
45  // constructor
47 
48  // constructor
49  ewaldtensor2(const T x) { XX = x; }
50 
51  inline ewaldtensor2 &operator+=(const ewaldtensor2 &right)
52  {
53  XX += right.XX;
54 
55  return *this;
56  }
57 };
58 
59 template <typename T>
61 {
62  public:
63  T XXXX;
64  T XXYY;
65 
66  // constructor
68 
69  // constructor
70  ewaldtensor4(const T x)
71  {
72  XXXX = x;
73  XXYY = x;
74  }
75 
76  inline ewaldtensor4 &operator+=(const ewaldtensor4 &right)
77  {
78  XXXX += right.XXXX;
79  XXYY += right.XXYY;
80 
81  return *this;
82  }
83 };
84 
85 template <typename T>
87 {
88  public:
89  T XXXXXX;
90  T XXXXYY;
91  T XXYYZZ;
92 
93  // constructor
95 
96  // constructor
97  ewaldtensor6(const T x)
98  {
99  XXXXXX = x;
100  XXXXYY = x;
101  XXYYZZ = x;
102  }
103 
104  inline ewaldtensor6 &operator+=(const ewaldtensor6 &right)
105  {
106  XXXXXX += right.XXXXXX;
107  XXXXYY += right.XXXXYY;
108  XXYYZZ += right.XXYYZZ;
109 
110  return *this;
111  }
112 };
113 
114 template <typename T>
116 {
117  public:
122 
123  // constructor
125 
126  // constructor
127  ewaldtensor8(const T x)
128  {
129  XXXXXXXX = x;
130  XXXXXXYY = x;
131  XXXXYYYY = x;
132  XXXXYYZZ = x;
133  }
134 
135  inline ewaldtensor8 &operator+=(const ewaldtensor8 &right)
136  {
137  XXXXXXXX += right.XXXXXXXX;
138  XXXXXXYY += right.XXXXXXYY;
139  XXXXYYYY += right.XXXXYYYY;
140  XXXXYYZZ += right.XXXXYYZZ;
141 
142  return *this;
143  }
144 };
145 
146 template <typename T>
148 {
149  public:
155 
156  // constructor
158 
159  // constructor
160  ewaldtensor10(const T x)
161  {
162  XXXXXXXXXX = x;
163  XXXXXXXXYY = x;
164  XXXXXXYYYY = x;
165  XXXXXXYYZZ = x;
166  XXXXYYYYZZ = x;
167  }
168 
169  inline ewaldtensor10 &operator+=(const ewaldtensor10 &right)
170  {
171  XXXXXXXXXX += right.XXXXXXXXXX;
172  XXXXXXXXYY += right.XXXXXXXXYY;
173  XXXXXXYYYY += right.XXXXXXYYYY;
174  XXXXXXYYZZ += right.XXXXXXYYZZ;
175  XXXXYYYYZZ += right.XXXXYYYYZZ;
176 
177  return *this;
178  }
179 };
180 
181 // multiply with a scalar factor
182 template <typename T>
183 inline ewaldtensor6<T> operator*(const double fac, const ewaldtensor6<T> &S)
184 {
185  ewaldtensor6<T> res;
186 
187  res.XXXXXX = fac * S.XXXXXX;
188  res.XXXXYY = fac * S.XXXXYY;
189  res.XXYYZZ = fac * S.XXYYZZ;
190 
191  return res;
192 }
193 
194 // multiply with a scalar factor
195 template <typename T>
196 inline ewaldtensor8<T> operator*(const double fac, const ewaldtensor8<T> &S)
197 {
198  ewaldtensor8<T> res;
199 
200  res.XXXXXXXX = fac * S.XXXXXXXX;
201  res.XXXXXXYY = fac * S.XXXXXXYY;
202  res.XXXXYYYY = fac * S.XXXXYYYY;
203  res.XXXXYYZZ = fac * S.XXXXYYZZ;
204 
205  return res;
206 }
207 
208 // multiply with a scalar factor
209 template <typename T>
210 inline ewaldtensor10<T> operator*(const double fac, const ewaldtensor10<T> &S)
211 {
212  ewaldtensor10<T> res;
213 
214  res.XXXXXXXXXX = fac * S.XXXXXXXXXX;
215  res.XXXXXXXXYY = fac * S.XXXXXXXXYY;
216  res.XXXXXXYYYY = fac * S.XXXXXXYYYY;
217  res.XXXXXXYYZZ = fac * S.XXXXXXYYZZ;
218  res.XXXXYYYYZZ = fac * S.XXXXYYYYZZ;
219 
220  return res;
221 }
222 
223 // contract a 2-ewaldtensor with a symmetric 2-tensor to yield a scalar
224 template <typename T>
225 inline T operator*(const ewaldtensor2<T> &S, const symtensor2<T> &D)
226 {
227  T res = S.XX * D.da[qZZ] + S.XX * D.da[qYY] + S.XX * D.da[qXX];
228 
229  return res;
230 }
231 
232 // contract a 4-ewaldtensor with a symmetric 4-tensor to yield a scalar
233 template <typename T>
234 inline T operator*(const ewaldtensor4<T> &S, const symtensor4<T> &D)
235 {
236  T res = S.XXXX * D.da[sZZZZ] + 6.0 * S.XXYY * D.da[sYYZZ] + 6.0 * S.XXYY * D.da[sXXZZ] + S.XXXX * D.da[sYYYY] +
237  6.0 * S.XXYY * D.da[sXXYY] + S.XXXX * D.da[sXXXX];
238 
239  return res;
240 }
241 
242 // contract a 4-ewaldtensor with a symmetric 3-tensor to yield a vector
243 template <typename T>
245 {
246  vector<T> res;
247 
248  res.da[0] = S.XXXX * D.da[dZZZ] + 3.0 * S.XXYY * D.da[dYYZ] + 3.0 * S.XXYY * D.da[dXXZ];
249 
250  res.da[1] = 3.0 * S.XXYY * D.da[dYZZ] + S.XXXX * D.da[dYYY] + 3.0 * S.XXYY * D.da[dXXY];
251 
252  res.da[2] = 3.0 * S.XXYY * D.da[dXZZ] + 3.0 * S.XXYY * D.da[dXYY] + S.XXXX * D.da[dXXX];
253 
254  return res;
255 }
256 
257 // contract a 6-ewaldtensor with a symmetric 5-tensor to yield a vector
258 template <typename T>
260 {
261  vector<T> res;
262 
263  res.da[0] = S.XXXXXX * D.da[rZZZZZ] + 10.0 * S.XXXXYY * D.da[rYYZZZ] + 10.0 * S.XXXXYY * D.da[rXXZZZ] +
264  5.0 * S.XXXXYY * D.da[rYYYYZ] + 30.0 * S.XXYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXYY * D.da[rXXXXZ];
265 
266  res.da[1] = 5.0 * S.XXXXYY * D.da[rYZZZZ] + 10.0 * S.XXXXYY * D.da[rYYYZZ] + 30.0 * S.XXYYZZ * D.da[rXXYZZ] +
267  S.XXXXXX * D.da[rYYYYY] + 10.0 * S.XXXXYY * D.da[rXXYYY] + 5.0 * S.XXXXYY * D.da[rXXXXY];
268 
269  res.da[2] = 5.0 * S.XXXXYY * D.da[rXZZZZ] + 30.0 * S.XXYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXYY * D.da[rXXXZZ] +
270  5.0 * S.XXXXYY * D.da[rXYYYY] + 10.0 * S.XXXXYY * D.da[rXXXYY] + S.XXXXXX * D.da[rXXXXX];
271 
272  return res;
273 }
274 
275 // contract a 2-ewaldtensor with a 0-tensor to yield a 2-tensor
276 template <typename T>
277 inline symtensor2<T> operator*(const ewaldtensor2<T> &S, const T &Q0)
278 {
279  symtensor2<T> res;
280 
281  res.da[qXX] = S.XX * Q0;
282 
283  res.da[qXY] = 0.0;
284 
285  res.da[qXZ] = 0.0;
286 
287  res.da[qYY] = S.XX * Q0;
288 
289  res.da[qYZ] = 0.0;
290 
291  res.da[qZZ] = S.XX * Q0;
292 
293  return res;
294 }
295 
296 // contract a 4-ewaldtensor with a symmetric 2-tensor to yield a 2-tensor
297 template <typename T>
299 {
300  symtensor2<T> res;
301 
302  res.da[qXX] = S.XXXX * D.da[qZZ] + S.XXYY * D.da[qYY] + S.XXYY * D.da[qXX];
303 
304  res.da[qXY] = 2.0 * S.XXYY * D.da[qYZ];
305 
306  res.da[qXZ] = 2.0 * S.XXYY * D.da[qXZ];
307 
308  res.da[qYY] = S.XXYY * D.da[qZZ] + S.XXXX * D.da[qYY] + S.XXYY * D.da[qXX];
309 
310  res.da[qYZ] = 2.0 * S.XXYY * D.da[qXY];
311 
312  res.da[qZZ] = S.XXYY * D.da[qZZ] + S.XXYY * D.da[qYY] + S.XXXX * D.da[qXX];
313 
314  return res;
315 }
316 
317 // contract a 6-ewaldtensor with a symmetric 4-tensor to yield a 3-tensor
318 template <typename T>
320 {
321  symtensor2<T> res;
322 
323  res.da[qXX] = S.XXXXXX * D.da[sZZZZ] + 6.0 * S.XXXXYY * D.da[sYYZZ] + 6.0 * S.XXXXYY * D.da[sXXZZ] + S.XXXXYY * D.da[sYYYY] +
324  6.0 * S.XXYYZZ * D.da[sXXYY] + S.XXXXYY * D.da[sXXXX];
325 
326  res.da[qXY] = 4.0 * S.XXXXYY * D.da[sYZZZ] + 4.0 * S.XXXXYY * D.da[sYYYZ] + 12.0 * S.XXYYZZ * D.da[sXXYZ];
327 
328  res.da[qXZ] = 4.0 * S.XXXXYY * D.da[sXZZZ] + 12.0 * S.XXYYZZ * D.da[sXYYZ] + 4.0 * S.XXXXYY * D.da[sXXXZ];
329 
330  res.da[qYY] = S.XXXXYY * D.da[sZZZZ] + 6.0 * S.XXXXYY * D.da[sYYZZ] + 6.0 * S.XXYYZZ * D.da[sXXZZ] + S.XXXXXX * D.da[sYYYY] +
331  6.0 * S.XXXXYY * D.da[sXXYY] + S.XXXXYY * D.da[sXXXX];
332 
333  res.da[qYZ] = 12.0 * S.XXYYZZ * D.da[sXYZZ] + 4.0 * S.XXXXYY * D.da[sXYYY] + 4.0 * S.XXXXYY * D.da[sXXXY];
334 
335  res.da[qZZ] = S.XXXXYY * D.da[sZZZZ] + 6.0 * S.XXYYZZ * D.da[sYYZZ] + 6.0 * S.XXXXYY * D.da[sXXZZ] + S.XXXXYY * D.da[sYYYY] +
336  6.0 * S.XXXXYY * D.da[sXXYY] + S.XXXXXX * D.da[sXXXX];
337 
338  return res;
339 }
340 
341 // contract a 6-ewaldtensor with a symmetric 3-tensor to yield a 3-tensor
342 template <typename T>
344 {
345  symtensor3<T> res;
346 
347  res.da[dXXX] = S.XXXXXX * D.da[dZZZ] + 3.0 * S.XXXXYY * D.da[dYYZ] + 3.0 * S.XXXXYY * D.da[dXXZ];
348 
349  res.da[dXXY] = 3.0 * S.XXXXYY * D.da[dYZZ] + S.XXXXYY * D.da[dYYY] + 3.0 * S.XXYYZZ * D.da[dXXY];
350 
351  res.da[dXXZ] = 3.0 * S.XXXXYY * D.da[dXZZ] + 3.0 * S.XXYYZZ * D.da[dXYY] + S.XXXXYY * D.da[dXXX];
352 
353  res.da[dXYY] = S.XXXXYY * D.da[dZZZ] + 3.0 * S.XXXXYY * D.da[dYYZ] + 3.0 * S.XXYYZZ * D.da[dXXZ];
354 
355  res.da[dXYZ] = 6.0 * S.XXYYZZ * D.da[dXYZ];
356 
357  res.da[dXZZ] = S.XXXXYY * D.da[dZZZ] + 3.0 * S.XXYYZZ * D.da[dYYZ] + 3.0 * S.XXXXYY * D.da[dXXZ];
358 
359  res.da[dYYY] = 3.0 * S.XXXXYY * D.da[dYZZ] + S.XXXXXX * D.da[dYYY] + 3.0 * S.XXXXYY * D.da[dXXY];
360 
361  res.da[dYYZ] = 3.0 * S.XXYYZZ * D.da[dXZZ] + 3.0 * S.XXXXYY * D.da[dXYY] + S.XXXXYY * D.da[dXXX];
362 
363  res.da[dYZZ] = 3.0 * S.XXYYZZ * D.da[dYZZ] + S.XXXXYY * D.da[dYYY] + 3.0 * S.XXXXYY * D.da[dXXY];
364 
365  res.da[dZZZ] = 3.0 * S.XXXXYY * D.da[dXZZ] + 3.0 * S.XXXXYY * D.da[dXYY] + S.XXXXXX * D.da[dXXX];
366 
367  return res;
368 }
369 
370 // contract a 8-ewaldtensor with a symmetric 5-tensor to yield a 3-tensor
371 template <typename T>
373 {
374  symtensor3<T> res;
375 
376  res.da[dXXX] = S.XXXXXXXX * D.da[rZZZZZ] + 10.0 * S.XXXXXXYY * D.da[rYYZZZ] + 10.0 * S.XXXXXXYY * D.da[rXXZZZ] +
377  5.0 * S.XXXXYYYY * D.da[rYYYYZ] + 30.0 * S.XXXXYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXYYYY * D.da[rXXXXZ];
378 
379  res.da[dXXY] = 5.0 * S.XXXXXXYY * D.da[rYZZZZ] + 10.0 * S.XXXXYYYY * D.da[rYYYZZ] + 30.0 * S.XXXXYYZZ * D.da[rXXYZZ] +
380  S.XXXXXXYY * D.da[rYYYYY] + 10.0 * S.XXXXYYZZ * D.da[rXXYYY] + 5.0 * S.XXXXYYZZ * D.da[rXXXXY];
381 
382  res.da[dXXZ] = 5.0 * S.XXXXXXYY * D.da[rXZZZZ] + 30.0 * S.XXXXYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXYYYY * D.da[rXXXZZ] +
383  5.0 * S.XXXXYYZZ * D.da[rXYYYY] + 10.0 * S.XXXXYYZZ * D.da[rXXXYY] + S.XXXXXXYY * D.da[rXXXXX];
384 
385  res.da[dXYY] = S.XXXXXXYY * D.da[rZZZZZ] + 10.0 * S.XXXXYYYY * D.da[rYYZZZ] + 10.0 * S.XXXXYYZZ * D.da[rXXZZZ] +
386  5.0 * S.XXXXXXYY * D.da[rYYYYZ] + 30.0 * S.XXXXYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXYYZZ * D.da[rXXXXZ];
387 
388  res.da[dXYZ] = 20.0 * S.XXXXYYZZ * D.da[rXYZZZ] + 20.0 * S.XXXXYYZZ * D.da[rXYYYZ] + 20.0 * S.XXXXYYZZ * D.da[rXXXYZ];
389 
390  res.da[dXZZ] = S.XXXXXXYY * D.da[rZZZZZ] + 10.0 * S.XXXXYYZZ * D.da[rYYZZZ] + 10.0 * S.XXXXYYYY * D.da[rXXZZZ] +
391  5.0 * S.XXXXYYZZ * D.da[rYYYYZ] + 30.0 * S.XXXXYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXXXYY * D.da[rXXXXZ];
392 
393  res.da[dYYY] = 5.0 * S.XXXXYYYY * D.da[rYZZZZ] + 10.0 * S.XXXXXXYY * D.da[rYYYZZ] + 30.0 * S.XXXXYYZZ * D.da[rXXYZZ] +
394  S.XXXXXXXX * D.da[rYYYYY] + 10.0 * S.XXXXXXYY * D.da[rXXYYY] + 5.0 * S.XXXXYYYY * D.da[rXXXXY];
395 
396  res.da[dYYZ] = 5.0 * S.XXXXYYZZ * D.da[rXZZZZ] + 30.0 * S.XXXXYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXYYZZ * D.da[rXXXZZ] +
397  5.0 * S.XXXXXXYY * D.da[rXYYYY] + 10.0 * S.XXXXYYYY * D.da[rXXXYY] + S.XXXXXXYY * D.da[rXXXXX];
398 
399  res.da[dYZZ] = 5.0 * S.XXXXYYZZ * D.da[rYZZZZ] + 10.0 * S.XXXXYYZZ * D.da[rYYYZZ] + 30.0 * S.XXXXYYZZ * D.da[rXXYZZ] +
400  S.XXXXXXYY * D.da[rYYYYY] + 10.0 * S.XXXXYYYY * D.da[rXXYYY] + 5.0 * S.XXXXXXYY * D.da[rXXXXY];
401 
402  res.da[dZZZ] = 5.0 * S.XXXXYYYY * D.da[rXZZZZ] + 30.0 * S.XXXXYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXXXYY * D.da[rXXXZZ] +
403  5.0 * S.XXXXYYYY * D.da[rXYYYY] + 10.0 * S.XXXXXXYY * D.da[rXXXYY] + S.XXXXXXXX * D.da[rXXXXX];
404 
405  return res;
406 }
407 
408 // contract a 4-ewaldtensor with a symmetric 0-tensor to yield a 4-tensor
409 template <typename T>
410 inline symtensor4<T> operator*(const ewaldtensor4<T> &S, const T &Q0)
411 {
412  symtensor4<T> res;
413 
414  res.da[sXXXX] = S.XXXX * Q0;
415 
416  res.da[sXXXY] = 0.0;
417 
418  res.da[sXXXZ] = 0.0;
419 
420  res.da[sXXYY] = S.XXYY * Q0;
421 
422  res.da[sXXYZ] = 0.0;
423 
424  res.da[sXXZZ] = S.XXYY * Q0;
425 
426  res.da[sXYYY] = 0.0;
427 
428  res.da[sXYYZ] = 0.0;
429 
430  res.da[sXYZZ] = 0.0;
431 
432  res.da[sXZZZ] = 0.0;
433 
434  res.da[sYYYY] = S.XXXX * Q0;
435 
436  res.da[sYYYZ] = 0.0;
437 
438  res.da[sYYZZ] = S.XXYY * Q0;
439 
440  res.da[sYZZZ] = 0.0;
441 
442  res.da[sZZZZ] = S.XXXX * Q0;
443 
444  return res;
445 }
446 
447 // contract a 6-ewaldtensor with a symmetric 2-tensor to yield a 4-tensor
448 template <typename T>
450 {
451  symtensor4<T> res;
452 
453  res.da[sXXXX] = S.XXXXXX * D.da[qZZ] + S.XXXXYY * D.da[qYY] + S.XXXXYY * D.da[qXX];
454 
455  res.da[sXXXY] = 2.0 * S.XXXXYY * D.da[qYZ];
456 
457  res.da[sXXXZ] = 2.0 * S.XXXXYY * D.da[qXZ];
458 
459  res.da[sXXYY] = S.XXXXYY * D.da[qZZ] + S.XXXXYY * D.da[qYY] + S.XXYYZZ * D.da[qXX];
460 
461  res.da[sXXYZ] = 2.0 * S.XXYYZZ * D.da[qXY];
462 
463  res.da[sXXZZ] = S.XXXXYY * D.da[qZZ] + S.XXYYZZ * D.da[qYY] + S.XXXXYY * D.da[qXX];
464 
465  res.da[sXYYY] = 2.0 * S.XXXXYY * D.da[qYZ];
466 
467  res.da[sXYYZ] = 2.0 * S.XXYYZZ * D.da[qXZ];
468 
469  res.da[sXYZZ] = 2.0 * S.XXYYZZ * D.da[qYZ];
470 
471  res.da[sXZZZ] = 2.0 * S.XXXXYY * D.da[qXZ];
472 
473  res.da[sYYYY] = S.XXXXYY * D.da[qZZ] + S.XXXXXX * D.da[qYY] + S.XXXXYY * D.da[qXX];
474 
475  res.da[sYYYZ] = 2.0 * S.XXXXYY * D.da[qXY];
476 
477  res.da[sYYZZ] = S.XXYYZZ * D.da[qZZ] + S.XXXXYY * D.da[qYY] + S.XXXXYY * D.da[qXX];
478 
479  res.da[sYZZZ] = 2.0 * S.XXXXYY * D.da[qXY];
480 
481  res.da[sZZZZ] = S.XXXXYY * D.da[qZZ] + S.XXXXYY * D.da[qYY] + S.XXXXXX * D.da[qXX];
482  return res;
483 }
484 
485 // contract a 8-ewaldtensor with a symmetric 4-tensor to yield a 4-tensor
486 template <typename T>
488 {
489  symtensor4<T> res;
490 
491  res.da[sXXXX] = S.XXXXXXXX * D.da[sZZZZ] + 6.0 * S.XXXXXXYY * D.da[sYYZZ] + 6.0 * S.XXXXXXYY * D.da[sXXZZ] +
492  S.XXXXYYYY * D.da[sYYYY] + 6.0 * S.XXXXYYZZ * D.da[sXXYY] + S.XXXXYYYY * D.da[sXXXX];
493 
494  res.da[sXXXY] = 4.0 * S.XXXXXXYY * D.da[sYZZZ] + 4.0 * S.XXXXYYYY * D.da[sYYYZ] + 12.0 * S.XXXXYYZZ * D.da[sXXYZ];
495 
496  res.da[sXXXZ] = 4.0 * S.XXXXXXYY * D.da[sXZZZ] + 12.0 * S.XXXXYYZZ * D.da[sXYYZ] + 4.0 * S.XXXXYYYY * D.da[sXXXZ];
497 
498  res.da[sXXYY] = S.XXXXXXYY * D.da[sZZZZ] + 6.0 * S.XXXXYYYY * D.da[sYYZZ] + 6.0 * S.XXXXYYZZ * D.da[sXXZZ] +
499  S.XXXXXXYY * D.da[sYYYY] + 6.0 * S.XXXXYYZZ * D.da[sXXYY] + S.XXXXYYZZ * D.da[sXXXX];
500 
501  res.da[sXXYZ] = 12.0 * S.XXXXYYZZ * D.da[sXYZZ] + 4.0 * S.XXXXYYZZ * D.da[sXYYY] + 4.0 * S.XXXXYYZZ * D.da[sXXXY];
502 
503  res.da[sXXZZ] = S.XXXXXXYY * D.da[sZZZZ] + 6.0 * S.XXXXYYZZ * D.da[sYYZZ] + 6.0 * S.XXXXYYYY * D.da[sXXZZ] +
504  S.XXXXYYZZ * D.da[sYYYY] + 6.0 * S.XXXXYYZZ * D.da[sXXYY] + S.XXXXXXYY * D.da[sXXXX];
505 
506  res.da[sXYYY] = 4.0 * S.XXXXYYYY * D.da[sYZZZ] + 4.0 * S.XXXXXXYY * D.da[sYYYZ] + 12.0 * S.XXXXYYZZ * D.da[sXXYZ];
507 
508  res.da[sXYYZ] = 4.0 * S.XXXXYYZZ * D.da[sXZZZ] + 12.0 * S.XXXXYYZZ * D.da[sXYYZ] + 4.0 * S.XXXXYYZZ * D.da[sXXXZ];
509 
510  res.da[sXYZZ] = 4.0 * S.XXXXYYZZ * D.da[sYZZZ] + 4.0 * S.XXXXYYZZ * D.da[sYYYZ] + 12.0 * S.XXXXYYZZ * D.da[sXXYZ];
511 
512  res.da[sXZZZ] = 4.0 * S.XXXXYYYY * D.da[sXZZZ] + 12.0 * S.XXXXYYZZ * D.da[sXYYZ] + 4.0 * S.XXXXXXYY * D.da[sXXXZ];
513 
514  res.da[sYYYY] = S.XXXXYYYY * D.da[sZZZZ] + 6.0 * S.XXXXXXYY * D.da[sYYZZ] + 6.0 * S.XXXXYYZZ * D.da[sXXZZ] +
515  S.XXXXXXXX * D.da[sYYYY] + 6.0 * S.XXXXXXYY * D.da[sXXYY] + S.XXXXYYYY * D.da[sXXXX];
516 
517  res.da[sYYYZ] = 12.0 * S.XXXXYYZZ * D.da[sXYZZ] + 4.0 * S.XXXXXXYY * D.da[sXYYY] + 4.0 * S.XXXXYYYY * D.da[sXXXY];
518 
519  res.da[sYYZZ] = S.XXXXYYZZ * D.da[sZZZZ] + 6.0 * S.XXXXYYZZ * D.da[sYYZZ] + 6.0 * S.XXXXYYZZ * D.da[sXXZZ] +
520  S.XXXXXXYY * D.da[sYYYY] + 6.0 * S.XXXXYYYY * D.da[sXXYY] + S.XXXXXXYY * D.da[sXXXX];
521 
522  res.da[sYZZZ] = 12.0 * S.XXXXYYZZ * D.da[sXYZZ] + 4.0 * S.XXXXYYYY * D.da[sXYYY] + 4.0 * S.XXXXXXYY * D.da[sXXXY];
523 
524  res.da[sZZZZ] = S.XXXXYYYY * D.da[sZZZZ] + 6.0 * S.XXXXYYZZ * D.da[sYYZZ] + 6.0 * S.XXXXXXYY * D.da[sXXZZ] +
525  S.XXXXYYYY * D.da[sYYYY] + 6.0 * S.XXXXXXYY * D.da[sXXYY] + S.XXXXXXXX * D.da[sXXXX];
526 
527  return res;
528 }
529 
530 // contract a 8-ewaldtensor with a symmetric 3-tensor to yield a 5-tensor
531 template <typename T>
533 {
534  symtensor5<T> res;
535 
536  res.da[rXXXXX] = S.XXXXXXXX * D.da[dZZZ] + 3.0 * S.XXXXXXYY * D.da[dYYZ] + 3.0 * S.XXXXXXYY * D.da[dXXZ];
537 
538  res.da[rXXXXY] = 3.0 * S.XXXXXXYY * D.da[dYZZ] + S.XXXXYYYY * D.da[dYYY] + 3.0 * S.XXXXYYZZ * D.da[dXXY];
539 
540  res.da[rXXXXZ] = 3.0 * S.XXXXXXYY * D.da[dXZZ] + 3.0 * S.XXXXYYZZ * D.da[dXYY] + S.XXXXYYYY * D.da[dXXX];
541 
542  res.da[rXXXYY] = S.XXXXXXYY * D.da[dZZZ] + 3.0 * S.XXXXYYYY * D.da[dYYZ] + 3.0 * S.XXXXYYZZ * D.da[dXXZ];
543 
544  res.da[rXXXYZ] = 6.0 * S.XXXXYYZZ * D.da[dXYZ];
545 
546  res.da[rXXXZZ] = S.XXXXXXYY * D.da[dZZZ] + 3.0 * S.XXXXYYZZ * D.da[dYYZ] + 3.0 * S.XXXXYYYY * D.da[dXXZ];
547 
548  res.da[rXXYYY] = 3.0 * S.XXXXYYYY * D.da[dYZZ] + S.XXXXXXYY * D.da[dYYY] + 3.0 * S.XXXXYYZZ * D.da[dXXY];
549 
550  res.da[rXXYYZ] = 3.0 * S.XXXXYYZZ * D.da[dXZZ] + 3.0 * S.XXXXYYZZ * D.da[dXYY] + S.XXXXYYZZ * D.da[dXXX];
551 
552  res.da[rXXYZZ] = 3.0 * S.XXXXYYZZ * D.da[dYZZ] + S.XXXXYYZZ * D.da[dYYY] + 3.0 * S.XXXXYYZZ * D.da[dXXY];
553 
554  res.da[rXXZZZ] = 3.0 * S.XXXXYYYY * D.da[dXZZ] + 3.0 * S.XXXXYYZZ * D.da[dXYY] + S.XXXXXXYY * D.da[dXXX];
555 
556  res.da[rXYYYY] = S.XXXXYYYY * D.da[dZZZ] + 3.0 * S.XXXXXXYY * D.da[dYYZ] + 3.0 * S.XXXXYYZZ * D.da[dXXZ];
557 
558  res.da[rXYYYZ] = 6.0 * S.XXXXYYZZ * D.da[dXYZ];
559 
560  res.da[rXYYZZ] = S.XXXXYYZZ * D.da[dZZZ] + 3.0 * S.XXXXYYZZ * D.da[dYYZ] + 3.0 * S.XXXXYYZZ * D.da[dXXZ];
561 
562  res.da[rXYZZZ] = 6.0 * S.XXXXYYZZ * D.da[dXYZ];
563 
564  res.da[rXZZZZ] = S.XXXXYYYY * D.da[dZZZ] + 3.0 * S.XXXXYYZZ * D.da[dYYZ] + 3.0 * S.XXXXXXYY * D.da[dXXZ];
565 
566  res.da[rYYYYY] = 3.0 * S.XXXXXXYY * D.da[dYZZ] + S.XXXXXXXX * D.da[dYYY] + 3.0 * S.XXXXXXYY * D.da[dXXY];
567 
568  res.da[rYYYYZ] = 3.0 * S.XXXXYYZZ * D.da[dXZZ] + 3.0 * S.XXXXXXYY * D.da[dXYY] + S.XXXXYYYY * D.da[dXXX];
569 
570  res.da[rYYYZZ] = 3.0 * S.XXXXYYZZ * D.da[dYZZ] + S.XXXXXXYY * D.da[dYYY] + 3.0 * S.XXXXYYYY * D.da[dXXY];
571 
572  res.da[rYYZZZ] = 3.0 * S.XXXXYYZZ * D.da[dXZZ] + 3.0 * S.XXXXYYYY * D.da[dXYY] + S.XXXXXXYY * D.da[dXXX];
573 
574  res.da[rYZZZZ] = 3.0 * S.XXXXYYZZ * D.da[dYZZ] + S.XXXXYYYY * D.da[dYYY] + 3.0 * S.XXXXXXYY * D.da[dXXY];
575 
576  res.da[rZZZZZ] = 3.0 * S.XXXXXXYY * D.da[dXZZ] + 3.0 * S.XXXXXXYY * D.da[dXYY] + S.XXXXXXXX * D.da[dXXX];
577 
578  return res;
579 }
580 
581 // contract a a 10-ewaldtensor with a symmetric 5-tensor to yield a 5-tensor
582 template <typename T>
584 {
585  symtensor5<T> res;
586 
587  res.da[rXXXXX] = S.XXXXXXXXXX * D.da[rZZZZZ] + 10.0 * S.XXXXXXXXYY * D.da[rYYZZZ] + 10.0 * S.XXXXXXXXYY * D.da[rXXZZZ] +
588  5.0 * S.XXXXXXYYYY * D.da[rYYYYZ] + 30.0 * S.XXXXXXYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXXXYYYY * D.da[rXXXXZ];
589 
590  res.da[rXXXXY] = 5.0 * S.XXXXXXXXYY * D.da[rYZZZZ] + 10.0 * S.XXXXXXYYYY * D.da[rYYYZZ] + 30.0 * S.XXXXXXYYZZ * D.da[rXXYZZ] +
591  S.XXXXXXYYYY * D.da[rYYYYY] + 10.0 * S.XXXXYYYYZZ * D.da[rXXYYY] + 5.0 * S.XXXXYYYYZZ * D.da[rXXXXY];
592 
593  res.da[rXXXXZ] = 5.0 * S.XXXXXXXXYY * D.da[rXZZZZ] + 30.0 * S.XXXXXXYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXXXYYYY * D.da[rXXXZZ] +
594  5.0 * S.XXXXYYYYZZ * D.da[rXYYYY] + 10.0 * S.XXXXYYYYZZ * D.da[rXXXYY] + S.XXXXXXYYYY * D.da[rXXXXX];
595 
596  res.da[rXXXYY] = S.XXXXXXXXYY * D.da[rZZZZZ] + 10.0 * S.XXXXXXYYYY * D.da[rYYZZZ] + 10.0 * S.XXXXXXYYZZ * D.da[rXXZZZ] +
597  5.0 * S.XXXXXXYYYY * D.da[rYYYYZ] + 30.0 * S.XXXXYYYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXYYYYZZ * D.da[rXXXXZ];
598 
599  res.da[rXXXYZ] = 20.0 * S.XXXXXXYYZZ * D.da[rXYZZZ] + 20.0 * S.XXXXYYYYZZ * D.da[rXYYYZ] + 20.0 * S.XXXXYYYYZZ * D.da[rXXXYZ];
600 
601  res.da[rXXXZZ] = S.XXXXXXXXYY * D.da[rZZZZZ] + 10.0 * S.XXXXXXYYZZ * D.da[rYYZZZ] + 10.0 * S.XXXXXXYYYY * D.da[rXXZZZ] +
602  5.0 * S.XXXXYYYYZZ * D.da[rYYYYZ] + 30.0 * S.XXXXYYYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXXXYYYY * D.da[rXXXXZ];
603 
604  res.da[rXXYYY] = 5.0 * S.XXXXXXYYYY * D.da[rYZZZZ] + 10.0 * S.XXXXXXYYYY * D.da[rYYYZZ] + 30.0 * S.XXXXYYYYZZ * D.da[rXXYZZ] +
605  S.XXXXXXXXYY * D.da[rYYYYY] + 10.0 * S.XXXXXXYYZZ * D.da[rXXYYY] + 5.0 * S.XXXXYYYYZZ * D.da[rXXXXY];
606 
607  res.da[rXXYYZ] = 5.0 * S.XXXXXXYYZZ * D.da[rXZZZZ] + 30.0 * S.XXXXYYYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXYYYYZZ * D.da[rXXXZZ] +
608  5.0 * S.XXXXXXYYZZ * D.da[rXYYYY] + 10.0 * S.XXXXYYYYZZ * D.da[rXXXYY] + S.XXXXXXYYZZ * D.da[rXXXXX];
609 
610  res.da[rXXYZZ] = 5.0 * S.XXXXXXYYZZ * D.da[rYZZZZ] + 10.0 * S.XXXXYYYYZZ * D.da[rYYYZZ] + 30.0 * S.XXXXYYYYZZ * D.da[rXXYZZ] +
611  S.XXXXXXYYZZ * D.da[rYYYYY] + 10.0 * S.XXXXYYYYZZ * D.da[rXXYYY] + 5.0 * S.XXXXXXYYZZ * D.da[rXXXXY];
612 
613  res.da[rXXZZZ] = 5.0 * S.XXXXXXYYYY * D.da[rXZZZZ] + 30.0 * S.XXXXYYYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXXXYYYY * D.da[rXXXZZ] +
614  5.0 * S.XXXXYYYYZZ * D.da[rXYYYY] + 10.0 * S.XXXXXXYYZZ * D.da[rXXXYY] + S.XXXXXXXXYY * D.da[rXXXXX];
615 
616  res.da[rXYYYY] = S.XXXXXXYYYY * D.da[rZZZZZ] + 10.0 * S.XXXXXXYYYY * D.da[rYYZZZ] + 10.0 * S.XXXXYYYYZZ * D.da[rXXZZZ] +
617  5.0 * S.XXXXXXXXYY * D.da[rYYYYZ] + 30.0 * S.XXXXXXYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXYYYYZZ * D.da[rXXXXZ];
618 
619  res.da[rXYYYZ] = 20.0 * S.XXXXYYYYZZ * D.da[rXYZZZ] + 20.0 * S.XXXXXXYYZZ * D.da[rXYYYZ] + 20.0 * S.XXXXYYYYZZ * D.da[rXXXYZ];
620 
621  res.da[rXYYZZ] = S.XXXXXXYYZZ * D.da[rZZZZZ] + 10.0 * S.XXXXYYYYZZ * D.da[rYYZZZ] + 10.0 * S.XXXXYYYYZZ * D.da[rXXZZZ] +
622  5.0 * S.XXXXXXYYZZ * D.da[rYYYYZ] + 30.0 * S.XXXXYYYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXXXYYZZ * D.da[rXXXXZ];
623 
624  res.da[rXYZZZ] = 20.0 * S.XXXXYYYYZZ * D.da[rXYZZZ] + 20.0 * S.XXXXYYYYZZ * D.da[rXYYYZ] + 20.0 * S.XXXXXXYYZZ * D.da[rXXXYZ];
625 
626  res.da[rXZZZZ] = S.XXXXXXYYYY * D.da[rZZZZZ] + 10.0 * S.XXXXYYYYZZ * D.da[rYYZZZ] + 10.0 * S.XXXXXXYYYY * D.da[rXXZZZ] +
627  5.0 * S.XXXXYYYYZZ * D.da[rYYYYZ] + 30.0 * S.XXXXXXYYZZ * D.da[rXXYYZ] + 5.0 * S.XXXXXXXXYY * D.da[rXXXXZ];
628 
629  res.da[rYYYYY] = 5.0 * S.XXXXXXYYYY * D.da[rYZZZZ] + 10.0 * S.XXXXXXXXYY * D.da[rYYYZZ] + 30.0 * S.XXXXXXYYZZ * D.da[rXXYZZ] +
630  S.XXXXXXXXXX * D.da[rYYYYY] + 10.0 * S.XXXXXXXXYY * D.da[rXXYYY] + 5.0 * S.XXXXXXYYYY * D.da[rXXXXY];
631 
632  res.da[rYYYYZ] = 5.0 * S.XXXXYYYYZZ * D.da[rXZZZZ] + 30.0 * S.XXXXXXYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXYYYYZZ * D.da[rXXXZZ] +
633  5.0 * S.XXXXXXXXYY * D.da[rXYYYY] + 10.0 * S.XXXXXXYYYY * D.da[rXXXYY] + S.XXXXXXYYYY * D.da[rXXXXX];
634 
635  res.da[rYYYZZ] = 5.0 * S.XXXXYYYYZZ * D.da[rYZZZZ] + 10.0 * S.XXXXXXYYZZ * D.da[rYYYZZ] + 30.0 * S.XXXXYYYYZZ * D.da[rXXYZZ] +
636  S.XXXXXXXXYY * D.da[rYYYYY] + 10.0 * S.XXXXXXYYYY * D.da[rXXYYY] + 5.0 * S.XXXXXXYYYY * D.da[rXXXXY];
637 
638  res.da[rYYZZZ] = 5.0 * S.XXXXYYYYZZ * D.da[rXZZZZ] + 30.0 * S.XXXXYYYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXXXYYZZ * D.da[rXXXZZ] +
639  5.0 * S.XXXXXXYYYY * D.da[rXYYYY] + 10.0 * S.XXXXXXYYYY * D.da[rXXXYY] + S.XXXXXXXXYY * D.da[rXXXXX];
640 
641  res.da[rYZZZZ] = 5.0 * S.XXXXYYYYZZ * D.da[rYZZZZ] + 10.0 * S.XXXXYYYYZZ * D.da[rYYYZZ] + 30.0 * S.XXXXXXYYZZ * D.da[rXXYZZ] +
642  S.XXXXXXYYYY * D.da[rYYYYY] + 10.0 * S.XXXXXXYYYY * D.da[rXXYYY] + 5.0 * S.XXXXXXXXYY * D.da[rXXXXY];
643 
644  res.da[rZZZZZ] = 5.0 * S.XXXXXXYYYY * D.da[rXZZZZ] + 30.0 * S.XXXXXXYYZZ * D.da[rXYYZZ] + 10.0 * S.XXXXXXXXYY * D.da[rXXXZZ] +
645  5.0 * S.XXXXXXYYYY * D.da[rXYYYY] + 10.0 * S.XXXXXXXXYY * D.da[rXXXYY] + S.XXXXXXXXXX * D.da[rXXXXX];
646 
647  return res;
648 }
649 
650 #endif
ewaldtensor0 & operator+=(const ewaldtensor0 &right)
Definition: ewaldtensors.h:31
ewaldtensor0(const T x)
Definition: ewaldtensors.h:29
ewaldtensor10 & operator+=(const ewaldtensor10 &right)
Definition: ewaldtensors.h:169
ewaldtensor10(const T x)
Definition: ewaldtensors.h:160
ewaldtensor2(const T x)
Definition: ewaldtensors.h:49
ewaldtensor2 & operator+=(const ewaldtensor2 &right)
Definition: ewaldtensors.h:51
ewaldtensor4 & operator+=(const ewaldtensor4 &right)
Definition: ewaldtensors.h:76
ewaldtensor4(const T x)
Definition: ewaldtensors.h:70
ewaldtensor6 & operator+=(const ewaldtensor6 &right)
Definition: ewaldtensors.h:104
ewaldtensor6(const T x)
Definition: ewaldtensors.h:97
ewaldtensor8(const T x)
Definition: ewaldtensors.h:127
ewaldtensor8 & operator+=(const ewaldtensor8 &right)
Definition: ewaldtensors.h:135
T da[10]
Definition: symtensors.h:302
T da[15]
Definition: symtensors.h:432
T da[21]
Definition: symtensors.h:519
T da[3]
Definition: symtensors.h:106
ewaldtensor6< T > operator*(const double fac, const ewaldtensor6< T > &S)
Definition: ewaldtensors.h:183
#define sXXYY
#define rYZZZZ
#define rXXYZZ
#define sZZZZ
#define dYZZ
#define rYYZZZ
#define sXXXY
#define sXXXX
#define rXXZZZ
#define sYYZZ
#define dXYY
#define rXXXYY
#define sXXYZ
#define qXX
#define sXYYZ
#define dZZZ
#define rXXXYZ
#define dYYY
#define dXYZ
#define sYYYZ
#define rXXYYY
#define rXXXXZ
#define sXZZZ
#define qYY
#define rXXXXY
#define rYYYYZ
#define rXYYYZ
#define qYZ
#define sYYYY
#define rXYYYY
#define sXYYY
#define dXXY
#define dXXX
#define dXXZ
#define rYYYZZ
#define dYYZ
#define rXXXXX
#define rXXYYZ
#define sXYZZ
#define qZZ
#define rZZZZZ
#define rXXXZZ
#define rXYYZZ
#define sXXXZ
#define sYZZZ
#define sXXZZ
#define qXY
#define rXYZZZ
#define rYYYYY
#define dXZZ
#define rXZZZZ
#define qXZ