OGS
LIE/HydroMechanics/LocalAssembler/LocalDataInitializer.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <functional>
7#include <memory>
8#include <type_traits>
9#include <typeindex>
10#include <typeinfo>
11#include <unordered_map>
12
19
20namespace ProcessLib
21{
22namespace LIE
23{
24namespace HydroMechanics
25{
35template <
36 typename LocalAssemblerInterface,
37 template <typename /* shp u */, typename /* shp p */, int /* global dim */>
38 class LocalAssemblerDataMatrix,
39 template <typename /* shp u */, typename /* shp p */, int /* global dim */>
40 class LocalAssemblerDataMatrixNearFracture,
41 template <typename /* shp u */, typename /* shp p */, int /* global dim */>
42 class LocalAssemblerDataFracture,
43 int DisplacementDim, typename... ConstructorArgs>
45{
47 {
48 template <typename ElementTraits>
49 constexpr bool operator()(ElementTraits*) const
50 {
51 if constexpr (DisplacementDim < ElementTraits::ShapeFunction::DIM)
52 {
53 return false;
54 }
55
56 // exclude 0D elements
57 return ElementTraits::Element::dimension >= 1 &&
58 ElementTraits::ShapeFunction::ORDER >= 1;
59 }
60 };
61
62public:
63 using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
64
66 NumLib::LocalToGlobalIndexMap const& dof_table,
67 NumLib::IntegrationOrder const integration_order)
68 : _dof_table(dof_table)
69 {
70 using EnabledElementTraits =
72 std::declval<IsElementEnabled>()));
73
75 [this, integration_order]<typename ET>(ET*)
76 {
77 using MeshElement = typename ET::Element;
78 using ShapeFunction = typename ET::ShapeFunction;
79 using LowerOrderShapeFunction =
80 typename ET::LowerOrderShapeFunction;
81
82 _builder[std::type_index(typeid(MeshElement))] =
84 LowerOrderShapeFunction>(
85 integration_order);
86 });
87 }
88
94 LADataIntfPtr operator()(std::size_t const id,
95 MeshLib::Element const& mesh_item,
96 ConstructorArgs&&... args) const
97 {
98 auto const type_idx = std::type_index(typeid(mesh_item));
99 auto const it = _builder.find(type_idx);
100
101 if (it == _builder.end())
102 {
103 OGS_FATAL(
104 "You are trying to build a local assembler for an unknown mesh "
105 "element type ({:s})."
106 " Maybe you have disabled this mesh element type in your build "
107 "configuration, or a mesh element order does not match shape "
108 "function order given in the project file.",
109 type_idx.name());
110 }
111
112 auto const n_local_dof = _dof_table.getNumberOfElementDOF(id);
113 auto const varIDs = _dof_table.getElementVariableIDs(id);
114 bool const isPressureDeactivated = (varIDs.front() != 0);
115 std::vector<int> involved_varIDs; // including deactivated elements
116 involved_varIDs.reserve(varIDs.size() + 1);
117 if (isPressureDeactivated)
118 {
119 involved_varIDs.push_back(0); // always pressure come in
120 }
121 involved_varIDs.insert(involved_varIDs.end(), varIDs.begin(),
122 varIDs.end());
123
124 std::vector<unsigned> dofIndex_to_localIndex;
125
126 // matrix and fracture assemblers with enrichments
127 dofIndex_to_localIndex.resize(n_local_dof);
128 std::vector<unsigned> vec_n_element_nodes;
129 // TODO how to get the shape function order for each variable?
130 vec_n_element_nodes.push_back(
131 mesh_item.getNumberOfBaseNodes()); // pressure
132 auto const max_varID = *std::max_element(varIDs.begin(), varIDs.end());
133 for (int i = 1; i < max_varID + 1; i++)
134 {
135 vec_n_element_nodes.push_back(
136 mesh_item.getNumberOfNodes()); // displacements
137 }
138
139 unsigned local_id = 0;
140 unsigned dof_id = 0;
141 for (unsigned i = 0; i < involved_varIDs.size(); i++)
142 {
143 auto const var_id = involved_varIDs[i];
144 auto const n_var_comp =
145 _dof_table.getNumberOfVariableComponents(var_id);
146 auto const n_var_element_nodes = vec_n_element_nodes[i];
147 for (int var_comp_id = 0; var_comp_id < n_var_comp; var_comp_id++)
148 {
149 auto const& ms = _dof_table.getMeshSubset(var_id, var_comp_id);
150 auto const mesh_id = ms.getMeshID();
151 for (unsigned k = 0; k < n_var_element_nodes; k++)
152 {
153 MeshLib::Location l(mesh_id,
155 getNodeIndex(mesh_item, k));
156 auto global_index =
157 _dof_table.getGlobalIndex(l, var_id, var_comp_id);
158 if (global_index != NumLib::MeshComponentMap::nop &&
159 dof_id < n_local_dof)
160 {
161 dofIndex_to_localIndex[dof_id++] = local_id;
162 }
163 local_id++;
164 }
165 }
166 }
167
168 return it->second(mesh_item, involved_varIDs.size(), n_local_dof,
169 dofIndex_to_localIndex,
170 std::forward<ConstructorArgs>(args)...);
171 }
172
173private:
174 using LADataBuilder = std::function<LADataIntfPtr(
175 MeshLib::Element const& e,
176 std::size_t const n_variables,
177 std::size_t const local_matrix_size,
178 std::vector<unsigned> const& dofIndex_to_localIndex,
179 ConstructorArgs&&...)>;
180
187 template <typename ShapeFunctionDisplacement,
188 typename ShapeFunctionPressure>
190 NumLib::IntegrationOrder const integration_order)
191 {
192 return [integration_order](
193 MeshLib::Element const& e,
194 std::size_t const n_variables,
195 std::size_t const local_matrix_size,
196 std::vector<unsigned> const& dofIndex_to_localIndex,
197 ConstructorArgs&&... args)
198 {
199 auto const& integration_method = NumLib::IntegrationMethodRegistry::
200 template getIntegrationMethod<
201 typename ShapeFunctionDisplacement::MeshElement>(
202 integration_order);
203
204 if (e.getDimension() == DisplacementDim)
205 {
206 if (n_variables == 2)
207 {
208 return LADataIntfPtr{
209 new LocalAssemblerDataMatrix<ShapeFunctionDisplacement,
210 ShapeFunctionPressure,
211 DisplacementDim>{
212 e, n_variables, local_matrix_size,
213 dofIndex_to_localIndex, integration_method,
214 std::forward<ConstructorArgs>(args)...}};
215 }
216 return LADataIntfPtr{new LocalAssemblerDataMatrixNearFracture<
217 ShapeFunctionDisplacement, ShapeFunctionPressure,
218 DisplacementDim>{e, n_variables, local_matrix_size,
219 dofIndex_to_localIndex, integration_method,
220 std::forward<ConstructorArgs>(args)...}};
221 }
222 return LADataIntfPtr{new LocalAssemblerDataFracture<
223 ShapeFunctionDisplacement, ShapeFunctionPressure,
224 DisplacementDim>{e, local_matrix_size, dofIndex_to_localIndex,
225 integration_method,
226 std::forward<ConstructorArgs>(args)...}};
227 };
228 }
229
231 std::unordered_map<std::type_index, LADataBuilder> _builder;
232
234};
235
236} // namespace HydroMechanics
237} // namespace LIE
238} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
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
LocalDataInitializer(NumLib::LocalToGlobalIndexMap const &dof_table, NumLib::IntegrationOrder const integration_order)
static LADataBuilder makeLocalAssemblerBuilder(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::unordered_map< std::type_index, LADataBuilder > _builder
Mapping of element types to local assembler constructors.
void foreach(Function &&f)
Definition TMP.h:150
decltype(auto) filter(Pred pred)
Definition TMP.h:71