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