12 #ifndef MFEM_TEMPLATE_ELEMENT_TRANSFORMATION
13 #define MFEM_TEMPLATE_ELEMENT_TRANSFORMATION
15 #include "../config/tconfig.hpp"
17 #include "../mesh/element.hpp"
32 template <
typename Mesh_t,
typename IR,
typename real_t =
double>
58 template <
typename coeff_t,
typename kernel_t>
struct Get
75 template<
int EvalOps,
typename impl_traits_t>
struct Result;
78 static const int sdim = Mesh_t::space_dim;
79 static const int dofs = FE_type::dofs;
80 static const int qpts = IR::qpts;
83 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
94 template <
typename v
int_t,
int NE>
95 inline MFEM_ALWAYS_INLINE
98 const int vsize =
sizeof(vint_t)/
sizeof(attrib[0][0]);
99 for (
int i = 0; i < NE; i++)
101 for (
int j = 0; j < vsize; i++)
114 nodes(mesh.Nodes.GetData()),
115 elements(mesh.m_mesh.GetElementsArray())
119 template<
int EvalOps,
typename impl_traits_t>
120 inline MFEM_ALWAYS_INLINE
126 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
127 template<
int EvalOps,
typename impl_traits_t>
128 inline MFEM_ALWAYS_INLINE
132 F.EvalSerialized(el, *
this, nodeData);
139 template <
typename it_t>
struct Result<0,it_t>
141 static const int ne = it_t::batch_size;
147 inline MFEM_ALWAYS_INLINE
153 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
154 inline MFEM_ALWAYS_INLINE
160 template <
typename it_t>
struct Result<1,it_t>
162 static const int ne = it_t::batch_size;
164 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
172 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
176 inline MFEM_ALWAYS_INLINE
179 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
180 MFEM_STATIC_ASSERT(ne == 1,
"only ne == 1 is supported");
182 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
185 T.
fes.SetElement(el);
187 nodes_dof.
layout, nodes_dof);
192 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
193 inline MFEM_ALWAYS_INLINE
196 const int SS =
sizeof(nodeData[0])/
sizeof(nodeData[0][0]);
197 MFEM_ASSERT(el % (SS*ne) == 0,
"invalid element index: " << el);
198 T.
evaluator.Calc(nodes_dof_t::layout.merge_23(),
199 &nodeData[el/SS*nodes_dof_t::size],
200 x.layout.merge_23(), x);
206 template <
typename it_t>
struct Result<2,it_t>
208 static const int ne = it_t::batch_size;
210 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
218 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
222 inline MFEM_ALWAYS_INLINE
225 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
226 MFEM_STATIC_ASSERT(ne == 1,
"only ne == 1 is supported");
228 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
231 T.
fes.SetElement(el);
233 nodes_dof.
layout, nodes_dof);
235 Jt.
layout.merge_34(), Jt);
238 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
239 inline MFEM_ALWAYS_INLINE
242 const int SS =
sizeof(nodeData[0])/
sizeof(nodeData[0][0]);
243 MFEM_ASSERT(el % (SS*ne) == 0,
"invalid element index: " << el);
244 T.
evaluator.CalcGrad(nodes_dof_t::layout.merge_23(),
245 &nodeData[el/SS*nodes_dof_t::size],
246 Jt.layout.merge_34(), Jt);
252 template <
typename it_t>
struct Result<3,it_t>
254 static const int ne = it_t::batch_size;
258 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
266 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
270 inline MFEM_ALWAYS_INLINE
273 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
274 MFEM_STATIC_ASSERT(ne == 1,
"only ne == 1 is supported");
276 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
279 T.
fes.SetElement(el);
281 nodes_dof.
layout, nodes_dof);
285 Jt.
layout.merge_34(), Jt);
288 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
289 inline MFEM_ALWAYS_INLINE
292 const int SS =
sizeof(nodeData[0])/
sizeof(nodeData[0][0]);
293 MFEM_ASSERT(el % (SS*ne) == 0,
"invalid element index: " << el);
294 T.
evaluator.Calc(nodes_dof_t::layout.merge_23(),
295 &nodeData[el/SS*nodes_dof_t::size],
296 x.layout.merge_23(), x);
297 T.
evaluator.CalcGrad(nodes_dof_t::layout.merge_23(),
298 &nodeData[el/SS*nodes_dof_t::size],
299 Jt.layout.merge_34(), Jt);
305 template <
typename it_t>
struct Result<6,it_t>
307 static const int ne = it_t::batch_size;
310 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
318 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
323 inline MFEM_ALWAYS_INLINE
326 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
327 MFEM_STATIC_ASSERT(ne == 1,
"only ne == 1 is supported");
329 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
332 T.
fes.SetElement(el);
334 nodes_dof.
layout, nodes_dof);
336 Jt.
layout.merge_34(), Jt);
340 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
341 inline MFEM_ALWAYS_INLINE
344 const int SS =
sizeof(nodeData[0])/
sizeof(nodeData[0][0]);
345 MFEM_ASSERT(el % (SS*ne) == 0,
"invalid element index: " << el);
346 T.
evaluator.CalcGrad(nodes_dof_t::layout.merge_23(),
347 &nodeData[el/SS*nodes_dof_t::size],
348 Jt.layout.merge_34(), Jt);
355 template <
typename it_t>
struct Result<10,it_t>
357 static const int ne = it_t::batch_size;
359 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
367 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
372 inline MFEM_ALWAYS_INLINE
375 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
376 MFEM_STATIC_ASSERT(ne == 1,
"only ne == 1 is supported");
378 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
381 T.
fes.SetElement(el);
383 nodes_dof.
layout, nodes_dof);
385 Jt.
layout.merge_34(), Jt);
389 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
390 inline MFEM_ALWAYS_INLINE
393 const int SS =
sizeof(nodeData[0])/
sizeof(nodeData[0][0]);
394 MFEM_ASSERT(el % (SS*ne) == 0,
"invalid element index: " << el);
395 T.
evaluator.CalcGrad(nodes_dof_t::layout.merge_23(),
396 &nodeData[el/SS*nodes_dof_t::size],
397 Jt.layout.merge_34(), Jt);
406 #endif // MFEM_TEMPLATE_ELEMENT_TRANSFORMATION
static const layout_type layout
int GetAttribute() const
Return element's attribute.
Abstract data type element.