OGS
LocalDataInitializer.h
Go to the documentation of this file.
1 
11 #pragma once
12 
13 #include <functional>
14 #include <memory>
15 #include <type_traits>
16 #include <typeindex>
17 #include <typeinfo>
18 #include <unordered_map>
19 
24 
25 #ifndef OGS_MAX_ELEMENT_DIM
26 static_assert(false, "The macro OGS_MAX_ELEMENT_DIM is undefined.");
27 #endif
28 
29 #ifndef OGS_MAX_ELEMENT_ORDER
30 static_assert(false, "The macro OGS_MAX_ELEMENT_ORDER is undefined.");
31 #endif
32 
33 // The following macros decide which element types will be compiled, i.e.
34 // which element types will be available for use in simulations.
35 
36 #ifdef OGS_ENABLE_ELEMENT_SIMPLEX
37 #define ENABLED_ELEMENT_TYPE_SIMPLEX 1u
38 #else
39 #define ENABLED_ELEMENT_TYPE_SIMPLEX 0u
40 #endif
41 
42 #ifdef OGS_ENABLE_ELEMENT_CUBOID
43 #define ENABLED_ELEMENT_TYPE_CUBOID 1u << 1
44 #else
45 #define ENABLED_ELEMENT_TYPE_CUBOID 0u
46 #endif
47 
48 #ifdef OGS_ENABLE_ELEMENT_PRISM
49 #define ENABLED_ELEMENT_TYPE_PRISM 1u << 2
50 #else
51 #define ENABLED_ELEMENT_TYPE_PRISM 0u
52 #endif
53 
54 #ifdef OGS_ENABLE_ELEMENT_PYRAMID
55 #define ENABLED_ELEMENT_TYPE_PYRAMID 1u << 3
56 #else
57 #define ENABLED_ELEMENT_TYPE_PYRAMID 0u
58 #endif
59 
60 // Dependent element types.
61 // All enabled element types
62 #define OGS_ENABLED_ELEMENTS \
63  ((ENABLED_ELEMENT_TYPE_SIMPLEX) | (ENABLED_ELEMENT_TYPE_CUBOID) | \
64  (ENABLED_ELEMENT_TYPE_PYRAMID) | (ENABLED_ELEMENT_TYPE_PRISM))
65 
66 // Include only what is needed (Well, the conditions are not sharp).
67 #if OGS_ENABLED_ELEMENTS != 0
70 #endif
71 
72 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0
75 #endif
76 
77 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0
80 #endif
81 
82 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0
85 #endif
86 
87 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0
90 #endif
91 
92 namespace ProcessLib
93 {
94 namespace HeatTransportBHE
95 {
101 template <typename LocalAssemblerInterface,
102  template <typename, typename>
103  class LocalAssemblerDataSoil,
104  template <typename, typename, typename>
105  class LocalAssemblerDataBHE,
106  typename... ConstructorArgs>
108 {
109 public:
110  using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
111 
113  NumLib::LocalToGlobalIndexMap const& dof_table)
114  : _dof_table(dof_table)
115  {
116  // REMARKS: At the moment, only a 3D mesh (soil) with 1D elements (BHE)
117  // are supported.
118 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 && \
119  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
120  _builder[std::type_index(typeid(MeshLib::Hex))] =
121  makeLocalAssemblerBuilder<NumLib::ShapeHex8>();
122 #endif
123 
124 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 && \
125  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
126  _builder[std::type_index(typeid(MeshLib::Hex20))] =
127  makeLocalAssemblerBuilder<NumLib::ShapeHex20>();
128 #endif
129 
130  // /// Simplices ////////////////////////////////////////////////
131 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
132  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
133  _builder[std::type_index(typeid(MeshLib::Tet))] =
134  makeLocalAssemblerBuilder<NumLib::ShapeTet4>();
135 #endif
136 
137 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
138  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
139  _builder[std::type_index(typeid(MeshLib::Tet10))] =
140  makeLocalAssemblerBuilder<NumLib::ShapeTet10>();
141 #endif
142 
143  // /// Prisms ////////////////////////////////////////////////////
144 
145 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
146  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
147  _builder[std::type_index(typeid(MeshLib::Prism))] =
148  makeLocalAssemblerBuilder<NumLib::ShapePrism6>();
149 #endif
150 
151 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
152  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
153  _builder[std::type_index(typeid(MeshLib::Prism15))] =
154  makeLocalAssemblerBuilder<NumLib::ShapePrism15>();
155 #endif
156 
157  // /// Pyramids //////////////////////////////////////////////////
158 
159 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
160  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
161  _builder[std::type_index(typeid(MeshLib::Pyramid))] =
162  makeLocalAssemblerBuilder<NumLib::ShapePyra5>();
163 #endif
164 
165 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
166  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
167  _builder[std::type_index(typeid(MeshLib::Pyramid13))] =
168  makeLocalAssemblerBuilder<NumLib::ShapePyra13>();
169 #endif
170  // /// Lines ///////////////////////////////////
171 
172 #if OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1
173  _builder[std::type_index(typeid(MeshLib::Line))] =
174  makeLocalAssemblerBuilderBHE<NumLib::ShapeLine2>();
175 #endif
176 
177 #if OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
178  _builder[std::type_index(typeid(MeshLib::Line3))] =
179  makeLocalAssemblerBuilderBHE<NumLib::ShapeLine3>();
180 #endif
181  }
182 
189  std::size_t const /*id*/,
190  MeshLib::Element const& mesh_item,
191  std::unordered_map<std::size_t, BHE::BHETypes*> const&
192  element_to_bhe_map,
193  ConstructorArgs&&... args) const
194  {
195  auto const type_idx = std::type_index(typeid(mesh_item));
196  auto const it = _builder.find(type_idx);
197 
198  if (it == _builder.end())
199  {
200  OGS_FATAL(
201  "You are trying to build a local assembler for an unknown mesh "
202  "element type ({:s})."
203  " Maybe you have disabled this mesh element type in your build "
204  "configuration, or a mesh element order does not match shape "
205  "function order given in the project file.",
206  type_idx.name());
207  }
208 
209  return it->second(mesh_item,
210  element_to_bhe_map,
211  std::forward<ConstructorArgs>(args)...);
212  }
213 
214 private:
215  using LADataBuilder = std::function<LADataIntfPtr(
216  MeshLib::Element const& e,
217  std::unordered_map<std::size_t, BHE::BHETypes*> const&
218  element_to_bhe_map,
219  ConstructorArgs&&...)>;
220 
221  template <typename ShapeFunction>
223  typename ShapeFunction::MeshElement>::IntegrationMethod;
224 
225  // local assembler builder implementations.
226  template <typename ShapeFunction>
227  using LADataSoil =
228  LocalAssemblerDataSoil<ShapeFunction, IntegrationMethod<ShapeFunction>>;
229 
230  template <typename ShapeFunction>
232  {
233  return [](MeshLib::Element const& e,
234  std::unordered_map<std::size_t, BHE::BHETypes*> const&
235  /* unused */,
236  ConstructorArgs&&... args) -> LADataIntfPtr {
237  if (e.getDimension() == 3) // soil elements
238  {
240  e, std::forward<ConstructorArgs>(args)...}};
241  }
242 
243  return nullptr;
244  };
245  }
246 
247  template <typename ShapeFunction, typename BHEType>
248  using LADataBHE = LocalAssemblerDataBHE<ShapeFunction,
250  BHEType>;
251  template <typename ShapeFunction>
253  {
254  return [](MeshLib::Element const& e,
255  std::unordered_map<std::size_t, BHE::BHETypes*> const&
256  element_to_bhe_map,
257  ConstructorArgs&&... args) -> LADataIntfPtr {
258  auto& bhe = *element_to_bhe_map.at(e.getID());
259 
260  if (std::holds_alternative<BHE::BHE_1U>(bhe))
261  {
263  e, std::get<BHE::BHE_1U>(bhe),
264  std::forward<ConstructorArgs>(args)...}};
265  }
266 
267  if (std::holds_alternative<BHE::BHE_CXA>(bhe))
268  {
270  e, std::get<BHE::BHE_CXA>(bhe),
271  std::forward<ConstructorArgs>(args)...}};
272  }
273 
274  if (std::holds_alternative<BHE::BHE_CXC>(bhe))
275  {
277  e, std::get<BHE::BHE_CXC>(bhe),
278  std::forward<ConstructorArgs>(args)...}};
279  }
280 
281  if (std::holds_alternative<BHE::BHE_2U>(bhe))
282  {
284  e, std::get<BHE::BHE_2U>(bhe),
285  std::forward<ConstructorArgs>(args)...}};
286  }
287 
288  if (std::holds_alternative<BHE::BHE_1P>(bhe))
289  {
291  e, std::get<BHE::BHE_1P>(bhe),
292  std::forward<ConstructorArgs>(args)...}};
293  }
294  OGS_FATAL(
295  "Trying to create local assembler for an unknown BHE type.");
296  };
297  }
298 
300  std::unordered_map<std::type_index, LADataBuilder> _builder;
301 
303 }; // namespace HeatTransportBHE
304 } // namespace HeatTransportBHE
305 } // namespace ProcessLib
306 
307 #undef ENABLED_ELEMENT_TYPE_SIMPLEX
308 #undef ENABLED_ELEMENT_TYPE_CUBOID
309 #undef ENABLED_ELEMENT_TYPE_PYRAMID
310 #undef ENABLED_ELEMENT_TYPE_PRISM
311 #undef OGS_ENABLED_ELEMENTS
#define OGS_FATAL(...)
Definition: Error.h:26
virtual constexpr unsigned getDimension() const =0
Get dimension of the mesh element.
virtual std::size_t getID() const final
Returns the ID of the element.
Definition: Element.h:82
LADataIntfPtr operator()(std::size_t const, MeshLib::Element const &mesh_item, std::unordered_map< std::size_t, BHE::BHETypes * > const &element_to_bhe_map, ConstructorArgs &&... args) const
LocalDataInitializer(NumLib::LocalToGlobalIndexMap const &dof_table)
typename NumLib::GaussLegendreIntegrationPolicy< typename ShapeFunction::MeshElement >::IntegrationMethod IntegrationMethod
LocalAssemblerDataSoil< ShapeFunction, IntegrationMethod< ShapeFunction > > LADataSoil
std::function< LADataIntfPtr(MeshLib::Element const &e, std::unordered_map< std::size_t, BHE::BHETypes * > const &element_to_bhe_map, ConstructorArgs &&...)> LADataBuilder
std::unique_ptr< LocalAssemblerInterface > LADataIntfPtr
std::unordered_map< std::type_index, LADataBuilder > _builder
Mapping of element types to local assembler constructors.
NumLib::LocalToGlobalIndexMap const & _dof_table
LocalAssemblerDataBHE< ShapeFunction, IntegrationMethod< ShapeFunction >, BHEType > LADataBHE