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 <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 // All enabled element types
61 #define OGS_ENABLED_ELEMENTS \
62  ((ENABLED_ELEMENT_TYPE_SIMPLEX) | (ENABLED_ELEMENT_TYPE_CUBOID) | \
63  (ENABLED_ELEMENT_TYPE_PYRAMID) | (ENABLED_ELEMENT_TYPE_PRISM))
64 
65 // Include only what is needed (Well, the conditions are not sharp).
66 #if OGS_ENABLED_ELEMENTS != 0
69 #endif
70 
71 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0
74 #endif
75 
76 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0
79 #endif
80 
81 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0
84 #endif
85 
86 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0
89 #endif
90 
91 namespace ProcessLib
92 {
93 namespace HeatTransportBHE
94 {
100 template <typename LocalAssemblerInterface,
101  template <typename, typename>
102  class LocalAssemblerDataSoil,
103  template <typename, typename, typename>
104  class LocalAssemblerDataBHE,
105  typename... ConstructorArgs>
107 {
108 public:
109  using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
110 
112  NumLib::LocalToGlobalIndexMap const& dof_table)
113  : _dof_table(dof_table)
114  {
115  // REMARKS: At the moment, only a 3D mesh (soil) with 1D elements (BHE)
116  // are supported.
117 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 && \
118  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
119  _builder[std::type_index(typeid(MeshLib::Hex))] =
120  makeLocalAssemblerBuilder<NumLib::ShapeHex8>();
121 #endif
122 
123 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_CUBOID) != 0 && \
124  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
125  _builder[std::type_index(typeid(MeshLib::Hex20))] =
126  makeLocalAssemblerBuilder<NumLib::ShapeHex20>();
127 #endif
128 
129  // /// Simplices ////////////////////////////////////////////////
130 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
131  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
132  _builder[std::type_index(typeid(MeshLib::Tet))] =
133  makeLocalAssemblerBuilder<NumLib::ShapeTet4>();
134 #endif
135 
136 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_SIMPLEX) != 0 && \
137  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
138  _builder[std::type_index(typeid(MeshLib::Tet10))] =
139  makeLocalAssemblerBuilder<NumLib::ShapeTet10>();
140 #endif
141 
142  // /// Prisms ////////////////////////////////////////////////////
143 
144 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
145  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
146  _builder[std::type_index(typeid(MeshLib::Prism))] =
147  makeLocalAssemblerBuilder<NumLib::ShapePrism6>();
148 #endif
149 
150 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PRISM) != 0 && \
151  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
152  _builder[std::type_index(typeid(MeshLib::Prism15))] =
153  makeLocalAssemblerBuilder<NumLib::ShapePrism15>();
154 #endif
155 
156  // /// Pyramids //////////////////////////////////////////////////
157 
158 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
159  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 1
160  _builder[std::type_index(typeid(MeshLib::Pyramid))] =
161  makeLocalAssemblerBuilder<NumLib::ShapePyra5>();
162 #endif
163 
164 #if (OGS_ENABLED_ELEMENTS & ENABLED_ELEMENT_TYPE_PYRAMID) != 0 && \
165  OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
166  _builder[std::type_index(typeid(MeshLib::Pyramid13))] =
167  makeLocalAssemblerBuilder<NumLib::ShapePyra13>();
168 #endif
169  // /// Lines ///////////////////////////////////
170 
171 #if OGS_MAX_ELEMENT_DIM >= 2 && OGS_MAX_ELEMENT_ORDER >= 1
172  _builder[std::type_index(typeid(MeshLib::Line))] =
173  makeLocalAssemblerBuilderBHE<NumLib::ShapeLine2>();
174 #endif
175 
176 #if OGS_MAX_ELEMENT_DIM >= 3 && OGS_MAX_ELEMENT_ORDER >= 2
177  _builder[std::type_index(typeid(MeshLib::Line3))] =
178  makeLocalAssemblerBuilderBHE<NumLib::ShapeLine3>();
179 #endif
180  }
181 
187  void operator()(std::size_t const /*id*/,
188  MeshLib::Element const& mesh_item,
189  LADataIntfPtr& data_ptr,
190  std::unordered_map<std::size_t, BHE::BHETypes*> const&
191  element_to_bhe_map,
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  OGS_FATAL(
200  "You are trying to build a local assembler for an unknown mesh "
201  "element type (%s)."
202  " Maybe you have disabled this mesh element type in your build "
203  "configuration or this process requires higher order elements.",
204  type_idx.name());
205  }
206 
207  data_ptr = it->second(mesh_item,
208  element_to_bhe_map,
209  std::forward<ConstructorArgs>(args)...);
210  }
211 
212 private:
213  using LADataBuilder = std::function<LADataIntfPtr(
214  MeshLib::Element const& e,
215  std::unordered_map<std::size_t, BHE::BHETypes*> const&
216  element_to_bhe_map,
217  ConstructorArgs&&...)>;
218 
219  template <typename ShapeFunction>
221  typename ShapeFunction::MeshElement>::IntegrationMethod;
222 
223  // local assembler builder implementations.
224  template <typename ShapeFunction>
225  using LADataSoil =
226  LocalAssemblerDataSoil<ShapeFunction, IntegrationMethod<ShapeFunction>>;
227 
228  template <typename ShapeFunction>
230  {
231  return [](MeshLib::Element const& e,
232  std::unordered_map<std::size_t, BHE::BHETypes*> const&
233  /* unused */,
234  ConstructorArgs&&... args) -> LADataIntfPtr {
235  if (e.getDimension() == 3) // soil elements
236  {
238  e, std::forward<ConstructorArgs>(args)...}};
239  }
240 
241  return nullptr;
242  };
243  }
244 
245  template <typename ShapeFunction, typename BHEType>
246  using LADataBHE = LocalAssemblerDataBHE<ShapeFunction,
248  BHEType>;
249  template <typename ShapeFunction>
251  {
252  return [](MeshLib::Element const& e,
253  std::unordered_map<std::size_t, BHE::BHETypes*> const&
254  element_to_bhe_map,
255  ConstructorArgs&&... args) -> LADataIntfPtr {
256  auto& bhe = *element_to_bhe_map.at(e.getID());
257 
258  if (std::holds_alternative<BHE::BHE_1U>(bhe))
259  {
261  e, std::get<BHE::BHE_1U>(bhe),
262  std::forward<ConstructorArgs>(args)...}};
263  }
264 
265  if (std::holds_alternative<BHE::BHE_CXA>(bhe))
266  {
268  e, std::get<BHE::BHE_CXA>(bhe),
269  std::forward<ConstructorArgs>(args)...}};
270  }
271 
272  if (std::holds_alternative<BHE::BHE_CXC>(bhe))
273  {
275  e, std::get<BHE::BHE_CXC>(bhe),
276  std::forward<ConstructorArgs>(args)...}};
277  }
278  OGS_FATAL(
279  "Trying to create local assembler for an unknown BHE type.");
280  };
281  }
282 
284  std::unordered_map<std::type_index, LADataBuilder> _builder;
285 
287 }; // namespace HeatTransportBHE
288 } // namespace HeatTransportBHE
289 } // namespace ProcessLib
290 
291 #undef ENABLED_ELEMENT_TYPE_SIMPLEX
292 #undef ENABLED_ELEMENT_TYPE_CUBOID
293 #undef ENABLED_ELEMENT_TYPE_PYRAMID
294 #undef ENABLED_ELEMENT_TYPE_PRISM
295 #undef OGS_ENABLED_ELEMENTS
std::unique_ptr< LocalAssemblerInterface > LADataIntfPtr
void operator()(std::size_t const, MeshLib::Element const &mesh_item, LADataIntfPtr &data_ptr, std::unordered_map< std::size_t, BHE::BHETypes *> const &element_to_bhe_map, ConstructorArgs &&... args) const
virtual unsigned getDimension() const =0
Get dimension of the mesh element.
LocalAssemblerDataSoil< ShapeFunction, IntegrationMethod< ShapeFunction > > LADataSoil
typename NumLib::GaussLegendreIntegrationPolicy< typename ShapeFunction::MeshElement >::IntegrationMethod IntegrationMethod
LocalAssemblerDataBHE< ShapeFunction, IntegrationMethod< ShapeFunction >, BHEType > LADataBHE
std::unordered_map< std::type_index, LADataBuilder > _builder
Mapping of element types to local assembler constructors.
NumLib::LocalToGlobalIndexMap const & _dof_table
virtual std::size_t getID() const final
Returns the ID of the element.
Definition: Element.h:90
#define OGS_FATAL(fmt,...)
Definition: Error.h:63
LocalDataInitializer(NumLib::LocalToGlobalIndexMap const &dof_table)
std::function< LADataIntfPtr(MeshLib::Element const &e, std::unordered_map< std::size_t, BHE::BHETypes * > const &element_to_bhe_map, ConstructorArgs &&...)> LADataBuilder