12 #ifndef MFEM_TEMPLATE_LAYOUT
13 #define MFEM_TEMPLATE_LAYOUT
15 #include "../config/tconfig.hpp"
16 #include "../fem/fespace.hpp"
17 #include "../general/cuda.hpp"
18 #include "../general/hip.hpp"
25 template <
int N1,
int S1>
27 template <
int N1,
int S1,
int N2,
int S2>
30 template <
int N1,
int S1>
35 static const int size = N1;
37 MFEM_HOST_DEVICE
static inline int ind(
int i1)
50 template <
int N1_1,
int N1_2>
54 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
59 template <
int N1,
int S1,
int N2,
int S2>
62 template <
int N1,
int S1>
67 static const int size = N1;
73 MFEM_HOST_DEVICE
inline int ind(
int i1)
const
86 template <
int N1_1,
int N1_2>
90 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
95 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3>
97 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3,
int N4,
int S4>
100 template <
int N1,
int S1,
int N2,
int S2>
108 MFEM_HOST_DEVICE
static inline int ind(
int i1,
int i2)
110 return (S1*i1+S2*i2);
121 template <
int M1,
int M2>
129 template <
int N1_1,
int N1_2>
133 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
136 template <
int N2_1,
int N2_2>
140 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2,
"invalid dimensions");
143 template <
int N1_1,
int N1_2,
int N2_1,
int N2_2>
147 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1 && N2_1*N2_2 == N2,
148 "invalid dimensions");
156 MFEM_STATIC_ASSERT(S2 == S1*N1 || S1 == S2*N2,
"invalid reshape");
165 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3>
167 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3,
int N4,
int S4>
170 template <
int N1,
int S1,
int N2,
int S2>
182 MFEM_HOST_DEVICE
inline int ind(
int i1,
int i2)
const
184 return offset+S1*i1+S2*i2;
195 template <
int M1,
int M2>
203 template <
int N1_1,
int N1_2>
207 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
210 template <
int N2_1,
int N2_2>
214 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2,
"invalid dimensions");
217 template <
int N1_1,
int N1_2,
int N2_1,
int N2_2>
222 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1 && N2_1*N2_2 == N2,
223 "invalid dimensions");
225 N1_1,S1,N1_2,S1*N1_1,N2_1,S2,N2_2,S2*N2_1>(
offset);
232 MFEM_STATIC_ASSERT(S2 == S1*N1 || S1 == S2*N2,
"invalid reshape");
241 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3>
242 struct StridedLayout3D
248 static const int size = N1*N2*N3;
250 static inline int ind(
int i1,
int i2,
int i3)
252 return S1*i1+S2*i2+S3*i3;
273 MFEM_STATIC_ASSERT(S2 == S1*N1,
"invalid reshape");
284 MFEM_STATIC_ASSERT(S3 == S2*N2,
"invalid reshape");
288 template <
int N1_1,
int N1_2>
292 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
295 template <
int N2_1,
int N2_2>
299 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2,
"invalid dimensions");
302 template <
int N3_1,
int N3_2>
306 MFEM_STATIC_ASSERT(N3_1*N3_2 == N3,
"invalid dimensions");
324 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3>
325 struct OffsetStridedLayout3D
331 static const int size = N1*N2*N3;
337 inline int ind(
int i1,
int i2,
int i3)
const
339 return offset+S1*i1+S2*i2+S3*i3;
360 MFEM_STATIC_ASSERT(S2 == S1*N1,
"invalid reshape");
367 MFEM_STATIC_ASSERT(S3 == S2*N2,
"invalid reshape");
371 template <
int N1_1,
int N1_2>
375 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
378 template <
int N2_1,
int N2_2>
382 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2,
"invalid dimensions");
387 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3,
int N4,
int S4>
388 struct StridedLayout4D
395 static const int size = N1*N2*N3*N4;
397 static inline int ind(
int i1,
int i2,
int i3,
int i4)
399 return S1*i1+S2*i2+S3*i3+S4*i4;
418 MFEM_STATIC_ASSERT(S2 == S1*N1,
"invalid reshape");
425 MFEM_STATIC_ASSERT(S4 == S3*N3,
"invalid reshape");
430 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3,
int N4,
int S4>
431 struct OffsetStridedLayout4D
438 static const int size = N1*N2*N3*N4;
444 inline int ind(
int i1,
int i2,
int i3,
int i4)
const
446 return offset+S1*i1+S2*i2+S3*i3+S4*i4;
450 template <
int N1,
int N2>
454 template <
int N1,
int N2,
int N3>
458 template <
int N1,
int N2,
int N3,
int N4>
492 Init(ordering, scalar_size, num_comp);
502 int ind(
int scalar_idx,
int comp_idx)
const
515 template <Ordering::Type Ord,
int NumComp = 0>
530 "invalid number of components");
537 MFEM_ASSERT(fes.
GetOrdering() == Ord,
"ordering mismatch");
539 "invalid number of components");
545 int ind(
int scalar_idx,
int comp_idx)
const
553 return comp_idx + (NumComp ? NumComp :
num_components) * scalar_idx;
560 (NumComp == 0 || NumComp == fes.
GetVDim()));
573 MFEM_ASSERT(fes.
GetVDim() == 1,
"invalid number of components");
578 int ind(
int scalar_idx,
int comp_idx)
const {
return scalar_idx; }
588 #endif // MFEM_TEMPLATE_LAYOUT
OffsetStridedLayout1D< N1, S1 > ind2(int i2) const
int ind(int scalar_idx, int comp_idx) const
Ordering::Type GetOrdering() const
Return the ordering method.
OffsetStridedLayout4D< N1_1, S1, N1_2, S1 *N1_1, N2_1, S2, N2_2, S2 *N2_1 > split_12() const
int GetNDofs() const
Returns number of degrees of freedom.
int NumComponents() const
OffsetStridedLayout2D< N1 *N2, S1, N3, S3 > merge_12() const
MFEM_HOST_DEVICE int ind(int i1) const
static MFEM_HOST_DEVICE int ind(int i1)
static StridedLayout2D< N1_1, S1, N1_2, S1 *N1_1 > split_1()
static StridedLayout4D< N1, S1, N2, S2, N3_1, S3, N3_2, S3 *N3_1 > split_3()
static OffsetStridedLayout2D< N2, S2, N3, S3 > ind1(int i1)
static StridedLayout3D< N1, S1, N3, S3, N2, S2 > transpose_23()
static bool Matches(const FiniteElementSpace &fes)
static StridedLayout2D< N1, S1, N2 *N3, S2 > merge_23()
OffsetStridedLayout4D(int offset_)
static StridedLayout2D< N2, S2, N1, S1 > transpose_12()
int NumComponents() const
OffsetStridedLayout1D< M1, S1 > sub(int o1) const
OffsetStridedLayout2D< N1, S1, N2, S2 > ind3(int i3) const
OffsetStridedLayout3D< N1_1, S1, N1_2, S1 *N1_1, N2, S2 > split_1() const
VectorLayout(const FiniteElementSpace &fes)
OffsetStridedLayout1D< N1 *N2,(S1< S2)?S1:S2 > merge_12() const
ScalarLayout(const FiniteElementSpace &fes)
OffsetStridedLayout2D< N1_1, S1, N1_2, S1 *N1_1 > split_1() const
static OffsetStridedLayout1D< M1, S1 > sub(int o1)
int ind(int i1, int i2, int i3, int i4) const
static OffsetStridedLayout3D< N1, S1, N2, S2, N3, S3 > ind4(int i4)
OffsetStridedLayout2D< N1, S1, N2 *N3, S2 > merge_23() const
static OffsetStridedLayout2D< N2, S2, N3, S3 > ind14(int i1, int i4)
OffsetStridedLayout3D(int offset_)
static StridedLayout3D< N1, S1, N2, S2, N3 *N4, S3 > merge_34()
OffsetStridedLayout4D< N1, S1, N2_1, S2, N2_2, S2 *N2_1, N3, S3 > split_2() const
static int ind(int i1, int i2, int i3, int i4)
VectorLayout(int scalar_size_, int num_comp_=NumComp)
static OffsetStridedLayout2D< N1, S1, N4, S4 > ind23(int i2, int i3)
static OffsetStridedLayout1D< N2, S2 > ind1(int i1)
static StridedLayout4D< N1, S1, N2_1, S2, N2_2, S2 *N2_1, N3, S3 > split_2()
OffsetStridedLayout2D< M1, S1, M2, S2 > sub(int o1, int o2) const
OffsetStridedLayout2D< N2, S2, N1, S1 > transpose_12() const
OffsetStridedLayout2D< N2, S2, N3, S3 > ind1(int i1) const
static StridedLayout3D< N1, S1, N2_1, S2, N2_2, S2 *N2_1 > split_2()
int GetVDim() const
Returns vector dimension.
void Init(Ordering::Type ordering, int scalar_size, int num_comp)
DynamicVectorLayout(const FiniteElementSpace &fes)
static OffsetStridedLayout2D< N1, S1, N2, S2 > ind3(int i3)
static int ind(int i1, int i2, int i3)
int ind(int scalar_idx, int comp_idx) const
static bool Matches(const FiniteElementSpace &fes)
static StridedLayout3D< N2, S2, N1, S1, N3, S3 > transpose_12()
static OffsetStridedLayout2D< M1, S1, M2, S2 > sub(int o1, int o2)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
static StridedLayout1D< N1 *N2,(S1< S2)?S1:S2 > merge_12()
int ind(int i1, int i2, int i3) const
OffsetStridedLayout2D(int offset_)
static StridedLayout2D< N1 *N2, S1, N3, S3 > merge_12()
static OffsetStridedLayout2D< N1, S1, N3, S3 > ind2(int i2)
static StridedLayout3D< N1_1, S1, N1_2, S1 *N1_1, N2, S2 > split_1()
static StridedLayout3D< N1 *N2, S1, N3, S3, N4, S4 > merge_12()
OffsetStridedLayout1D(int offset_)
int NumComponents() const
int ind(int scalar_idx, int comp_idx) const
static StridedLayout4D< N1_1, S1, N1_2, S1 *N1_1, N2, S2, N3, S3 > split_1()
static OffsetStridedLayout1D< N1, S1 > ind2(int i2)
OffsetStridedLayout4D< N1_1, S1, N1_2, S1 *N1_1, N2, S2, N3, S3 > split_1() const
OffsetStridedLayout3D< N1, S1, N2_1, S2, N2_2, S2 *N2_1 > split_2() const
MFEM_HOST_DEVICE int ind(int i1, int i2) const
static MFEM_HOST_DEVICE int ind(int i1, int i2)
static StridedLayout3D< N3, S3, N2, S2, N1, S1 > transpose_13()
OffsetStridedLayout1D< N2, S2 > ind1(int i1) const
DynamicVectorLayout(Ordering::Type ordering, int scalar_size, int num_comp)
OffsetStridedLayout2D< N1, S1, N3, S3 > ind2(int i2) const
static StridedLayout4D< N1_1, S1, N1_2, S1 *N1_1, N2_1, S2, N2_2, S2 *N2_1 > split_12()
static bool Matches(const FiniteElementSpace &fes)