OGS 6.2.0-97-g4a610c866
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 
68 // All enabled element types
69 #define OGS_ENABLED_ELEMENTS \
70  ((ENABLED_ELEMENT_TYPE_SIMPLEX) | (ENABLED_ELEMENT_TYPE_CUBOID) | \
71  (ENABLED_ELEMENT_TYPE_PYRAMID) | (ENABLED_ELEMENT_TYPE_PRISM))
72 
73 // Include only what is needed (Well, the conditions are not sharp).
74 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0
77 #endif
78 
79 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0
82 #endif
83 
84 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0
87 #endif
88 
89 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0
93 #endif
94 
95 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0
98 #endif
99 
100 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0
103 #endif
104 
105 namespace ProcessLib
106 {
112 template <typename LocalAssemblerInterface,
113  template <typename, typename, int>
114  class SmallDeformationLocalAssembler,
115  int GlobalDim, typename... ConstructorArgs>
117 {
118 public:
119  using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
120 
122  NumLib::LocalToGlobalIndexMap const& dof_table)
123  : _dof_table(dof_table)
124  {
125 // /// Quads and Hexahedra ///////////////////////////////////
126 
127 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 && \
128  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1
129  _builder[std::type_index(typeid(MeshLib::Quad))] =
130  makeLocalAssemblerBuilder<NumLib::ShapeQuad4>();
131 #endif
132 
133 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 && \
134  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
135  _builder[std::type_index(typeid(MeshLib::Hex))] =
136  makeLocalAssemblerBuilder<NumLib::ShapeHex8>();
137 #endif
138 
139 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0 && \
140  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2
141  _builder[std::type_index(typeid(MeshLib::Quad8))] =
142  makeLocalAssemblerBuilder<NumLib::ShapeQuad8>();
143  _builder[std::type_index(typeid(MeshLib::Quad9))] =
144  makeLocalAssemblerBuilder<NumLib::ShapeQuad9>();
145 #endif
146 
147 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 && \
148  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
149  _builder[std::type_index(typeid(MeshLib::Hex20))] =
150  makeLocalAssemblerBuilder<NumLib::ShapeHex20>();
151 #endif
152 
153 // /// Simplices ////////////////////////////////////////////////
154 
155 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 && \
156  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1
157  _builder[std::type_index(typeid(MeshLib::Tri))] =
158  makeLocalAssemblerBuilder<NumLib::ShapeTri3>();
159 #endif
160 
161 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
162  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
163  _builder[std::type_index(typeid(MeshLib::Tet))] =
164  makeLocalAssemblerBuilder<NumLib::ShapeTet4>();
165 #endif
166 
167 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0 && \
168  OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 2
169  _builder[std::type_index(typeid(MeshLib::Tri6))] =
170  makeLocalAssemblerBuilder<NumLib::ShapeTri6>();
171 #endif
172 
173 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
174  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
175  _builder[std::type_index(typeid(MeshLib::Tet10))] =
176  makeLocalAssemblerBuilder<NumLib::ShapeTet10>();
177 #endif
178 
179 // /// Prisms ////////////////////////////////////////////////////
180 
181 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
182  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
183  _builder[std::type_index(typeid(MeshLib::Prism))] =
184  makeLocalAssemblerBuilder<NumLib::ShapePrism6>();
185 #endif
186 
187 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
188  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
189  _builder[std::type_index(typeid(MeshLib::Prism15))] =
190  makeLocalAssemblerBuilder<NumLib::ShapePrism15>();
191 #endif
192 
193 // /// Pyramids //////////////////////////////////////////////////
194 
195 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
196  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
197  _builder[std::type_index(typeid(MeshLib::Pyramid))] =
198  makeLocalAssemblerBuilder<NumLib::ShapePyra5>();
199 #endif
200 
201 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
202  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
203  _builder[std::type_index(typeid(MeshLib::Pyramid13))] =
204  makeLocalAssemblerBuilder<NumLib::ShapePyra13>();
205 #endif
206  }
207 
213  void operator()(std::size_t const id,
214  MeshLib::Element const& mesh_item,
215  LADataIntfPtr& data_ptr,
216  ConstructorArgs&&... args) const
217  {
218  auto const type_idx = std::type_index(typeid(mesh_item));
219  auto const it = _builder.find(type_idx);
220 
221  if (it != _builder.end())
222  {
223  auto const num_local_dof = _dof_table.getNumberOfElementDOF(id);
224  data_ptr = it->second(mesh_item, num_local_dof,
225  std::forward<ConstructorArgs>(args)...);
226  }
227  else
228  {
229  OGS_FATAL(
230  "You are trying to build a local assembler for an unknown mesh "
231  "element type (%s)."
232  " Maybe you have disabled this mesh element type in your build "
233  "configuration or this process requires higher order elements.",
234  type_idx.name());
235  }
236  }
237 
238 private:
239  using LADataBuilder =
240  std::function<LADataIntfPtr(MeshLib::Element const& e,
241  std::size_t const local_matrix_size,
242  ConstructorArgs&&...)>;
243 
244  template <typename ShapeFunction>
246  typename ShapeFunction::MeshElement>::IntegrationMethod;
247 
248  template <typename ShapeFunction>
249  using LAData = SmallDeformationLocalAssembler<
250  ShapeFunction, IntegrationMethod<ShapeFunction>, GlobalDim>;
251 
255  template <typename ShapeFunction>
257  {
258  return makeLocalAssemblerBuilder<ShapeFunction>(
259  static_cast<std::integral_constant<
260  bool, (GlobalDim >= ShapeFunction::DIM)>*>(nullptr));
261  }
262 
263 
265  std::unordered_map<std::type_index, LADataBuilder> _builder;
266 
268 
269  // local assembler builder implementations.
270 private:
276  template <typename ShapeFunction>
277  static LADataBuilder makeLocalAssemblerBuilder(std::true_type*)
278  {
279  return [](MeshLib::Element const& e,
280  std::size_t const local_matrix_size,
281  ConstructorArgs&&... args) {
283  e, local_matrix_size, std::forward<ConstructorArgs>(args)...}};
284  };
285  }
286 
289  template <typename ShapeFunction>
290  static LADataBuilder makeLocalAssemblerBuilder(std::false_type*)
291  {
292  return nullptr;
293  }
294 };
295 
296 } // namespace ProcessLib
297 
298 #undef ENABLED_ELEMENT_TYPE_SIMPLEX
299 #undef ENABLED_ELEMENT_TYPE_CUBOID
300 #undef ENABLED_ELEMENT_TYPE_PYRAMID
301 #undef ENABLED_ELEMENT_TYPE_PRISM
302 #undef ENABLED_ELEMENT_TYPE_TRI
303 #undef ENABLED_ELEMENT_TYPE_QUAD
304 #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)
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