Nalu
Nalu: a generalized unstructured massively parallel low Mach flow code designed to support a variety of energy applications of interest (most notably Wind ECP) built on the Sierra Toolkit and Trilinos solver Tpetra/Epetra stack. The open source BSD, clause 3 license model has been chosen for the code base. See LICENSE for more information. http://NaluCFD.org
TensorOps.h
Go to the documentation of this file.
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2014 Sandia Corporation. */
3 /* This software is released under the license detailed */
4 /* in the file, LICENSE, which is located in the top-level Nalu */
5 /* directory structure */
6 /*------------------------------------------------------------------------*/
7 #ifndef TensorOps_h
8 #define TensorOps_h
9 
10 #include <vector>
11 #include <array>
12 #include <limits>
13 
14 #include <stk_util/environment/ReportHandler.hpp>
15 
16 #include <Kokkos_Core.hpp>
17 #include <SimdInterface.h>
18 
19 
20 #ifdef __INTEL_COMPILER
21 #define POINTER_RESTRICT restrict
22 #else
23 #define POINTER_RESTRICT __restrict__
24 #endif
25 
26 namespace sierra{
27 namespace nalu{
28 
29  inline constexpr double tiny_positive_value() {
30  return (1.0e6*std::numeric_limits<double>::min());
31  }
32 
33  template <typename ScalarType>
34  KOKKOS_FORCEINLINE_FUNCTION ScalarType vecnorm_sq2(const ScalarType* x) {
35  return (x[0] * x[0] + x[1] * x[1]);
36  }
37 
38  template <typename ScalarType>
39  KOKKOS_FORCEINLINE_FUNCTION ScalarType vecnorm_sq3(const ScalarType* x) {
40  return (x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
41  }
42 
43  template <typename ScalarType>
44  ScalarType ddot(const ScalarType* u, const ScalarType* v, int n)
45  {
46  ScalarType val = 0.0;
47  for (int i = 0; i < n; ++i) {
48  val += u[i] * v[i];
49  }
50  return val;
51  }
52 
53  template <typename ScalarType>
54  void cross3(const ScalarType* u, const ScalarType* v, ScalarType* cross)
55  {
56  cross[0] = u[1]*v[2] - u[2]*v[1];
57  cross[1] = -(u[0]*v[2] - u[2]*v[0]);
58  cross[2] = u[0]*v[1] - u[1]*v[0];
59  }
60 
61  template <typename ScalarType>
62  KOKKOS_FORCEINLINE_FUNCTION ScalarType determinant22(const ScalarType* mat)
63  {
64  enum { XX = 0, XY = 1, YX = 2, YY = 3 };
65  return (mat[XX] * mat[YY] - mat[XY] * mat[YX]);
66  }
67 
68  template <typename ScalarType>
69  KOKKOS_FORCEINLINE_FUNCTION ScalarType determinant33(const ScalarType* mat) {
70  enum { XX = 0, XY = 1, XZ = 2, YX = 3, YY = 4, YZ = 5, ZX = 6, ZY = 7, ZZ = 8 };
71  return (mat[XX] * (mat[YY] * mat[ZZ] - mat[YZ] * mat[ZY])
72  - mat[XY] * (mat[YX] * mat[ZZ] - mat[YZ] * mat[ZX])
73  + mat[XZ] * (mat[YX] * mat[ZY] - mat[YY] * mat[ZX]));
74  }
75 
76  template <typename ScalarType>
77  KOKKOS_FORCEINLINE_FUNCTION void adjugate_matrix33(const ScalarType jact[3][3], ScalarType adjJac[3][3])
78  {
79  adjJac[0][0] = jact[1][1] * jact[2][2] - jact[2][1] * jact[1][2];
80  adjJac[0][1] = jact[1][2] * jact[2][0] - jact[2][2] * jact[1][0];
81  adjJac[0][2] = jact[1][0] * jact[2][1] - jact[2][0] * jact[1][1];
82 
83  adjJac[1][0] = jact[0][2] * jact[2][1] - jact[2][2] * jact[0][1];
84  adjJac[1][1] = jact[0][0] * jact[2][2] - jact[2][0] * jact[0][2];
85  adjJac[1][2] = jact[0][1] * jact[2][0] - jact[2][1] * jact[0][0];
86 
87  adjJac[2][0] = jact[0][1] * jact[1][2] - jact[1][1] * jact[0][2];
88  adjJac[2][1] = jact[0][2] * jact[1][0] - jact[1][2] * jact[0][0];
89  adjJac[2][2] = jact[0][0] * jact[1][1] - jact[1][0] * jact[0][1];
90  }
91 
92  template <typename ScalarType>
93  KOKKOS_FORCEINLINE_FUNCTION void invert_matrix33(const ScalarType A[3][3], ScalarType Ainv[3][3])
94  {
95  ScalarType inv_detj = 1.0 / determinant33(&A[0][0]);
96 
97  Ainv[0][0] = inv_detj*(A[1][1] * A[2][2] - A[2][1] * A[1][2]);
98  Ainv[0][1] = inv_detj*(A[1][2] * A[2][0] - A[2][2] * A[1][0]);
99  Ainv[0][2] = inv_detj*(A[1][0] * A[2][1] - A[2][0] * A[1][1]);
100 
101  Ainv[1][0] = inv_detj*(A[0][2] * A[2][1] - A[2][2] * A[0][1]);
102  Ainv[1][1] = inv_detj*(A[0][0] * A[2][2] - A[2][0] * A[0][2]);
103  Ainv[1][2] = inv_detj*(A[0][1] * A[2][0] - A[2][1] * A[0][0]);
104 
105  Ainv[2][0] = inv_detj*(A[0][1] * A[1][2] - A[1][1] * A[0][2]);
106  Ainv[2][1] = inv_detj*(A[0][2] * A[1][0] - A[1][2] * A[0][0]);
107  Ainv[2][2] = inv_detj*(A[0][0] * A[1][1] - A[1][0] * A[0][1]);
108  }
109 
110  template <typename ScalarType>
111  KOKKOS_FORCEINLINE_FUNCTION void invert_matrix33(
112  const ScalarType* POINTER_RESTRICT A,
113  ScalarType* POINTER_RESTRICT Ainv)
114  {
115  enum { XX = 0, XY = 1, XZ = 2, YX = 3, YY = 4, YZ = 5, ZX = 6, ZY = 7, ZZ = 8 };
116  ScalarType inv_detj = 1.0 / determinant33(A);
117 
118  Ainv[XX] = inv_detj*(A[YY] * A[ZZ] - A[ZY] * A[YZ]);
119  Ainv[XY] = inv_detj*(A[YZ] * A[ZX] - A[ZZ] * A[YX]);
120  Ainv[XZ] = inv_detj*(A[YX] * A[ZY] - A[ZX] * A[YY]);
121  Ainv[YX] = inv_detj*(A[XZ] * A[ZY] - A[ZZ] * A[XY]);
122  Ainv[YY] = inv_detj*(A[XX] * A[ZZ] - A[ZX] * A[XZ]);
123  Ainv[YZ] = inv_detj*(A[XY] * A[ZX] - A[ZY] * A[XX]);
124  Ainv[ZX] = inv_detj*(A[XY] * A[YZ] - A[YY] * A[XZ]);
125  Ainv[ZY] = inv_detj*(A[XZ] * A[YZ] - A[YZ] * A[XX]);
126  Ainv[ZZ] = inv_detj*(A[XX] * A[YY] - A[YX] * A[XY]);
127  }
128 
129  template <typename ScalarType>
130  KOKKOS_FORCEINLINE_FUNCTION void solve22(
131  const ScalarType* POINTER_RESTRICT A,
132  const ScalarType* POINTER_RESTRICT b,
133  ScalarType* POINTER_RESTRICT x)
134  {
135  ThrowAssert(stk::simd::are_any(determinant22(A) > tiny_positive_value()));
136  enum { XX = 0, XY = 1, YX = 2, YY = 3 };
137  enum { X_RANK1 = 0, Y_RANK1 = 1};
138 
139  const ScalarType inv_detA = 1.0 / determinant22(A);
140  x[X_RANK1] = (A[YY] * b[X_RANK1] - A[XY] * b[Y_RANK1]) * inv_detA;
141  x[Y_RANK1] = -(A[YX] * b[X_RANK1] - A[XX] * b[Y_RANK1]) * inv_detA;
142  }
143 
144  // computes b = A^-1 x;
145  template <typename ScalarType>
146  KOKKOS_FORCEINLINE_FUNCTION void solve33(
147  const ScalarType* POINTER_RESTRICT A,
148  const ScalarType* POINTER_RESTRICT b,
149  ScalarType* POINTER_RESTRICT x)
150  {
151  ThrowAssert(stk::simd::are_any(determinant33(A) > tiny_positive_value()));
152 
153 
154  enum { XX = 0, XY = 1, XZ = 2, YX = 3, YY = 4, YZ = 5, ZX = 6, ZY = 7, ZZ = 8 };
155  enum { X_RANK1 = 0, Y_RANK1 = 1, Z_RANK1 = 2 };
156 
157  const ScalarType inv_detA = 1.0 / determinant33(A);
158  x[X_RANK1] = ((A[YY] * A[ZZ] - A[YZ] * A[ZY]) * b[X_RANK1] + (A[XZ] * A[ZY] - A[XY] * A[ZZ]) * b[Y_RANK1] +
159  (A[XY] * A[YZ] - A[XZ] * A[YY]) * b[Z_RANK1]) *
160  inv_detA;
161 
162  x[Y_RANK1] = ((A[YZ] * A[ZX] - A[YX] * A[ZZ]) * b[X_RANK1] + (A[XX] * A[ZZ] - A[XZ] * A[ZX]) * b[Y_RANK1] +
163  (A[XZ] * A[YX] - A[XX] * A[YZ]) * b[Z_RANK1]) *
164  inv_detA;
165 
166  x[Z_RANK1] = ((A[YX] * A[ZY] - A[YY] * A[ZX]) * b[X_RANK1] + (A[XY] * A[ZX] - A[XX] * A[ZY]) * b[Y_RANK1] +
167  (A[XX] * A[YY] - A[XY] * A[YX]) * b[Z_RANK1]) *
168  inv_detA;
169  }
170 
171  template <typename ScalarType>
172  KOKKOS_FORCEINLINE_FUNCTION void matvec22(const ScalarType* A, const ScalarType* x, ScalarType* b)
173  {
174  b[0] = A[0] * x[0] + A[1] * x[1];
175  b[1] = A[2] * x[0] + A[3] * x[1];
176  }
177 
178  template <typename ScalarType>
179  KOKKOS_FORCEINLINE_FUNCTION void mxm22(const ScalarType* A, const ScalarType* B, ScalarType* C)
180  {
181  C[0] = A[0] * B[0] + A[1] * B[2];
182  C[1] = A[0] * B[1] + A[1] * B[3];
183  C[2] = A[2] * B[0] + A[3] * B[2];
184  C[3] = A[2] * B[1] + A[3] * B[3];
185  }
186 
187  template <typename ScalarType>
188  KOKKOS_FORCEINLINE_FUNCTION void mxm33(const ScalarType* A, const ScalarType* B, ScalarType* C)
189  {
190  enum { XX = 0, XY = 1, XZ = 2, YX = 3, YY = 4, YZ = 5, ZX = 6, ZY = 7, ZZ = 8 };
191  C[XX] = A[XX] * B[XX] + A[XY] * B[YX] + A[XZ] * B[ZX];
192  C[XY] = A[XX] * B[XY] + A[XY] * B[YY] + A[XZ] * B[ZY];
193  C[XZ] = A[XX] * B[XZ] + A[XY] * B[YZ] + A[XZ] * B[ZZ];
194  C[YX] = A[YX] * B[XX] + A[YY] * B[YX] + A[YZ] * B[ZX];
195  C[YY] = A[YX] * B[XY] + A[YY] * B[YY] + A[YZ] * B[ZY];
196  C[YZ] = A[YX] * B[XZ] + A[YY] * B[YZ] + A[YZ] * B[ZZ];
197  C[ZX] = A[ZX] * B[XX] + A[ZY] * B[YX] + A[ZZ] * B[ZX];
198  C[ZY] = A[ZX] * B[XY] + A[ZY] * B[YY] + A[ZZ] * B[ZY];
199  C[ZZ] = A[ZX] * B[XZ] + A[ZY] * B[YZ] + A[ZZ] * B[ZZ];
200  }
201 
202  template <typename ScalarType>
203  KOKKOS_FORCEINLINE_FUNCTION void matvec33(const ScalarType* A, const ScalarType* x, ScalarType* b)
204  {
205  b[0] = A[0] * x[0] + A[1] * x[1] + A[2] * x[2];
206  b[1] = A[3] * x[0] + A[4] * x[1] + A[5] * x[2];
207  b[2] = A[6] * x[0] + A[7] * x[1] + A[8] * x[2];
208  }
209 
210  template <typename ScalarType>
211  KOKKOS_FORCEINLINE_FUNCTION void transpose22(const ScalarType* A, ScalarType* At)
212  {
213  At[0] = A[0];
214  At[1] = A[2];
215  At[2] = A[1];
216  At[3] = A[3];
217  }
218 
219  template <typename ScalarType>
220  KOKKOS_FORCEINLINE_FUNCTION void transpose33(const ScalarType* A, ScalarType* At)
221  {
222  enum { XX = 0, XY = 1, XZ = 2, YX = 3, YY = 4, YZ = 5, ZX = 6, ZY = 7, ZZ = 8 };
223  At[XX] = A[XX];
224  At[YY] = A[YY];
225  At[ZZ] = A[ZZ];
226 
227  At[XY] = A[YX];
228  At[XZ] = A[ZX];
229  At[YX] = A[XY];
230  At[YZ] = A[ZY];
231  At[ZX] = A[XZ];
232  At[ZY] = A[YZ];
233  }
234 
235 }
236 }
237 
238 #endif
Definition: ABLForcingAlgorithm.C:26
KOKKOS_FORCEINLINE_FUNCTION void mxm33(const ScalarType *A, const ScalarType *B, ScalarType *C)
Definition: TensorOps.h:188
ScalarType ddot(const ScalarType *u, const ScalarType *v, int n)
Definition: TensorOps.h:44
KOKKOS_FORCEINLINE_FUNCTION void matvec22(const ScalarType *A, const ScalarType *x, ScalarType *b)
Definition: TensorOps.h:172
KOKKOS_FORCEINLINE_FUNCTION void solve22(const ScalarType *POINTER_RESTRICT A, const ScalarType *POINTER_RESTRICT b, ScalarType *POINTER_RESTRICT x)
Definition: TensorOps.h:130
KOKKOS_FORCEINLINE_FUNCTION void transpose33(const ScalarType *A, ScalarType *At)
Definition: TensorOps.h:220
STK SIMD Interface.
KOKKOS_FORCEINLINE_FUNCTION ScalarType determinant22(const ScalarType *mat)
Definition: TensorOps.h:62
void cross3(const ScalarType *u, const ScalarType *v, ScalarType *cross)
Definition: TensorOps.h:54
KOKKOS_FORCEINLINE_FUNCTION void mxm22(const ScalarType *A, const ScalarType *B, ScalarType *C)
Definition: TensorOps.h:179
KOKKOS_FORCEINLINE_FUNCTION void adjugate_matrix33(const ScalarType jact[3][3], ScalarType adjJac[3][3])
Definition: TensorOps.h:77
KOKKOS_FORCEINLINE_FUNCTION ScalarType determinant33(const ScalarType *mat)
Definition: TensorOps.h:69
KOKKOS_FORCEINLINE_FUNCTION void matvec33(const ScalarType *A, const ScalarType *x, ScalarType *b)
Definition: TensorOps.h:203
KOKKOS_FORCEINLINE_FUNCTION ScalarType vecnorm_sq3(const ScalarType *x)
Definition: TensorOps.h:39
constexpr double tiny_positive_value()
Definition: TensorOps.h:29
KOKKOS_FORCEINLINE_FUNCTION ScalarType vecnorm_sq2(const ScalarType *x)
Definition: TensorOps.h:34
KOKKOS_FORCEINLINE_FUNCTION void solve33(const ScalarType *POINTER_RESTRICT A, const ScalarType *POINTER_RESTRICT b, ScalarType *POINTER_RESTRICT x)
Definition: TensorOps.h:146
#define POINTER_RESTRICT
Definition: TensorOps.h:23
KOKKOS_FORCEINLINE_FUNCTION void transpose22(const ScalarType *A, ScalarType *At)
Definition: TensorOps.h:211
KOKKOS_FORCEINLINE_FUNCTION void invert_matrix33(const ScalarType A[3][3], ScalarType Ainv[3][3])
Definition: TensorOps.h:93