OGS 6.1.0-1721-g6382411ad
LocalDataInitializer.h
Go to the documentation of this file.
1 
10 #pragma once
11 
12 #include <functional>
13 #include <memory>
14 #include <type_traits>
15 #include <typeindex>
16 #include <typeinfo>
17 #include <unordered_map>
18 
23 
24 #ifndef OGS_MAX_ELEMENT_DIM
25 static_assert(false, "The macro OGS_MAX_ELEMENT_DIM is undefined.");
26 #endif
27 
28 #ifndef OGS_MAX_ELEMENT_ORDER
29 static_assert(false, "The macro OGS_MAX_ELEMENT_ORDER is undefined.");
30 #endif
31 
32 // The following macros decide which element types will be compiled, i.e.
33 // which element types will be available for use in simulations.
34 
35 #ifdef OGS_ENABLE_ELEMENT_SIMPLEX
36 #define ENABLED_ELEMENT_TYPE_SIMPLEX 1u
37 #else
38 #define ENABLED_ELEMENT_TYPE_SIMPLEX 0u
39 #endif
40 
41 #ifdef OGS_ENABLE_ELEMENT_CUBOID
42 #define ENABLED_ELEMENT_TYPE_CUBOID 1u << 1
43 #else
44 #define ENABLED_ELEMENT_TYPE_CUBOID 0u
45 #endif
46 
47 #ifdef OGS_ENABLE_ELEMENT_PRISM
48 #define ENABLED_ELEMENT_TYPE_PRISM 1u << 2
49 #else
50 #define ENABLED_ELEMENT_TYPE_PRISM 0u
51 #endif
52 
53 #ifdef OGS_ENABLE_ELEMENT_PYRAMID
54 #define ENABLED_ELEMENT_TYPE_PYRAMID 1u << 3
55 #else
56 #define ENABLED_ELEMENT_TYPE_PYRAMID 0u
57 #endif
58 
59 // Dependent element types.
60 // Faces of tets, pyramids and prisms are triangles
61 #define ENABLED_ELEMENT_TYPE_TRI \
62  ((ENABLED_ELEMENT_TYPE_SIMPLEX) | (ENABLED_ELEMENT_TYPE_PYRAMID) | \
63  (ENABLED_ELEMENT_TYPE_PRISM))
64 // Faces of hexes, pyramids and prisms are quads
65 #define ENABLED_ELEMENT_TYPE_QUAD \
66  ((ENABLED_ELEMENT_TYPE_CUBOID) | (ENABLED_ELEMENT_TYPE_PYRAMID) | \
67  (ENABLED_ELEMENT_TYPE_PRISM))
68 
69 // All enabled element types
70 #define OGS_ENABLED_ELEMENTS \
71  ((ENABLED_ELEMENT_TYPE_SIMPLEX) | (ENABLED_ELEMENT_TYPE_CUBOID) | \
72  (ENABLED_ELEMENT_TYPE_PYRAMID) | (ENABLED_ELEMENT_TYPE_PRISM))
73 
74 // Include only what is needed (Well, the conditions are not sharp).
75 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0
78 #endif
79 
80 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_TRI) != 0
83 #endif
84 
85 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0
88 #endif
89 
90 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_QUAD) != 0
94 #endif
95 
96 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0
99 #endif
100 
101 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0
104 #endif
105 
106 namespace ProcessLib
107 {
108 namespace HydroMechanics
109 {
119 template <typename LocalAssemblerInterface,
120  template <typename, typename, typename, int>
121  class HydroMechanicsLocalAssembler,
122  int GlobalDim, typename... ConstructorArgs>
124 {
125 public:
126  using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
127 
129  const unsigned shapefunction_order)
130  : _dof_table(dof_table)
131  {
132  if (shapefunction_order != 2)
133  OGS_FATAL(
134  "The given shape function order %d is not supported.\nOnly "
135  "shape functions of order 2 are supported.",
136  shapefunction_order);
137 // /// Quads and Hexahedra ///////////////////////////////////
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 >= 2
157  _builder[std::type_index(typeid(MeshLib::Tri6))] =
158  makeLocalAssemblerBuilder<NumLib::ShapeTri6>();
159 #endif
160 
161 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
162  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
163  _builder[std::type_index(typeid(MeshLib::Tet10))] =
164  makeLocalAssemblerBuilder<NumLib::ShapeTet10>();
165 #endif
166 
167 // /// Prisms ////////////////////////////////////////////////////
168 
169 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
170  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
171  _builder[std::type_index(typeid(MeshLib::Prism15))] =
172  makeLocalAssemblerBuilder<NumLib::ShapePrism15>();
173 #endif
174 
175 // /// Pyramids //////////////////////////////////////////////////
176 
177 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
178  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
179  _builder[std::type_index(typeid(MeshLib::Pyramid13))] =
180  makeLocalAssemblerBuilder<NumLib::ShapePyra13>();
181 #endif
182  }
183 
189  void operator()(std::size_t const id,
190  MeshLib::Element const& mesh_item,
191  LADataIntfPtr& data_ptr,
192  ConstructorArgs&&... args) const
193  {
194  auto const type_idx = std::type_index(typeid(mesh_item));
195  auto const it = _builder.find(type_idx);
196 
197  if (it != _builder.end())
198  {
199  auto const num_local_dof = _dof_table.getNumberOfElementDOF(id);
200  data_ptr = it->second(mesh_item, num_local_dof,
201  std::forward<ConstructorArgs>(args)...);
202  }
203  else
204  {
205  OGS_FATAL(
206  "You are trying to build a local assembler for an unknown mesh "
207  "element type (%s)."
208  " Maybe you have disabled this mesh element type in your build "
209  "configuration or this process requires higher order elements.",
210  type_idx.name());
211  }
212  }
213 
214 private:
215  using LADataBuilder =
216  std::function<LADataIntfPtr(MeshLib::Element const& e,
217  std::size_t const local_matrix_size,
218  ConstructorArgs&&...)>;
219 
220  template <typename ShapeFunctionDisplacement>
222  typename ShapeFunctionDisplacement::MeshElement>::IntegrationMethod;
223 
224  template <typename ShapeFunctionDisplacement,
225  typename ShapeFunctionPressure>
226  using LAData = HydroMechanicsLocalAssembler<
227  ShapeFunctionDisplacement, ShapeFunctionPressure,
229 
233  template <typename ShapeFunctionDisplacement>
235  {
236  return makeLocalAssemblerBuilder<ShapeFunctionDisplacement>(
237  static_cast<std::integral_constant<
238  bool, (GlobalDim >= ShapeFunctionDisplacement::DIM)>*>(
239  nullptr));
240  }
241 
243  std::unordered_map<std::type_index, LADataBuilder> _builder;
244 
246 
247  // local assembler builder implementations.
248 private:
255  template <typename ShapeFunctionDisplacement>
256  static LADataBuilder makeLocalAssemblerBuilder(std::true_type*)
257  {
258  // (Lower order elements = Order(ShapeFunctionDisplacement) - 1).
259  using ShapeFunctionPressure =
261  return [](MeshLib::Element const& e,
262  std::size_t const local_matrix_size,
263  ConstructorArgs&&... args) {
264  return LADataIntfPtr{
266  e, local_matrix_size,
267  std::forward<ConstructorArgs>(args)...}};
268  };
269  }
270 
273  template <typename ShapeFunctionDisplacement>
274  static LADataBuilder makeLocalAssemblerBuilder(std::false_type*)
275  {
276  return nullptr;
277  }
278 };
279 
280 } // namespace HydroMechanics
281 } // namespace ProcessLib
282 
283 #undef ENABLED_ELEMENT_TYPE_SIMPLEX
284 #undef ENABLED_ELEMENT_TYPE_CUBOID
285 #undef ENABLED_ELEMENT_TYPE_PYRAMID
286 #undef ENABLED_ELEMENT_TYPE_PRISM
287 #undef ENABLED_ELEMENT_TYPE_TRI
288 #undef ENABLED_ELEMENT_TYPE_QUAD
289 #undef OGS_ENABLED_ELEMENTS
std::unordered_map< std::type_index, LADataBuilder > _builder
Mapping of element types to local assembler constructors.
std::function< LADataIntfPtr(MeshLib::Element const &e, std::size_t const local_matrix_size, ConstructorArgs &&...)> LADataBuilder
std::size_t getNumberOfElementDOF(std::size_t const mesh_item_id) const
static LADataBuilder makeLocalAssemblerBuilder(std::false_type *)
std::unique_ptr< LocalAssemblerInterface > LADataIntfPtr
typename NumLib::GaussLegendreIntegrationPolicy< typename ShapeFunctionDisplacement::MeshElement >::IntegrationMethod IntegrationMethod
LocalDataInitializer(NumLib::LocalToGlobalIndexMap const &dof_table, const unsigned shapefunction_order)
static LADataBuilder makeLocalAssemblerBuilder(std::true_type *)
NumLib::LocalToGlobalIndexMap const & _dof_table
void operator()(std::size_t const id, MeshLib::Element const &mesh_item, LADataIntfPtr &data_ptr, ConstructorArgs &&... args) const
#define OGS_FATAL(fmt,...)
Definition: Error.h:71