OGS
LIE/SmallDeformation/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
18
19namespace ProcessLib
20{
21namespace LIE
22{
23namespace SmallDeformation
24{
30template <typename LocalAssemblerInterface,
31 template <typename, int> class LocalAssemblerDataMatrix,
32 template <typename, int> class LocalAssemblerDataMatrixNearFracture,
33 template <typename, int> class LocalAssemblerDataFracture,
34 int DisplacementDim, typename... ConstructorArgs>
36{
38 {
39 template <typename ElementTraits>
40 constexpr bool operator()(ElementTraits*) const
41 {
42 if constexpr (DisplacementDim < ElementTraits::ShapeFunction::DIM)
43 {
44 return false;
45 }
46
47 // exclude 0D elements
48 return ElementTraits::Element::dimension >= 1;
49 }
50 };
51
52public:
53 using LADataIntfPtr = std::unique_ptr<LocalAssemblerInterface>;
54
56 NumLib::LocalToGlobalIndexMap const& dof_table,
57 NumLib::IntegrationOrder const integration_order)
58 : _dof_table(dof_table)
59 {
60 // REMARKS: At the moment, only a 2D mesh with 1D elements are
61 // supported.
62
63 using EnabledElementTraits =
65 std::declval<IsElementEnabled>()));
66
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))] =
75 });
76 }
77
83 LADataIntfPtr operator()(std::size_t const id,
84 MeshLib::Element const& mesh_item,
85 ConstructorArgs&&... args) const
86 {
87 auto const type_idx = std::type_index(typeid(mesh_item));
88 auto const it = _builder.find(type_idx);
89
90 if (it == _builder.end())
91 {
93 "You are trying to build a local assembler for an unknown mesh "
94 "element type ({:s})."
95 " Maybe you have disabled this mesh element type in your build "
96 "configuration, or a mesh element order does not match shape "
97 "function order given in the project file.",
98 type_idx.name());
99 }
100
101 auto const n_local_dof = _dof_table.getNumberOfElementDOF(id);
102 auto const n_global_components =
103 _dof_table.getNumberOfElementComponents(id);
104 auto const varIDs = _dof_table.getElementVariableIDs(id);
105
106 std::vector<unsigned> dofIndex_to_localIndex;
107 if (mesh_item.getDimension() < DisplacementDim ||
108 n_global_components > DisplacementDim)
109 {
110 dofIndex_to_localIndex.resize(n_local_dof);
111 unsigned dof_id = 0;
112 unsigned local_id = 0;
113 for (auto i : varIDs)
114 {
115 for (int j = 0; j < _dof_table.getNumberOfVariableComponents(i);
116 j++)
117 {
118 auto const& ms = _dof_table.getMeshSubset(i, j);
119 auto const mesh_id = ms.getMeshID();
120 for (unsigned k = 0; k < mesh_item.getNumberOfNodes(); k++)
121 {
122 MeshLib::Location l(mesh_id,
124 getNodeIndex(mesh_item, k));
125 auto global_index = _dof_table.getGlobalIndex(l, i, j);
126 if (global_index != NumLib::MeshComponentMap::nop)
127 {
128 dofIndex_to_localIndex[dof_id++] = local_id;
129 }
130 local_id++;
131 }
132 }
133 }
134 }
135
136 return it->second(mesh_item, varIDs.size(), n_local_dof,
137 dofIndex_to_localIndex,
138 std::forward<ConstructorArgs>(args)...);
139 }
140
141private:
142 using LADataBuilder = std::function<LADataIntfPtr(
143 MeshLib::Element const& e,
144 std::size_t const n_variables,
145 std::size_t const local_matrix_size,
146 std::vector<unsigned> const& dofIndex_to_localIndex,
147 ConstructorArgs&&...)>;
148
154 template <typename ShapeFunction>
156 NumLib::IntegrationOrder const integration_order)
157 {
158 return [integration_order](
159 MeshLib::Element const& e,
160 std::size_t const n_variables,
161 std::size_t const local_matrix_size,
162 std::vector<unsigned> const& dofIndex_to_localIndex,
163 ConstructorArgs&&... args)
164 {
165 auto const& integration_method = NumLib::IntegrationMethodRegistry::
166 template getIntegrationMethod<
167 typename ShapeFunction::MeshElement>(integration_order);
168
169 if (e.getDimension() == DisplacementDim)
170 {
171 if (dofIndex_to_localIndex.empty())
172 {
173 return LADataIntfPtr{
174 new LocalAssemblerDataMatrix<ShapeFunction,
175 DisplacementDim>{
176 e, local_matrix_size, integration_method,
177 std::forward<ConstructorArgs>(args)...}};
178 }
179
180 return LADataIntfPtr{
181 new LocalAssemblerDataMatrixNearFracture<ShapeFunction,
182 DisplacementDim>{
183 e, n_variables, local_matrix_size,
184 dofIndex_to_localIndex, integration_method,
185 std::forward<ConstructorArgs>(args)...}};
186 }
187 return LADataIntfPtr{
188 new LocalAssemblerDataFracture<ShapeFunction, DisplacementDim>{
189 e, n_variables, local_matrix_size, dofIndex_to_localIndex,
190 integration_method,
191 std::forward<ConstructorArgs>(args)...}};
192 };
193 }
194
196 std::unordered_map<std::type_index, LADataBuilder> _builder;
197
199};
200
201} // namespace SmallDeformation
202} // namespace LIE
203} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
virtual unsigned getNumberOfNodes() 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