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
26
27namespace ProcessLib
28{
29namespace HeatTransportBHE
30{
36template <typename LocalAssemblerInterface,
37 template <typename /* shp fct */>
38 class LocalAssemblerDataSoil,
39 template <typename /* shp fct */, typename /* bhe type */>
40 class LocalAssemblerDataBHE,
41 typename... ConstructorArgs>
43{
44 template <unsigned DIM>
46 {
47 template <typename ElementTraits>
48 constexpr bool operator()(ElementTraits*) const
49 {
50 return ElementTraits::Element::dimension == DIM;
51 }
52 };
53
54public:
55 using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
56
58 NumLib::LocalToGlobalIndexMap const& dof_table,
59 NumLib::IntegrationOrder const integration_order)
60 : _dof_table(dof_table)
61 {
62 // 3D soil elements
63 using Enabled3DElementTraits =
64 decltype(BaseLib::TMP::filter<EnabledElementTraitsLagrange>(
65 std::declval<IsNDElement<3>>()));
66
67 BaseLib::TMP::foreach<Enabled3DElementTraits>(
68 [this, integration_order]<typename ET>(ET*)
69 {
70 using MeshElement = typename ET::Element;
71 using ShapeFunction = typename ET::ShapeFunction;
72
73 _builder[std::type_index(typeid(MeshElement))] =
74 makeLocalAssemblerBuilder<ShapeFunction>(integration_order);
75 });
76
77 // 1D BHE elements
78 using Enabled1DElementTraits =
79 decltype(BaseLib::TMP::filter<EnabledElementTraitsLagrange>(
80 std::declval<IsNDElement<1>>()));
81
82 BaseLib::TMP::foreach<Enabled1DElementTraits>(
83 [this, integration_order]<typename ET>(ET*)
84 {
85 using MeshElement = typename ET::Element;
86 using ShapeFunction = typename ET::ShapeFunction;
87
88 _builder[std::type_index(typeid(MeshElement))] =
89 makeLocalAssemblerBuilderBHE<ShapeFunction>(
90 integration_order);
91 });
92 }
93
100 std::size_t const /*id*/,
101 MeshLib::Element const& mesh_item,
102 std::unordered_map<std::size_t, BHE::BHETypes*> const&
103 element_to_bhe_map,
104 ConstructorArgs&&... args) const
105 {
106 auto const type_idx = std::type_index(typeid(mesh_item));
107 auto const it = _builder.find(type_idx);
108
109 if (it == _builder.end())
110 {
111 OGS_FATAL(
112 "You are trying to build a local assembler for an unknown mesh "
113 "element type ({:s})."
114 " Maybe you have disabled this mesh element type in your build "
115 "configuration, or a mesh element order does not match shape "
116 "function order given in the project file.",
117 type_idx.name());
118 }
119
120 return it->second(mesh_item,
121 element_to_bhe_map,
122 std::forward<ConstructorArgs>(args)...);
123 }
124
125private:
126 using LADataBuilder = std::function<LADataIntfPtr(
127 MeshLib::Element const& e,
128 std::unordered_map<std::size_t, BHE::BHETypes*> const&
129 element_to_bhe_map,
130 ConstructorArgs&&...)>;
131
132 template <typename ShapeFunction>
134 NumLib::IntegrationOrder const integration_order)
135 {
136 return [integration_order](
137 MeshLib::Element const& e,
138 std::unordered_map<std::size_t, BHE::BHETypes*> const&
139 /* unused */,
140 ConstructorArgs&&... args) -> LADataIntfPtr
141 {
142 auto const& integration_method = NumLib::IntegrationMethodRegistry::
143 template getIntegrationMethod<
144 typename ShapeFunction::MeshElement>(integration_order);
145
146 if (e.getDimension() == 3) // soil elements
147 {
148 return LADataIntfPtr{new LocalAssemblerDataSoil<ShapeFunction>{
149 e, integration_method,
150 std::forward<ConstructorArgs>(args)...}};
151 }
152
153 return nullptr;
154 };
155 }
156
157 template <typename ShapeFunction>
159 NumLib::IntegrationOrder const integration_order)
160 {
161 return [integration_order](
162 MeshLib::Element const& e,
163 std::unordered_map<std::size_t, BHE::BHETypes*> const&
164 element_to_bhe_map,
165 ConstructorArgs&&... args) -> LADataIntfPtr
166 {
167 auto const& integration_method = NumLib::IntegrationMethodRegistry::
168 template getIntegrationMethod<
169 typename ShapeFunction::MeshElement>(integration_order);
170
171 auto& bhe = *element_to_bhe_map.at(e.getID());
172
173 if (std::holds_alternative<BHE::BHE_1U>(bhe))
174 {
175 return LADataIntfPtr{
176 new LocalAssemblerDataBHE<ShapeFunction, BHE::BHE_1U>{
177 e, integration_method, std::get<BHE::BHE_1U>(bhe),
178 std::forward<ConstructorArgs>(args)...}};
179 }
180
181 if (std::holds_alternative<BHE::BHE_CXA>(bhe))
182 {
183 return LADataIntfPtr{
184 new LocalAssemblerDataBHE<ShapeFunction, BHE::BHE_CXA>{
185 e, integration_method, std::get<BHE::BHE_CXA>(bhe),
186 std::forward<ConstructorArgs>(args)...}};
187 }
188
189 if (std::holds_alternative<BHE::BHE_CXC>(bhe))
190 {
191 return LADataIntfPtr{
192 new LocalAssemblerDataBHE<ShapeFunction, BHE::BHE_CXC>{
193 e, integration_method, std::get<BHE::BHE_CXC>(bhe),
194 std::forward<ConstructorArgs>(args)...}};
195 }
196
197 if (std::holds_alternative<BHE::BHE_2U>(bhe))
198 {
199 return LADataIntfPtr{
200 new LocalAssemblerDataBHE<ShapeFunction, BHE::BHE_2U>{
201 e, integration_method, std::get<BHE::BHE_2U>(bhe),
202 std::forward<ConstructorArgs>(args)...}};
203 }
204
205 if (std::holds_alternative<BHE::BHE_1P>(bhe))
206 {
207 return LADataIntfPtr{
208 new LocalAssemblerDataBHE<ShapeFunction, BHE::BHE_1P>{
209 e, integration_method, std::get<BHE::BHE_1P>(bhe),
210 std::forward<ConstructorArgs>(args)...}};
211 }
212 OGS_FATAL(
213 "Trying to create local assembler for an unknown BHE type.");
214 };
215 }
216
218 std::unordered_map<std::type_index, LADataBuilder> _builder;
219
221};
222} // namespace HeatTransportBHE
223} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
virtual constexpr unsigned getDimension() const =0
Get dimension of the mesh element.
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:89
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
static LADataBuilder makeLocalAssemblerBuilderBHE(NumLib::IntegrationOrder const integration_order)
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
static LADataBuilder makeLocalAssemblerBuilder(NumLib::IntegrationOrder const integration_order)
LocalDataInitializer(NumLib::LocalToGlobalIndexMap const &dof_table, NumLib::IntegrationOrder const integration_order)
std::unordered_map< std::type_index, LADataBuilder > _builder
Mapping of element types to local assembler constructors.
NumLib::LocalToGlobalIndexMap const & _dof_table