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"
22#include "ParameterLib/Utils.h"
32
33namespace
34{
36 BaseLib::ConfigTree const& config,
37 std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes)
38{
39 //
40 // Get the mesh name from the config.
41 //
42 std::string mesh_name; // Either given directly in <mesh> or constructed
43 // from <geometrical_set>_<geometry>.
44
45#ifdef DOXYGEN_DOCU_ONLY
47 config.getConfigParameterOptional<std::string>("mesh");
48#endif // DOXYGEN_DOCU_ONLY
49
50 auto optional_mesh_name =
52 config.getConfigParameterOptional<std::string>("mesh");
53 if (optional_mesh_name)
54 {
55 mesh_name = *optional_mesh_name;
56 }
57 else
58 {
59#ifdef DOXYGEN_DOCU_ONLY
61 config.getConfigParameterOptional<std::string>("geometrical_set");
63 config.getConfigParameter<std::string>("geometry");
64#endif // DOXYGEN_DOCU_ONLY
65
66 // Looking for the mesh created before for the given geometry.
67 auto const geometrical_set_name =
69 config.getConfigParameter<std::string>("geometrical_set");
70 auto const geometry_name =
72 config.getConfigParameter<std::string>("geometry");
73
74 mesh_name = MeshGeoToolsLib::meshNameFromGeometry(geometrical_set_name,
75 geometry_name);
76 }
77
78 //
79 // Find and extract mesh from the list of meshes.
80 //
81 auto const& mesh = MeshLib::findMeshByName(meshes, mesh_name);
82 DBUG("Found mesh '{:s}' with id {:d}.", mesh.getName(), mesh.getID());
83
84 return mesh;
85}
86} // namespace
87
88namespace ProcessLib
89{
91 BaseLib::ConfigTree const& config, MeshLib::Mesh& mesh,
92 std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes,
93 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
94 std::map<std::string,
95 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
96 curves)
97 :
98 _name(config.getConfigParameter<std::string>("name")),
99 _mesh(mesh),
101 _n_components(config.getConfigParameter<int>("components")),
103 _shapefunction_order(config.getConfigParameter<unsigned>("order")),
104 _deactivated_subdomains(
105 createDeactivatedSubdomains(config, mesh, parameters, curves)),
106 _initial_condition(ParameterLib::findParameter<double>(
108 config.getConfigParameter<std::string>("initial_condition"),
109 parameters, _n_components, &mesh)),
110 _compensate_non_equilibrium_initial_residuum(
112 config.getConfigParameter<bool>(
113 "compensate_non_equilibrium_initial_residuum", false))
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 auto const type =
169 st_config.peekConfigParameter<std::string>("type");
170
171 if (!component_id)
172 {
173 if (_n_components == 1)
174 {
175 // default value for single component vars.
176 component_id = 0;
177 }
178 else if (type == "Anchor")
179 {
180 // dummy value
181 component_id = 0;
182 }
183 else
184 {
185 OGS_FATAL(
186 "Specifying the component id (<component>) for a "
187 "source term for a non-scalar process variable is "
188 "mandatory.");
189 }
190 }
191
192 _source_term_configs.emplace_back(std::move(st_config), st_mesh,
193 *component_id);
194 }
195 }
196 else
197 {
198 INFO("No source terms for process variable '{:s}' found.", _name);
199 }
200
201 if (!_deactivated_subdomains.empty())
202 {
203 _is_active = getOrCreateMeshProperty<unsigned char>(
204 _mesh, _name + "_active", MeshLib::MeshItemType::Cell, 1);
205 std::fill(std::begin(*_is_active), std::end(*_is_active), 1u);
206 }
207}
208
210
211std::string const& ProcessVariable::getName() const
212{
213 return _name;
214}
215
217{
218 return _mesh;
219}
220
221std::vector<std::unique_ptr<BoundaryCondition>>
223 const NumLib::LocalToGlobalIndexMap& dof_table,
224 const int variable_id,
225 unsigned const integration_order,
226 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
227 Process const& process,
228 std::vector<std::reference_wrapper<ProcessVariable>> const&
229 all_process_variables_for_this_process,
230 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media)
231{
232 std::vector<std::unique_ptr<BoundaryCondition>> bcs;
233 bcs.reserve(_bc_configs.size());
234
235 for (auto const& config : _bc_configs)
236 {
237 auto bc = createBoundaryCondition(
238 config, dof_table, _mesh, variable_id, integration_order,
239 _shapefunction_order, parameters, process,
240 all_process_variables_for_this_process, media);
241#ifdef USE_PETSC
242 if (bc == nullptr)
243 {
244 continue;
245 }
246#endif // USE_PETSC
247 bcs.push_back(std::move(bc));
248 }
249
251 parameters, bcs);
252
253 return bcs;
254}
255
257 const NumLib::LocalToGlobalIndexMap& dof_table, const int variable_id,
258 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
259 std::vector<std::unique_ptr<BoundaryCondition>>& bcs)
260{
261 for (auto const& deactivated_subdomain : _deactivated_subdomains)
262 {
263 auto const& deactivated_subdomain_mesh =
264 deactivated_subdomain.deactivated_subdomain_mesh;
265 auto const* parameter = &ParameterLib::findParameter<double>(
267 bool const set_outer_nodes_dirichlet_values =
268 deactivated_subdomain.boundary_value_parameter != nullptr;
269 if (set_outer_nodes_dirichlet_values)
270 {
271 parameter = deactivated_subdomain.boundary_value_parameter;
272 }
273
274 for (int component_id = 0;
275 component_id <
276 dof_table.getNumberOfVariableComponents(variable_id);
277 component_id++)
278 {
279 auto bc = std::make_unique<DeactivatedSubdomainDirichlet>(
280 *_is_active, deactivated_subdomain.time_interval, *parameter,
281 set_outer_nodes_dirichlet_values, deactivated_subdomain_mesh,
282 dof_table, variable_id, component_id);
283
284#ifdef USE_PETSC
285 // TODO: make it work under PETSc too.
286 if (bc == nullptr)
287 {
288 continue;
289 }
290#endif // USE_PETSC
291 bcs.push_back(std::move(bc));
292 }
293 }
294}
295
297{
298 if (_deactivated_subdomains.empty())
299 {
300 return;
301 }
302
304
305 // If none of the deactivated subdomains is active at current time, then the
306 // _ids_of_active_elements remain empty.
307 if (std::none_of(
309 [&](auto const& ds) { return ds.isInTimeSupportInterval(time); }))
310 {
311 // Also mark all of the elements as active.
312 assert(_is_active != nullptr); // guaranteed by constructor
313 std::fill(std::begin(*_is_active), std::end(*_is_active), 1u);
314
315 return;
316 }
317
318 auto is_active_in_subdomain = [&](std::size_t const element_id,
319 DeactivatedSubdomain const& ds) -> bool
320 {
321 return (!ds.isInTimeSupportInterval(time)) ||
322 !ds.isDeactivated(*_mesh.getElement(element_id), time);
323 };
324
325 auto is_active_in_all_subdomains = [&](std::size_t const element_id) -> bool
326 {
327 return std::all_of(begin(_deactivated_subdomains),
329 [&](auto const& ds)
330 { return is_active_in_subdomain(element_id, ds); });
331 };
332
333 auto const number_of_elements = _mesh.getNumberOfElements();
334 for (std::size_t element_id = 0; element_id < number_of_elements;
335 element_id++)
336 {
337 if (is_active_in_all_subdomains(element_id))
338 {
339 _ids_of_active_elements.push_back(element_id);
340 }
341 }
342
343 // all elements are deactivated
344 std::fill(std::begin(*_is_active), std::end(*_is_active), 0u);
345
346 for (auto const id : _ids_of_active_elements)
347 {
348 (*_is_active)[id] = 1u;
349 }
350}
351
352std::vector<std::unique_ptr<SourceTerm>> ProcessVariable::createSourceTerms(
353 const NumLib::LocalToGlobalIndexMap& dof_table,
354 const int variable_id,
355 unsigned const integration_order,
356 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
357 std::vector<std::reference_wrapper<ProcessVariable>> const&
358 all_process_variables_for_this_process)
359{
360 std::vector<std::unique_ptr<SourceTerm>> source_terms;
361
362 transform(cbegin(_source_term_configs), cend(_source_term_configs),
363 back_inserter(source_terms),
364 [&](auto const& config)
365 {
366 return createSourceTerm(
367 config, dof_table, config.mesh, variable_id,
368 integration_order, _shapefunction_order, parameters,
369 all_process_variables_for_this_process);
370 });
371
372 return source_terms;
373}
374
376
377} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
Definition of the Mesh class.
Definition of the Node class.
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
std::optional< T > getConfigParameterOptional(std::string const &param) const
T getConfigParameter(std::string const &param) const
const Element * getElement(std::size_t idx) const
Get the element with the given index.
Definition Mesh.h:94
std::size_t getNumberOfElements() const
Get the number of elements.
Definition Mesh.h:97
int getNumberOfVariableComponents(int variable_id) const
void updateDeactivatedSubdomains(double const time)
std::vector< BoundaryConditionConfig > _bc_configs
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)
MeshLib::Mesh const & getMesh() const
Returns a mesh on which the process variable is defined.
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, std::vector< std::reference_wrapper< ProcessVariable > > const &all_process_variables_for_this_process)
std::vector< DeactivatedSubdomain > _deactivated_subdomains
std::string const & getName() const
MeshLib::PropertyVector< unsigned char > * _is_active
std::vector< std::size_t > _ids_of_active_elements
std::vector< SourceTermConfig > _source_term_configs
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::reference_wrapper< ProcessVariable > > const &all_process_variables_for_this_process, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium > > const &media)
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 meshNameFromGeometry(std::string const &geometrical_set_name, std::string const &geometry_name)
Mesh & findMeshByName(std::vector< std::unique_ptr< Mesh > > const &meshes, std::string_view const name)
Definition Mesh.cpp:364
OGS_NO_DANGLING 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< 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, std::vector< std::reference_wrapper< ProcessVariable > > const &all_process_variables_for_this_process)
std::vector< DeactivatedSubdomain > 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< 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::reference_wrapper< ProcessVariable > > const &all_process_variables_for_this_process, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium > > const &media)
MeshLib::Mesh const & findMeshInConfig(BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes)
static PROCESSLIB_EXPORT const std::string zero_parameter_name