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
25
26namespace ProcessLib
27{
28namespace LIE
29{
30namespace SmallDeformation
31{
37template <typename LocalAssemblerInterface,
38 template <typename, int> class LocalAssemblerDataMatrix,
39 template <typename, int> class LocalAssemblerDataMatrixNearFracture,
40 template <typename, int> class LocalAssemblerDataFracture,
41 int GlobalDim, typename... ConstructorArgs>
43{
45 {
46 template <typename ElementTraits>
47 constexpr bool operator()(ElementTraits*) const
48 {
49 if constexpr (GlobalDim < ElementTraits::ShapeFunction::DIM)
50 {
51 return false;
52 }
53
54 // exclude 0D elements
55 return ElementTraits::Element::dimension >= 1;
56 }
57 };
58
59public:
60 using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
61
63 NumLib::LocalToGlobalIndexMap const& dof_table,
64 NumLib::IntegrationOrder const integration_order)
65 : _dof_table(dof_table)
66 {
67 // REMARKS: At the moment, only a 2D mesh with 1D elements are
68 // supported.
69
70 using EnabledElementTraits =
71 decltype(BaseLib::TMP::filter<EnabledElementTraitsLagrange>(
72 std::declval<IsElementEnabled>()));
73
74 BaseLib::TMP::foreach<EnabledElementTraits>(
75 [this, integration_order]<typename ET>(ET*)
76 {
77 using MeshElement = typename ET::Element;
78 using ShapeFunction = typename ET::ShapeFunction;
79
80 _builder[std::type_index(typeid(MeshElement))] =
81 makeLocalAssemblerBuilder<ShapeFunction>(integration_order);
82 });
83 }
84
90 LADataIntfPtr operator()(std::size_t const id,
91 MeshLib::Element const& mesh_item,
92 ConstructorArgs&&... args) const
93 {
94 auto const type_idx = std::type_index(typeid(mesh_item));
95 auto const it = _builder.find(type_idx);
96
97 if (it == _builder.end())
98 {
100 "You are trying to build a local assembler for an unknown mesh "
101 "element type ({:s})."
102 " Maybe you have disabled this mesh element type in your build "
103 "configuration, or a mesh element order does not match shape "
104 "function order given in the project file.",
105 type_idx.name());
106 }
107
108 auto const n_local_dof = _dof_table.getNumberOfElementDOF(id);
109 auto const n_global_components =
111 auto const varIDs = _dof_table.getElementVariableIDs(id);
112
113 std::vector<unsigned> dofIndex_to_localIndex;
114 if (mesh_item.getDimension() < GlobalDim ||
115 n_global_components > GlobalDim)
116 {
117 dofIndex_to_localIndex.resize(n_local_dof);
118 unsigned dof_id = 0;
119 unsigned local_id = 0;
120 for (auto i : varIDs)
121 {
122 for (int j = 0; j < _dof_table.getNumberOfVariableComponents(i);
123 j++)
124 {
125 auto const& ms = _dof_table.getMeshSubset(i, j);
126 auto const mesh_id = ms.getMeshID();
127 for (unsigned k = 0; k < mesh_item.getNumberOfNodes(); k++)
128 {
129 MeshLib::Location l(mesh_id,
131 getNodeIndex(mesh_item, k));
132 auto global_index = _dof_table.getGlobalIndex(l, i, j);
133 if (global_index != NumLib::MeshComponentMap::nop)
134 {
135 dofIndex_to_localIndex[dof_id++] = local_id;
136 }
137 local_id++;
138 }
139 }
140 }
141 }
142
143 return it->second(mesh_item, varIDs.size(), n_local_dof,
144 dofIndex_to_localIndex,
145 std::forward<ConstructorArgs>(args)...);
146 }
147
148private:
149 using LADataBuilder = std::function<LADataIntfPtr(
150 MeshLib::Element const& e,
151 std::size_t const n_variables,
152 std::size_t const local_matrix_size,
153 std::vector<unsigned> const& dofIndex_to_localIndex,
154 ConstructorArgs&&...)>;
155
161 template <typename ShapeFunction>
163 NumLib::IntegrationOrder const integration_order)
164 {
165 return [integration_order](
166 MeshLib::Element const& e,
167 std::size_t const n_variables,
168 std::size_t const local_matrix_size,
169 std::vector<unsigned> const& dofIndex_to_localIndex,
170 ConstructorArgs&&... args)
171 {
172 auto const& integration_method = NumLib::IntegrationMethodRegistry::
173 template getIntegrationMethod<
174 typename ShapeFunction::MeshElement>(integration_order);
175
176 if (e.getDimension() == GlobalDim)
177 {
178 if (dofIndex_to_localIndex.empty())
179 {
180 return LADataIntfPtr{
181 new LocalAssemblerDataMatrix<ShapeFunction, GlobalDim>{
182 e, local_matrix_size, integration_method,
183 std::forward<ConstructorArgs>(args)...}};
184 }
185
186 return LADataIntfPtr{
187 new LocalAssemblerDataMatrixNearFracture<ShapeFunction,
188 GlobalDim>{
189 e, n_variables, local_matrix_size,
190 dofIndex_to_localIndex, integration_method,
191 std::forward<ConstructorArgs>(args)...}};
192 }
193 return LADataIntfPtr{
194 new LocalAssemblerDataFracture<ShapeFunction, GlobalDim>{
195 e, n_variables, local_matrix_size, dofIndex_to_localIndex,
196 integration_method,
197 std::forward<ConstructorArgs>(args)...}};
198 };
199 }
200
202 std::unordered_map<std::type_index, LADataBuilder> _builder;
203
205};
206
207} // namespace SmallDeformation
208} // namespace LIE
209} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
virtual unsigned getNumberOfNodes() const =0
virtual constexpr unsigned getDimension() const =0
Get dimension of the mesh element.
std::size_t getMeshID() const
return this mesh ID
Definition MeshSubset.h:76
std::size_t getNumberOfElementDOF(std::size_t const mesh_item_id) const
GlobalIndexType getGlobalIndex(MeshLib::Location const &l, int const variable_id, int const component_id) const
int getNumberOfVariableComponents(int variable_id) const
MeshLib::MeshSubset const & getMeshSubset(int const variable_id, int const component_id) const
std::size_t getNumberOfElementComponents(std::size_t const mesh_item_id) const
std::vector< int > getElementVariableIDs(std::size_t const mesh_item_id) const
static constexpr NUMLIB_EXPORT GlobalIndexType const nop
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
static LADataBuilder makeLocalAssemblerBuilder(NumLib::IntegrationOrder const integration_order)
LADataIntfPtr operator()(std::size_t const id, MeshLib::Element const &mesh_item, ConstructorArgs &&... args) const
std::unique_ptr< LocalAssemblerInterface > LADataIntfPtr
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.