GADGET-4
symtensors.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 SYMTENSORS_H
13 #define SYMTENSORS_H
14 
15 #include "symtensor_indices.h"
16 
17 void symtensor_test(void);
18 
19 template <typename T1, typename T2>
20 struct which_return;
21 
22 template <typename T>
23 struct which_return<T, T>
24 {
25  typedef T type;
26 };
27 
28 template <>
29 struct which_return<float, double>
30 {
31  typedef double type;
32 };
33 
34 template <>
35 struct which_return<double, float>
36 {
37  typedef double type;
38 };
39 
40 template <>
41 struct which_return<int, float>
42 {
43  typedef float type;
44 };
45 
46 template <>
47 struct which_return<float, int>
48 {
49  typedef float type;
50 };
51 
52 template <>
53 struct which_return<int, double>
54 {
55  typedef double type;
56 };
57 
58 template <>
59 struct which_return<double, int>
60 {
61  typedef double type;
62 };
63 
64 /* with the above construction, the expression
65  *
66  * typename which_return<T1, T2>::type
67  *
68  * gives us now the more accurate type if mixed precisions are used for T1 and T2
69  */
70 
71 template <typename T>
72 struct compl_return;
73 
74 template <typename T>
76 {
77  typedef double type;
78 };
79 
80 template <>
81 struct compl_return<float>
82 {
83  typedef double type;
84 };
85 
86 template <>
87 struct compl_return<double>
88 {
89  typedef float type;
90 };
91 
92 /* with the above construction, the expression
93  *
94  * typename compl_return<T>::type
95  *
96  * gives us the type float of T is double, and the type double if T is type float (i.e. the complementary type)
97  * If T is another type, we'll get the type double
98  * We'll use this to define some implicit type casts.
99  */
100 
101 // vector
102 template <typename T>
103 class vector
104 {
105  public:
106  T da[3];
107 
108  vector() {} /* constructor */
109 
110  inline vector(const T x) /* constructor */
111  {
112  da[0] = x;
113  da[1] = x;
114  da[2] = x;
115  }
116 
117  inline vector(const T x, const T y, const T z) /* constructor */
118  {
119  da[0] = x;
120  da[1] = y;
121  da[2] = z;
122  }
123 
124  inline vector(const float *x) /* constructor */
125  {
126  da[0] = x[0];
127  da[1] = x[1];
128  da[2] = x[2];
129  }
130 
131  inline vector(const double *x) /* constructor */
132  {
133  da[0] = x[0];
134  da[1] = x[1];
135  da[2] = x[2];
136  }
137 
138  /* implicit conversion operator to type double or float as needed */
140  operator vector<float_or_double>() const { return vector<float_or_double>(da); }
141 
142  inline vector &operator+=(const vector<double> &right)
143  {
144  da[0] += right.da[0];
145  da[1] += right.da[1];
146  da[2] += right.da[2];
147 
148  return *this;
149  }
150 
151  inline vector &operator+=(const vector<float> &right)
152  {
153  da[0] += right.da[0];
154  da[1] += right.da[1];
155  da[2] += right.da[2];
156 
157  return *this;
158  }
159 
160  inline vector &operator-=(const vector<double> &right)
161  {
162  da[0] -= right.da[0];
163  da[1] -= right.da[1];
164  da[2] -= right.da[2];
165 
166  return *this;
167  }
168 
169  inline vector &operator-=(const vector<float> &right)
170  {
171  da[0] -= right.da[0];
172  da[1] -= right.da[1];
173  da[2] -= right.da[2];
174 
175  return *this;
176  }
177 
178  inline vector &operator*=(const T fac)
179  {
180  da[0] *= fac;
181  da[1] *= fac;
182  da[2] *= fac;
183 
184  return *this;
185  }
186 
187  inline T r2(void) { return da[0] * da[0] + da[1] * da[1] + da[2] * da[2]; }
188 
189  inline double norm(void) { return sqrt(da[0] * da[0] + da[1] * da[1] + da[2] * da[2]); }
190 
191  inline T &operator[](const size_t index) { return da[index]; }
192 };
193 
194 // fully symmetric 2-tensor (i.e. symmetic 3x3 matrix)
195 template <typename T>
197 {
198  public:
199  T da[6];
200 
201  symtensor2() {} /* constructor */
202 
203  inline symtensor2(const T x) /* constructor */
204  {
205  da[0] = x;
206  da[1] = x;
207  da[2] = x;
208  da[3] = x;
209  da[4] = x;
210  da[5] = x;
211  }
212 
213  inline symtensor2(const float *x) /* constructor */
214  {
215  da[0] = x[0];
216  da[1] = x[1];
217  da[2] = x[2];
218  da[3] = x[3];
219  da[4] = x[4];
220  da[5] = x[5];
221  }
222 
223  inline symtensor2(const double *x) /* constructor */
224  {
225  da[0] = x[0];
226  da[1] = x[1];
227  da[2] = x[2];
228  da[3] = x[3];
229  da[4] = x[4];
230  da[5] = x[5];
231  }
232 
233  /* implicit conversion operator to type float or double as needed */
236 
237  inline symtensor2(const vector<T> &v, const vector<T> &w) /* constructor based on the outer product of two vectors */
238  {
239  da[qXX] = v.da[0] * w.da[0];
240  da[qYY] = v.da[1] * w.da[1];
241  da[qZZ] = v.da[2] * w.da[2];
242  da[qXY] = v.da[0] * w.da[1];
243  da[qXZ] = v.da[0] * w.da[2];
244  da[qYZ] = v.da[1] * w.da[2];
245  }
246 
247  inline symtensor2 &operator+=(const symtensor2 &right)
248  {
249  da[0] += right.da[0];
250  da[1] += right.da[1];
251  da[2] += right.da[2];
252  da[3] += right.da[3];
253  da[4] += right.da[4];
254  da[5] += right.da[5];
255 
256  return *this;
257  }
258 
259  inline symtensor2 &operator-=(const symtensor2 &right)
260  {
261  da[0] -= right.da[0];
262  da[1] -= right.da[1];
263  da[2] -= right.da[2];
264  da[3] -= right.da[3];
265  da[4] -= right.da[4];
266  da[5] -= right.da[5];
267 
268  return *this;
269  }
270 
271  inline symtensor2 &operator*=(const T fac)
272  {
273  da[0] *= fac;
274  da[1] *= fac;
275  da[2] *= fac;
276  da[3] *= fac;
277  da[4] *= fac;
278  da[5] *= fac;
279 
280  return *this;
281  }
282 
283  inline T &operator[](const size_t index) { return da[index]; }
284 
285  inline T trace(void) { return da[qXX] + da[qYY] + da[qZZ]; }
286 
287  inline double norm(void)
288  {
289  double sum2 = 0;
290  for(int i = 0; i < 6; i++)
291  sum2 += da[i] * da[i];
292 
293  return sqrt(sum2 / 6);
294  }
295 };
296 
297 // fully symmetric 3-tensor (3x3x3)
298 template <typename T>
300 {
301  public:
302  T da[10];
303 
304  symtensor3() {} /* constructor */
305 
306  inline symtensor3(const T x) /* constructor */
307  {
308  da[0] = x;
309  da[1] = x;
310  da[2] = x;
311  da[3] = x;
312  da[4] = x;
313  da[5] = x;
314  da[6] = x;
315  da[7] = x;
316  da[8] = x;
317  da[9] = x;
318  }
319 
320  inline symtensor3(const float *x) /* constructor */
321  {
322  da[0] = x[0];
323  da[1] = x[1];
324  da[2] = x[2];
325  da[3] = x[3];
326  da[4] = x[4];
327  da[5] = x[5];
328  da[6] = x[6];
329  da[7] = x[7];
330  da[8] = x[8];
331  da[9] = x[9];
332  }
333 
334  inline symtensor3(const double *x) /* constructor */
335  {
336  da[0] = x[0];
337  da[1] = x[1];
338  da[2] = x[2];
339  da[3] = x[3];
340  da[4] = x[4];
341  da[5] = x[5];
342  da[6] = x[6];
343  da[7] = x[7];
344  da[8] = x[8];
345  da[9] = x[9];
346  }
347 
348  /* implicit conversion operator to type float or double as needed */
351 
352  /* constructor based on the outer product */
353  inline symtensor3(const vector<T> &v, const symtensor2<T> &D)
354  {
355  da[dXXX] = D.da[qXX] * v.da[0];
356  da[dXXY] = D.da[qXX] * v.da[1];
357  da[dXXZ] = D.da[qXX] * v.da[2];
358  da[dXYY] = D.da[qXY] * v.da[1];
359  da[dXYZ] = D.da[qXY] * v.da[2];
360  da[dXZZ] = D.da[qXZ] * v.da[2];
361  da[dYYY] = D.da[qYY] * v.da[1];
362  da[dYYZ] = D.da[qYY] * v.da[2];
363  da[dYZZ] = D.da[qYZ] * v.da[2];
364  da[dZZZ] = D.da[qZZ] * v.da[2];
365  }
366 
367  inline symtensor3 &operator+=(const symtensor3 &right)
368  {
369  da[0] += right.da[0];
370  da[1] += right.da[1];
371  da[2] += right.da[2];
372  da[3] += right.da[3];
373  da[4] += right.da[4];
374  da[5] += right.da[5];
375  da[6] += right.da[6];
376  da[7] += right.da[7];
377  da[8] += right.da[8];
378  da[9] += right.da[9];
379 
380  return *this;
381  }
382 
383  inline symtensor3 &operator-=(const symtensor3 &right)
384  {
385  da[0] -= right.da[0];
386  da[1] -= right.da[1];
387  da[2] -= right.da[2];
388  da[3] -= right.da[3];
389  da[4] -= right.da[4];
390  da[5] -= right.da[5];
391  da[6] -= right.da[6];
392  da[7] -= right.da[7];
393  da[8] -= right.da[8];
394  da[9] -= right.da[9];
395 
396  return *this;
397  }
398 
399  inline symtensor3 &operator*=(const T fac)
400  {
401  da[0] *= fac;
402  da[1] *= fac;
403  da[2] *= fac;
404  da[3] *= fac;
405  da[4] *= fac;
406  da[5] *= fac;
407  da[6] *= fac;
408  da[7] *= fac;
409  da[8] *= fac;
410  da[9] *= fac;
411 
412  return *this;
413  }
414 
415  inline T &operator[](const size_t index) { return da[index]; }
416 
417  inline double norm(void)
418  {
419  double sum2 = 0;
420  for(int i = 0; i < 10; i++)
421  sum2 += da[i] * da[i];
422 
423  return sqrt(sum2 / 10);
424  }
425 };
426 
427 // fully symmetric 4-tensor (3x3x3x3)
428 template <typename T>
430 {
431  public:
432  T da[15];
433 
434  symtensor4() {} /* constructor */
435 
436  inline symtensor4(const T x) /* constructor */
437  {
438  for(int i = 0; i < 15; i++)
439  da[i] = x;
440  }
441 
442  inline symtensor4(const float *x) /* constructor */
443  {
444  for(int i = 0; i < 15; i++)
445  da[i] = x[i];
446  }
447 
448  inline symtensor4(const double *x) /* constructor */
449  {
450  for(int i = 0; i < 15; i++)
451  da[i] = x[i];
452  }
453 
454  /* implicit conversion operator to type float or double as needed */
457 
458  /* constructor based on an outer product */
459  inline symtensor4(const vector<T> &v, const symtensor3<T> &D)
460  {
461  da[sXXXX] = D.da[dXXX] * v.da[0];
462  da[sXXXY] = D.da[dXXX] * v.da[1];
463  da[sXXXZ] = D.da[dXXX] * v.da[2];
464  da[sXXYY] = D.da[dXXY] * v.da[1];
465  da[sXXYZ] = D.da[dXXY] * v.da[2];
466  da[sXXZZ] = D.da[dXXZ] * v.da[2];
467  da[sXYYY] = D.da[dXYY] * v.da[1];
468  da[sXYYZ] = D.da[dXYY] * v.da[2];
469  da[sXYZZ] = D.da[dXYZ] * v.da[2];
470  da[sXZZZ] = D.da[dXZZ] * v.da[2];
471  da[sYYYY] = D.da[dYYY] * v.da[1];
472  da[sYYYZ] = D.da[dYYY] * v.da[2];
473  da[sYYZZ] = D.da[dYYZ] * v.da[2];
474  da[sYZZZ] = D.da[dYZZ] * v.da[2];
475  da[sZZZZ] = D.da[dZZZ] * v.da[2];
476  }
477 
478  inline symtensor4 &operator+=(const symtensor4 &right)
479  {
480  for(int i = 0; i < 15; i++)
481  da[i] += right.da[i];
482 
483  return *this;
484  }
485 
486  inline symtensor4 &operator-=(const symtensor4 &right)
487  {
488  for(int i = 0; i < 15; i++)
489  da[i] -= right.da[i];
490 
491  return *this;
492  }
493 
494  inline symtensor4 &operator*=(const T fac)
495  {
496  for(int i = 0; i < 15; i++)
497  da[i] *= fac;
498 
499  return *this;
500  }
501 
502  inline T &operator[](const size_t index) { return da[index]; }
503 
504  inline double norm(void)
505  {
506  double sum2 = 0;
507  for(int i = 0; i < 15; i++)
508  sum2 += da[i] * da[i];
509 
510  return sqrt(sum2 / 15);
511  }
512 };
513 
514 // fully symmetric 5-tensor (3x3x3x3x3)
515 template <typename T>
517 {
518  public:
519  T da[21];
520 
521  symtensor5() {} /* constructor */
522 
523  inline symtensor5(const T x) /* constructor */
524  {
525  for(int i = 0; i < 21; i++)
526  da[i] = x;
527  }
528 
529  inline symtensor5(const float *x) /* constructor */
530  {
531  for(int i = 0; i < 21; i++)
532  da[i] = x[i];
533  }
534 
535  inline symtensor5(const double *x) /* constructor */
536  {
537  for(int i = 0; i < 21; i++)
538  da[i] = x[i];
539  }
540 
541  /* implicit conversion operator to type float or double as needed */
544 
545  /* constructor based on an outer product */
546  inline symtensor5(const vector<T> &v, const symtensor4<T> &D)
547  {
548  da[rXXXXX] = D.da[sXXXX] * v.da[0];
549  da[rXXXXY] = D.da[sXXXX] * v.da[1];
550  da[rXXXXZ] = D.da[sXXXX] * v.da[2];
551  da[rXXXYY] = D.da[sXXXY] * v.da[1];
552  da[rXXXYZ] = D.da[sXXXY] * v.da[2];
553  da[rXXXZZ] = D.da[sXXXZ] * v.da[2];
554  da[rXXYYY] = D.da[sXXYY] * v.da[1];
555  da[rXXYYZ] = D.da[sXXYY] * v.da[2];
556  da[rXXYZZ] = D.da[sXXYZ] * v.da[2];
557  da[rXXZZZ] = D.da[sXXZZ] * v.da[2];
558  da[rXYYYY] = D.da[sXYYY] * v.da[1];
559  da[rXYYYZ] = D.da[sXYYY] * v.da[2];
560  da[rXYYZZ] = D.da[sXYYZ] * v.da[2];
561  da[rXYZZZ] = D.da[sXYZZ] * v.da[2];
562  da[rXZZZZ] = D.da[sXZZZ] * v.da[2];
563  da[rYYYYY] = D.da[sYYYY] * v.da[1];
564  da[rYYYYZ] = D.da[sYYYY] * v.da[2];
565  da[rYYYZZ] = D.da[sYYYZ] * v.da[2];
566  da[rYYZZZ] = D.da[sYYZZ] * v.da[2];
567  da[rYZZZZ] = D.da[sYZZZ] * v.da[2];
568  da[rZZZZZ] = D.da[sZZZZ] * v.da[2];
569  }
570 
571  inline symtensor5 &operator+=(const symtensor5 &right)
572  {
573  for(int i = 0; i < 21; i++)
574  da[i] += right.da[i];
575 
576  return *this;
577  }
578 
579  inline symtensor5 &operator-=(const symtensor5 &right)
580  {
581  for(int i = 0; i < 21; i++)
582  da[i] -= right.da[i];
583 
584  return *this;
585  }
586 
587  inline symtensor5 &operator*=(const T fac)
588  {
589  for(int i = 0; i < 21; i++)
590  da[i] *= fac;
591 
592  return *this;
593  }
594 
595  inline T &operator[](const size_t index) { return da[index]; }
596 
597  inline double norm(void)
598  {
599  double sum2 = 0;
600  for(int i = 0; i < 21; i++)
601  sum2 += da[i] * da[i];
602 
603  return sqrt(sum2 / 21);
604  }
605 };
606 
607 // fully symmetric 6-tensor (3x3x3x3x3x3)
608 template <typename T>
610 {
611  public:
612  T da[28];
613 
614  symtensor6() {} /* constructor */
615 
616  inline symtensor6(const T x) /* constructor */
617  {
618  for(int i = 0; i < 28; i++)
619  da[i] = x;
620  }
621 
622  inline symtensor6(const float *x) /* constructor */
623  {
624  for(int i = 0; i < 28; i++)
625  da[i] = x[i];
626  }
627 
628  inline symtensor6(const double *x) /* constructor */
629  {
630  for(int i = 0; i < 28; i++)
631  da[i] = x[i];
632  }
633 
634  /* implicit conversion operator to type float or double as needed */
637 
638  /* constructor based on an outer product */
639  inline symtensor6(const vector<T> &v, const symtensor5<T> &D)
640  {
641  da[pXXXXXX] = D.da[rXXXXX] * v.da[0];
642  da[pXXXXXY] = D.da[rXXXXX] * v.da[1];
643  da[pXXXXXZ] = D.da[rXXXXX] * v.da[2];
644  da[pXXXXYY] = D.da[rXXXXY] * v.da[1];
645  da[pXXXXYZ] = D.da[rXXXXY] * v.da[2];
646  da[pXXXXZZ] = D.da[rXXXXZ] * v.da[2];
647  da[pXXXYYY] = D.da[rXXXYY] * v.da[1];
648  da[pXXXYYZ] = D.da[rXXXYY] * v.da[2];
649  da[pXXXYZZ] = D.da[rXXXYZ] * v.da[2];
650  da[pXXXZZZ] = D.da[rXXXZZ] * v.da[2];
651  da[pXXYYYY] = D.da[rXXYYY] * v.da[1];
652  da[pXXYYYZ] = D.da[rXXYYY] * v.da[2];
653  da[pXXYYZZ] = D.da[rXXYYZ] * v.da[2];
654  da[pXXYZZZ] = D.da[rXXYZZ] * v.da[2];
655  da[pXXZZZZ] = D.da[rXXZZZ] * v.da[2];
656  da[pXYYYYY] = D.da[rXYYYY] * v.da[1];
657  da[pXYYYYZ] = D.da[rXYYYY] * v.da[2];
658  da[pXYYYZZ] = D.da[rXYYYZ] * v.da[2];
659  da[pXYYZZZ] = D.da[rXYYZZ] * v.da[2];
660  da[pXYZZZZ] = D.da[rXYZZZ] * v.da[2];
661  da[pXZZZZZ] = D.da[rXZZZZ] * v.da[2];
662  da[pYYYYYY] = D.da[rYYYYY] * v.da[1];
663  da[pYYYYYZ] = D.da[rYYYYY] * v.da[2];
664  da[pYYYYZZ] = D.da[rYYYYZ] * v.da[2];
665  da[pYYYZZZ] = D.da[rYYYZZ] * v.da[2];
666  da[pYYZZZZ] = D.da[rYYZZZ] * v.da[2];
667  da[pYZZZZZ] = D.da[rYZZZZ] * v.da[2];
668  da[pZZZZZZ] = D.da[rZZZZZ] * v.da[2];
669  }
670 
671  inline symtensor6 &operator+=(const symtensor6 &right)
672  {
673  for(int i = 0; i < 28; i++)
674  da[i] += right.da[i];
675 
676  return *this;
677  }
678 
679  inline symtensor6 &operator-=(const symtensor6 &right)
680  {
681  for(int i = 0; i < 28; i++)
682  da[i] -= right.da[i];
683 
684  return *this;
685  }
686 
687  inline symtensor6 &operator*=(const T fac)
688  {
689  for(int i = 0; i < 28; i++)
690  da[i] *= fac;
691 
692  return *this;
693  }
694 
695  inline T &operator[](const size_t index) { return da[index]; }
696 
697  inline double norm(void)
698  {
699  double sum2 = 0;
700  for(int i = 0; i < 28; i++)
701  sum2 += da[i] * da[i];
702 
703  return sqrt(sum2 / 28);
704  }
705 };
706 
707 // fully symmetric 7-tensor (3x3x3x3x3x3x3)
708 template <typename T>
710 {
711  public:
712  T da[36];
713 
714  symtensor7() {} /* constructor */
715 
716  inline symtensor7(const T x) /* constructor */
717  {
718  for(int i = 0; i < 36; i++)
719  da[i] = x;
720  }
721 
722  inline symtensor7(const float *x) /* constructor */
723  {
724  for(int i = 0; i < 36; i++)
725  da[i] = x[i];
726  }
727 
728  inline symtensor7(const double *x) /* constructor */
729  {
730  for(int i = 0; i < 36; i++)
731  da[i] = x[i];
732  }
733 
734  /* implicit conversion operator to type float or double as needed */
737 
738  inline symtensor7 &operator+=(const symtensor7 &right)
739  {
740  for(int i = 0; i < 36; i++)
741  da[i] += right.da[i];
742 
743  return *this;
744  }
745 
746  inline symtensor7 &operator-=(const symtensor7 &right)
747  {
748  for(int i = 0; i < 36; i++)
749  da[i] -= right.da[i];
750 
751  return *this;
752  }
753 
754  inline symtensor7 &operator*=(const T fac)
755  {
756  for(int i = 0; i < 36; i++)
757  da[i] *= fac;
758 
759  return *this;
760  }
761 
762  inline T &operator[](const size_t index) { return da[index]; }
763 
764  inline double norm(void)
765  {
766  double sum2 = 0;
767  for(int i = 0; i < 36; i++)
768  sum2 += da[i] * da[i];
769 
770  return sqrt(sum2 / 36);
771  }
772 };
773 
774 //------------- let's defined additions of these tensors
775 
776 // add two vectors
777 template <typename T1, typename T2>
779 {
781 
782  res.da[0] = left.da[0] + right.da[0];
783  res.da[1] = left.da[1] + right.da[1];
784  res.da[2] = left.da[2] + right.da[2];
785 
786  return res;
787 }
788 
789 // add two 2-tensors
790 template <typename T1, typename T2>
792 {
794 
795  for(int i = 0; i < 6; i++)
796  res.da[i] = left.da[i] + right.da[i];
797 
798  return res;
799 }
800 
801 // add two 3-tensors
802 template <typename T1, typename T2>
804 {
806 
807  for(int i = 0; i < 10; i++)
808  res.da[i] = left.da[i] + right.da[i];
809 
810  return res;
811 }
812 
813 // add two 4-tensors
814 template <typename T1, typename T2>
816 {
818 
819  for(int i = 0; i < 15; i++)
820  res.da[i] = left.da[i] + right.da[i];
821 
822  return res;
823 }
824 
825 // add two 5-tensors
826 template <typename T1, typename T2>
828 {
830 
831  for(int i = 0; i < 21; i++)
832  res.da[i] = left.da[i] + right.da[i];
833 
834  return res;
835 }
836 
837 // add two 6-tensors
838 template <typename T1, typename T2>
840 {
842 
843  for(int i = 0; i < 28; i++)
844  res.da[i] = left.da[i] + right.da[i];
845 
846  return res;
847 }
848 
849 // add two 7-tensors
850 template <typename T1, typename T2>
852 {
854 
855  for(int i = 0; i < 36; i++)
856  res.da[i] = left.da[i] + right.da[i];
857 
858  return res;
859 }
860 
861 //------------- let's defined subtractions of these tensors
862 
863 // subtract two vectors
864 template <typename T1, typename T2>
866 {
868 
869  res.da[0] = left.da[0] - right.da[0];
870  res.da[1] = left.da[1] - right.da[1];
871  res.da[2] = left.da[2] - right.da[2];
872 
873  return res;
874 }
875 
876 // subtract two 2-tensors
877 template <typename T1, typename T2>
879 {
881 
882  for(int i = 0; i < 6; i++)
883  res.da[i] = left.da[i] - right.da[i];
884 
885  return res;
886 }
887 
888 // subtract two 3-tensors
889 template <typename T1, typename T2>
891 {
893 
894  for(int i = 0; i < 10; i++)
895  res.da[i] = left.da[i] - right.da[i];
896 
897  return res;
898 }
899 
900 // subtract two 4-tensors
901 template <typename T1, typename T2>
903 {
905 
906  for(int i = 0; i < 15; i++)
907  res.da[i] = left.da[i] - right.da[i];
908 
909  return res;
910 }
911 
912 // subtract two 5-tensors
913 template <typename T1, typename T2>
915 {
917 
918  for(int i = 0; i < 21; i++)
919  res.da[i] = left.da[i] - right.da[i];
920 
921  return res;
922 }
923 
924 // subtract two 6-tensors
925 template <typename T1, typename T2>
927 {
929 
930  for(int i = 0; i < 28; i++)
931  res.da[i] = left.da[i] - right.da[i];
932 
933  return res;
934 }
935 
936 // subtract two 7-tensors
937 template <typename T1, typename T2>
939 {
941 
942  for(int i = 0; i < 36; i++)
943  res.da[i] = left.da[i] - right.da[i];
944 
945  return res;
946 }
947 
948 //------------- let's define multiplications with a scalar
949 
950 // scalar times vector multiply
951 template <typename T1, typename T2>
953 {
955  for(int i = 0; i < 3; i++)
956  res.da[i] = fac * v.da[i];
957 
958  return res;
959 }
960 
961 // scalar times 2-tensor multiply
962 template <typename T1, typename T2>
964 {
966  for(int i = 0; i < 6; i++)
967  res.da[i] = fac * v.da[i];
968 
969  return res;
970 }
971 
972 // scalar times 3-tensor multiply
973 template <typename T1, typename T2>
975 {
977  for(int i = 0; i < 10; i++)
978  res.da[i] = fac * v.da[i];
979 
980  return res;
981 }
982 
983 // scalar times 4-tensor multiply
984 template <typename T1, typename T2>
986 {
988  for(int i = 0; i < 15; i++)
989  res.da[i] = fac * v.da[i];
990 
991  return res;
992 }
993 
994 // scalar times 5-tensor multiply
995 template <typename T1, typename T2>
997 {
999  for(int i = 0; i < 21; i++)
1000  res.da[i] = fac * v.da[i];
1001 
1002  return res;
1003 }
1004 
1005 // scalar times 6-tensor multiply
1006 template <typename T1, typename T2>
1008 {
1010  for(int i = 0; i < 28; i++)
1011  res.da[i] = fac * v.da[i];
1012 
1013  return res;
1014 }
1015 
1016 // scalar 7-tensor multiply
1017 template <typename T1, typename T2>
1019 {
1021  for(int i = 0; i < 36; i++)
1022  res.da[i] = fac * v.da[i];
1023 
1024  return res;
1025 }
1026 
1027 //------------- let's defined contractions of these tensors
1028 
1029 // 2-tensor contraction with a vector (ordinary matrix-vector multiplication)
1030 template <typename T1, typename T2>
1032 {
1034 
1035  res.da[0] = D.da[qXX] * v.da[0] + D.da[qXY] * v.da[1] + D.da[qXZ] * v.da[2];
1036  res.da[1] = D.da[qYX] * v.da[0] + D.da[qYY] * v.da[1] + D.da[qYZ] * v.da[2];
1037  res.da[2] = D.da[qZX] * v.da[0] + D.da[qZY] * v.da[1] + D.da[qZZ] * v.da[2];
1038 
1039  return res;
1040 }
1041 
1042 // scalar product of two vectors
1043 template <typename T1, typename T2>
1044 inline typename which_return<T1, T2>::type operator*(const vector<T1> &v, const vector<T2> &w)
1045 {
1046  return v.da[0] * w.da[0] + v.da[1] * w.da[1] + v.da[2] * w.da[2];
1047 }
1048 
1049 // contract two 2-tensors to a scalar
1050 template <typename T1, typename T2>
1052 {
1053  return (D.da[qXX] * Q.da[qXX] + D.da[qYY] * Q.da[qYY] + D.da[qZZ] * Q.da[qZZ]) +
1054  2 * (D.da[qXY] * Q.da[qXY] + D.da[qXZ] * Q.da[qXZ] + D.da[qYZ] * Q.da[qYZ]);
1055 }
1056 
1057 // contract two 3-tensors to yield a scalar
1058 template <typename T1, typename T2>
1060 {
1061  return D.da[dXXX] * Q.da[dXXX] + D.da[dYYY] * Q.da[dYYY] + D.da[dZZZ] * Q.da[dZZZ] +
1062  3 * (D.da[dYZZ] * Q.da[dYZZ] + D.da[dYYZ] * Q.da[dYYZ] + D.da[dXZZ] * Q.da[dXZZ] + D.da[dXYY] * Q.da[dXYY] +
1063  D.da[dXXY] * Q.da[dXXY] + D.da[dXXZ] * Q.da[dXXZ]) +
1064  6 * D.da[dXYZ] * Q.da[dXYZ];
1065  ;
1066 }
1067 
1068 // contract a 4-tensor with a 4-tensor to yield a scalar
1069 template <typename T1, typename T2>
1070 inline typename which_return<T1, T2>::type operator*(const symtensor4<T1> &D, const symtensor4<T2> &Q) // checked
1071 {
1072  return D.da[sZZZZ] * Q.da[sZZZZ] + D.da[sYYYY] * Q.da[sYYYY] + D.da[sXXXX] * Q.da[sXXXX] +
1073  6 * (D.da[sYYZZ] * Q.da[sYYZZ] + D.da[sXXZZ] * Q.da[sXXZZ] + D.da[sXXYY] * Q.da[sXXYY]) +
1074  4 * (D.da[sYZZZ] * Q.da[sYZZZ] + D.da[sYYYZ] * Q.da[sYYYZ] + D.da[sXZZZ] * Q.da[sXZZZ] + D.da[sXYYY] * Q.da[sXYYY] +
1075  D.da[sXXXZ] * Q.da[sXXXZ] + D.da[sXXXY] * Q.da[sXXXY]) +
1076  12 * (D.da[sXYZZ] * Q.da[sXYZZ] + D.da[sXYYZ] * Q.da[sXYYZ] + D.da[sXXYZ] * Q.da[sXXYZ]);
1077 }
1078 
1079 // contract a 3-tensor with a vector to yield a 2-tensor
1080 template <typename T1, typename T2>
1082 {
1084 
1085  res.da[qXX] = D.da[dXXX] * v.da[0] + D.da[dXXY] * v.da[1] + D.da[dXXZ] * v.da[2];
1086  res.da[qYY] = D.da[dYYX] * v.da[0] + D.da[dYYY] * v.da[1] + D.da[dYYZ] * v.da[2];
1087  res.da[qZZ] = D.da[dZZX] * v.da[0] + D.da[dZZY] * v.da[1] + D.da[dZZZ] * v.da[2];
1088  res.da[qXY] = D.da[dXYX] * v.da[0] + D.da[dXYY] * v.da[1] + D.da[dXYZ] * v.da[2];
1089  res.da[qXZ] = D.da[dXZX] * v.da[0] + D.da[dXZY] * v.da[1] + D.da[dXZZ] * v.da[2];
1090  res.da[qYZ] = D.da[dYZX] * v.da[0] + D.da[dYZY] * v.da[1] + D.da[dYZZ] * v.da[2];
1091 
1092  return res;
1093 }
1094 
1095 // contract a 3-tensor with a 2-tensor to yield a vector
1096 template <typename T1, typename T2>
1098 {
1100 
1101  res.da[0] = (D.da[dXXX] * Q.da[qXX] + D.da[dXYY] * Q.da[qYY] + D.da[dXZZ] * Q.da[qZZ]) +
1102  2 * (D.da[dXXY] * Q.da[qXY] + D.da[dXXZ] * Q.da[qXZ] + D.da[dXYZ] * Q.da[qYZ]);
1103  res.da[1] = (D.da[dYXX] * Q.da[qXX] + D.da[dYYY] * Q.da[qYY] + D.da[dYZZ] * Q.da[qZZ]) +
1104  2 * (D.da[dYXY] * Q.da[qXY] + D.da[dYXZ] * Q.da[qXZ] + D.da[dYYZ] * Q.da[qYZ]);
1105  res.da[2] = (D.da[dZXX] * Q.da[qXX] + D.da[dZYY] * Q.da[qYY] + D.da[dZZZ] * Q.da[qZZ]) +
1106  2 * (D.da[dZXY] * Q.da[qXY] + D.da[dZXZ] * Q.da[qXZ] + D.da[dZYZ] * Q.da[qYZ]);
1107 
1108  return res;
1109 }
1110 
1111 // contract a 4-tensor with a 3-tensor to yield a vector
1112 template <typename T1, typename T2>
1114 {
1116 
1117  res[0] = D.da[sXXXX] * Q.da[dXXX] + D.da[sXYYY] * Q.da[dYYY] + D.da[sXZZZ] * Q.da[dZZZ] +
1118  3 * (D.da[sXYZZ] * Q.da[dYZZ] + D.da[sXYYZ] * Q.da[dYYZ] + D.da[sXXZZ] * Q.da[dXZZ] + D.da[sXXYY] * Q.da[dXYY] +
1119  D.da[sXXXY] * Q.da[dXXY] + D.da[sXXXZ] * Q.da[dXXZ]) +
1120  6 * D.da[sXXYZ] * Q.da[dXYZ];
1121 
1122  res[1] = D.da[sYXXX] * Q.da[dXXX] + D.da[sYYYY] * Q.da[dYYY] + D.da[sYZZZ] * Q.da[dZZZ] +
1123  3 * (D.da[sYYZZ] * Q.da[dYZZ] + D.da[sYYYZ] * Q.da[dYYZ] + D.da[sYXZZ] * Q.da[dXZZ] + D.da[sYXYY] * Q.da[dXYY] +
1124  D.da[sYXXY] * Q.da[dXXY] + D.da[sYXXZ] * Q.da[dXXZ]) +
1125  6 * D.da[sYXYZ] * Q.da[dXYZ];
1126 
1127  res[2] = D.da[sZXXX] * Q.da[dXXX] + D.da[sZYYY] * Q.da[dYYY] + D.da[sZZZZ] * Q.da[dZZZ] +
1128  3 * (D.da[sZYZZ] * Q.da[dYZZ] + D.da[sZYYZ] * Q.da[dYYZ] + D.da[sZXZZ] * Q.da[dXZZ] + D.da[sZXYY] * Q.da[dXYY] +
1129  D.da[sZXXY] * Q.da[dXXY] + D.da[sZXXZ] * Q.da[dXXZ]) +
1130  6 * D.da[sZXYZ] * Q.da[dXYZ];
1131 
1132  return res;
1133 }
1134 
1135 // contract a 4-tensor with a vector to yield a 3-tensor
1136 template <typename T1, typename T2>
1138 {
1140 
1141  res.da[dXXX] = D.da[sXXXX] * v.da[0] + D.da[sXXXY] * v.da[1] + D.da[sXXXZ] * v.da[2];
1142  res.da[dYYY] = D.da[sYYYX] * v.da[0] + D.da[sYYYY] * v.da[1] + D.da[sYYYZ] * v.da[2];
1143  res.da[dZZZ] = D.da[sZZZX] * v.da[0] + D.da[sZZZY] * v.da[1] + D.da[sZZZZ] * v.da[2];
1144  res.da[dXYY] = D.da[sXYYX] * v.da[0] + D.da[sXYYY] * v.da[1] + D.da[sXYYZ] * v.da[2];
1145  res.da[dXZZ] = D.da[sXZZX] * v.da[0] + D.da[sXZZY] * v.da[1] + D.da[sXZZZ] * v.da[2];
1146  res.da[dYXX] = D.da[sYXXX] * v.da[0] + D.da[sYXXY] * v.da[1] + D.da[sYXXZ] * v.da[2];
1147  res.da[dYZZ] = D.da[sYZZX] * v.da[0] + D.da[sYZZY] * v.da[1] + D.da[sYZZZ] * v.da[2];
1148  res.da[dZXX] = D.da[sZXXX] * v.da[0] + D.da[sZXXY] * v.da[1] + D.da[sZXXZ] * v.da[2];
1149  res.da[dZYY] = D.da[sZYYX] * v.da[0] + D.da[sZYYY] * v.da[1] + D.da[sZYYZ] * v.da[2];
1150  res.da[dXYZ] = D.da[sXYZX] * v.da[0] + D.da[sXYZY] * v.da[1] + D.da[sXYZZ] * v.da[2];
1151 
1152  return res;
1153 }
1154 
1155 // contract a 5-tensor with a 4-tensor to yield a vector
1156 template <typename T1, typename T2>
1158 {
1160 
1161  res.da[0] = D.da[rXZZZZ] * Q.da[sZZZZ] + D.da[rXYYYY] * Q.da[sYYYY] + D.da[rXXXXX] * Q.da[sXXXX] +
1162  6 * (D.da[rXYYZZ] * Q.da[sYYZZ] + D.da[rXXXZZ] * Q.da[sXXZZ] + D.da[rXXXYY] * Q.da[sXXYY]) +
1163  4 * (D.da[rXYZZZ] * Q.da[sYZZZ] + D.da[rXYYYZ] * Q.da[sYYYZ] + D.da[rXXZZZ] * Q.da[sXZZZ] + D.da[rXXYYY] * Q.da[sXYYY] +
1164  D.da[rXXXXZ] * Q.da[sXXXZ] + D.da[rXXXXY] * Q.da[sXXXY]) +
1165  12 * (D.da[rXXYZZ] * Q.da[sXYZZ] + D.da[rXXYYZ] * Q.da[sXYYZ] + D.da[rXXXYZ] * Q.da[sXXYZ]);
1166 
1167  res.da[1] = D.da[rYZZZZ] * Q.da[sZZZZ] + D.da[rYYYYY] * Q.da[sYYYY] + D.da[rYXXXX] * Q.da[sXXXX] +
1168  6 * (D.da[rYYYZZ] * Q.da[sYYZZ] + D.da[rYXXZZ] * Q.da[sXXZZ] + D.da[rYXXYY] * Q.da[sXXYY]) +
1169  4 * (D.da[rYYZZZ] * Q.da[sYZZZ] + D.da[rYYYYZ] * Q.da[sYYYZ] + D.da[rYXZZZ] * Q.da[sXZZZ] + D.da[rYXYYY] * Q.da[sXYYY] +
1170  D.da[rYXXXZ] * Q.da[sXXXZ] + D.da[rYXXXY] * Q.da[sXXXY]) +
1171  12 * (D.da[rYXYZZ] * Q.da[sXYZZ] + D.da[rYXYYZ] * Q.da[sXYYZ] + D.da[rYXXYZ] * Q.da[sXXYZ]);
1172 
1173  res.da[2] = D.da[rZZZZZ] * Q.da[sZZZZ] + D.da[rZYYYY] * Q.da[sYYYY] + D.da[rZXXXX] * Q.da[sXXXX] +
1174  6 * (D.da[rZYYZZ] * Q.da[sYYZZ] + D.da[rZXXZZ] * Q.da[sXXZZ] + D.da[rZXXYY] * Q.da[sXXYY]) +
1175  4 * (D.da[rZYZZZ] * Q.da[sYZZZ] + D.da[rZYYYZ] * Q.da[sYYYZ] + D.da[rZXZZZ] * Q.da[sXZZZ] + D.da[rZXYYY] * Q.da[sXYYY] +
1176  D.da[rZXXXZ] * Q.da[sXXXZ] + D.da[rZXXXY] * Q.da[sXXXY]) +
1177  12 * (D.da[rZXYZZ] * Q.da[sXYZZ] + D.da[rZXYYZ] * Q.da[sXYYZ] + D.da[rZXXYZ] * Q.da[sXXYZ]);
1178 
1179  return res;
1180 }
1181 
1182 // contract a 4-tensor with a 2-tensor to yield a 2-tensor
1183 template <typename T1, typename T2>
1185 {
1187 
1188  res.da[qXX] = D.da[sXXXX] * Q.da[qXX] + D.da[sXXYY] * Q.da[qYY] + D.da[sXXZZ] * Q.da[qZZ] +
1189  2 * (D.da[sXXXY] * Q.da[qXY] + D.da[sXXXZ] * Q.da[qXZ] + D.da[sXXYZ] * Q.da[qYZ]);
1190  res.da[qYY] = D.da[sYYXX] * Q.da[qXX] + D.da[sYYYY] * Q.da[qYY] + D.da[sYYZZ] * Q.da[qZZ] +
1191  2 * (D.da[sYYXY] * Q.da[qXY] + D.da[sYYXZ] * Q.da[qXZ] + D.da[sYYYZ] * Q.da[qYZ]);
1192  res.da[qZZ] = D.da[sZZXX] * Q.da[qXX] + D.da[sZZYY] * Q.da[qYY] + D.da[sZZZZ] * Q.da[qZZ] +
1193  2 * (D.da[sZZXY] * Q.da[qXY] + D.da[sZZXZ] * Q.da[qXZ] + D.da[sZZYZ] * Q.da[qYZ]);
1194  res.da[qXY] = D.da[sXYXX] * Q.da[qXX] + D.da[sXYYY] * Q.da[qYY] + D.da[sXYZZ] * Q.da[qZZ] +
1195  2 * (D.da[sXYXY] * Q.da[qXY] + D.da[sXYXZ] * Q.da[qXZ] + D.da[sXYYZ] * Q.da[qYZ]);
1196  res.da[qXZ] = D.da[sXZXX] * Q.da[qXX] + D.da[sXZYY] * Q.da[qYY] + D.da[sXZZZ] * Q.da[qZZ] +
1197  2 * (D.da[sXZXY] * Q.da[qXY] + D.da[sXZXZ] * Q.da[qXZ] + D.da[sXZYZ] * Q.da[qYZ]);
1198  res.da[qYZ] = D.da[sYZXX] * Q.da[qXX] + D.da[sYZYY] * Q.da[qYY] + D.da[sYZZZ] * Q.da[qZZ] +
1199  2 * (D.da[sYZXY] * Q.da[qXY] + D.da[sYZXZ] * Q.da[qXZ] + D.da[sYZYZ] * Q.da[qYZ]);
1200 
1201  return res;
1202 }
1203 
1204 // contract a 5-tensor with a 3-tensor to yield a 2-tensor
1205 template <typename T1, typename T2>
1207 {
1209 
1210  res.da[qXX] = D.da[rXXXXX] * Q.da[dXXX] + D.da[rXXYYY] * Q.da[dYYY] + D.da[rXXZZZ] * Q.da[dZZZ] +
1211  3 * (D.da[rXXYZZ] * Q.da[dYZZ] + D.da[rXXYYZ] * Q.da[dYYZ] + D.da[rXXXZZ] * Q.da[dXZZ] + D.da[rXXXYY] * Q.da[dXYY] +
1212  D.da[rXXXXY] * Q.da[dXXY] + D.da[rXXXXZ] * Q.da[dXXZ]) +
1213  6 * D.da[rXXXYZ] * Q.da[dXYZ];
1214 
1215  res.da[qYY] = D.da[rYYXXX] * Q.da[dXXX] + D.da[rYYYYY] * Q.da[dYYY] + D.da[rYYZZZ] * Q.da[dZZZ] +
1216  3 * (D.da[rYYYZZ] * Q.da[dYZZ] + D.da[rYYYYZ] * Q.da[dYYZ] + D.da[rYYXZZ] * Q.da[dXZZ] + D.da[rYYXYY] * Q.da[dXYY] +
1217  D.da[rYYXXY] * Q.da[dXXY] + D.da[rYYXXZ] * Q.da[dXXZ]) +
1218  6 * D.da[rYYXYZ] * Q.da[dXYZ];
1219 
1220  res.da[qZZ] = D.da[rZZXXX] * Q.da[dXXX] + D.da[rZZYYY] * Q.da[dYYY] + D.da[rZZZZZ] * Q.da[dZZZ] +
1221  3 * (D.da[rZZYZZ] * Q.da[dYZZ] + D.da[rZZYYZ] * Q.da[dYYZ] + D.da[rZZXZZ] * Q.da[dXZZ] + D.da[rZZXYY] * Q.da[dXYY] +
1222  D.da[rZZXXY] * Q.da[dXXY] + D.da[rZZXXZ] * Q.da[dXXZ]) +
1223  6 * D.da[rZZXYZ] * Q.da[dXYZ];
1224 
1225  res.da[qXY] = D.da[rXYXXX] * Q.da[dXXX] + D.da[rXYYYY] * Q.da[dYYY] + D.da[rXYZZZ] * Q.da[dZZZ] +
1226  3 * (D.da[rXYYZZ] * Q.da[dYZZ] + D.da[rXYYYZ] * Q.da[dYYZ] + D.da[rXYXZZ] * Q.da[dXZZ] + D.da[rXYXYY] * Q.da[dXYY] +
1227  D.da[rXYXXY] * Q.da[dXXY] + D.da[rXYXXZ] * Q.da[dXXZ]) +
1228  6 * D.da[rXYXYZ] * Q.da[dXYZ];
1229 
1230  res.da[qXZ] = D.da[rXZXXX] * Q.da[dXXX] + D.da[rXZYYY] * Q.da[dYYY] + D.da[rXZZZZ] * Q.da[dZZZ] +
1231  3 * (D.da[rXZYZZ] * Q.da[dYZZ] + D.da[rXZYYZ] * Q.da[dYYZ] + D.da[rXZXZZ] * Q.da[dXZZ] + D.da[rXZXYY] * Q.da[dXYY] +
1232  D.da[rXZXXY] * Q.da[dXXY] + D.da[rXZXXZ] * Q.da[dXXZ]) +
1233  6 * D.da[rXZXYZ] * Q.da[dXYZ];
1234 
1235  res.da[qYZ] = D.da[rYZXXX] * Q.da[dXXX] + D.da[rYZYYY] * Q.da[dYYY] + D.da[rYZZZZ] * Q.da[dZZZ] +
1236  3 * (D.da[rYZYZZ] * Q.da[dYZZ] + D.da[rYZYYZ] * Q.da[dYYZ] + D.da[rYZXZZ] * Q.da[dXZZ] + D.da[rYZXYY] * Q.da[dXYY] +
1237  D.da[rYZXXY] * Q.da[dXXY] + D.da[rYZXXZ] * Q.da[dXXZ]) +
1238  6 * D.da[rYZXYZ] * Q.da[dXYZ];
1239 
1240  return res;
1241 }
1242 
1243 // contract a 5-tensor with a 2-tensor to yield a 3-tensor
1244 template <typename T1, typename T2>
1246 {
1248 
1249  res.da[dXXX] = (D.da[rXXXXX] * Q.da[qXX] + D.da[rXXXYY] * Q.da[qYY] + D.da[rXXXZZ] * Q.da[qZZ]) +
1250  2 * (D.da[rXXXXY] * Q.da[qXY] + D.da[rXXXXZ] * Q.da[qXZ] + D.da[rXXXYZ] * Q.da[qYZ]);
1251 
1252  res.da[dYYY] = (D.da[rYYYXX] * Q.da[qXX] + D.da[rYYYYY] * Q.da[qYY] + D.da[rYYYZZ] * Q.da[qZZ]) +
1253  2 * (D.da[rYYYXY] * Q.da[qXY] + D.da[rYYYXZ] * Q.da[qXZ] + D.da[rYYYYZ] * Q.da[qYZ]);
1254 
1255  res.da[dZZZ] = (D.da[rZZZXX] * Q.da[qXX] + D.da[rZZZYY] * Q.da[qYY] + D.da[rZZZZZ] * Q.da[qZZ]) +
1256  2 * (D.da[rZZZXY] * Q.da[qXY] + D.da[rZZZXZ] * Q.da[qXZ] + D.da[rZZZYZ] * Q.da[qYZ]);
1257 
1258  res.da[dXYY] = (D.da[rXYYXX] * Q.da[qXX] + D.da[rXYYYY] * Q.da[qYY] + D.da[rXYYZZ] * Q.da[qZZ]) +
1259  2 * (D.da[rXYYXY] * Q.da[qXY] + D.da[rXYYXZ] * Q.da[qXZ] + D.da[rXYYYZ] * Q.da[qYZ]);
1260 
1261  res.da[dXZZ] = (D.da[rXZZXX] * Q.da[qXX] + D.da[rXZZYY] * Q.da[qYY] + D.da[rXZZZZ] * Q.da[qZZ]) +
1262  2 * (D.da[rXZZXY] * Q.da[qXY] + D.da[rXZZXZ] * Q.da[qXZ] + D.da[rXZZYZ] * Q.da[qYZ]);
1263 
1264  res.da[dYXX] = (D.da[rYXXXX] * Q.da[qXX] + D.da[rYXXYY] * Q.da[qYY] + D.da[rYXXZZ] * Q.da[qZZ]) +
1265  2 * (D.da[rYXXXY] * Q.da[qXY] + D.da[rYXXXZ] * Q.da[qXZ] + D.da[rYXXYZ] * Q.da[qYZ]);
1266 
1267  res.da[dYZZ] = (D.da[rYZZXX] * Q.da[qXX] + D.da[rYZZYY] * Q.da[qYY] + D.da[rYZZZZ] * Q.da[qZZ]) +
1268  2 * (D.da[rYZZXY] * Q.da[qXY] + D.da[rYZZXZ] * Q.da[qXZ] + D.da[rYZZYZ] * Q.da[qYZ]);
1269 
1270  res.da[dZXX] = (D.da[rZXXXX] * Q.da[qXX] + D.da[rZXXYY] * Q.da[qYY] + D.da[rZXXZZ] * Q.da[qZZ]) +
1271  2 * (D.da[rZXXXY] * Q.da[qXY] + D.da[rZXXXZ] * Q.da[qXZ] + D.da[rZXXYZ] * Q.da[qYZ]);
1272 
1273  res.da[dZYY] = (D.da[rZYYXX] * Q.da[qXX] + D.da[rZYYYY] * Q.da[qYY] + D.da[rZYYZZ] * Q.da[qZZ]) +
1274  2 * (D.da[rZYYXY] * Q.da[qXY] + D.da[rZYYXZ] * Q.da[qXZ] + D.da[rZYYYZ] * Q.da[qYZ]);
1275 
1276  res.da[dXYZ] = (D.da[rXYZXX] * Q.da[qXX] + D.da[rXYZYY] * Q.da[qYY] + D.da[rXYZZZ] * Q.da[qZZ]) +
1277  2 * (D.da[rXYZXY] * Q.da[qXY] + D.da[rXYZXZ] * Q.da[qXZ] + D.da[rXYZYZ] * Q.da[qYZ]);
1278 
1279  return res;
1280 }
1281 
1282 // contract a 5-tensor with a vector to yield a 4-tensor
1283 template <typename T1, typename T2>
1285 {
1287 
1288  res.da[sXXXX] = D.da[rXXXXX] * v.da[0] + D.da[rXXXXY] * v.da[1] + D.da[rXXXXZ] * v.da[2];
1289  res.da[sXXXY] = D.da[rXXXYX] * v.da[0] + D.da[rXXXYY] * v.da[1] + D.da[rXXXYZ] * v.da[2];
1290  res.da[sXXXZ] = D.da[rXXXZX] * v.da[0] + D.da[rXXXZY] * v.da[1] + D.da[rXXXZZ] * v.da[2];
1291  res.da[sXXYY] = D.da[rXXYYX] * v.da[0] + D.da[rXXYYY] * v.da[1] + D.da[rXXYYZ] * v.da[2];
1292  res.da[sXXYZ] = D.da[rXXYZX] * v.da[0] + D.da[rXXYZY] * v.da[1] + D.da[rXXYZZ] * v.da[2];
1293  res.da[sXXZZ] = D.da[rXXZZX] * v.da[0] + D.da[rXXZZY] * v.da[1] + D.da[rXXZZZ] * v.da[2];
1294  res.da[sXYYY] = D.da[rXYYYX] * v.da[0] + D.da[rXYYYY] * v.da[1] + D.da[rXYYYZ] * v.da[2];
1295  res.da[sXYYZ] = D.da[rXYYZX] * v.da[0] + D.da[rXYYZY] * v.da[1] + D.da[rXYYZZ] * v.da[2];
1296  res.da[sXYZZ] = D.da[rXYZZX] * v.da[0] + D.da[rXYZZY] * v.da[1] + D.da[rXYZZZ] * v.da[2];
1297  res.da[sXZZZ] = D.da[rXZZZX] * v.da[0] + D.da[rXZZZY] * v.da[1] + D.da[rXZZZZ] * v.da[2];
1298  res.da[sYYYY] = D.da[rYYYYX] * v.da[0] + D.da[rYYYYY] * v.da[1] + D.da[rYYYYZ] * v.da[2];
1299  res.da[sYYYZ] = D.da[rYYYZX] * v.da[0] + D.da[rYYYZY] * v.da[1] + D.da[rYYYZZ] * v.da[2];
1300  res.da[sYYZZ] = D.da[rYYZZX] * v.da[0] + D.da[rYYZZY] * v.da[1] + D.da[rYYZZZ] * v.da[2];
1301  res.da[sYZZZ] = D.da[rYZZZX] * v.da[0] + D.da[rYZZZY] * v.da[1] + D.da[rYZZZZ] * v.da[2];
1302  res.da[sZZZZ] = D.da[rZZZZX] * v.da[0] + D.da[rZZZZY] * v.da[1] + D.da[rZZZZZ] * v.da[2];
1303 
1304  return res;
1305 }
1306 
1307 // contract a 5-tensor with a 5-tensor to yield a scalar
1308 template <typename T1, typename T2>
1310 {
1311  return D.da[rXXXXX] * Q.da[rXXXXX] + D.da[rYYYYY] * Q.da[rYYYYY] + D.da[rZZZZZ] * Q.da[rZZZZZ] +
1312  5 * (D.da[rYZZZZ] * Q.da[rYZZZZ] + D.da[rXYYYY] * Q.da[rXYYYY] + D.da[rYYYYZ] * Q.da[rYYYYZ] + D.da[rXXXXZ] * Q.da[rXXXXZ] +
1313  D.da[rXXXXY] * Q.da[rXXXXY] + D.da[rXZZZZ] * Q.da[rXZZZZ]) +
1314  10 * (D.da[rXXZZZ] * Q.da[rXXZZZ] + D.da[rYYZZZ] * Q.da[rYYZZZ] + D.da[rYYYZZ] * Q.da[rYYYZZ] + D.da[rXXXYY] * Q.da[rXXXYY] +
1315  D.da[rXXYYY] * Q.da[rXXYYY] + D.da[rXXXZZ] * Q.da[rXXXZZ]) +
1316  20 * (D.da[rXYYYZ] * Q.da[rXYYYZ] + D.da[rXYZZZ] * Q.da[rXYZZZ] + D.da[rXXXYZ] * Q.da[rXXXYZ]) +
1317  30 * (D.da[rXYYZZ] * Q.da[rXYYZZ] + D.da[rXXYYZ] * Q.da[rXXYYZ] + D.da[rXXYZZ] * Q.da[rXXYZZ]);
1318 }
1319 
1320 template <typename T1, typename T2>
1322 {
1323  typedef typename which_return<T1, T2>::type T;
1324 
1325  symtensor2<T> Dv = D * v;
1326 
1327  vector<T> res = Dv * v;
1328 
1329  return res;
1330 }
1331 
1332 template <typename T1, typename T2>
1334 {
1335  typedef typename which_return<T1, T2>::type T;
1336 
1337  symtensor3<T> Dv = D * v;
1338  symtensor2<T> Dvv = Dv * v;
1339 
1340  vector<T> res = Dvv * v;
1341 
1342  return res;
1343 }
1344 
1345 template <typename T1, typename T2>
1347 {
1348  typedef typename which_return<T1, T2>::type T;
1349 
1350  symtensor4<T> Dv = D * v;
1351  symtensor3<T> Dvv = Dv * v;
1352  symtensor2<T> Dvvv = Dvv * v;
1353 
1354  vector<T> res = Dvvv * v;
1355 
1356  return res;
1357 }
1358 
1359 // contract a 6-tensor with a vector to yield a 5-tensor
1360 template <typename T1, typename T2>
1362 {
1364 
1365  res.da[rXXXXX] = D.da[pXXXXXX] * v.da[0] + D.da[pXXXXXY] * v.da[1] + D.da[pXXXXXZ] * v.da[2];
1366  res.da[rXXXXY] = D.da[pXXXXXY] * v.da[0] + D.da[pXXXXYY] * v.da[1] + D.da[pXXXXYZ] * v.da[2];
1367  res.da[rXXXXZ] = D.da[pXXXXXZ] * v.da[0] + D.da[pXXXXYZ] * v.da[1] + D.da[pXXXXZZ] * v.da[2];
1368  res.da[rXXXYY] = D.da[pXXXXYY] * v.da[0] + D.da[pXXXYYY] * v.da[1] + D.da[pXXXYYZ] * v.da[2];
1369  res.da[rXXXYZ] = D.da[pXXXXYZ] * v.da[0] + D.da[pXXXYYZ] * v.da[1] + D.da[pXXXYZZ] * v.da[2];
1370  res.da[rXXXZZ] = D.da[pXXXXZZ] * v.da[0] + D.da[pXXXYZZ] * v.da[1] + D.da[pXXXZZZ] * v.da[2];
1371  res.da[rXXYYY] = D.da[pXXXYYY] * v.da[0] + D.da[pXXYYYY] * v.da[1] + D.da[pXXYYYZ] * v.da[2];
1372  res.da[rXXYYZ] = D.da[pXXXYYZ] * v.da[0] + D.da[pXXYYYZ] * v.da[1] + D.da[pXXYYZZ] * v.da[2];
1373  res.da[rXXYZZ] = D.da[pXXXYZZ] * v.da[0] + D.da[pXXYYZZ] * v.da[1] + D.da[pXXYZZZ] * v.da[2];
1374  res.da[rXXZZZ] = D.da[pXXXZZZ] * v.da[0] + D.da[pXXYZZZ] * v.da[1] + D.da[pXXZZZZ] * v.da[2];
1375  res.da[rXYYYY] = D.da[pXXYYYY] * v.da[0] + D.da[pXYYYYY] * v.da[1] + D.da[pXYYYYZ] * v.da[2];
1376  res.da[rXYYYZ] = D.da[pXXYYYZ] * v.da[0] + D.da[pXYYYYZ] * v.da[1] + D.da[pXYYYZZ] * v.da[2];
1377  res.da[rXYYZZ] = D.da[pXXYYZZ] * v.da[0] + D.da[pXYYYZZ] * v.da[1] + D.da[pXYYZZZ] * v.da[2];
1378  res.da[rXYZZZ] = D.da[pXXYZZZ] * v.da[0] + D.da[pXYYZZZ] * v.da[1] + D.da[pXYZZZZ] * v.da[2];
1379  res.da[rXZZZZ] = D.da[pXXZZZZ] * v.da[0] + D.da[pXYZZZZ] * v.da[1] + D.da[pXZZZZZ] * v.da[2];
1380  res.da[rYYYYY] = D.da[pXYYYYY] * v.da[0] + D.da[pYYYYYY] * v.da[1] + D.da[pYYYYYZ] * v.da[2];
1381  res.da[rYYYYZ] = D.da[pXYYYYZ] * v.da[0] + D.da[pYYYYYZ] * v.da[1] + D.da[pYYYYZZ] * v.da[2];
1382  res.da[rYYYZZ] = D.da[pXYYYZZ] * v.da[0] + D.da[pYYYYZZ] * v.da[1] + D.da[pYYYZZZ] * v.da[2];
1383  res.da[rYYZZZ] = D.da[pXYYZZZ] * v.da[0] + D.da[pYYYZZZ] * v.da[1] + D.da[pYYZZZZ] * v.da[2];
1384  res.da[rYZZZZ] = D.da[pXYZZZZ] * v.da[0] + D.da[pYYZZZZ] * v.da[1] + D.da[pYZZZZZ] * v.da[2];
1385  res.da[rZZZZZ] = D.da[pXZZZZZ] * v.da[0] + D.da[pYZZZZZ] * v.da[1] + D.da[pZZZZZZ] * v.da[2];
1386 
1387  return res;
1388 }
1389 
1390 // contract a 7-tensor with a vector to yield a 6-tensor
1391 template <typename T1, typename T2>
1393 {
1395 
1396  res.da[pXXXXXX] = D.da[tXXXXXXX] * v.da[0] + D.da[tXXXXXXY] * v.da[1] + D.da[tXXXXXXZ] * v.da[2];
1397  res.da[pXXXXXY] = D.da[tXXXXXXY] * v.da[0] + D.da[tXXXXXYY] * v.da[1] + D.da[tXXXXXYZ] * v.da[2];
1398  res.da[pXXXXXZ] = D.da[tXXXXXXZ] * v.da[0] + D.da[tXXXXXYZ] * v.da[1] + D.da[tXXXXXZZ] * v.da[2];
1399  res.da[pXXXXYY] = D.da[tXXXXXYY] * v.da[0] + D.da[tXXXXYYY] * v.da[1] + D.da[tXXXXYYZ] * v.da[2];
1400  res.da[pXXXXYZ] = D.da[tXXXXXYZ] * v.da[0] + D.da[tXXXXYYZ] * v.da[1] + D.da[tXXXXYZZ] * v.da[2];
1401  res.da[pXXXXZZ] = D.da[tXXXXXZZ] * v.da[0] + D.da[tXXXXYZZ] * v.da[1] + D.da[tXXXXZZZ] * v.da[2];
1402  res.da[pXXXYYY] = D.da[tXXXXYYY] * v.da[0] + D.da[tXXXYYYY] * v.da[1] + D.da[tXXXYYYZ] * v.da[2];
1403  res.da[pXXXYYZ] = D.da[tXXXXYYZ] * v.da[0] + D.da[tXXXYYYZ] * v.da[1] + D.da[tXXXYYZZ] * v.da[2];
1404  res.da[pXXXYZZ] = D.da[tXXXXYZZ] * v.da[0] + D.da[tXXXYYZZ] * v.da[1] + D.da[tXXXYZZZ] * v.da[2];
1405  res.da[pXXXZZZ] = D.da[tXXXXZZZ] * v.da[0] + D.da[tXXXYZZZ] * v.da[1] + D.da[tXXXZZZZ] * v.da[2];
1406  res.da[pXXYYYY] = D.da[tXXXYYYY] * v.da[0] + D.da[tXXYYYYY] * v.da[1] + D.da[tXXYYYYZ] * v.da[2];
1407  res.da[pXXYYYZ] = D.da[tXXXYYYZ] * v.da[0] + D.da[tXXYYYYZ] * v.da[1] + D.da[tXXYYYZZ] * v.da[2];
1408  res.da[pXXYYZZ] = D.da[tXXXYYZZ] * v.da[0] + D.da[tXXYYYZZ] * v.da[1] + D.da[tXXYYZZZ] * v.da[2];
1409  res.da[pXXYZZZ] = D.da[tXXXYZZZ] * v.da[0] + D.da[tXXYYZZZ] * v.da[1] + D.da[tXXYZZZZ] * v.da[2];
1410  res.da[pXXZZZZ] = D.da[tXXXZZZZ] * v.da[0] + D.da[tXXYZZZZ] * v.da[1] + D.da[tXXZZZZZ] * v.da[2];
1411  res.da[pXYYYYY] = D.da[tXXYYYYY] * v.da[0] + D.da[tXYYYYYY] * v.da[1] + D.da[tXYYYYYZ] * v.da[2];
1412  res.da[pXYYYYZ] = D.da[tXXYYYYZ] * v.da[0] + D.da[tXYYYYYZ] * v.da[1] + D.da[tXYYYYZZ] * v.da[2];
1413  res.da[pXYYYZZ] = D.da[tXXYYYZZ] * v.da[0] + D.da[tXYYYYZZ] * v.da[1] + D.da[tXYYYZZZ] * v.da[2];
1414  res.da[pXYYZZZ] = D.da[tXXYYZZZ] * v.da[0] + D.da[tXYYYZZZ] * v.da[1] + D.da[tXYYZZZZ] * v.da[2];
1415  res.da[pXYZZZZ] = D.da[tXXYZZZZ] * v.da[0] + D.da[tXYYZZZZ] * v.da[1] + D.da[tXYZZZZZ] * v.da[2];
1416  res.da[pXZZZZZ] = D.da[tXXZZZZZ] * v.da[0] + D.da[tXYZZZZZ] * v.da[1] + D.da[tXZZZZZZ] * v.da[2];
1417  res.da[pYYYYYY] = D.da[tXYYYYYY] * v.da[0] + D.da[tYYYYYYY] * v.da[1] + D.da[tYYYYYYZ] * v.da[2];
1418  res.da[pYYYYYZ] = D.da[tXYYYYYZ] * v.da[0] + D.da[tYYYYYYZ] * v.da[1] + D.da[tYYYYYZZ] * v.da[2];
1419  res.da[pYYYYZZ] = D.da[tXYYYYZZ] * v.da[0] + D.da[tYYYYYZZ] * v.da[1] + D.da[tYYYYZZZ] * v.da[2];
1420  res.da[pYYYZZZ] = D.da[tXYYYZZZ] * v.da[0] + D.da[tYYYYZZZ] * v.da[1] + D.da[tYYYZZZZ] * v.da[2];
1421  res.da[pYYZZZZ] = D.da[tXYYZZZZ] * v.da[0] + D.da[tYYYZZZZ] * v.da[1] + D.da[tYYZZZZZ] * v.da[2];
1422  res.da[pYZZZZZ] = D.da[tXYZZZZZ] * v.da[0] + D.da[tYYZZZZZ] * v.da[1] + D.da[tYZZZZZZ] * v.da[2];
1423  res.da[pZZZZZZ] = D.da[tXZZZZZZ] * v.da[0] + D.da[tYZZZZZZ] * v.da[1] + D.da[tZZZZZZZ] * v.da[2];
1424 
1425  return res;
1426 }
1427 
1428 //------------- let's define some outer products
1429 
1430 /* produce a vector as the cross product of two vectors */
1431 template <typename T1, typename T2>
1433 {
1435 
1436  res.da[0] = v.da[1] * w.da[2] - v.da[2] * w.da[1];
1437  res.da[1] = v.da[2] * w.da[0] - v.da[0] * w.da[2];
1438  res.da[2] = v.da[0] * w.da[1] - v.da[1] * w.da[0];
1439 
1440  return res;
1441 }
1442 
1443 /* produce a 2-tensor from the outer product of two vectors */
1444 template <typename T1, typename T2>
1446 {
1448 
1449  res.da[qXX] = v.da[0] * w.da[0];
1450  res.da[qYY] = v.da[1] * w.da[1];
1451  res.da[qZZ] = v.da[2] * w.da[2];
1452  res.da[qXY] = v.da[0] * w.da[1];
1453  res.da[qXZ] = v.da[0] * w.da[2];
1454  res.da[qYZ] = v.da[1] * w.da[2];
1455 
1456  return res;
1457 }
1458 
1459 /* produce a 3-tensor from the outer product of a vector and a 2-tensor */
1460 template <typename T1, typename T2>
1462 {
1464 
1465  res.da[dXXX] = D.da[qXX] * v.da[0];
1466  res.da[dXXY] = D.da[qXX] * v.da[1];
1467  res.da[dXXZ] = D.da[qXX] * v.da[2];
1468  res.da[dXYY] = D.da[qXY] * v.da[1];
1469  res.da[dXYZ] = D.da[qXY] * v.da[2];
1470  res.da[dXZZ] = D.da[qXZ] * v.da[2];
1471  res.da[dYYY] = D.da[qYY] * v.da[1];
1472  res.da[dYYZ] = D.da[qYY] * v.da[2];
1473  res.da[dYZZ] = D.da[qYZ] * v.da[2];
1474  res.da[dZZZ] = D.da[qZZ] * v.da[2];
1475 
1476  return res;
1477 }
1478 
1479 /* produce a 4-tensor from the outer product of a vector and a 3-tensor */
1480 template <typename T1, typename T2>
1482 {
1484 
1485  res.da[sXXXX] = D.da[dXXX] * v.da[0];
1486  res.da[sXXXY] = D.da[dXXX] * v.da[1];
1487  res.da[sXXXZ] = D.da[dXXX] * v.da[2];
1488  res.da[sXXYY] = D.da[dXXY] * v.da[1];
1489  res.da[sXXYZ] = D.da[dXXY] * v.da[2];
1490  res.da[sXXZZ] = D.da[dXXZ] * v.da[2];
1491  res.da[sXYYY] = D.da[dXYY] * v.da[1];
1492  res.da[sXYYZ] = D.da[dXYY] * v.da[2];
1493  res.da[sXYZZ] = D.da[dXYZ] * v.da[2];
1494  res.da[sXZZZ] = D.da[dXZZ] * v.da[2];
1495  res.da[sYYYY] = D.da[dYYY] * v.da[1];
1496  res.da[sYYYZ] = D.da[dYYY] * v.da[2];
1497  res.da[sYYZZ] = D.da[dYYZ] * v.da[2];
1498  res.da[sYZZZ] = D.da[dYZZ] * v.da[2];
1499  res.da[sZZZZ] = D.da[dZZZ] * v.da[2];
1500 
1501  return res;
1502 }
1503 
1504 /* produce a 5-tensor from the outer product of a vector and a 4-tensor */
1505 template <typename T1, typename T2>
1507 {
1509 
1510  res.da[rXXXXX] = D.da[sXXXX] * v.da[0];
1511  res.da[rXXXXY] = D.da[sXXXX] * v.da[1];
1512  res.da[rXXXXZ] = D.da[sXXXX] * v.da[2];
1513  res.da[rXXXYY] = D.da[sXXXY] * v.da[1];
1514  res.da[rXXXYZ] = D.da[sXXXY] * v.da[2];
1515  res.da[rXXXZZ] = D.da[sXXXZ] * v.da[2];
1516  res.da[rXXYYY] = D.da[sXXYY] * v.da[1];
1517  res.da[rXXYYZ] = D.da[sXXYY] * v.da[2];
1518  res.da[rXXYZZ] = D.da[sXXYZ] * v.da[2];
1519  res.da[rXXZZZ] = D.da[sXXZZ] * v.da[2];
1520  res.da[rXYYYY] = D.da[sXYYY] * v.da[1];
1521  res.da[rXYYYZ] = D.da[sXYYY] * v.da[2];
1522  res.da[rXYYZZ] = D.da[sXYYZ] * v.da[2];
1523  res.da[rXYZZZ] = D.da[sXYZZ] * v.da[2];
1524  res.da[rXZZZZ] = D.da[sXZZZ] * v.da[2];
1525  res.da[rYYYYY] = D.da[sYYYY] * v.da[1];
1526  res.da[rYYYYZ] = D.da[sYYYY] * v.da[2];
1527  res.da[rYYYZZ] = D.da[sYYYZ] * v.da[2];
1528  res.da[rYYZZZ] = D.da[sYYZZ] * v.da[2];
1529  res.da[rYZZZZ] = D.da[sYZZZ] * v.da[2];
1530  res.da[rZZZZZ] = D.da[sZZZZ] * v.da[2];
1531 
1532  return res;
1533 }
1534 
1535 /* produce a 6-tensor from the outer product of a vector and a 5-tensor */
1536 template <typename T1, typename T2>
1538 {
1540 
1541  res.da[pXXXXXX] = D.da[rXXXXX] * v.da[0];
1542  res.da[pXXXXXY] = D.da[rXXXXX] * v.da[1];
1543  res.da[pXXXXXZ] = D.da[rXXXXX] * v.da[2];
1544  res.da[pXXXXYY] = D.da[rXXXXY] * v.da[1];
1545  res.da[pXXXXYZ] = D.da[rXXXXY] * v.da[2];
1546  res.da[pXXXXZZ] = D.da[rXXXXZ] * v.da[2];
1547  res.da[pXXXYYY] = D.da[rXXXYY] * v.da[1];
1548  res.da[pXXXYYZ] = D.da[rXXXYY] * v.da[2];
1549  res.da[pXXXYZZ] = D.da[rXXXYZ] * v.da[2];
1550  res.da[pXXXZZZ] = D.da[rXXXZZ] * v.da[2];
1551  res.da[pXXYYYY] = D.da[rXXYYY] * v.da[1];
1552  res.da[pXXYYYZ] = D.da[rXXYYY] * v.da[2];
1553  res.da[pXXYYZZ] = D.da[rXXYYZ] * v.da[2];
1554  res.da[pXXYZZZ] = D.da[rXXYZZ] * v.da[2];
1555  res.da[pXXZZZZ] = D.da[rXXZZZ] * v.da[2];
1556  res.da[pXYYYYY] = D.da[rXYYYY] * v.da[1];
1557  res.da[pXYYYYZ] = D.da[rXYYYY] * v.da[2];
1558  res.da[pXYYYZZ] = D.da[rXYYYZ] * v.da[2];
1559  res.da[pXYYZZZ] = D.da[rXYYZZ] * v.da[2];
1560  res.da[pXYZZZZ] = D.da[rXYZZZ] * v.da[2];
1561  res.da[pXZZZZZ] = D.da[rXZZZZ] * v.da[2];
1562  res.da[pYYYYYY] = D.da[rYYYYY] * v.da[1];
1563  res.da[pYYYYYZ] = D.da[rYYYYY] * v.da[2];
1564  res.da[pYYYYZZ] = D.da[rYYYYZ] * v.da[2];
1565  res.da[pYYYZZZ] = D.da[rYYYZZ] * v.da[2];
1566  res.da[pYYZZZZ] = D.da[rYYZZZ] * v.da[2];
1567  res.da[pYZZZZZ] = D.da[rYZZZZ] * v.da[2];
1568  res.da[pZZZZZZ] = D.da[rZZZZZ] * v.da[2];
1569 
1570  return res;
1571 }
1572 
1573 /* produce a 7-tensor from the outer product of a vector and a 6-tensor */
1574 template <typename T1, typename T2>
1576 {
1578 
1579  res.da[tXXXXXXX] = D.da[pXXXXXX] * v.da[0];
1580  res.da[tXXXXXXY] = D.da[pXXXXXX] * v.da[1];
1581  res.da[tXXXXXXZ] = D.da[pXXXXXX] * v.da[2];
1582  res.da[tXXXXXYY] = D.da[pXXXXXY] * v.da[1];
1583  res.da[tXXXXXYZ] = D.da[pXXXXXY] * v.da[2];
1584  res.da[tXXXXXZZ] = D.da[pXXXXXZ] * v.da[2];
1585  res.da[tXXXXYYY] = D.da[pXXXXYY] * v.da[1];
1586  res.da[tXXXXYYZ] = D.da[pXXXXYY] * v.da[2];
1587  res.da[tXXXXYZZ] = D.da[pXXXXYZ] * v.da[2];
1588  res.da[tXXXXZZZ] = D.da[pXXXXZZ] * v.da[2];
1589  res.da[tXXXYYYY] = D.da[pXXXYYY] * v.da[1];
1590  res.da[tXXXYYYZ] = D.da[pXXXYYY] * v.da[2];
1591  res.da[tXXXYYZZ] = D.da[pXXXYYZ] * v.da[2];
1592  res.da[tXXXYZZZ] = D.da[pXXXYZZ] * v.da[2];
1593  res.da[tXXXZZZZ] = D.da[pXXXZZZ] * v.da[2];
1594  res.da[tXXYYYYY] = D.da[pXXYYYY] * v.da[1];
1595  res.da[tXXYYYYZ] = D.da[pXXYYYY] * v.da[2];
1596  res.da[tXXYYYZZ] = D.da[pXXYYYZ] * v.da[2];
1597  res.da[tXXYYZZZ] = D.da[pXXYYZZ] * v.da[2];
1598  res.da[tXXYZZZZ] = D.da[pXXYZZZ] * v.da[2];
1599  res.da[tXXZZZZZ] = D.da[pXXZZZZ] * v.da[2];
1600  res.da[tXYYYYYY] = D.da[pXYYYYY] * v.da[1];
1601  res.da[tXYYYYYZ] = D.da[pXYYYYY] * v.da[2];
1602  res.da[tXYYYYZZ] = D.da[pXYYYYZ] * v.da[2];
1603  res.da[tXYYYZZZ] = D.da[pXYYYZZ] * v.da[2];
1604  res.da[tXYYZZZZ] = D.da[pXYYZZZ] * v.da[2];
1605  res.da[tXYZZZZZ] = D.da[pXYZZZZ] * v.da[2];
1606  res.da[tXZZZZZZ] = D.da[pXZZZZZ] * v.da[2];
1607  res.da[tYYYYYYY] = D.da[pYYYYYY] * v.da[1];
1608  res.da[tYYYYYYZ] = D.da[pYYYYYY] * v.da[2];
1609  res.da[tYYYYYZZ] = D.da[pYYYYYZ] * v.da[2];
1610  res.da[tYYYYZZZ] = D.da[pYYYYZZ] * v.da[2];
1611  res.da[tYYYZZZZ] = D.da[pYYYZZZ] * v.da[2];
1612  res.da[tYYZZZZZ] = D.da[pYYZZZZ] * v.da[2];
1613  res.da[tYZZZZZZ] = D.da[pYZZZZZ] * v.da[2];
1614  res.da[tZZZZZZZ] = D.da[pZZZZZZ] * v.da[2];
1615 
1616  return res;
1617 }
1618 
1619 /* compute the sum of the three possible outer products of a 2-tensor and a vector, yielding a symmetric 3-tensor */
1620 template <typename T1, typename T2>
1622 {
1624 
1625  res.da[dXXX] = 3 * D.da[qXX] * v.da[0];
1626  res.da[dYYY] = 3 * D.da[qYY] * v.da[1];
1627  res.da[dZZZ] = 3 * D.da[qZZ] * v.da[2];
1628  res.da[dXYY] = 2 * D.da[qXY] * v.da[1] + D.da[qYY] * v.da[0];
1629  res.da[dXZZ] = 2 * D.da[qXZ] * v.da[2] + D.da[qZZ] * v.da[0];
1630  res.da[dYXX] = 2 * D.da[qXY] * v.da[0] + D.da[qXX] * v.da[1];
1631  res.da[dYZZ] = 2 * D.da[qYZ] * v.da[2] + D.da[qZZ] * v.da[1];
1632  res.da[dZXX] = 2 * D.da[qXZ] * v.da[0] + D.da[qXX] * v.da[2];
1633  res.da[dZYY] = 2 * D.da[qYZ] * v.da[1] + D.da[qYY] * v.da[2];
1634  res.da[dXYZ] = D.da[qXY] * v.da[2] + D.da[qYZ] * v.da[0] + D.da[qZX] * v.da[1];
1635 
1636  return res;
1637 }
1638 
1639 /* compute the sum of the four possible outer products of a 3-tensor and a vector, yielding a symmetric 4-tensor */
1640 template <typename T1, typename T2>
1642 {
1644 
1645  res.da[sXXXX] = 4 * D.da[dXXX] * v.da[0];
1646  res.da[sZZZZ] = 4 * D.da[dZZZ] * v.da[2];
1647  res.da[sYYYY] = 4 * D.da[dYYY] * v.da[1];
1648  res.da[sXXXY] = 3 * D.da[dXXY] * v.da[0] + D.da[dXXX] * v.da[1];
1649  res.da[sXXXZ] = 3 * D.da[dXXZ] * v.da[0] + D.da[dXXX] * v.da[2];
1650  res.da[sXYYY] = 3 * D.da[dXYY] * v.da[1] + D.da[dYYY] * v.da[0];
1651  res.da[sYYYZ] = 3 * D.da[dYYZ] * v.da[1] + D.da[dYYY] * v.da[2];
1652  res.da[sXZZZ] = 3 * D.da[dXZZ] * v.da[2] + D.da[dZZZ] * v.da[0];
1653  res.da[sYZZZ] = 3 * D.da[dYZZ] * v.da[2] + D.da[dZZZ] * v.da[1];
1654  res.da[sXXYY] = 2 * D.da[dXXY] * v.da[1] + 2 * D.da[dXYY] * v.da[0];
1655  res.da[sXXZZ] = 2 * D.da[dXXZ] * v.da[2] + 2 * D.da[dXZZ] * v.da[0];
1656  res.da[sYYZZ] = 2 * D.da[dYYZ] * v.da[2] + 2 * D.da[dYZZ] * v.da[1];
1657  res.da[sXXYZ] = 2 * D.da[dXYZ] * v.da[0] + D.da[dXXY] * v.da[2] + D.da[dXXZ] * v.da[1];
1658  res.da[sXYYZ] = 2 * D.da[dXYZ] * v.da[1] + D.da[dXYY] * v.da[2] + D.da[dYYZ] * v.da[0];
1659  res.da[sXYZZ] = 2 * D.da[dXYZ] * v.da[2] + D.da[dXZZ] * v.da[1] + D.da[dYZZ] * v.da[0];
1660 
1661  return res;
1662 }
1663 
1664 /* compute the sum of the six possible outer products of a 2-tensor with another 2-tensor, yielding a symmetric 4-tensor */
1665 template <typename T1, typename T2>
1667 {
1669 
1670  res.da[sXXXX] = 6 * D.da[qXX] * S.da[qXX];
1671  res.da[sYYYY] = 6 * D.da[qYY] * S.da[qYY];
1672  res.da[sZZZZ] = 6 * D.da[qZZ] * S.da[qZZ];
1673  res.da[sXXXY] = 3 * D.da[qXX] * S.da[qXY] + 3 * D.da[qXY] * S.da[qXX];
1674  res.da[sXXXZ] = 3 * D.da[qXX] * S.da[qXZ] + 3 * D.da[qXZ] * S.da[qXX];
1675  res.da[sXYYY] = 3 * D.da[qXY] * S.da[qYY] + 3 * D.da[qYY] * S.da[qXY];
1676  res.da[sXZZZ] = 3 * D.da[qZZ] * S.da[qXZ] + 3 * D.da[qXZ] * S.da[qZZ];
1677  res.da[sYYYZ] = 3 * D.da[qYY] * S.da[qYZ] + 3 * D.da[qYZ] * S.da[qYY];
1678  res.da[sYZZZ] = 3 * D.da[qZZ] * S.da[qYZ] + 3 * D.da[qYZ] * S.da[qZZ];
1679  res.da[sXXYY] = D.da[qXX] * S.da[qYY] + D.da[qYY] * S.da[qXX] + 4 * D.da[qXY] * S.da[qXY];
1680  res.da[sXXZZ] = D.da[qXX] * S.da[qZZ] + D.da[qZZ] * S.da[qXX] + 4 * D.da[qXZ] * S.da[qXZ];
1681  res.da[sYYZZ] = D.da[qYY] * S.da[qZZ] + D.da[qZZ] * S.da[qYY] + 4 * D.da[qYZ] * S.da[qYZ];
1682  res.da[sXXYZ] = D.da[qXX] * S.da[qYZ] + 2 * D.da[qXY] * S.da[qXZ] + 2 * D.da[qXZ] * S.da[qXY] + D.da[qYZ] * S.da[qXX];
1683  res.da[sXYZZ] = D.da[qZZ] * S.da[qXY] + 2 * D.da[qXZ] * S.da[qYZ] + 2 * D.da[qYZ] * S.da[qXZ] + D.da[qXY] * S.da[qZZ];
1684  res.da[sXYYZ] = D.da[qYY] * S.da[qXZ] + 2 * D.da[qXY] * S.da[qYZ] + 2 * D.da[qYZ] * S.da[qXY] + D.da[qXZ] * S.da[qYY];
1685 
1686  return res;
1687 }
1688 
1689 /* compute the sum of the five possible outer products of a 4-tensor and a vector, yielding a symmetric 5-tensor */
1690 template <typename T1, typename T2>
1692 {
1694 
1695  res.da[rXXXXX] = 5 * D.da[sXXXX] * v.da[0];
1696  res.da[rXXXXY] = 4 * D.da[sXXXY] * v.da[0] + D.da[sXXXX] * v.da[1];
1697  res.da[rXXXXZ] = 4 * D.da[sXXXZ] * v.da[0] + D.da[sXXXX] * v.da[2];
1698  res.da[rXXXYX] = 3 * D.da[sXXYX] * v.da[0] + D.da[sXXXX] * v.da[1] + D.da[sXXXY] * v.da[0];
1699  res.da[rXXXYY] = 3 * D.da[sXXYY] * v.da[0] + 2 * D.da[sXXXY] * v.da[1];
1700  res.da[rXXXYZ] = 3 * D.da[sXXYZ] * v.da[0] + D.da[sXXXZ] * v.da[1] + D.da[sXXXY] * v.da[2];
1701  res.da[rXXXZX] = 3 * D.da[sXXZX] * v.da[0] + D.da[sXXXX] * v.da[2] + D.da[sXXXZ] * v.da[0];
1702  res.da[rXXXZY] = 3 * D.da[sXXZY] * v.da[0] + D.da[sXXXY] * v.da[2] + D.da[sXXXZ] * v.da[1];
1703  res.da[rXXXZZ] = 3 * D.da[sXXZZ] * v.da[0] + 2 * D.da[sXXXZ] * v.da[2];
1704  res.da[rXXYYY] = 2 * D.da[sXYYY] * v.da[0] + 3 * D.da[sXXYY] * v.da[1];
1705  res.da[rXXYYZ] = 2 * D.da[sXYYZ] * v.da[0] + 2 * D.da[sXXYZ] * v.da[1] + D.da[sXXYY] * v.da[2];
1706  res.da[rXXYZY] = 2 * D.da[sXYZY] * v.da[0] + D.da[sXXZY] * v.da[1] + D.da[sXXYY] * v.da[2] + D.da[sXXYZ] * v.da[1];
1707  res.da[rXXYZZ] = 2 * D.da[sXYZZ] * v.da[0] + D.da[sXXZZ] * v.da[1] + 2 * D.da[sXXYZ] * v.da[2];
1708  res.da[rXXZZZ] = 2 * D.da[sXZZZ] * v.da[0] + 3 * D.da[sXXZZ] * v.da[2];
1709  res.da[rXYYYY] = D.da[sYYYY] * v.da[0] + 4 * D.da[sXYYY] * v.da[1];
1710  res.da[rXYYYZ] = D.da[sYYYZ] * v.da[0] + 3 * D.da[sXYYZ] * v.da[1] + D.da[sXYYY] * v.da[2];
1711  res.da[rXYYZY] = D.da[sYYZY] * v.da[0] + 2 * D.da[sXYZY] * v.da[1] + D.da[sXYYY] * v.da[2] + D.da[sXYYZ] * v.da[1];
1712  res.da[rXYYZZ] = D.da[sYYZZ] * v.da[0] + 2 * D.da[sXYZZ] * v.da[1] + 2 * D.da[sXYYZ] * v.da[2];
1713  res.da[rXYZZZ] = D.da[sYZZZ] * v.da[0] + D.da[sXZZZ] * v.da[1] + 3 * D.da[sXYZZ] * v.da[2];
1714  res.da[rXZZZZ] = D.da[sZZZZ] * v.da[0] + 4 * D.da[sXZZZ] * v.da[2];
1715  res.da[rYYYYY] = 5 * D.da[sYYYY] * v.da[1];
1716  res.da[rYYYYZ] = 4 * D.da[sYYYZ] * v.da[1] + D.da[sYYYY] * v.da[2];
1717  res.da[rYYYZY] = 3 * D.da[sYYZY] * v.da[1] + D.da[sYYYY] * v.da[2] + D.da[sYYYZ] * v.da[1];
1718  res.da[rYYYZZ] = 3 * D.da[sYYZZ] * v.da[1] + 2 * D.da[sYYYZ] * v.da[2];
1719  res.da[rYYZZZ] = 2 * D.da[sYZZZ] * v.da[1] + 3 * D.da[sYYZZ] * v.da[2];
1720  res.da[rYZZZZ] = D.da[sZZZZ] * v.da[1] + 4 * D.da[sYZZZ] * v.da[2];
1721  res.da[rZZZZZ] = 5 * D.da[sZZZZ] * v.da[2];
1722 
1723  return res;
1724 }
1725 
1726 /* compute the sum of the 10 possible outer products of a 3-tensor with another 2-tensor, yielding a symmetric 5-tensor */
1727 template <typename T1, typename T2>
1729 {
1731 
1732  res.da[rXXXXX] = 10 * D.da[dXXX] * S.da[qXX];
1733  res.da[rXXXXY] = 6 * D.da[dXXY] * S.da[qXX] + 4 * D.da[dXXX] * S.da[qXY];
1734  res.da[rXXXXZ] = 6 * D.da[dXXZ] * S.da[qXX] + 4 * D.da[dXXX] * S.da[qXZ];
1735  res.da[rXXXYX] = 3 * D.da[dXYX] * S.da[qXX] + 3 * D.da[dXXX] * S.da[qXY] + 3 * D.da[dXXY] * S.da[qXX] + D.da[dXXX] * S.da[qYX];
1736  res.da[rXXXYY] = 3 * D.da[dXYY] * S.da[qXX] + 6 * D.da[dXXY] * S.da[qXY] + D.da[dXXX] * S.da[qYY];
1737  res.da[rXXXYZ] = 3 * D.da[dXYZ] * S.da[qXX] + 3 * D.da[dXXZ] * S.da[qXY] + 3 * D.da[dXXY] * S.da[qXZ] + D.da[dXXX] * S.da[qYZ];
1738  res.da[rXXXZX] = 3 * D.da[dXZX] * S.da[qXX] + 3 * D.da[dXXX] * S.da[qXZ] + 3 * D.da[dXXZ] * S.da[qXX] + D.da[dXXX] * S.da[qZX];
1739  res.da[rXXXZY] = 3 * D.da[dXZY] * S.da[qXX] + 3 * D.da[dXXY] * S.da[qXZ] + 3 * D.da[dXXZ] * S.da[qXY] + D.da[dXXX] * S.da[qZY];
1740  res.da[rXXXZZ] = 3 * D.da[dXZZ] * S.da[qXX] + 6 * D.da[dXXZ] * S.da[qXZ] + D.da[dXXX] * S.da[qZZ];
1741  res.da[rXXYYY] = D.da[dYYY] * S.da[qXX] + 6 * D.da[dXYY] * S.da[qXY] + 3 * D.da[dXXY] * S.da[qYY];
1742  res.da[rXXYYZ] = D.da[dYYZ] * S.da[qXX] + 4 * D.da[dXYZ] * S.da[qXY] + 2 * D.da[dXYY] * S.da[qXZ] + D.da[dXXZ] * S.da[qYY] +
1743  2 * D.da[dXXY] * S.da[qYZ];
1744  res.da[rXXYZY] = D.da[dYZY] * S.da[qXX] + 2 * D.da[dXZY] * S.da[qXY] + 2 * D.da[dXYY] * S.da[qXZ] + 2 * D.da[dXYZ] * S.da[qXY] +
1745  D.da[dXXY] * S.da[qYZ] + D.da[dXXZ] * S.da[qYY] + D.da[dXXY] * S.da[qZY];
1746  res.da[rXXYZZ] = D.da[dYZZ] * S.da[qXX] + 2 * D.da[dXZZ] * S.da[qXY] + 4 * D.da[dXYZ] * S.da[qXZ] + 2 * D.da[dXXZ] * S.da[qYZ] +
1747  D.da[dXXY] * S.da[qZZ];
1748  res.da[rXXZZZ] = D.da[dZZZ] * S.da[qXX] + 6 * D.da[dXZZ] * S.da[qXZ] + 3 * D.da[dXXZ] * S.da[qZZ];
1749  res.da[rXYYYY] = 4 * D.da[dYYY] * S.da[qXY] + 6 * D.da[dXYY] * S.da[qYY];
1750  res.da[rXYYYZ] = 3 * D.da[dYYZ] * S.da[qXY] + D.da[dYYY] * S.da[qXZ] + 3 * D.da[dXYZ] * S.da[qYY] + 3 * D.da[dXYY] * S.da[qYZ];
1751  res.da[rXYYZY] = 2 * D.da[dYZY] * S.da[qXY] + D.da[dYYY] * S.da[qXZ] + D.da[dYYZ] * S.da[qXY] + D.da[dXZY] * S.da[qYY] +
1752  2 * D.da[dXYY] * S.da[qYZ] + 2 * D.da[dXYZ] * S.da[qYY] + D.da[dXYY] * S.da[qZY];
1753  res.da[rXYYZZ] = 2 * D.da[dYZZ] * S.da[qXY] + 2 * D.da[dYYZ] * S.da[qXZ] + D.da[dXZZ] * S.da[qYY] + 4 * D.da[dXYZ] * S.da[qYZ] +
1754  D.da[dXYY] * S.da[qZZ];
1755  res.da[rXYZZZ] = D.da[dZZZ] * S.da[qXY] + 3 * D.da[dYZZ] * S.da[qXZ] + 3 * D.da[dXZZ] * S.da[qYZ] + 3 * D.da[dXYZ] * S.da[qZZ];
1756  res.da[rXZZZZ] = 4 * D.da[dZZZ] * S.da[qXZ] + 6 * D.da[dXZZ] * S.da[qZZ];
1757  res.da[rYYYYY] = 10 * D.da[dYYY] * S.da[qYY];
1758  res.da[rYYYYZ] = 6 * D.da[dYYZ] * S.da[qYY] + 4 * D.da[dYYY] * S.da[qYZ];
1759  res.da[rYYYZY] = 3 * D.da[dYZY] * S.da[qYY] + 3 * D.da[dYYY] * S.da[qYZ] + 3 * D.da[dYYZ] * S.da[qYY] + D.da[dYYY] * S.da[qZY];
1760  res.da[rYYYZZ] = 3 * D.da[dYZZ] * S.da[qYY] + 6 * D.da[dYYZ] * S.da[qYZ] + D.da[dYYY] * S.da[qZZ];
1761  res.da[rYYZZZ] = D.da[dZZZ] * S.da[qYY] + 6 * D.da[dYZZ] * S.da[qYZ] + 3 * D.da[dYYZ] * S.da[qZZ];
1762  res.da[rYZZZZ] = 4 * D.da[dZZZ] * S.da[qYZ] + 6 * D.da[dYZZ] * S.da[qZZ];
1763  res.da[rZZZZZ] = 10 * D.da[dZZZ] * S.da[qZZ];
1764 
1765  return res;
1766 }
1767 
1769 {
1771  ADD
1772 };
1773 
1774 template <typename T, typename TypeGfac>
1775 inline void setup_D3(enum setup_options opt, symtensor3<T> &D3, vector<T> &dxyz, symtensor2<T> &aux2, symtensor3<T> &aux3, TypeGfac g2,
1776  TypeGfac g3)
1777 {
1778  // Note: dxyz, aux2 are input parameters, whereas aux3 is an output parameter!
1779 
1780  aux3 = dxyz % aux2; // construct outer product of the two vectors
1781  if(opt == INIT)
1782  D3 = g3 * aux3;
1783  else
1784  D3 += g3 * aux3;
1785 
1786  vector<T> g2_dxyz = g2 * dxyz;
1787 
1788  D3[dXXX] += 3 * g2_dxyz[0];
1789  D3[dYYY] += 3 * g2_dxyz[1];
1790  D3[dZZZ] += 3 * g2_dxyz[2];
1791 
1792  D3[dXXY] += g2_dxyz[1];
1793  D3[dXXZ] += g2_dxyz[2];
1794  D3[dXYY] += g2_dxyz[0];
1795  D3[dXZZ] += g2_dxyz[0];
1796  D3[dYYZ] += g2_dxyz[2];
1797  D3[dYZZ] += g2_dxyz[1];
1798 }
1799 
1800 template <typename T, typename TypeGfac>
1801 inline void setup_D4(enum setup_options opt, symtensor4<T> &D4, vector<T> &dxyz, symtensor2<T> &aux2, symtensor3<T> &aux3,
1802  symtensor4<T> &aux4, TypeGfac g2, TypeGfac g3, TypeGfac g4)
1803 {
1804  // Note: dxyz, aux2, and aux3 are input parameters, whereas aux4 is an output parameter!
1805 
1806  aux4 = dxyz % aux3; // construct outer product
1807  if(opt == INIT)
1808  D4 = g4 * aux4;
1809  else
1810  D4 += g4 * aux4;
1811 
1812  D4[sXXXX] += 3 * g2;
1813  D4[sYYYY] += 3 * g2;
1814  D4[sZZZZ] += 3 * g2;
1815  D4[sXXYY] += g2;
1816  D4[sXXZZ] += g2;
1817  D4[sYYZZ] += g2;
1818 
1819  symtensor2<T> g3aux2 = g3 * aux2;
1820 
1821  D4[sXXXX] += 6 * g3aux2[qXX];
1822  D4[sYYYY] += 6 * g3aux2[qYY];
1823  D4[sZZZZ] += 6 * g3aux2[qZZ];
1824 
1825  D4[sXXXY] += 3 * g3aux2[qXY];
1826  D4[sXYYY] += 3 * g3aux2[qXY];
1827  D4[sXXXZ] += 3 * g3aux2[qXZ];
1828  D4[sXZZZ] += 3 * g3aux2[qXZ];
1829  D4[sYYYZ] += 3 * g3aux2[qYZ];
1830  D4[sYZZZ] += 3 * g3aux2[qYZ];
1831 
1832  D4[sXXYY] += g3aux2[qXX] + g3aux2[qYY];
1833  D4[sXXZZ] += g3aux2[qXX] + g3aux2[qZZ];
1834  D4[sYYZZ] += g3aux2[qYY] + g3aux2[qZZ];
1835 
1836  D4[sXXYZ] += g3aux2[qYZ];
1837  D4[sXYYZ] += g3aux2[qXZ];
1838  D4[sXYZZ] += g3aux2[qXY];
1839 }
1840 
1841 template <typename T, typename TypeGfac>
1842 inline void setup_D5(enum setup_options opt, symtensor5<T> &D5, vector<T> &dxyz, symtensor3<T> &aux3, symtensor4<T> &aux4,
1843  symtensor5<T> &aux5, TypeGfac g3, TypeGfac g4, TypeGfac g5)
1844 {
1845  // Note: dxyz, aux3, and aux4 are input parameters, whereas aux5 is an output parameter!
1846 
1847  aux5 = dxyz % aux4; // construct outer product
1848  if(opt == INIT)
1849  D5 = g5 * aux5;
1850  else
1851  D5 += g5 * aux5;
1852 
1853  vector<T> g3_dxyz = g3 * dxyz;
1854 
1855  D5[rXXXXX] += 15 * g3_dxyz[0];
1856  D5[rYYYYY] += 15 * g3_dxyz[1];
1857  D5[rZZZZZ] += 15 * g3_dxyz[2];
1858 
1859  D5[rXXXXY] += 3 * g3_dxyz[1];
1860  D5[rXXXXZ] += 3 * g3_dxyz[2];
1861  D5[rXYYYY] += 3 * g3_dxyz[0];
1862  D5[rXZZZZ] += 3 * g3_dxyz[0];
1863  D5[rYYYYZ] += 3 * g3_dxyz[2];
1864  D5[rYZZZZ] += 3 * g3_dxyz[1];
1865 
1866  D5[rXXXYY] += 3 * g3_dxyz[0];
1867  D5[rXXXZZ] += 3 * g3_dxyz[0];
1868  D5[rXXYYY] += 3 * g3_dxyz[1];
1869  D5[rXXZZZ] += 3 * g3_dxyz[2];
1870  D5[rYYYZZ] += 3 * g3_dxyz[1];
1871  D5[rYYZZZ] += 3 * g3_dxyz[2];
1872 
1873  D5[rXXYZZ] += g3_dxyz[1];
1874  D5[rXXYYZ] += g3_dxyz[2];
1875  D5[rXYYZZ] += g3_dxyz[0];
1876 
1877  D5[rXXXYZ] += 0;
1878  D5[rXYYYZ] += 0;
1879  D5[rXYZZZ] += 0;
1880 
1882  symtensor3<T> g4aux3 = g4 * aux3;
1883 
1884  D5[rXXXXX] += 10 * g4aux3[dXXX];
1885  D5[rYYYYY] += 10 * g4aux3[dYYY];
1886  D5[rZZZZZ] += 10 * g4aux3[dZZZ];
1887 
1888  D5[rXXXXY] += 6 * g4aux3[dXXY];
1889  D5[rXXXXZ] += 6 * g4aux3[dXXZ];
1890  D5[rXYYYY] += 6 * g4aux3[dYYX];
1891  D5[rXZZZZ] += 6 * g4aux3[dZZX];
1892  D5[rYYYYZ] += 6 * g4aux3[dYYZ];
1893  D5[rYZZZZ] += 6 * g4aux3[dZZY];
1894 
1895  D5[rXXXYY] += g4aux3[dXXX] + 3 * g4aux3[dXYY];
1896  D5[rXXXZZ] += g4aux3[dXXX] + 3 * g4aux3[dXZZ];
1897  D5[rXXYYY] += g4aux3[dYYY] + 3 * g4aux3[dYXX];
1898  D5[rXXZZZ] += g4aux3[dZZZ] + 3 * g4aux3[dZXX];
1899  D5[rYYYZZ] += g4aux3[dYYY] + 3 * g4aux3[dYZZ];
1900  D5[rYYZZZ] += g4aux3[dZZZ] + 3 * g4aux3[dZYY];
1901 
1902  D5[rXXYZZ] += g4aux3[dYZZ] + g4aux3[dXXY];
1903  D5[rXXYYZ] += g4aux3[dYYZ] + g4aux3[dXXZ];
1904  D5[rXYYZZ] += g4aux3[dXZZ] + g4aux3[dXYY];
1905 
1906  D5[rXXXYZ] += 3 * g4aux3[dXYZ];
1907  D5[rXYYYZ] += 3 * g4aux3[dXYZ];
1908  D5[rXYZZZ] += 3 * g4aux3[dXYZ];
1909 }
1910 
1911 template <typename T, typename TypeGfac>
1912 inline void setup_D6(enum setup_options opt, symtensor6<T> &D6, vector<T> &dxyz, TypeGfac g3, TypeGfac g4, TypeGfac g5, TypeGfac g6)
1913 {
1914 #define X 0
1915 #define Y 1
1916 #define Z 2
1917 
1918  if(opt == INIT)
1919  D6 = static_cast<T>(0);
1920 
1921  D6[pXXXXXX] += 15 * g3 + g4 * (45 * dxyz[X] * dxyz[X]) + g5 * (15 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X]) +
1922  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X];
1923 
1924  D6[pXXXXXY] += g4 * (15 * dxyz[X] * dxyz[Y]) + g5 * (10 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y]) +
1925  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y];
1926 
1927  D6[pXXXXXZ] += g4 * (15 * dxyz[X] * dxyz[Z]) + g5 * (10 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z]) +
1928  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z];
1929 
1930  D6[pXXXXYY] += 3 * g3 + g4 * (6 * dxyz[X] * dxyz[X] + 3 * dxyz[Y] * dxyz[Y]) +
1931  g5 * (6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] + dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X]) +
1932  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y];
1933 
1934  D6[pXXXXYZ] += g4 * (3 * dxyz[Y] * dxyz[Z]) + g5 * (6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z]) +
1935  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z];
1936 
1937  D6[pXXXXZZ] += 3 * g3 + g4 * (6 * dxyz[X] * dxyz[X] + 3 * dxyz[Z] * dxyz[Z]) +
1938  g5 * (6 * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X]) +
1939  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z];
1940 
1941  D6[pXXXYYY] += g4 * (9 * dxyz[X] * dxyz[Y]) +
1942  g5 * (3 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] + 3 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y]) +
1943  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y];
1944 
1945  D6[pXXXYYZ] += g4 * (3 * dxyz[X] * dxyz[Z]) +
1946  g5 * (3 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z]) +
1947  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z];
1948 
1949  D6[pXXXYZZ] += g4 * (3 * dxyz[X] * dxyz[Y]) +
1950  g5 * (3 * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y]) +
1951  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z];
1952 
1953  D6[pXXXZZZ] += g4 * (9 * dxyz[X] * dxyz[Z]) +
1954  g5 * (3 * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 3 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z]) +
1955  g6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z];
1956 
1957  D6[pXXYYYY] += 3 * g3 + g4 * (3 * dxyz[X] * dxyz[X] + 6 * dxyz[Y] * dxyz[Y]) +
1958  g5 * (dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] + 6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y]) +
1959  g6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y];
1960 
1961  D6[pXXYYYZ] += g4 * (3 * dxyz[Y] * dxyz[Z]) +
1962  g5 * (dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] + 3 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z]) +
1963  g6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z];
1964 
1965  D6[pXXYYZZ] +=
1966  1 * g3 + g4 * (dxyz[X] * dxyz[X] + dxyz[Y] * dxyz[Y] + dxyz[Z] * dxyz[Z]) +
1967  g5 * (dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y]) +
1968  g6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z];
1969 
1970  D6[pXXYZZZ] += g4 * (3 * dxyz[Y] * dxyz[Z]) +
1971  g5 * (dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 3 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z]) +
1972  g6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z];
1973 
1974  D6[pXXZZZZ] += 3 * g3 + g4 * (3 * dxyz[X] * dxyz[X] + 6 * dxyz[Z] * dxyz[Z]) +
1975  g5 * (dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 6 * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z]) +
1976  g6 * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
1977 
1978  D6[pXYYYYY] += g4 * (15 * dxyz[X] * dxyz[Y]) + g5 * (10 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
1979  g6 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y];
1980 
1981  D6[pXYYYYZ] += g4 * (3 * dxyz[X] * dxyz[Z]) + g5 * (6 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
1982  g6 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z];
1983 
1984  D6[pXYYYZZ] += g4 * (3 * dxyz[X] * dxyz[Y]) +
1985  g5 * (3 * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
1986  g6 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z];
1987 
1988  D6[pXYYZZZ] += g4 * (3 * dxyz[X] * dxyz[Z]) +
1989  g5 * (dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 3 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
1990  g6 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z];
1991 
1992  D6[pXYZZZZ] += g4 * (3 * dxyz[X] * dxyz[Y]) + g5 * (6 * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
1993  g6 * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
1994 
1995  D6[pXZZZZZ] += g4 * (15 * dxyz[X] * dxyz[Z]) + g5 * (10 * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
1996  g6 * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
1997 
1998  D6[pYYYYYY] += 15 * g3 + g4 * (45 * dxyz[Y] * dxyz[Y]) + g5 * (15 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
1999  g6 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y];
2000 
2001  D6[pYYYYYZ] += g4 * (15 * dxyz[Y] * dxyz[Z]) + g5 * (10 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2002  g6 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z];
2003 
2004  D6[pYYYYZZ] += 3 * g3 + g4 * (6 * dxyz[Y] * dxyz[Y] + 3 * dxyz[Z] * dxyz[Z]) +
2005  g5 * (6 * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] + dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2006  g6 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z];
2007 
2008  D6[pYYYZZZ] += g4 * (9 * dxyz[Y] * dxyz[Z]) +
2009  g5 * (3 * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 3 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2010  g6 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2011 
2012  D6[pYYZZZZ] += 3 * g3 + g4 * (3 * dxyz[Y] * dxyz[Y] + 6 * dxyz[Z] * dxyz[Z]) +
2013  g5 * (dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 6 * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2014  g6 * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2015 
2016  D6[pYZZZZZ] += g4 * (15 * dxyz[Y] * dxyz[Z]) + g5 * (10 * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2017  g6 * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2018 
2019  D6[pZZZZZZ] += 15 * g3 + g4 * (45 * dxyz[Z] * dxyz[Z]) + g5 * (15 * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2020  g6 * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2021 
2022 #undef X
2023 #undef Y
2024 #undef Z
2025 }
2026 
2027 template <typename T, typename TypeGfac>
2028 inline void setup_D7(enum setup_options opt, symtensor7<T> &D7, vector<T> &dxyz, TypeGfac g4, TypeGfac g5, TypeGfac g6, TypeGfac g7)
2029 {
2030 #define X 0
2031 #define Y 1
2032 #define Z 2
2033 
2034  if(opt == INIT)
2035  D7 = static_cast<T>(0);
2036 
2037  D7[tXXXXXXX] += g4 * (105 * dxyz[X]) + g5 * (105 * dxyz[X] * dxyz[X] * dxyz[X]) +
2038  g6 * (21 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X]) +
2039  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X];
2040 
2041  D7[tXXXXXXY] += g4 * (15 * dxyz[Y]) + g5 * (45 * dxyz[X] * dxyz[X] * dxyz[Y]) +
2042  g6 * (15 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y]) +
2043  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y];
2044 
2045  D7[tXXXXXXZ] += g4 * (15 * dxyz[Z]) + g5 * (45 * dxyz[X] * dxyz[X] * dxyz[Z]) +
2046  g6 * (15 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z]) +
2047  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z];
2048 
2049  D7[tXXXXXYY] += g4 * (15 * dxyz[X]) + g5 * (10 * dxyz[X] * dxyz[X] * dxyz[X] + 15 * dxyz[X] * dxyz[Y] * dxyz[Y]) +
2050  g6 * (10 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] + dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X]) +
2051  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y];
2052 
2053  D7[tXXXXXYZ] += g5 * (15 * dxyz[X] * dxyz[Y] * dxyz[Z]) + g6 * (10 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z]) +
2054  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z];
2055 
2056  D7[tXXXXXZZ] += g4 * (15 * dxyz[X]) + g5 * (10 * dxyz[X] * dxyz[X] * dxyz[X] + 15 * dxyz[X] * dxyz[Z] * dxyz[Z]) +
2057  g6 * (10 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X]) +
2058  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z];
2059 
2060  D7[tXXXXYYY] += g4 * (9 * dxyz[Y]) + g5 * (18 * dxyz[X] * dxyz[X] * dxyz[Y] + 3 * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2061  g6 * (6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] + 3 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y]) +
2062  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y];
2063 
2064  D7[tXXXXYYZ] += g4 * (3 * dxyz[Z]) + g5 * (6 * dxyz[X] * dxyz[X] * dxyz[Z] + 3 * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2065  g6 * (6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z]) +
2066  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z];
2067 
2068  D7[tXXXXYZZ] += g4 * (3 * dxyz[Y]) + g5 * (6 * dxyz[X] * dxyz[X] * dxyz[Y] + 3 * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2069  g6 * (6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y]) +
2070  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z];
2071 
2072  D7[tXXXXZZZ] += g4 * (9 * dxyz[Z]) + g5 * (18 * dxyz[X] * dxyz[X] * dxyz[Z] + 3 * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2073  g6 * (6 * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 3 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z]) +
2074  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2075 
2076  D7[tXXXYYYY] += g4 * (9 * dxyz[X]) + g5 * (3 * dxyz[X] * dxyz[X] * dxyz[X] + 18 * dxyz[X] * dxyz[Y] * dxyz[Y]) +
2077  g6 * (3 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] + 6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y]) +
2078  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y];
2079 
2080  D7[tXXXYYYZ] += g5 * (9 * dxyz[X] * dxyz[Y] * dxyz[Z]) +
2081  g6 * (3 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] + 3 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z]) +
2082  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z];
2083 
2084  D7[tXXXYYZZ] += g4 * (3 * dxyz[X]) +
2085  g5 * (dxyz[X] * dxyz[X] * dxyz[X] + 3 * dxyz[X] * dxyz[Y] * dxyz[Y] + 3 * dxyz[X] * dxyz[Z] * dxyz[Z]) +
2086  g6 * (3 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] +
2087  dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y]) +
2088  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z];
2089 
2090  D7[tXXXYZZZ] += g5 * (9 * dxyz[X] * dxyz[Y] * dxyz[Z]) +
2091  g6 * (3 * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 3 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z]) +
2092  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2093 
2094  D7[tXXXZZZZ] += g4 * (9 * dxyz[X]) + g5 * (3 * dxyz[X] * dxyz[X] * dxyz[X] + 18 * dxyz[X] * dxyz[Z] * dxyz[Z]) +
2095  g6 * (3 * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 6 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z]) +
2096  g7 * dxyz[X] * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2097 
2098  D7[tXXYYYYY] += g4 * (15 * dxyz[Y]) + g5 * (15 * dxyz[X] * dxyz[X] * dxyz[Y] + 10 * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2099  g6 * (dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] + 10 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2100  g7 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y];
2101 
2102  D7[tXXYYYYZ] += g4 * (3 * dxyz[Z]) + g5 * (3 * dxyz[X] * dxyz[X] * dxyz[Z] + 6 * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2103  g6 * (dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] + 6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2104  g7 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z];
2105 
2106  D7[tXXYYYZZ] += g4 * (3 * dxyz[Y]) +
2107  g5 * (3 * dxyz[X] * dxyz[X] * dxyz[Y] + dxyz[Y] * dxyz[Y] * dxyz[Y] + 3 * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2108  g6 * (dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] + 3 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] +
2109  dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2110  g7 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z];
2111 
2112  D7[tXXYYZZZ] += g4 * (3 * dxyz[Z]) +
2113  g5 * (3 * dxyz[X] * dxyz[X] * dxyz[Z] + 3 * dxyz[Y] * dxyz[Y] * dxyz[Z] + dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2114  g6 * (dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] +
2115  3 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2116  g7 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2117 
2118  D7[tXXYZZZZ] += g4 * (3 * dxyz[Y]) + g5 * (3 * dxyz[X] * dxyz[X] * dxyz[Y] + 6 * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2119  g6 * (dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 6 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2120  g7 * dxyz[X] * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2121 
2122  D7[tXXZZZZZ] += g4 * (15 * dxyz[Z]) + g5 * (15 * dxyz[X] * dxyz[X] * dxyz[Z] + 10 * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2123  g6 * (dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 10 * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2124  g7 * dxyz[X] * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2125 
2126  D7[tXYYYYYY] += g4 * (15 * dxyz[X]) + g5 * (45 * dxyz[X] * dxyz[Y] * dxyz[Y]) +
2127  g6 * (15 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2128  g7 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y];
2129 
2130  D7[tXYYYYYZ] += g5 * (15 * dxyz[X] * dxyz[Y] * dxyz[Z]) + g6 * (10 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2131  g7 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z];
2132 
2133  D7[tXYYYYZZ] += g4 * (3 * dxyz[X]) + g5 * (6 * dxyz[X] * dxyz[Y] * dxyz[Y] + 3 * dxyz[X] * dxyz[Z] * dxyz[Z]) +
2134  g6 * (6 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] + dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2135  g7 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z];
2136 
2137  D7[tXYYYZZZ] += g5 * (9 * dxyz[X] * dxyz[Y] * dxyz[Z]) +
2138  g6 * (3 * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 3 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2139  g7 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2140 
2141  D7[tXYYZZZZ] += g4 * (3 * dxyz[X]) + g5 * (3 * dxyz[X] * dxyz[Y] * dxyz[Y] + 6 * dxyz[X] * dxyz[Z] * dxyz[Z]) +
2142  g6 * (dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 6 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2143  g7 * dxyz[X] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2144 
2145  D7[tXYZZZZZ] += g5 * (15 * dxyz[X] * dxyz[Y] * dxyz[Z]) + g6 * (10 * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2146  g7 * dxyz[X] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2147 
2148  D7[tXZZZZZZ] += g4 * (15 * dxyz[X]) + g5 * (45 * dxyz[X] * dxyz[Z] * dxyz[Z]) +
2149  g6 * (15 * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2150  g7 * dxyz[X] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2151 
2152  D7[tYYYYYYY] += g4 * (105 * dxyz[Y]) + g5 * (105 * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2153  g6 * (21 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2154  g7 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y];
2155 
2156  D7[tYYYYYYZ] += g4 * (15 * dxyz[Z]) + g5 * (45 * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2157  g6 * (15 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2158  g7 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z];
2159 
2160  D7[tYYYYYZZ] += g4 * (15 * dxyz[Y]) + g5 * (10 * dxyz[Y] * dxyz[Y] * dxyz[Y] + 15 * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2161  g6 * (10 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] + dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y]) +
2162  g7 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z];
2163 
2164  D7[tYYYYZZZ] += g4 * (9 * dxyz[Z]) + g5 * (18 * dxyz[Y] * dxyz[Y] * dxyz[Z] + 3 * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2165  g6 * (6 * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 3 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z]) +
2166  g7 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2167 
2168  D7[tYYYZZZZ] += g4 * (9 * dxyz[Y]) + g5 * (3 * dxyz[Y] * dxyz[Y] * dxyz[Y] + 18 * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2169  g6 * (3 * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 6 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2170  g7 * dxyz[Y] * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2171 
2172  D7[tYYZZZZZ] += g4 * (15 * dxyz[Z]) + g5 * (15 * dxyz[Y] * dxyz[Y] * dxyz[Z] + 10 * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2173  g6 * (dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] + 10 * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2174  g7 * dxyz[Y] * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2175 
2176  D7[tYZZZZZZ] += g4 * (15 * dxyz[Y]) + g5 * (45 * dxyz[Y] * dxyz[Z] * dxyz[Z]) +
2177  g6 * (15 * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2178  g7 * dxyz[Y] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2179 
2180  D7[tZZZZZZZ] += g4 * (105 * dxyz[Z]) + g5 * (105 * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2181  g6 * (21 * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z]) +
2182  g7 * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z] * dxyz[Z];
2183 
2184 #undef X
2185 #undef Y
2186 #undef Z
2187 }
2188 
2189 #endif
compl_return< T >::type float_or_double
Definition: symtensors.h:234
T trace(void)
Definition: symtensors.h:285
symtensor2 & operator+=(const symtensor2 &right)
Definition: symtensors.h:247
T & operator[](const size_t index)
Definition: symtensors.h:283
symtensor2(const float *x)
Definition: symtensors.h:213
symtensor2(const double *x)
Definition: symtensors.h:223
double norm(void)
Definition: symtensors.h:287
symtensor2 & operator*=(const T fac)
Definition: symtensors.h:271
symtensor2(const T x)
Definition: symtensors.h:203
symtensor2(const vector< T > &v, const vector< T > &w)
Definition: symtensors.h:237
symtensor2 & operator-=(const symtensor2 &right)
Definition: symtensors.h:259
symtensor3 & operator-=(const symtensor3 &right)
Definition: symtensors.h:383
compl_return< T >::type float_or_double
Definition: symtensors.h:349
symtensor3 & operator+=(const symtensor3 &right)
Definition: symtensors.h:367
symtensor3(const float *x)
Definition: symtensors.h:320
T & operator[](const size_t index)
Definition: symtensors.h:415
double norm(void)
Definition: symtensors.h:417
T da[10]
Definition: symtensors.h:302
symtensor3(const T x)
Definition: symtensors.h:306
symtensor3(const double *x)
Definition: symtensors.h:334
symtensor3 & operator*=(const T fac)
Definition: symtensors.h:399
symtensor3(const vector< T > &v, const symtensor2< T > &D)
Definition: symtensors.h:353
symtensor4 & operator-=(const symtensor4 &right)
Definition: symtensors.h:486
symtensor4(const double *x)
Definition: symtensors.h:448
compl_return< T >::type float_or_double
Definition: symtensors.h:455
symtensor4 & operator*=(const T fac)
Definition: symtensors.h:494
symtensor4(const float *x)
Definition: symtensors.h:442
symtensor4(const T x)
Definition: symtensors.h:436
T & operator[](const size_t index)
Definition: symtensors.h:502
double norm(void)
Definition: symtensors.h:504
T da[15]
Definition: symtensors.h:432
symtensor4(const vector< T > &v, const symtensor3< T > &D)
Definition: symtensors.h:459
symtensor4 & operator+=(const symtensor4 &right)
Definition: symtensors.h:478
symtensor5 & operator-=(const symtensor5 &right)
Definition: symtensors.h:579
symtensor5(const vector< T > &v, const symtensor4< T > &D)
Definition: symtensors.h:546
symtensor5(const double *x)
Definition: symtensors.h:535
symtensor5(const T x)
Definition: symtensors.h:523
compl_return< T >::type float_or_double
Definition: symtensors.h:542
symtensor5 & operator+=(const symtensor5 &right)
Definition: symtensors.h:571
T & operator[](const size_t index)
Definition: symtensors.h:595
symtensor5 & operator*=(const T fac)
Definition: symtensors.h:587
double norm(void)
Definition: symtensors.h:597
symtensor5(const float *x)
Definition: symtensors.h:529
T da[21]
Definition: symtensors.h:519
symtensor6 & operator-=(const symtensor6 &right)
Definition: symtensors.h:679
symtensor6(const vector< T > &v, const symtensor5< T > &D)
Definition: symtensors.h:639
symtensor6(const float *x)
Definition: symtensors.h:622
compl_return< T >::type float_or_double
Definition: symtensors.h:635
symtensor6 & operator+=(const symtensor6 &right)
Definition: symtensors.h:671
T & operator[](const size_t index)
Definition: symtensors.h:695
double norm(void)
Definition: symtensors.h:697
symtensor6(const T x)
Definition: symtensors.h:616
symtensor6(const double *x)
Definition: symtensors.h:628
symtensor6 & operator*=(const T fac)
Definition: symtensors.h:687
T da[28]
Definition: symtensors.h:612
compl_return< T >::type float_or_double
Definition: symtensors.h:735
T & operator[](const size_t index)
Definition: symtensors.h:762
double norm(void)
Definition: symtensors.h:764
symtensor7(const T x)
Definition: symtensors.h:716
symtensor7 & operator-=(const symtensor7 &right)
Definition: symtensors.h:746
symtensor7(const double *x)
Definition: symtensors.h:728
symtensor7(const float *x)
Definition: symtensors.h:722
symtensor7 & operator*=(const T fac)
Definition: symtensors.h:754
T da[36]
Definition: symtensors.h:712
symtensor7 & operator+=(const symtensor7 &right)
Definition: symtensors.h:738
vector & operator-=(const vector< double > &right)
Definition: symtensors.h:160
vector & operator*=(const T fac)
Definition: symtensors.h:178
vector(const T x)
Definition: symtensors.h:110
vector & operator+=(const vector< float > &right)
Definition: symtensors.h:151
vector(const T x, const T y, const T z)
Definition: symtensors.h:117
vector(const double *x)
Definition: symtensors.h:131
compl_return< T >::type float_or_double
Definition: symtensors.h:139
T & operator[](const size_t index)
Definition: symtensors.h:191
T r2(void)
Definition: symtensors.h:187
double norm(void)
Definition: symtensors.h:189
vector & operator-=(const vector< float > &right)
Definition: symtensors.h:169
vector()
Definition: symtensors.h:108
vector & operator+=(const vector< double > &right)
Definition: symtensors.h:142
vector(const float *x)
Definition: symtensors.h:124
T da[3]
Definition: symtensors.h:106
expr sqrt(half arg)
Definition: half.hpp:2777
double type
Definition: symtensors.h:77
defines some symbols for accessing the elements of (storage-optimized) symmetric tensors
#define tXXXZZZZ
#define tZZZZZZZ
#define rXZYYZ
#define tXYYZZZZ
#define pXYYYZZ
#define sXXYY
#define rYZZZZ
#define rZXXXX
#define sXYXX
#define tYYZZZZZ
#define rXXYZZ
#define rYZYZZ
#define sZYYY
#define tXYYYYYZ
#define sXXYX
#define sZZZZ
#define dYZZ
#define rYZZYZ
#define tXXYYYYZ
#define sYXZZ
#define rYYYXY
#define rYYZZZ
#define sXXXY
#define sYYXY
#define pYYYYYY
#define sXXXX
#define sZZXX
#define pXXXXYZ
#define rZZXYY
#define rXXZZZ
#define sYYZZ
#define rXZXXZ
#define rZYYYY
#define rXYXXZ
#define sXYZY
#define rXYZZY
#define rXYYZY
#define rXZXYY
#define dXYY
#define rXXXYY
#define rXYXXX
#define tXXXXXXX
#define sZXXX
#define sZZYZ
#define rZZXXZ
#define dYXZ
#define sXXYZ
#define rXZZZX
#define pXXZZZZ
#define rZZZYY
#define pXYYYYY
#define dXZX
#define tXXZZZZZ
#define tXYYYZZZ
#define sZZYY
#define sXYXY
#define rYZZXZ
#define rYYXZZ
#define rXZZXZ
#define qYX
#define dYZY
#define pXYYZZZ
#define rYYYZX
#define tYYYZZZZ
#define rXZXYZ
#define qXX
#define rYZXXX
#define rXXZZX
#define sXYYZ
#define pXXXYYY
#define rZZZXX
#define sYZZX
#define rYZZYY
#define rXYYZX
#define dZZZ
#define rXXXYZ
#define rXXXZY
#define rXYYXX
#define tYYYYYZZ
#define dYYY
#define sYYZY
#define rXYZXX
#define rYYXXX
#define rZYYXX
#define rZXXXY
#define rZXXZZ
#define dXYZ
#define rXYZXY
#define rYXXXX
#define pXXYYYZ
#define sYZZY
#define rYYXYY
#define rXYZYZ
#define rYYXXZ
#define sYYXZ
#define sZXXY
#define sYXXX
#define sYYYZ
#define rXXYYY
#define qZX
#define rZYZZZ
#define tXXXYYYZ
#define sXXZX
#define tXYZZZZZ
#define sZZZY
#define rYXYYY
#define sYXYZ
#define rYZXXZ
#define rXXXXZ
#define rXYZXZ
#define sXZZZ
#define dXYX
#define dYXY
#define qYY
#define rYXXYZ
#define dYYX
#define rXXXXY
#define rZXXYY
#define rYZXZZ
#define sZXXZ
#define rZZZYZ
#define rXZZZY
#define tXXYYYYY
#define rYYYYZ
#define rZZZXZ
#define rZXYZZ
#define sXYXZ
#define rXYXZZ
#define pXXXXXZ
#define rXYYYZ
#define sXYZX
#define tXXXXYZZ
#define tXXXYZZZ
#define pXYZZZZ
#define qYZ
#define rZXYYY
#define sZZXZ
#define rZZXXY
#define tXXXYYZZ
#define dZZY
#define sYZXX
#define rXYXYY
#define tYYYYYYZ
#define rYYYZY
#define rXXYZY
#define sYYYY
#define rXYYYY
#define rXZZXY
#define sZYZZ
#define sXYYY
#define sZYYX
#define rZZXYZ
#define dXXY
#define sYYYX
#define rXYXXY
#define rXZYYY
#define pXXXYYZ
#define rYZXYZ
#define sYXYY
#define tXXXXXYZ
#define rZZXZZ
#define rXXYZX
#define tXXXXZZZ
#define pYZZZZZ
#define pXXYYYY
#define dZXY
#define pZZZZZZ
#define rZXXXZ
#define rXYYXZ
#define sXZXZ
#define dXXX
#define rXZXXY
#define dZYZ
#define dXXZ
#define rXZZYZ
#define rYYYZZ
#define pXYYYYZ
#define rXYZZX
#define sZYYZ
#define dYYZ
#define rYXZZZ
#define sZXZZ
#define rXZZYY
#define pYYYZZZ
#define rYXYYZ
#define tXXYZZZZ
#define rYZXYY
#define rXZZXX
#define rXXXYX
#define rYXYZZ
#define rYZZZY
#define rZZZZY
#define pXXXXXX
#define rXZXXX
#define rYYXXY
#define rYXXYY
#define tXXXXXXY
#define rYYZZX
#define rXXXXX
#define pYYZZZZ
#define tXXXXXZZ
#define pXXXYZZ
#define rXXYYZ
#define dZZX
#define tYZZZZZZ
#define rZZZXY
#define rYYXYZ
#define tXXXXYYY
#define pXXXXZZ
#define rYZXXY
#define sXYZZ
#define sXZZX
#define rYZZXX
#define rZYYXZ
#define rZZZZX
#define rYYYYX
#define qZZ
#define pXXXXXY
#define sXZYZ
#define rZXXYZ
#define tXXXXXXZ
#define sXZYY
#define rXYYYX
#define rZYYXY
#define sYXXZ
#define rZZZZZ
#define rYXXZZ
#define sXZZY
#define sYZYZ
#define dYXX
#define rXZYZZ
#define rXXXZZ
#define rXYYZZ
#define sXXXZ
#define rYXXXY
#define sXXZY
#define rXYYXY
#define tXYYYYZZ
#define rZXYYZ
#define dXZY
#define dZYY
#define sYZZZ
#define sXXZZ
#define sYYXX
#define pXXYZZZ
#define sZXYY
#define tXYYYYYY
#define sYZXZ
#define tXXXYYYY
#define rXXXZX
#define tYYYYYYY
#define rZYYYZ
#define rZZXXX
#define pYYYYYZ
#define dYZX
#define rYZYYY
#define rYYYXX
#define qXY
#define rYZZXY
#define rXYXYZ
#define dZXZ
#define sYXXY
#define rYZYYZ
#define dZXX
#define rZYYZZ
#define rZZYYY
#define pXXXXYY
#define qZY
#define rXYZZZ
#define sZZXY
#define tYYYYZZZ
#define pYYYYZZ
#define sXZXX
#define sXZXY
#define rXXZZY
#define rZXZZZ
#define rYYYXZ
#define tXXXXXYY
#define rYYYYY
#define sZXYZ
#define sYZYY
#define tXZZZZZZ
#define rXYZYY
#define rXZXZZ
#define pXXXZZZ
#define rYXXXZ
#define rZZYZZ
#define pXXYYZZ
#define tXXYYZZZ
#define sZZZX
#define sYZXY
#define rXXYYX
#define rYYZZY
#define rZZYYZ
#define dXZZ
#define tXXXXYYZ
#define rYZZZX
#define rXZZZZ
#define qXZ
#define sXYYX
#define tXXYYYZZ
#define pXZZZZZ
vector< typename which_return< T1, T2 >::type > operator+(const vector< T1 > &left, const vector< T2 > &right)
Definition: symtensors.h:778
symtensor2< typename which_return< T1, T2 >::type > operator%(const vector< T1 > &v, const vector< T2 > &w)
Definition: symtensors.h:1445
void setup_D6(enum setup_options opt, symtensor6< T > &D6, vector< T > &dxyz, TypeGfac g3, TypeGfac g4, TypeGfac g5, TypeGfac g6)
Definition: symtensors.h:1912
#define X
void setup_D5(enum setup_options opt, symtensor5< T > &D5, vector< T > &dxyz, symtensor3< T > &aux3, symtensor4< T > &aux4, symtensor5< T > &aux5, TypeGfac g3, TypeGfac g4, TypeGfac g5)
Definition: symtensors.h:1842
vector< typename which_return< T1, T2 >::type > contract_twice(const symtensor3< T1 > &D, const vector< T2 > &v)
Definition: symtensors.h:1321
#define Z
void symtensor_test(void)
#define Y
void setup_D3(enum setup_options opt, symtensor3< T > &D3, vector< T > &dxyz, symtensor2< T > &aux2, symtensor3< T > &aux3, TypeGfac g2, TypeGfac g3)
Definition: symtensors.h:1775
vector< typename which_return< T1, T2 >::type > operator-(const vector< T1 > &left, const vector< T2 > &right)
Definition: symtensors.h:865
vector< typename which_return< T1, T2 >::type > contract_thrice(const symtensor4< T1 > &D, const vector< T2 > &v)
Definition: symtensors.h:1333
vector< typename which_return< T1, T2 >::type > contract_fourtimes(const symtensor5< T1 > &D, const vector< T2 > &v)
Definition: symtensors.h:1346
void setup_D7(enum setup_options opt, symtensor7< T > &D7, vector< T > &dxyz, TypeGfac g4, TypeGfac g5, TypeGfac g6, TypeGfac g7)
Definition: symtensors.h:2028
setup_options
Definition: symtensors.h:1769
@ INIT
Definition: symtensors.h:1770
@ ADD
Definition: symtensors.h:1771
symtensor3< typename which_return< T1, T2 >::type > outer_prod_sum(const symtensor2< T1 > &D, const vector< T2 > &v)
Definition: symtensors.h:1621
vector< typename which_return< T1, T2 >::type > operator*(const T1 fac, const vector< T2 > &v)
Definition: symtensors.h:952
vector< typename which_return< T1, T2 >::type > operator^(const vector< T1 > &v, const vector< T2 > &w)
Definition: symtensors.h:1432
void setup_D4(enum setup_options opt, symtensor4< T > &D4, vector< T > &dxyz, symtensor2< T > &aux2, symtensor3< T > &aux3, symtensor4< T > &aux4, TypeGfac g2, TypeGfac g3, TypeGfac g4)
Definition: symtensors.h:1801