MFEM  v3.4
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
teltrans.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #ifndef MFEM_TEMPLATE_ELEMENT_TRANSFORMATION
13 #define MFEM_TEMPLATE_ELEMENT_TRANSFORMATION
14 
15 #include "../config/tconfig.hpp"
16 #include "tevaluator.hpp"
17 #include "../mesh/element.hpp"
18 
19 namespace mfem
20 {
21 
22 // Templated element transformation classes, cf. eltrans.?pp
23 
24 // Element transformation class, templated on a mesh type and an integration
25 // rule. It is constructed from a mesh (e.g. class TMesh) and shape evaluator
26 // (e.g. class ShapeEvaluator) objects. Allows computation of physical
27 // coordinates and Jacobian matrices corresponding to the reference integration
28 // points. The desired result is specified through the template subclass Result
29 // and stored in an object of the same type.
30 template <typename Mesh_t, typename IR, typename real_t = double>
32 {
33 public:
34  typedef real_t real_type;
35  typedef typename Mesh_t::FE_type FE_type;
36  typedef typename Mesh_t::FESpace_type FESpace_type;
37  typedef typename Mesh_t::nodeLayout_type nodeLayout_type;
39 
41 
42  // Enumeration for the result type of the TElementTransformation::Eval()
43  // method. The types can obtained by summing constants from this enumeration
44  // and used as a template parameter in struct Result.
46  {
47  EvalNone = 0,
52  };
53 
54  template <typename coeff_t, typename kernel_t> struct Get
55  {
56  static const int EvalOps =
57  (EvalCoordinates * coeff_t::uses_coordinates +
58  EvalJacobians * coeff_t::uses_Jacobians +
59  LoadAttributes * coeff_t::uses_attributes +
60  LoadElementIdxs * coeff_t::uses_element_idxs) |
61  (EvalJacobians * kernel_t::uses_Jacobians);
62  };
63 
64  // Templated struct Result, used to specify the type result that is computed
65  // by the TElementTransformation::Eval() method and stored in this structure.
66  // The template parameter EvalOps is a sum (bitwise or) of constants from
67  // the enum EvalOperations. The parameter NE is the number of elements to be
68  // processed in the Eval() method.
69  template<int EvalOps, int NE> struct Result;
70 
71  static const int dim = Mesh_t::dim;
72  static const int sdim = Mesh_t::space_dim;
73  static const int dofs = FE_type::dofs;
74  static const int qpts = IR::qpts;
75 
76 protected:
77 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
79 #endif
80 
84  const real_t *nodes;
85 
86  const Element* const *elements;
87 
88  template <int NE>
89  inline MFEM_ALWAYS_INLINE
90  void SetAttributes(int el, int (&attrib)[NE]) const
91  {
92  for (int i = 0; i < NE; i++)
93  {
94  attrib[i] = elements[el+i]->GetAttribute();
95  }
96  }
97 
98 public:
99  // Constructor.
100  TElementTransformation(const Mesh_t &mesh, const ShapeEval &eval)
101  : evaluator(eval),
102  fes(mesh.t_fes),
103  node_layout(mesh.node_layout),
104  nodes(mesh.Nodes.GetData()), // real_t = double
105  elements(mesh.m_mesh.GetElementsArray())
106  { }
107 
108  // Evaluate coordinates and/or Jacobian matrices at quadrature points.
109  template<int EvalOps, int NE>
110  inline MFEM_ALWAYS_INLINE
111  void Eval(int el, Result<EvalOps,NE> &F)
112  {
113  F.Eval(el, *this);
114  }
115 
116 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
117  template<int EvalOps, int NE>
118  inline MFEM_ALWAYS_INLINE
119  void EvalSerialized(int el, const real_t *nodeData, Result<EvalOps,NE> &F)
120  {
121  F.EvalSerialized(el, *this, nodeData);
122  }
123 #endif
124 
125  template <int NE> struct Result<0,NE> // 0 = EvalNone
126  {
127  static const int ne = NE;
128  // x_type x;
129  // Jt_type Jt;
130  // int attrib[NE];
131  // int first_elem_idx;
132  inline MFEM_ALWAYS_INLINE
133  void Eval(int el, T_type &T)
134  {
135  // T.SetAttributes(el, attrib);
136  // first_elem_idx = el;
137  }
138 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
139  inline MFEM_ALWAYS_INLINE
140  void EvalSerialized(int el, T_type &T, const real_t *nodeData) { }
141 #endif
142  };
143  template <int NE> struct Result<1,NE> // 1 = EvalCoordinates
144  {
145  static const int ne = NE;
146 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
148 #else
149  typedef TTensor3<qpts,sdim,NE,real_t/*,true*/> x_type;
150 #endif
152 
154 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
156 #endif
157 
158  inline MFEM_ALWAYS_INLINE
159  void Eval(int el, T_type &T)
160  {
161 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
162  MFEM_STATIC_ASSERT(NE == 1, "only NE == 1 is supported");
164 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
166 #endif
167  T.fes.SetElement(el);
168  T.fes.VectorExtract(T.node_layout, T.nodes,
169  nodes_dof.layout, nodes_dof);
170  T.evaluator.Calc(nodes_dof.layout.merge_23(), nodes_dof,
171  x.layout.merge_23(), x);
172  }
173 
174 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
175  inline MFEM_ALWAYS_INLINE
176  void EvalSerialized(int el, T_type &T, const real_t *nodeData)
177  {
178  T.evaluator.Calc(nodes_dof_t::layout.merge_23(),
179  &nodeData[el*nodes_dof_t::size],
180  x.layout.merge_23(), x);
181  }
182 #endif
183  };
184  template <int NE> struct Result<2,NE> // 2 = EvalJacobians
185  {
186  static const int ne = NE;
187 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
189 #else
190  typedef TTensor4<qpts,dim,sdim,NE,real_t/*,true*/> Jt_type;
191 #endif
193 
195 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
197 #endif
198 
199  inline MFEM_ALWAYS_INLINE
200  void Eval(int el, T_type &T)
201  {
202 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
203  MFEM_STATIC_ASSERT(NE == 1, "only NE == 1 is supported");
205 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
207 #endif
208  T.fes.SetElement(el);
209  T.fes.VectorExtract(T.node_layout, T.nodes,
210  nodes_dof.layout, nodes_dof);
211  T.evaluator.CalcGrad(nodes_dof.layout.merge_23(), nodes_dof,
212  Jt.layout.merge_34(), Jt);
213  }
214 
215 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
216  inline MFEM_ALWAYS_INLINE
217  void EvalSerialized(int el, T_type &T, const real_t *nodeData)
218  {
219  T.evaluator.CalcGrad(nodes_dof_t::layout.merge_23(),
220  &nodeData[el*nodes_dof_t::size],
221  Jt.layout.merge_34(), Jt);
222  }
223 #endif
224  };
225  template <int NE> struct Result<3,NE> // 3 = EvalCoordinates|EvalJacobians
226  {
227  static const int ne = NE;
230 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
232 #else
233  typedef TTensor4<qpts,dim,sdim,NE,real_t/*,true*/> Jt_type;
234 #endif
236 
238 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
240 #endif
241 
242  inline MFEM_ALWAYS_INLINE
243  void Eval(int el, T_type &T)
244  {
245 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
246  MFEM_STATIC_ASSERT(NE == 1, "only NE == 1 is supported");
248 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
250 #endif
251  T.fes.SetElement(el);
252  T.fes.VectorExtract(T.node_layout, T.nodes,
253  nodes_dof.layout, nodes_dof);
254  T.evaluator.Calc(nodes_dof.layout.merge_23(), nodes_dof,
255  x.layout.merge_23(), x);
256  T.evaluator.CalcGrad(nodes_dof.layout.merge_23(), nodes_dof,
257  Jt.layout.merge_34(), Jt);
258  }
259 
260 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
261  inline MFEM_ALWAYS_INLINE
262  void EvalSerialized(int el, T_type &T, const real_t *nodeData)
263  {
264  T.evaluator.Calc(nodes_dof_t::layout.merge_23(),
265  &nodeData[el*nodes_dof_t::size],
266  x.layout.merge_23(), x);
267  T.evaluator.CalcGrad(nodes_dof_t::layout.merge_23(),
268  &nodeData[el*nodes_dof_t::size],
269  Jt.layout.merge_34(), Jt);
270  }
271 #endif
272  };
273  template <int NE> struct Result<6,NE> // 6 = EvalJacobians|LoadAttributes
274  {
275  static const int ne = NE;
276 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
278 #else
279  typedef TTensor4<qpts,dim,sdim,NE,real_t/*,true*/> Jt_type;
280 #endif
282 
284 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
286 #endif
287  int attrib[NE];
288 
289  inline MFEM_ALWAYS_INLINE
290  void Eval(int el, T_type &T)
291  {
292 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
293  MFEM_STATIC_ASSERT(NE == 1, "only NE == 1 is supported");
295 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
297 #endif
298  T.fes.SetElement(el);
299  T.fes.VectorExtract(T.node_layout, T.nodes,
300  nodes_dof.layout, nodes_dof);
301  T.evaluator.CalcGrad(nodes_dof.layout.merge_23(), nodes_dof,
302  Jt.layout.merge_34(), Jt);
303  T.SetAttributes(el, attrib);
304  }
305 
306 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
307  inline MFEM_ALWAYS_INLINE
308  void EvalSerialized(int el, T_type &T, const real_t *nodeData)
309  {
310  T.evaluator.CalcGrad(nodes_dof_t::layout.merge_23(),
311  &nodeData[el*nodes_dof_t::size],
312  Jt.layout.merge_34(), Jt);
313  T.SetAttributes(el, attrib);
314  }
315 #endif
316  };
317  template <int NE> struct Result<10,NE> // 10 = EvalJacobians|LoadElementIdxs
318  {
319  static const int ne = NE;
320 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
322 #else
323  typedef TTensor4<qpts,dim,sdim,NE,real_t/*,true*/> Jt_type;
324 #endif
326 
328 #ifdef MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES
330 #endif
332 
333  inline MFEM_ALWAYS_INLINE
334  void Eval(int el, T_type &T)
335  {
336 #ifdef MFEM_TEMPLATE_ELTRANS_HAS_NODE_DOFS
337  MFEM_STATIC_ASSERT(NE == 1, "only NE == 1 is supported");
339 #elif !defined(MFEM_TEMPLATE_ELTRANS_RESULT_HAS_NODES)
341 #endif
342  T.fes.SetElement(el);
343  T.fes.VectorExtract(T.node_layout, T.nodes,
344  nodes_dof.layout, nodes_dof);
345  T.evaluator.CalcGrad(nodes_dof.layout.merge_23(), nodes_dof,
346  Jt.layout.merge_34(), Jt);
347  first_elem_idx = el;
348  }
349 
350 #ifdef MFEM_TEMPLATE_ENABLE_SERIALIZE
351  inline MFEM_ALWAYS_INLINE
352  void EvalSerialized(int el, T_type &T, const real_t *nodeData)
353  {
354  T.evaluator.CalcGrad(nodes_dof_t::layout.merge_23(),
355  &nodeData[el*nodes_dof_t::size],
356  Jt.layout.merge_34(), Jt);
357  first_elem_idx = el;
358  }
359 #endif
360  };
361 };
362 
363 } // namespace mfem
364 
365 #endif // MFEM_TEMPLATE_ELEMENT_TRANSFORMATION
MFEM_ALWAYS_INLINE void EvalSerialized(int el, T_type &T, const real_t *nodeData)
Definition: teltrans.hpp:140
Mesh_t::nodeLayout_type nodeLayout_type
Definition: teltrans.hpp:37
TTensor3< dofs, sdim, NE, real_t > nodes_dof_t
Definition: teltrans.hpp:283
TTensor4< qpts, dim, sdim, NE, real_t, true > Jt_type
Definition: teltrans.hpp:321
MFEM_ALWAYS_INLINE void EvalSerialized(int el, const real_t *nodeData, Result< EvalOps, NE > &F)
Definition: teltrans.hpp:119
TTensor3< qpts, sdim, NE, real_t, true > x_type
Definition: teltrans.hpp:147
MFEM_ALWAYS_INLINE void Eval(int el, T_type &T)
Definition: teltrans.hpp:334
MFEM_ALWAYS_INLINE void SetAttributes(int el, int(&attrib)[NE]) const
Definition: teltrans.hpp:90
TTensor4< qpts, dim, sdim, NE, real_t > Jt_type
Definition: teltrans.hpp:190
MFEM_ALWAYS_INLINE void EvalSerialized(int el, T_type &T, const real_t *nodeData)
Definition: teltrans.hpp:352
MFEM_ALWAYS_INLINE void Eval(int el, T_type &T)
Definition: teltrans.hpp:159
MFEM_ALWAYS_INLINE void Eval(int el, T_type &T)
Definition: teltrans.hpp:200
static const int dofs
Definition: teltrans.hpp:73
TTensor4< qpts, dim, sdim, NE, real_t, true > Jt_type
Definition: teltrans.hpp:277
static const layout_type layout
Definition: ttensor.hpp:347
TTensor4< qpts, dim, sdim, NE, real_t, true > Jt_type
Definition: teltrans.hpp:231
TTensor3< dofs, sdim, NE, real_t > nodes_dof_t
Definition: teltrans.hpp:327
MFEM_ALWAYS_INLINE void Eval(int el, T_type &T)
Definition: teltrans.hpp:290
TElementTransformation(const Mesh_t &mesh, const ShapeEval &eval)
Definition: teltrans.hpp:100
MFEM_ALWAYS_INLINE void EvalSerialized(int el, T_type &T, const real_t *nodeData)
Definition: teltrans.hpp:176
TTensor3< qpts, sdim, NE, real_t, true > x_type
Definition: teltrans.hpp:228
static const int qpts
Definition: teltrans.hpp:74
int dim
Definition: ex3.cpp:47
MFEM_ALWAYS_INLINE void EvalSerialized(int el, T_type &T, const real_t *nodeData)
Definition: teltrans.hpp:308
TTensor3< dofs, sdim, NE, real_t > nodes_dof_t
Definition: teltrans.hpp:153
TTensor3< dofs, sdim, 1, real_t > nodes_dof
Definition: teltrans.hpp:78
int GetAttribute() const
Return element&#39;s attribute.
Definition: element.hpp:50
ShapeEvaluator< FE_type, IR, real_t > ShapeEval
Definition: teltrans.hpp:38
TTensor3< dofs, sdim, NE, real_t > nodes_dof_t
Definition: teltrans.hpp:194
MFEM_ALWAYS_INLINE void Eval(int el, T_type &T)
Definition: teltrans.hpp:133
TTensor3< qpts, sdim, NE, real_t > x_type
Definition: teltrans.hpp:149
TTensor4< qpts, dim, sdim, NE, real_t > Jt_type
Definition: teltrans.hpp:279
MFEM_ALWAYS_INLINE void Eval(int el, Result< EvalOps, NE > &F)
Definition: teltrans.hpp:111
const Element *const * elements
Definition: teltrans.hpp:86
static const int dim
Definition: teltrans.hpp:71
TTensor4< qpts, dim, sdim, NE, real_t > Jt_type
Definition: teltrans.hpp:233
TTensor4< qpts, dim, sdim, NE, real_t, true > Jt_type
Definition: teltrans.hpp:188
nodeLayout_type node_layout
Definition: teltrans.hpp:83
TTensor3< dofs, sdim, NE, real_t > nodes_dof_t
Definition: teltrans.hpp:237
TElementTransformation< Mesh_t, IR, real_t > T_type
Definition: teltrans.hpp:40
MFEM_ALWAYS_INLINE void EvalSerialized(int el, T_type &T, const real_t *nodeData)
Definition: teltrans.hpp:217
MFEM_ALWAYS_INLINE void Eval(int el, T_type &T)
Definition: teltrans.hpp:243
Abstract data type element.
Definition: element.hpp:27
Mesh_t::FE_type FE_type
Definition: teltrans.hpp:35
MFEM_ALWAYS_INLINE void EvalSerialized(int el, T_type &T, const real_t *nodeData)
Definition: teltrans.hpp:262
TTensor4< qpts, dim, sdim, NE, real_t > Jt_type
Definition: teltrans.hpp:323
static const int sdim
Definition: teltrans.hpp:72
Mesh_t::FESpace_type FESpace_type
Definition: teltrans.hpp:36