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 =
79 std::declval<IsElementEnabled>()));
80
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 dof_id < n_local_dof)
167 {
168 dofIndex_to_localIndex[dof_id++] = local_id;
169 }
170 local_id++;
171 }
172 }
173 }
174
175 return it->second(mesh_item, involved_varIDs.size(), n_local_dof,
176 dofIndex_to_localIndex,
177 std::forward<ConstructorArgs>(args)...);
178 }
179
180private:
181 using LADataBuilder = std::function<LADataIntfPtr(
182 MeshLib::Element const& e,
183 std::size_t const n_variables,
184 std::size_t const local_matrix_size,
185 std::vector<unsigned> const& dofIndex_to_localIndex,
186 ConstructorArgs&&...)>;
187
194 template <typename ShapeFunctionDisplacement,
195 typename ShapeFunctionPressure>
197 NumLib::IntegrationOrder const integration_order)
198 {
199 return [integration_order](
200 MeshLib::Element const& e,
201 std::size_t const n_variables,
202 std::size_t const local_matrix_size,
203 std::vector<unsigned> const& dofIndex_to_localIndex,
204 ConstructorArgs&&... args)
205 {
206 auto const& integration_method = NumLib::IntegrationMethodRegistry::
207 template getIntegrationMethod<
208 typename ShapeFunctionDisplacement::MeshElement>(
209 integration_order);
210
211 if (e.getDimension() == GlobalDim)
212 {
213 if (n_variables == 2)
214 {
215 return LADataIntfPtr{new LocalAssemblerDataMatrix<
216 ShapeFunctionDisplacement, ShapeFunctionPressure,
217 GlobalDim>{e, n_variables, local_matrix_size,
218 dofIndex_to_localIndex, integration_method,
219 std::forward<ConstructorArgs>(args)...}};
220 }
221 return LADataIntfPtr{new LocalAssemblerDataMatrixNearFracture<
222 ShapeFunctionDisplacement, ShapeFunctionPressure,
223 GlobalDim>{e, n_variables, local_matrix_size,
224 dofIndex_to_localIndex, integration_method,
225 std::forward<ConstructorArgs>(args)...}};
226 }
227 return LADataIntfPtr{new LocalAssemblerDataFracture<
228 ShapeFunctionDisplacement, ShapeFunctionPressure, GlobalDim>{
229 e, local_matrix_size, dofIndex_to_localIndex,
230 integration_method, std::forward<ConstructorArgs>(args)...}};
231 };
232 }
233
235 std::unordered_map<std::type_index, LADataBuilder> _builder;
236
238};
239
240} // namespace HydroMechanics
241} // namespace LIE
242} // 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.
void foreach(Function &&f)
Definition TMP.h:157
decltype(auto) filter(Pred pred)
Definition TMP.h:78