OGS 6.2.1-97-g73d1aeda3
LocalDataInitializer.h
Go to the documentation of this file.
1 
10 #pragma once
11 
12 #include <functional>
13 #include <memory>
14 #include <typeindex>
15 #include <typeinfo>
16 #include <type_traits>
17 #include <unordered_map>
18 
22 
23 #ifndef OGS_MAX_ELEMENT_DIM
24 static_assert(false, "The macro OGS_MAX_ELEMENT_DIM is undefined.");
25 #endif
26 
27 #ifndef OGS_MAX_ELEMENT_ORDER
28 static_assert(false, "The macro OGS_MAX_ELEMENT_ORDER is undefined.");
29 #endif
30 
31 // The following macros decide which element types will be compiled, i.e.
32 // which element types will be available for use in simulations.
33 
34 #ifdef OGS_ENABLE_ELEMENT_SIMPLEX
35 #define ENABLED_ELEMENT_TYPE_SIMPLEX 1u
36 #else
37 #define ENABLED_ELEMENT_TYPE_SIMPLEX 0u
38 #endif
39 
40 #ifdef OGS_ENABLE_ELEMENT_CUBOID
41 #define ENABLED_ELEMENT_TYPE_CUBOID 1u << 1
42 #else
43 #define ENABLED_ELEMENT_TYPE_CUBOID 0u
44 #endif
45 
46 #ifdef OGS_ENABLE_ELEMENT_PRISM
47 #define ENABLED_ELEMENT_TYPE_PRISM 1u << 2
48 #else
49 #define ENABLED_ELEMENT_TYPE_PRISM 0u
50 #endif
51 
52 #ifdef OGS_ENABLE_ELEMENT_PYRAMID
53 #define ENABLED_ELEMENT_TYPE_PYRAMID 1u << 3
54 #else
55 #define ENABLED_ELEMENT_TYPE_PYRAMID 0u
56 #endif
57 
58 // Dependent element types.
59 // Faces of tets, pyramids and prisms are triangles
60 #define ENABLED_ELEMENT_TYPE_TRI \
61  ((ENABLED_ELEMENT_TYPE_SIMPLEX) | (ENABLED_ELEMENT_TYPE_PYRAMID) | \
62  (ENABLED_ELEMENT_TYPE_PRISM))
63 // Faces of hexes, pyramids and prisms are quads
64 #define ENABLED_ELEMENT_TYPE_QUAD \
65  ((ENABLED_ELEMENT_TYPE_CUBOID) | (ENABLED_ELEMENT_TYPE_PYRAMID) | \
66  (ENABLED_ELEMENT_TYPE_PRISM))
67 // Faces of triangles and quads are lines
68 #define ENABLED_ELEMENT_TYPE_LINE \
69  ((ENABLED_ELEMENT_TYPE_TRI) | (ENABLED_ELEMENT_TYPE_QUAD))
70 
71 // All enabled element types
72 #define OGS_ENABLED_ELEMENTS \
73  ((ENABLED_ELEMENT_TYPE_SIMPLEX) | (ENABLED_ELEMENT_TYPE_CUBOID) | \
74  (ENABLED_ELEMENT_TYPE_PYRAMID) | (ENABLED_ELEMENT_TYPE_PRISM))
75 
76 // Include only what is needed (Well, the conditions are not sharp).
77 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0
81 #endif
82 
83 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0
86 #endif
87 
88 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0
91 #endif
92 
93 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0
96 #endif
97 
98 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0
102 #endif
103 
104 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0
107 #endif
108 
109 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0
112 #endif
113 
114 namespace ProcessLib
115 {
121 template <typename LocalAssemblerInterface,
122  template <typename, typename, unsigned> class LocalAssemblerData,
123  unsigned GlobalDim, typename... ConstructorArgs>
124 class LocalDataInitializer final
125 {
126 public:
127  using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
128 
130  const unsigned shapefunction_order)
131  : _dof_table(dof_table)
132  {
133  if (shapefunction_order < 1 || 2 < shapefunction_order)
134  OGS_FATAL("The given shape function order %d is not supported",
135  shapefunction_order);
136 
137  if (shapefunction_order == 1)
138  {
139 // /// Lines and points ///////////////////////////////////
140 
141 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 && \
142  OGS_MAX_ELEMENT_DIM >= 0 && OGS_MAX_ELEMENT_ORDER >= 1
143  _builder[std::type_index(typeid(MeshLib::Point))] =
144  makeLocalAssemblerBuilder<NumLib::ShapePoint1>();
145 #endif
146 
147 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 && \
148  OGS_MAX_ELEMENT_DIM >= 1 && OGS_MAX_ELEMENT_ORDER >= 1
149  _builder[std::type_index(typeid(MeshLib::Line))] =
150  makeLocalAssemblerBuilder<NumLib::ShapeLine2>();
151 #endif
152 
153 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 && \
154  OGS_MAX_ELEMENT_DIM >= 1 && OGS_MAX_ELEMENT_ORDER >= 2
155  _builder[std::type_index(typeid(MeshLib::Line3))] =
156  makeLocalAssemblerBuilder<NumLib::ShapeLine2>();
157 #endif
158 
159 // /// Quads and Hexahedra ///////////////////////////////////
160 
161 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 && \
162  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1
163  _builder[std::type_index(typeid(MeshLib::Quad))] =
164  makeLocalAssemblerBuilder<NumLib::ShapeQuad4>();
165 #endif
166 
167 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 && \
168  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
169  _builder[std::type_index(typeid(MeshLib::Hex))] =
170  makeLocalAssemblerBuilder<NumLib::ShapeHex8>();
171 #endif
172 
173 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 && \
174  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2
175  _builder[std::type_index(typeid(MeshLib::Quad8))] =
176  makeLocalAssemblerBuilder<NumLib::ShapeQuad4>();
177  _builder[std::type_index(typeid(MeshLib::Quad9))] =
178  makeLocalAssemblerBuilder<NumLib::ShapeQuad4>();
179 #endif
180 
181 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 && \
182  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
183  _builder[std::type_index(typeid(MeshLib::Hex20))] =
184  makeLocalAssemblerBuilder<NumLib::ShapeHex8>();
185 #endif
186 
187 // /// Simplices ////////////////////////////////////////////////
188 
189 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 && \
190  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1
191  _builder[std::type_index(typeid(MeshLib::Tri))] =
192  makeLocalAssemblerBuilder<NumLib::ShapeTri3>();
193 #endif
194 
195 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
196  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
197  _builder[std::type_index(typeid(MeshLib::Tet))] =
198  makeLocalAssemblerBuilder<NumLib::ShapeTet4>();
199 #endif
200 
201 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 && \
202  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2
203  _builder[std::type_index(typeid(MeshLib::Tri6))] =
204  makeLocalAssemblerBuilder<NumLib::ShapeTri3>();
205 #endif
206 
207 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
208  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
209  _builder[std::type_index(typeid(MeshLib::Tet10))] =
210  makeLocalAssemblerBuilder<NumLib::ShapeTet4>();
211 #endif
212 
213 // /// Prisms ////////////////////////////////////////////////////
214 
215 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
216  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
217  _builder[std::type_index(typeid(MeshLib::Prism))] =
218  makeLocalAssemblerBuilder<NumLib::ShapePrism6>();
219 #endif
220 
221 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
222  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
223  _builder[std::type_index(typeid(MeshLib::Prism15))] =
224  makeLocalAssemblerBuilder<NumLib::ShapePrism6>();
225 #endif
226 
227 // /// Pyramids //////////////////////////////////////////////////
228 
229 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
230  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
231  _builder[std::type_index(typeid(MeshLib::Pyramid))] =
232  makeLocalAssemblerBuilder<NumLib::ShapePyra5>();
233 #endif
234 
235 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
236  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
237  _builder[std::type_index(typeid(MeshLib::Pyramid13))] =
238  makeLocalAssemblerBuilder<NumLib::ShapePyra5>();
239 #endif
240  }
241  else if (shapefunction_order == 2)
242  {
243 // /// Lines and points ///////////////////////////////////
244 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 && \
245  OGS_MAX_ELEMENT_DIM >= 0 && OGS_MAX_ELEMENT_ORDER >= 1
246  _builder[std::type_index(typeid(MeshLib::Point))] =
247  makeLocalAssemblerBuilder<NumLib::ShapePoint1>();
248 #endif
249 
250 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_LINE) != 0 && \
251  OGS_MAX_ELEMENT_DIM >= 1 && OGS_MAX_ELEMENT_ORDER >= 2
252  _builder[std::type_index(typeid(MeshLib::Line3))] =
253  makeLocalAssemblerBuilder<NumLib::ShapeLine3>();
254 #endif
255 
256 // /// Quads and Hexahedra ///////////////////////////////////
257 
258 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 && \
259  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2
260  _builder[std::type_index(typeid(MeshLib::Quad8))] =
261  makeLocalAssemblerBuilder<NumLib::ShapeQuad8>();
262  _builder[std::type_index(typeid(MeshLib::Quad9))] =
263  makeLocalAssemblerBuilder<NumLib::ShapeQuad9>();
264 #endif
265 
266 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 && \
267  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
268  _builder[std::type_index(typeid(MeshLib::Hex20))] =
269  makeLocalAssemblerBuilder<NumLib::ShapeHex20>();
270 #endif
271 
272 // /// Simplices ////////////////////////////////////////////////
273 
274 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 && \
275  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2
276  _builder[std::type_index(typeid(MeshLib::Tri6))] =
277  makeLocalAssemblerBuilder<NumLib::ShapeTri6>();
278 #endif
279 
280 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
281  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
282  _builder[std::type_index(typeid(MeshLib::Tet10))] =
283  makeLocalAssemblerBuilder<NumLib::ShapeTet10>();
284 #endif
285 
286 // /// Prisms ////////////////////////////////////////////////////
287 
288 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
289  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
290  _builder[std::type_index(typeid(MeshLib::Prism15))] =
291  makeLocalAssemblerBuilder<NumLib::ShapePrism15>();
292 #endif
293 
294 // /// Pyramids //////////////////////////////////////////////////
295 
296 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
297  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
298  _builder[std::type_index(typeid(MeshLib::Pyramid13))] =
299  makeLocalAssemblerBuilder<NumLib::ShapePyra13>();
300 #endif
301  }
302  }
303 
309  void operator()(std::size_t const id,
310  MeshLib::Element const& mesh_item,
311  LADataIntfPtr& data_ptr,
312  ConstructorArgs&&... args) const
313  {
314  auto const type_idx = std::type_index(typeid(mesh_item));
315  auto const it = _builder.find(type_idx);
316 
317  if (it != _builder.end())
318  {
319  auto const num_local_dof = _dof_table.getNumberOfElementDOF(id);
320  data_ptr = it->second(mesh_item, num_local_dof,
321  std::forward<ConstructorArgs>(args)...);
322  }
323  else
324  {
325  OGS_FATAL(
326  "You are trying to build a local assembler for an unknown mesh "
327  "element type (%s)."
328  " Maybe you have disabled this mesh element type in your build "
329  "configuration.",
330  type_idx.name());
331  }
332  }
333 
334 private:
335  using LADataBuilder =
336  std::function<LADataIntfPtr(MeshLib::Element const& e,
337  std::size_t const local_matrix_size,
338  ConstructorArgs&&...)>;
339 
340  template <typename ShapeFunction>
342  typename ShapeFunction::MeshElement>::IntegrationMethod;
343 
344  template <typename ShapeFunction>
345  using LAData =
346  LocalAssemblerData<ShapeFunction, IntegrationMethod<ShapeFunction>,
347  GlobalDim>;
348 
352  template <typename ShapeFunction>
354  {
355  return makeLocalAssemblerBuilder<ShapeFunction>(
356  static_cast<std::integral_constant<
357  bool, (GlobalDim >= ShapeFunction::DIM)>*>(nullptr));
358  }
359 
360 
362  std::unordered_map<std::type_index, LADataBuilder> _builder;
363 
365 
366  // local assembler builder implementations.
367 private:
373  template <typename ShapeFunction>
374  static LADataBuilder makeLocalAssemblerBuilder(std::true_type* /*unused*/)
375  {
376  return [](MeshLib::Element const& e,
377  std::size_t const local_matrix_size,
378  ConstructorArgs&&... args) {
380  e, local_matrix_size, std::forward<ConstructorArgs>(args)...}};
381  };
382  }
383 
386  template <typename ShapeFunction>
387  static LADataBuilder makeLocalAssemblerBuilder(std::false_type* /*unused*/)
388  {
389  return nullptr;
390  }
391 };
392 
393 } // namespace ProcessLib
394 
395 #undef ENABLED_ELEMENT_TYPE_SIMPLEX
396 #undef ENABLED_ELEMENT_TYPE_CUBOID
397 #undef ENABLED_ELEMENT_TYPE_PYRAMID
398 #undef ENABLED_ELEMENT_TYPE_PRISM
399 #undef ENABLED_ELEMENT_TYPE_LINE
400 #undef ENABLED_ELEMENT_TYPE_TRI
401 #undef ENABLED_ELEMENT_TYPE_QUAD
402 #undef OGS_ENABLED_ELEMENTS
std::function< LADataIntfPtr(MeshLib::Element const &e, std::size_t const local_matrix_size, ConstructorArgs &&...)> LADataBuilder
static LADataBuilder makeLocalAssemblerBuilder(std::true_type *)
LocalDataInitializer(NumLib::LocalToGlobalIndexMap const &dof_table, const unsigned shapefunction_order)
std::size_t getNumberOfElementDOF(std::size_t const mesh_item_id) const
std::unordered_map< std::type_index, LADataBuilder > _builder
Mapping of element types to local assembler constructors.
SmallDeformationLocalAssembler< ShapeFunction, IntegrationMethod< ShapeFunction >, GlobalDim > LAData
NumLib::LocalToGlobalIndexMap const & _dof_table
void operator()(std::size_t const id, MeshLib::Element const &mesh_item, LADataIntfPtr &data_ptr, ConstructorArgs &&... args) const
typename NumLib::GaussLegendreIntegrationPolicy< typename ShapeFunction::MeshElement >::IntegrationMethod IntegrationMethod
static LADataBuilder makeLocalAssemblerBuilder(std::false_type *)
static LADataBuilder makeLocalAssemblerBuilder()
#define OGS_FATAL(fmt,...)
Definition: Error.h:63
std::unique_ptr< LocalAssemblerInterface > LADataIntfPtr