OGS
ProcessVariable.cpp
Go to the documentation of this file.
1 
11 #include "ProcessVariable.h"
12 
13 #include <algorithm>
14 #include <utility>
15 
16 #include "BaseLib/Algorithm.h"
17 #include "BaseLib/Logging.h"
19 #include "MeshLib/Mesh.h"
20 #include "MeshLib/Node.h"
21 #include "ParameterLib/Utils.h"
28 
29 namespace
30 {
32  BaseLib::ConfigTree const& config,
33  std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes)
34 {
35  //
36  // Get the mesh name from the config.
37  //
38  std::string mesh_name; // Either given directly in <mesh> or constructed
39  // from <geometrical_set>_<geometry>.
40 
41 #ifdef DOXYGEN_DOCU_ONLY
43  config.getConfigParameterOptional<std::string>("mesh");
44 #endif // DOXYGEN_DOCU_ONLY
45 
46  auto optional_mesh_name =
48  config.getConfigParameterOptional<std::string>("mesh");
49  if (optional_mesh_name)
50  {
51  mesh_name = *optional_mesh_name;
52  }
53  else
54  {
55 #ifdef DOXYGEN_DOCU_ONLY
57  config.getConfigParameterOptional<std::string>("geometrical_set");
59  config.getConfigParameter<std::string>("geometry");
60 #endif // DOXYGEN_DOCU_ONLY
61 
62  // Looking for the mesh created before for the given geometry.
63  auto const geometrical_set_name =
65  config.getConfigParameter<std::string>("geometrical_set");
66  auto const geometry_name =
68  config.getConfigParameter<std::string>("geometry");
69 
70  mesh_name = MeshGeoToolsLib::meshNameFromGeometry(geometrical_set_name,
71  geometry_name);
72  }
73 
74  //
75  // Find and extract mesh from the list of meshes.
76  //
77  auto const& mesh = *BaseLib::findElementOrError(
78  begin(meshes), end(meshes),
79  [&mesh_name](auto const& mesh)
80  {
81  assert(mesh != nullptr);
82  return mesh->getName() == mesh_name;
83  },
84  "Required mesh with name '" + mesh_name + "' not found.");
85  DBUG("Found mesh '{:s}' with id {:d}.", mesh.getName(), mesh.getID());
86 
87  return mesh;
88 }
89 } // namespace
90 
91 namespace ProcessLib
92 {
94  BaseLib::ConfigTree const& config,
95  MeshLib::Mesh& mesh,
96  std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes,
97  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
98  std::map<std::string,
99  std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
100  curves)
101  :
102  _name(config.getConfigParameter<std::string>("name")),
103  _mesh(mesh),
105  _n_components(config.getConfigParameter<int>("components")),
107  _shapefunction_order(config.getConfigParameter<unsigned>("order")),
108  _deactivated_subdomains(
109  createDeactivatedSubdomains(config, mesh, parameters, curves)),
110  _initial_condition(ParameterLib::findParameter<double>(
112  config.getConfigParameter<std::string>("initial_condition"),
113  parameters, _n_components, &mesh))
114 {
115  DBUG("Constructing process variable {:s}", _name);
116 
118  {
119  OGS_FATAL("The given shape function order {:d} is not supported",
121  }
122 
123  // Boundary conditions
124  if (auto bcs_config =
126  config.getConfigSubtreeOptional("boundary_conditions"))
127  {
128  for (
129  auto bc_config :
131  bcs_config->getConfigSubtreeList("boundary_condition"))
132  {
133  auto const& bc_mesh = findMeshInConfig(bc_config, meshes);
134  auto component_id =
136  bc_config.getConfigParameterOptional<int>("component");
137 
138  if (!component_id && _n_components == 1)
139  {
140  // default value for single component vars.
141  component_id = 0;
142  }
143 
144  _bc_configs.emplace_back(std::move(bc_config), bc_mesh,
145  component_id);
146  }
147  }
148  else
149  {
150  INFO("No boundary conditions for process variable '{:s}' found.",
151  _name);
152  }
153 
154  // Source terms
156  if (auto sts_config = config.getConfigSubtreeOptional("source_terms"))
157  {
158  for (
159  auto st_config :
161  sts_config->getConfigSubtreeList("source_term"))
162  {
163  MeshLib::Mesh const& st_mesh = findMeshInConfig(st_config, meshes);
164  auto component_id =
166  st_config.getConfigParameterOptional<int>("component");
167 
168  if (!component_id && _n_components == 1)
169  {
170  // default value for single component vars.
171  component_id = 0;
172  }
173 
174  _source_term_configs.emplace_back(std::move(st_config), st_mesh,
175  component_id);
176  }
177  }
178  else
179  {
180  INFO("No source terms for process variable '{:s}' found.", _name);
181  }
182 }
183 
185  : _name(std::move(other._name)),
186  _mesh(other._mesh),
187  _n_components(other._n_components),
188  _shapefunction_order(other._shapefunction_order),
189  _deactivated_subdomains(std::move(other._deactivated_subdomains)),
190  _initial_condition(std::move(other._initial_condition)),
191  _bc_configs(std::move(other._bc_configs)),
192  _source_term_configs(std::move(other._source_term_configs))
193 {
194 }
195 
196 std::string const& ProcessVariable::getName() const
197 {
198  return _name;
199 }
200 
202 {
203  return _mesh;
204 }
205 
206 std::vector<std::unique_ptr<BoundaryCondition>>
208  const NumLib::LocalToGlobalIndexMap& dof_table,
209  const int variable_id,
210  unsigned const integration_order,
211  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
212  Process const& process)
213 {
214  std::vector<std::unique_ptr<BoundaryCondition>> bcs;
215  bcs.reserve(_bc_configs.size());
216 
217  for (auto& config : _bc_configs)
218  {
219  auto bc = createBoundaryCondition(
220  config, dof_table, _mesh, variable_id, integration_order,
221  _shapefunction_order, parameters, process);
222 #ifdef USE_PETSC
223  if (bc == nullptr)
224  {
225  continue;
226  }
227 #endif // USE_PETSC
228  bcs.push_back(std::move(bc));
229  }
230 
231  if (_deactivated_subdomains.empty())
232  {
233  return bcs;
234  }
235 
237  parameters, bcs);
238  return bcs;
239 }
240 
242  const NumLib::LocalToGlobalIndexMap& dof_table, const int variable_id,
243  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
244  std::vector<std::unique_ptr<BoundaryCondition>>& bcs)
245 {
246  for (auto const& deactivated_subdomain : _deactivated_subdomains)
247  {
248  auto const& deactivated_subdomain_meshes =
249  deactivated_subdomain->deactivated_subdomain_meshes;
250  for (auto const& deactivated_subdomain_mesh :
251  deactivated_subdomain_meshes)
252  {
253  auto const* parameter = &ParameterLib::findParameter<double>(
255  bool const set_outer_nodes_dirichlet_values =
256  deactivated_subdomain->boundary_value_parameter != nullptr;
257  if (set_outer_nodes_dirichlet_values)
258  {
259  parameter = deactivated_subdomain->boundary_value_parameter;
260  }
261 
262  for (int component_id = 0;
263  component_id <
264  dof_table.getNumberOfVariableComponents(variable_id);
265  component_id++)
266  {
267  auto bc = std::make_unique<DeactivatedSubdomainDirichlet>(
269  deactivated_subdomain->time_interval, *parameter,
270  set_outer_nodes_dirichlet_values,
271  *deactivated_subdomain_mesh, dof_table, variable_id,
272  component_id);
273 
274 #ifdef USE_PETSC
275  // TODO: make it work under PETSc too.
276  if (bc == nullptr)
277  {
278  continue;
279  }
280 #endif // USE_PETSC
281  bcs.push_back(std::move(bc));
282  }
283  }
284  }
285 }
286 
288 {
289  _ids_of_active_elements.clear();
290 
291  // If none of the deactivated subdomains is active at current time, then the
292  // _ids_of_active_elements remain empty.
293  if (std::none_of(
295  [&](auto const& ds) { return ds->isInTimeSupportInterval(time); }))
296  {
297  return;
298  }
299 
300  auto const* const material_ids = MeshLib::materialIDs(_mesh);
301 
302  auto is_active_in_subdomain = [&](std::size_t const i,
303  DeactivatedSubdomain const& ds) -> bool
304  {
305  if (!ds.isInTimeSupportInterval(time))
306  {
307  return true;
308  }
309 
310  auto const& deactivated_materialIDs = ds.materialIDs;
311 
312  auto const& element_center = getCenterOfGravity(*_mesh.getElement(i));
313  if (std::binary_search(deactivated_materialIDs.begin(),
314  deactivated_materialIDs.end(),
315  (*material_ids)[i]) &&
316  ds.isDeactivated(element_center, time))
317  {
318  return false;
319  }
320  return true;
321  };
322 
323  auto const number_of_elements = _mesh.getNumberOfElements();
324  for (std::size_t i = 0; i < number_of_elements; i++)
325  {
326  if (std::all_of(
328  [&](auto const& ds) { return is_active_in_subdomain(i, *ds); }))
329  {
331  }
332  }
333 }
334 
335 std::vector<std::unique_ptr<SourceTerm>> ProcessVariable::createSourceTerms(
336  const NumLib::LocalToGlobalIndexMap& dof_table,
337  const int variable_id,
338  unsigned const integration_order,
339  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters)
340 {
341  std::vector<std::unique_ptr<SourceTerm>> source_terms;
342 
343  transform(cbegin(_source_term_configs), cend(_source_term_configs),
344  back_inserter(source_terms),
345  [&](auto const& config)
346  {
347  return createSourceTerm(config, dof_table, config.mesh,
348  variable_id, integration_order,
349  _shapefunction_order, parameters);
350  });
351 
352  return source_terms;
353 }
354 
355 } // namespace ProcessLib
#define OGS_FATAL(...)
Definition: Error.h:26
void INFO(char const *fmt, Args const &... args)
Definition: Logging.h:32
void DBUG(char const *fmt, Args const &... args)
Definition: Logging.h:27
Definition of the Mesh class.
Definition of the Node class.
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
Definition: ConfigTree.cpp:155
std::optional< T > getConfigParameterOptional(std::string const &param) const
T getConfigParameter(std::string const &param) const
virtual std::size_t getID() const final
Returns the ID of the element.
Definition: Element.h:82
const Element * getElement(std::size_t idx) const
Get the element with the given index.
Definition: Mesh.h:77
std::size_t getNumberOfElements() const
Get the number of elements.
Definition: Mesh.h:86
int getNumberOfVariableComponents(int variable_id) const
void updateDeactivatedSubdomains(double const time)
std::vector< BoundaryConditionConfig > _bc_configs
MeshLib::Mesh const & getMesh() const
Returns a mesh on which the process variable is defined.
void createBoundaryConditionsForDeactivatedSubDomains(const NumLib::LocalToGlobalIndexMap &dof_table, const int variable_id, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, std::vector< std::unique_ptr< BoundaryCondition >> &bcs)
std::string const & getName() const
std::vector< std::unique_ptr< SourceTerm > > createSourceTerms(const NumLib::LocalToGlobalIndexMap &dof_table, const int variable_id, unsigned const integration_order, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters)
ProcessVariable(BaseLib::ConfigTree const &config, MeshLib::Mesh &mesh, std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation >> const &curves)
std::vector< std::unique_ptr< BoundaryCondition > > createBoundaryConditions(const NumLib::LocalToGlobalIndexMap &dof_table, const int variable_id, unsigned const integration_order, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, Process const &process)
std::vector< std::size_t > _ids_of_active_elements
std::vector< SourceTermConfig > _source_term_configs
std::vector< std::unique_ptr< DeactivatedSubdomain const > > _deactivated_subdomains
constexpr bool none_of(List const &values)
Checks if none of the elements in the given list are true.
Definition: Algorithm.h:357
constexpr bool all_of(List const &values)
Checks if all of the elements in the given list are true.
Definition: Algorithm.h:341
std::iterator_traits< InputIt >::reference findElementOrError(InputIt begin, InputIt end, Predicate predicate, std::string const &error="")
Definition: Algorithm.h:69
std::string meshNameFromGeometry(std::string const &geometrical_set_name, std::string const &geometry_name)
PropertyVector< int > const * materialIDs(Mesh const &mesh)
Definition: Mesh.cpp:258
MeshLib::Node getCenterOfGravity(Element const &element)
Calculates the center of gravity for the mesh element.
Definition: Element.cpp:126
Parameter< ParameterDataType > & findParameter(std::string const &parameter_name, std::vector< std::unique_ptr< ParameterBase >> const &parameters, int const num_components, MeshLib::Mesh const *const mesh=nullptr)
Definition: Utils.h:102
std::unique_ptr< BoundaryCondition > createBoundaryCondition(const BoundaryConditionConfig &config, const NumLib::LocalToGlobalIndexMap &dof_table, const MeshLib::Mesh &bulk_mesh, const int variable_id, const unsigned integration_order, const unsigned shapefunction_order, const std::vector< std::unique_ptr< ParameterLib::ParameterBase >> &parameters, const Process &process)
std::vector< std::unique_ptr< DeactivatedSubdomain const > > createDeactivatedSubdomains(BaseLib::ConfigTree const &config, MeshLib::Mesh const &mesh, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation >> const &curves)
std::unique_ptr< SourceTerm > createSourceTerm(const SourceTermConfig &config, const NumLib::LocalToGlobalIndexMap &dof_table_bulk, const MeshLib::Mesh &source_term_mesh, const int variable_id, const unsigned integration_order, const unsigned shapefunction_order, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters)
MeshLib::Mesh const & findMeshInConfig(BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< MeshLib::Mesh >> const &meshes)
static const std::string zero_parameter_name