OGS
PrimaryVariableConstraintDirichletBoundaryCondition.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#include <algorithm>
7#include <vector>
8
10#include "BaseLib/Logging.h"
15#include "ParameterLib/Utils.h"
16#include "ProcessLib/Process.h"
17
18namespace ProcessLib
19{
22 ParameterLib::Parameter<double> const& parameter,
23 MeshLib::Mesh const& bc_mesh,
24 NumLib::LocalToGlobalIndexMap const& dof_table_bulk,
25 int const variable_id, int const component_id,
26 ParameterLib::Parameter<double> const& threshold_parameter,
27 bool const less)
28 : _parameter(parameter),
29 _bc_mesh(bc_mesh),
30 _variable_id(variable_id),
31 _component_id(component_id),
32 _threshold_parameter(threshold_parameter),
33 _less(less)
34{
37
38 std::vector<MeshLib::Node*> const& bc_nodes = bc_mesh.getNodes();
39 MeshLib::MeshSubset bc_mesh_subset(_bc_mesh, bc_nodes);
40
41 // Create local DOF table from the BC mesh subset for the given variable
42 // and component id.
44 variable_id, {component_id}, std::move(bc_mesh_subset));
45}
46
48 const double t, GlobalVector const& x,
50{
52
53 bc_values.ids.clear();
54 bc_values.values.clear();
55
56 auto const& nodes_in_bc_mesh = _bc_mesh.getNodes();
57 // convert mesh node ids to global index for the given component
58 bc_values.ids.reserve(bc_values.ids.size() + nodes_in_bc_mesh.size());
59 bc_values.values.reserve(bc_values.values.size() + nodes_in_bc_mesh.size());
60 for (auto const* const node : nodes_in_bc_mesh)
61 {
62 auto const id = node->getID();
63 // TODO: that might be slow, but only done once
64 auto const global_index = _dof_table_boundary->getGlobalIndex(
67 if (global_index == NumLib::MeshComponentMap::nop)
68 {
69 continue;
70 }
71 // For the DDC approach (e.g. with PETSc option), the negative
72 // index of global_index means that the entry by that index is a ghost
73 // one, which should be dropped. Especially for PETSc routines
74 // MatZeroRows and MatZeroRowsColumns, which are called to apply the
75 // Dirichlet BC, the negative index is not accepted like other matrix or
76 // vector PETSc routines. Therefore, the following if-condition is
77 // applied.
78 if (global_index >= 0)
79 {
80 // fetch the value of the primary variable
81 auto const local_x = x.get(std::vector{global_index});
82 pos.setNodeID(id);
83 pos.setCoordinates(*node);
84 if (_less && local_x[0] < _threshold_parameter(t, pos).front())
85 {
86 bc_values.ids.emplace_back(global_index);
87 bc_values.values.emplace_back(_parameter(t, pos).front());
88 }
89 else if (!_less &&
90 local_x[0] > _threshold_parameter(t, pos).front())
91 {
92 bc_values.ids.emplace_back(global_index);
93 bc_values.values.emplace_back(_parameter(t, pos).front());
94 }
95 }
96 }
97}
98
101 BaseLib::ConfigTree const& config)
102{
103 DBUG("Parsing PrimaryVariableConstraintDirichletBoundaryCondition config.");
105 config.checkConfigParameter("type", "PrimaryVariableConstraintDirichlet");
106
108 auto const name = config.getConfigParameter<std::string>("parameter");
109 DBUG("parameter {:s}", name);
110
111 auto const threshold_parameter_name =
113 config.getConfigParameter<std::string>("threshold_parameter");
114 DBUG("parameter {:s} as threshold_parameter", threshold_parameter_name);
115
116 auto const comparison_operator_string =
118 config.getConfigParameter<std::string>("comparison_operator");
119
120 return {name, threshold_parameter_name, comparison_operator_string};
121}
122
123std::unique_ptr<PrimaryVariableConstraintDirichletBoundaryCondition>
126 MeshLib::Mesh const& bc_mesh,
127 NumLib::LocalToGlobalIndexMap const& dof_table_bulk, int const variable_id,
128 int const component_id,
129 const std::vector<std::unique_ptr<ParameterLib::ParameterBase>>& parameters)
130{
131 DBUG("Constructing PrimaryVariableConstraintDirichletBoundaryCondition.");
132
133 auto& parameter = ParameterLib::findParameter<double>(
134 config.parameter_name, parameters, 1, &bc_mesh);
135
136 auto& threshold_parameter = ParameterLib::findParameter<double>(
137 config.threshold_parameter_name, parameters, 1, &bc_mesh);
138
139 if (config.comparison_operator_string != "greater" &&
140 config.comparison_operator_string != "less")
141 {
142 OGS_FATAL(
143 "The comparison operator is '{:s}', but has to be either "
144 "'greater' or 'less'.",
146 }
147 bool const less = config.comparison_operator_string == "less";
148
149// In case of partitioned mesh the boundary could be empty, i.e. there is no
150// boundary condition.
151#ifdef USE_PETSC
152 // This can be extracted to createBoundaryCondition() but then the config
153 // parameters are not read and will cause an error.
154 // TODO (naumov): Add a function to ConfigTree for skipping the tags of the
155 // subtree and move the code up in createBoundaryCondition().
156 if (bc_mesh.getDimension() == 0 && bc_mesh.getNumberOfNodes() == 0 &&
157 bc_mesh.getNumberOfElements() == 0)
158 {
159 return nullptr;
160 }
161#endif // USE_PETSC
162
163 return std::make_unique<
165 parameter, bc_mesh, dof_table_bulk, variable_id, component_id,
166 threshold_parameter, less);
167}
168
169} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:19
MathLib::EigenVector GlobalVector
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
T getConfigParameter(std::string const &param) const
void checkConfigParameter(std::string const &param, std::string_view const value) const
double get(IndexType rowId) const
get entry
Definition EigenVector.h:52
A subset of nodes on a single mesh.
Definition MeshSubset.h:17
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition Mesh.h:97
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
Definition Mesh.h:79
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:91
std::size_t getNumberOfElements() const
Get the number of elements.
Definition Mesh.h:88
std::unique_ptr< LocalToGlobalIndexMap > deriveBoundaryConstrainedMap(int const variable_id, std::vector< int > const &component_ids, MeshLib::MeshSubset &&new_mesh_subset) const
static constexpr NUMLIB_EXPORT GlobalIndexType const nop
void setNodeID(std::size_t node_id)
void setCoordinates(MathLib::Point3d const &coordinates)
void getEssentialBCValues(const double t, GlobalVector const &x, NumLib::IndexValueVector< GlobalIndexType > &bc_values) const override
Writes the values of essential BCs to bc_values.
PrimaryVariableConstraintDirichletBoundaryCondition(ParameterLib::Parameter< double > const &parameter, MeshLib::Mesh const &bc_mesh, NumLib::LocalToGlobalIndexMap const &dof_table_bulk, int const variable_id, int const component_id, ParameterLib::Parameter< double > const &threshold_parameter, bool const less)
ParameterLib::Parameter< double > const & _parameter
< parameter that defines the Dirirchlet-type condition values
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)
PrimaryVariableConstraintDirichletBoundaryConditionConfig parsePrimaryVariableConstraintDirichletBoundaryCondition(BaseLib::ConfigTree const &config)
void checkParametersOfDirichletBoundaryCondition(MeshLib::Mesh const &bc_mesh, NumLib::LocalToGlobalIndexMap const &dof_table_bulk, int const variable_id, int const component_id)
std::unique_ptr< PrimaryVariableConstraintDirichletBoundaryCondition > createPrimaryVariableConstraintDirichletBoundaryCondition(PrimaryVariableConstraintDirichletBoundaryConditionConfig const &config, MeshLib::Mesh const &bc_mesh, NumLib::LocalToGlobalIndexMap const &dof_table_bulk, int const variable_id, int const component_id, const std::vector< std::unique_ptr< ParameterLib::ParameterBase > > &parameters)
std::vector< IndexType > ids
std::vector< double > values