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 LIE
30{
31namespace HydroMechanics
32{
42template <
43 typename LocalAssemblerInterface,
44 template <typename /* shp u */, typename /* shp p */, int /* global dim */>
45 class LocalAssemblerDataMatrix,
46 template <typename /* shp u */, typename /* shp p */, int /* global dim */>
47 class LocalAssemblerDataMatrixNearFracture,
48 template <typename /* shp u */, typename /* shp p */, int /* global dim */>
49 class LocalAssemblerDataFracture,
50 int GlobalDim, typename... ConstructorArgs>
52{
54 {
55 template <typename ElementTraits>
56 constexpr bool operator()(ElementTraits*) const
57 {
58 if constexpr (GlobalDim < ElementTraits::ShapeFunction::DIM)
59 {
60 return false;
61 }
62
63 // exclude 0D elements
64 return ElementTraits::Element::dimension >= 1 &&
65 ElementTraits::ShapeFunction::ORDER >= 1;
66 }
67 };
68
69public:
70 using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
71
73 NumLib::LocalToGlobalIndexMap const& dof_table,
74 NumLib::IntegrationOrder const integration_order)
75 : _dof_table(dof_table)
76 {
77 using EnabledElementTraits =
78 decltype(BaseLib::TMP::filter<EnabledElementTraitsLagrange>(
79 std::declval<IsElementEnabled>()));
80
81 BaseLib::TMP::foreach<EnabledElementTraits>(
82 [this, integration_order]<typename ET>(ET*)
83 {
84 using MeshElement = typename ET::Element;
85 using ShapeFunction = typename ET::ShapeFunction;
86 using LowerOrderShapeFunction =
87 typename ET::LowerOrderShapeFunction;
88
89 _builder[std::type_index(typeid(MeshElement))] =
90 makeLocalAssemblerBuilder<ShapeFunction,
91 LowerOrderShapeFunction>(
92 integration_order);
93 });
94 }
95
101 LADataIntfPtr operator()(std::size_t const id,
102 MeshLib::Element const& mesh_item,
103 ConstructorArgs&&... args) const
104 {
105 auto const type_idx = std::type_index(typeid(mesh_item));
106 auto const it = _builder.find(type_idx);
107
108 if (it == _builder.end())
109 {
110 OGS_FATAL(
111 "You are trying to build a local assembler for an unknown mesh "
112 "element type ({:s})."
113 " Maybe you have disabled this mesh element type in your build "
114 "configuration, or a mesh element order does not match shape "
115 "function order given in the project file.",
116 type_idx.name());
117 }
118
119 auto const n_local_dof = _dof_table.getNumberOfElementDOF(id);
120 auto const varIDs = _dof_table.getElementVariableIDs(id);
121 bool const isPressureDeactivated = (varIDs.front() != 0);
122 std::vector<int> involved_varIDs; // including deactivated elements
123 involved_varIDs.reserve(varIDs.size() + 1);
124 if (isPressureDeactivated)
125 {
126 involved_varIDs.push_back(0); // always pressure come in
127 }
128 involved_varIDs.insert(involved_varIDs.end(), varIDs.begin(),
129 varIDs.end());
130
131 std::vector<unsigned> dofIndex_to_localIndex;
132
133 // matrix and fracture assemblers with enrichments
134 dofIndex_to_localIndex.resize(n_local_dof);
135 std::vector<unsigned> vec_n_element_nodes;
136 // TODO how to get the shape function order for each variable?
137 vec_n_element_nodes.push_back(
138 mesh_item.getNumberOfBaseNodes()); // pressure
139 auto const max_varID = *std::max_element(varIDs.begin(), varIDs.end());
140 for (int i = 1; i < max_varID + 1; i++)
141 {
142 vec_n_element_nodes.push_back(
143 mesh_item.getNumberOfNodes()); // displacements
144 }
145
146 unsigned local_id = 0;
147 unsigned dof_id = 0;
148 for (unsigned i = 0; i < involved_varIDs.size(); i++)
149 {
150 auto const var_id = involved_varIDs[i];
151 auto const n_var_comp =
152 _dof_table.getNumberOfVariableComponents(var_id);
153 auto const n_var_element_nodes = vec_n_element_nodes[i];
154 for (int var_comp_id = 0; var_comp_id < n_var_comp; var_comp_id++)
155 {
156 auto const& ms = _dof_table.getMeshSubset(var_id, var_comp_id);
157 auto const mesh_id = ms.getMeshID();
158 for (unsigned k = 0; k < n_var_element_nodes; k++)
159 {
160 MeshLib::Location l(mesh_id,
162 getNodeIndex(mesh_item, k));
163 auto global_index =
164 _dof_table.getGlobalIndex(l, var_id, var_comp_id);
165 if (global_index != NumLib::MeshComponentMap::nop)
166 {
167 dofIndex_to_localIndex[dof_id++] = local_id;
168 }
169 local_id++;
170 }
171 }
172 }
173
174 return it->second(mesh_item, involved_varIDs.size(), n_local_dof,
175 dofIndex_to_localIndex,
176 std::forward<ConstructorArgs>(args)...);
177 }
178
179private:
180 using LADataBuilder = std::function<LADataIntfPtr(
181 MeshLib::Element const& e,
182 std::size_t const n_variables,
183 std::size_t const local_matrix_size,
184 std::vector<unsigned> const& dofIndex_to_localIndex,
185 ConstructorArgs&&...)>;
186
193 template <typename ShapeFunctionDisplacement,
194 typename ShapeFunctionPressure>
196 NumLib::IntegrationOrder const integration_order)
197 {
198 return [integration_order](
199 MeshLib::Element const& e,
200 std::size_t const n_variables,
201 std::size_t const local_matrix_size,
202 std::vector<unsigned> const& dofIndex_to_localIndex,
203 ConstructorArgs&&... args)
204 {
205 auto const& integration_method = NumLib::IntegrationMethodRegistry::
206 template getIntegrationMethod<
207 typename ShapeFunctionDisplacement::MeshElement>(
208 integration_order);
209
210 if (e.getDimension() == GlobalDim)
211 {
212 if (n_variables == 2)
213 {
214 return LADataIntfPtr{new LocalAssemblerDataMatrix<
215 ShapeFunctionDisplacement, ShapeFunctionPressure,
216 GlobalDim>{e, n_variables, local_matrix_size,
217 dofIndex_to_localIndex, integration_method,
218 std::forward<ConstructorArgs>(args)...}};
219 }
220 return LADataIntfPtr{new LocalAssemblerDataMatrixNearFracture<
221 ShapeFunctionDisplacement, ShapeFunctionPressure,
222 GlobalDim>{e, n_variables, local_matrix_size,
223 dofIndex_to_localIndex, integration_method,
224 std::forward<ConstructorArgs>(args)...}};
225 }
226 return LADataIntfPtr{new LocalAssemblerDataFracture<
227 ShapeFunctionDisplacement, ShapeFunctionPressure, GlobalDim>{
228 e, local_matrix_size, dofIndex_to_localIndex,
229 integration_method, std::forward<ConstructorArgs>(args)...}};
230 };
231 }
232
234 std::unordered_map<std::type_index, LADataBuilder> _builder;
235
237};
238
239} // namespace HydroMechanics
240} // namespace LIE
241} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
virtual unsigned getNumberOfNodes() const =0
virtual unsigned getNumberOfBaseNodes() const =0
virtual constexpr unsigned getDimension() const =0
Get dimension of the mesh element.
static constexpr NUMLIB_EXPORT GlobalIndexType const nop
static LADataBuilder makeLocalAssemblerBuilder(NumLib::IntegrationOrder const integration_order)
LocalDataInitializer(NumLib::LocalToGlobalIndexMap const &dof_table, NumLib::IntegrationOrder const integration_order)
LADataIntfPtr operator()(std::size_t const id, MeshLib::Element const &mesh_item, ConstructorArgs &&... args) const
std::function< LADataIntfPtr( MeshLib::Element const &e, std::size_t const n_variables, std::size_t const local_matrix_size, std::vector< unsigned > const &dofIndex_to_localIndex, ConstructorArgs &&...)> LADataBuilder
std::unique_ptr< LocalAssemblerInterface > LADataIntfPtr
std::unordered_map< std::type_index, LADataBuilder > _builder
Mapping of element types to local assembler constructors.