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