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
168 if (!component_id)
169 {
170 if (_n_components == 1)
171 {
172 // default value for single component vars.
173 component_id = 0;
174 }
175 else
176 {
177 OGS_FATAL(
178 "Specifying the component id (<component>) for a "
179 "source term for a non-scalar process variable is "
180 "mandatory.");
181 }
182 }
183
184 _source_term_configs.emplace_back(std::move(st_config), st_mesh,
185 *component_id);
186 }
187 }
188 else
189 {
190 INFO("No source terms for process variable '{:s}' found.", _name);
191 }
192
193 if (!_deactivated_subdomains.empty())
194 {
195 _is_active = getOrCreateMeshProperty<unsigned char>(
196 _mesh, _name + "_active", MeshLib::MeshItemType::Cell, 1);
197 std::fill(std::begin(*_is_active), std::end(*_is_active), 1u);
198 }
199}
200
202
203std::string const& ProcessVariable::getName() const
204{
205 return _name;
206}
207
209{
210 return _mesh;
211}
212
213std::vector<std::unique_ptr<BoundaryCondition>>
215 const NumLib::LocalToGlobalIndexMap& dof_table,
216 const int variable_id,
217 unsigned const integration_order,
218 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
219 Process const& process,
220 std::vector<std::reference_wrapper<ProcessVariable>> const&
221 all_process_variables_for_this_process,
222 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media)
223{
224 std::vector<std::unique_ptr<BoundaryCondition>> bcs;
225 bcs.reserve(_bc_configs.size());
226
227 for (auto const& config : _bc_configs)
228 {
229 auto bc = createBoundaryCondition(
230 config, dof_table, _mesh, variable_id, integration_order,
231 _shapefunction_order, parameters, process,
232 all_process_variables_for_this_process, media);
233#ifdef USE_PETSC
234 if (bc == nullptr)
235 {
236 continue;
237 }
238#endif // USE_PETSC
239 bcs.push_back(std::move(bc));
240 }
241
243 parameters, bcs);
244
245 return bcs;
246}
247
249 const NumLib::LocalToGlobalIndexMap& dof_table, const int variable_id,
250 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
251 std::vector<std::unique_ptr<BoundaryCondition>>& bcs)
252{
253 for (auto const& deactivated_subdomain : _deactivated_subdomains)
254 {
255 auto const& deactivated_subdomain_mesh =
256 deactivated_subdomain.deactivated_subdomain_mesh;
257 auto const* parameter = &ParameterLib::findParameter<double>(
259 bool const set_outer_nodes_dirichlet_values =
260 deactivated_subdomain.boundary_value_parameter != nullptr;
261 if (set_outer_nodes_dirichlet_values)
262 {
263 parameter = deactivated_subdomain.boundary_value_parameter;
264 }
265
266 for (int component_id = 0;
267 component_id <
268 dof_table.getNumberOfVariableComponents(variable_id);
269 component_id++)
270 {
271 auto bc = std::make_unique<DeactivatedSubdomainDirichlet>(
272 *_is_active, deactivated_subdomain.time_interval, *parameter,
273 set_outer_nodes_dirichlet_values, deactivated_subdomain_mesh,
274 dof_table, variable_id, component_id);
275
276#ifdef USE_PETSC
277 // TODO: make it work under PETSc too.
278 if (bc == nullptr)
279 {
280 continue;
281 }
282#endif // USE_PETSC
283 bcs.push_back(std::move(bc));
284 }
285 }
286}
287
289{
290 if (_deactivated_subdomains.empty())
291 {
292 return;
293 }
294
296
297 // If none of the deactivated subdomains is active at current time, then the
298 // _ids_of_active_elements remain empty.
299 if (std::none_of(
301 [&](auto const& ds) { return ds.isInTimeSupportInterval(time); }))
302 {
303 // Also mark all of the elements as active.
304 assert(_is_active != nullptr); // guaranteed by constructor
305 std::fill(std::begin(*_is_active), std::end(*_is_active), 1u);
306
307 return;
308 }
309
310 auto is_active_in_subdomain = [&](std::size_t const element_id,
311 DeactivatedSubdomain const& ds) -> bool
312 {
313 return (!ds.isInTimeSupportInterval(time)) ||
314 !ds.isDeactivated(*_mesh.getElement(element_id), time);
315 };
316
317 auto is_active_in_all_subdomains = [&](std::size_t const element_id) -> bool
318 {
319 return std::all_of(begin(_deactivated_subdomains),
321 [&](auto const& ds)
322 { return is_active_in_subdomain(element_id, ds); });
323 };
324
325 auto const number_of_elements = _mesh.getNumberOfElements();
326 for (std::size_t element_id = 0; element_id < number_of_elements;
327 element_id++)
328 {
329 if (is_active_in_all_subdomains(element_id))
330 {
331 _ids_of_active_elements.push_back(element_id);
332 }
333 }
334
335 // all elements are deactivated
336 std::fill(std::begin(*_is_active), std::end(*_is_active), 0u);
337
338 for (auto const id : _ids_of_active_elements)
339 {
340 (*_is_active)[id] = 1u;
341 }
342}
343
344std::vector<std::unique_ptr<SourceTerm>> ProcessVariable::createSourceTerms(
345 const NumLib::LocalToGlobalIndexMap& dof_table,
346 const int variable_id,
347 unsigned const integration_order,
348 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
349 std::vector<std::reference_wrapper<ProcessVariable>> const&
350 all_process_variables_for_this_process)
351{
352 std::vector<std::unique_ptr<SourceTerm>> source_terms;
353
354 transform(cbegin(_source_term_configs), cend(_source_term_configs),
355 back_inserter(source_terms),
356 [&](auto const& config)
357 {
358 return createSourceTerm(
359 config, dof_table, config.mesh, variable_id,
360 integration_order, _shapefunction_order, parameters,
361 all_process_variables_for_this_process);
362 });
363
364 return source_terms;
365}
366
368
369} // 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:363
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 &)
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)
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