12 #ifndef MFEM_TEMPLATE_LAYOUT
13 #define MFEM_TEMPLATE_LAYOUT
15 #include "../config/tconfig.hpp"
16 #include "../fem/fespace.hpp"
17 #include "../general/backends.hpp"
24 template <
int N1,
int S1>
26 template <
int N1,
int S1,
int N2,
int S2>
29 template <
int N1,
int S1>
34 static const int size = N1;
36 MFEM_HOST_DEVICE
static inline int ind(
int i1)
49 template <
int N1_1,
int N1_2>
53 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
58 template <
int N1,
int S1,
int N2,
int S2>
61 template <
int N1,
int S1>
66 static const int size = N1;
72 MFEM_HOST_DEVICE
inline int ind(
int i1)
const
85 template <
int N1_1,
int N1_2>
89 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
94 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3>
96 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3,
int N4,
int S4>
99 template <
int N1,
int S1,
int N2,
int S2>
107 MFEM_HOST_DEVICE
static inline int ind(
int i1,
int i2)
109 return (S1*i1+S2*i2);
120 template <
int M1,
int M2>
128 template <
int N1_1,
int N1_2>
132 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
135 template <
int N2_1,
int N2_2>
139 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2,
"invalid dimensions");
142 template <
int N1_1,
int N1_2,
int N2_1,
int N2_2>
146 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1 && N2_1*N2_2 == N2,
147 "invalid dimensions");
155 MFEM_STATIC_ASSERT(S2 == S1*N1 || S1 == S2*N2,
"invalid reshape");
164 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3>
166 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3,
int N4,
int S4>
169 template <
int N1,
int S1,
int N2,
int S2>
181 MFEM_HOST_DEVICE
inline int ind(
int i1,
int i2)
const
183 return offset+S1*i1+S2*i2;
194 template <
int M1,
int M2>
202 template <
int N1_1,
int N1_2>
206 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
209 template <
int N2_1,
int N2_2>
213 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2,
"invalid dimensions");
216 template <
int N1_1,
int N1_2,
int N2_1,
int N2_2>
221 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1 && N2_1*N2_2 == N2,
222 "invalid dimensions");
224 N1_1,S1,N1_2,S1*N1_1,N2_1,S2,N2_2,S2*N2_1>(
offset);
231 MFEM_STATIC_ASSERT(S2 == S1*N1 || S1 == S2*N2,
"invalid reshape");
240 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3>
241 struct StridedLayout3D
247 static const int size = N1*N2*N3;
249 static inline int ind(
int i1,
int i2,
int i3)
251 return S1*i1+S2*i2+S3*i3;
272 MFEM_STATIC_ASSERT(S2 == S1*N1,
"invalid reshape");
283 MFEM_STATIC_ASSERT(S3 == S2*N2,
"invalid reshape");
287 template <
int N1_1,
int N1_2>
291 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
294 template <
int N2_1,
int N2_2>
298 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2,
"invalid dimensions");
301 template <
int N3_1,
int N3_2>
305 MFEM_STATIC_ASSERT(N3_1*N3_2 == N3,
"invalid dimensions");
323 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3>
324 struct OffsetStridedLayout3D
330 static const int size = N1*N2*N3;
336 inline int ind(
int i1,
int i2,
int i3)
const
338 return offset+S1*i1+S2*i2+S3*i3;
359 MFEM_STATIC_ASSERT(S2 == S1*N1,
"invalid reshape");
366 MFEM_STATIC_ASSERT(S3 == S2*N2,
"invalid reshape");
370 template <
int N1_1,
int N1_2>
374 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1,
"invalid dimensions");
377 template <
int N2_1,
int N2_2>
381 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2,
"invalid dimensions");
386 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3,
int N4,
int S4>
387 struct StridedLayout4D
394 static const int size = N1*N2*N3*N4;
396 static inline int ind(
int i1,
int i2,
int i3,
int i4)
398 return S1*i1+S2*i2+S3*i3+S4*i4;
417 MFEM_STATIC_ASSERT(S2 == S1*N1,
"invalid reshape");
424 MFEM_STATIC_ASSERT(S4 == S3*N3,
"invalid reshape");
429 template <
int N1,
int S1,
int N2,
int S2,
int N3,
int S3,
int N4,
int S4>
430 struct OffsetStridedLayout4D
437 static const int size = N1*N2*N3*N4;
443 inline int ind(
int i1,
int i2,
int i3,
int i4)
const
445 return offset+S1*i1+S2*i2+S3*i3+S4*i4;
449 template <
int N1,
int N2>
453 template <
int N1,
int N2,
int N3>
457 template <
int N1,
int N2,
int N3,
int N4>
491 Init(ordering, scalar_size, num_comp);
501 int ind(
int scalar_idx,
int comp_idx)
const
514 template <Ordering::Type Ord,
int NumComp = 0>
529 "invalid number of components");
536 MFEM_ASSERT(fes.
GetOrdering() == Ord,
"ordering mismatch");
538 "invalid number of components");
544 int ind(
int scalar_idx,
int comp_idx)
const
552 return comp_idx + (NumComp ? NumComp :
num_components) * scalar_idx;
559 (NumComp == 0 || NumComp == fes.
GetVDim()));
572 MFEM_ASSERT(fes.
GetVDim() == 1,
"invalid number of components");
577 int ind(
int scalar_idx,
int comp_idx)
const {
return scalar_idx; }
587 #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)