OGS
ProcessLib::ConstraintDirichletBoundaryCondition Class Referencefinal

Detailed Description

The ConstraintDirichletBoundaryCondition class describes a Dirichlet-type boundary condition that is constant in space and time where the domain can shrink and grow within the simulation. The expected parameter in the passed configuration is "value" which, when not present defaults to zero.

Definition at line 18 of file ConstraintDirichletBoundaryCondition.h.

#include <ConstraintDirichletBoundaryCondition.h>

Inheritance diagram for ProcessLib::ConstraintDirichletBoundaryCondition:
[legend]
Collaboration diagram for ProcessLib::ConstraintDirichletBoundaryCondition:
[legend]

Public Member Functions

 ConstraintDirichletBoundaryCondition (ParameterLib::Parameter< double > const &parameter, NumLib::LocalToGlobalIndexMap const &dof_table_bulk, int const variable_id, int const component_id, MeshLib::Mesh const &bc_mesh, unsigned const integration_order, MeshLib::Mesh const &bulk_mesh, double const constraint_threshold, bool const lower, std::function< Eigen::Vector3d(std::size_t const, MathLib::Point3d const &, double const, std::vector< GlobalVector * > const &)> getFlux)
void preTimestep (double const t, std::vector< GlobalVector * > const &x, int const process_id) override
void getEssentialBCValues (const double t, const GlobalVector &x, NumLib::IndexValueVector< GlobalIndexType > &bc_values) const override
 Writes the values of essential BCs to bc_values.
Public Member Functions inherited from ProcessLib::BoundaryCondition
virtual void applyNaturalBC (const double, std::vector< GlobalVector * > const &, int const, GlobalMatrix *, GlobalVector &, GlobalMatrix *)
virtual void postTimestep (const double, std::vector< GlobalVector * > const &, int const)
virtual ~BoundaryCondition ()=default

Private Attributes

ParameterLib::Parameter< double > const & _parameter
std::unique_ptr< NumLib::LocalToGlobalIndexMap_dof_table_boundary
int const _variable_id
int const _component_id
MeshLib::Mesh const & _bc_mesh
unsigned const _integration_order
 Integration order for integration over the lower-dimensional elements.
std::vector< std::pair< std::size_t, unsigned > > _bulk_ids
std::vector< double > _flux_values
 Stores the results of the flux computations per boundary element.
std::vector< std::unique_ptr< ConstraintDirichletBoundaryConditionLocalAssemblerInterface > > _local_assemblers
 Local assemblers for each boundary element.
double const _constraint_threshold
bool const _lower
MeshLib::Mesh const & _bulk_mesh
std::function< Eigen::Vector3d(std::size_t const, MathLib::Point3d const &, double const, std::vector< GlobalVector * > const &)> _getFlux
 The function _getFlux calculates the flux through the boundary element.

Constructor & Destructor Documentation

◆ ConstraintDirichletBoundaryCondition()

ProcessLib::ConstraintDirichletBoundaryCondition::ConstraintDirichletBoundaryCondition ( ParameterLib::Parameter< double > const & parameter,
NumLib::LocalToGlobalIndexMap const & dof_table_bulk,
int const variable_id,
int const component_id,
MeshLib::Mesh const & bc_mesh,
unsigned const integration_order,
MeshLib::Mesh const & bulk_mesh,
double const constraint_threshold,
bool const lower,
std::function< Eigen::Vector3d(std::size_t const, MathLib::Point3d const &, double const, std::vector< GlobalVector * > const &)> getFlux )
Parameters
parameterUsed for setting the values for the boundary condition.
dof_table_bulkThe bulk local to global index map is used to derive the local to global index map for the boundary.
variable_idThe variable id is needed to determine the global index.
component_idThe component id is needed to determine the global index.
bc_meshLower dimensional mesh the boundary condition is defined on. The bc_mesh must have the two PropertyVector objects 'bulk_element_ids' and 'bulk_node_ids' containing the corresponding information.
integration_orderOrder the order of integration used to compute the constraint.
bulk_meshThe FE mesh for the simulation.
constraint_thresholdThe threshold value used for the switch off/on decision.
lowerBoolean value used for the calculation of the constraint criterion, i.e., if lower is set to true the criterion 'calculated_value < constraint_threshold' is evaluated to switch on/off the boundary condition, else 'calculated_value > constraint_threshold' is evaluated.
getFluxThe function used for the flux calculation.
Note
The function has to be stored by value, else the process value is not captured properly.

Definition at line 17 of file ConstraintDirichletBoundaryCondition.cpp.

27 : _parameter(parameter),
28 _variable_id(variable_id),
29 _component_id(component_id),
30 _bc_mesh(bc_mesh),
31 _integration_order(integration_order),
32 _constraint_threshold(constraint_threshold),
33 _lower(lower),
34 _bulk_mesh(bulk_mesh),
35 _getFlux(getFlux)
36{
37 if (variable_id >=
38 static_cast<int>(dof_table_bulk.getNumberOfVariables()) ||
39 component_id >=
40 dof_table_bulk.getNumberOfVariableComponents(variable_id))
41 {
43 "Variable id or component id too high. Actual values: ({:d}, "
44 "{:d}), maximum values: ({:d}, {:d}).",
45 variable_id, component_id, dof_table_bulk.getNumberOfVariables(),
46 dof_table_bulk.getNumberOfVariableComponents(variable_id));
47 }
48
49 std::vector<MeshLib::Node*> const& bc_nodes = _bc_mesh.getNodes();
50 DBUG(
51 "Found {:d} nodes for constraint Dirichlet BCs for the variable {:d} "
52 "and component {:d}",
53 bc_nodes.size(), variable_id, component_id);
54
55 MeshLib::MeshSubset bc_mesh_subset{_bc_mesh, bc_nodes};
56
57 // Create local DOF table from intersected mesh subsets for the given
58 // variable and component ids.
59 _dof_table_boundary = dof_table_bulk.deriveBoundaryConstrainedMap(
60 variable_id, {component_id}, std::move(bc_mesh_subset));
61
62 auto const& bc_elements(_bc_mesh.getElements());
63 _local_assemblers.resize(bc_elements.size());
64 _flux_values.resize(bc_elements.size());
65 // create _bulk_ids vector
66 auto const* bulk_element_ids = MeshLib::bulkElementIDs(_bc_mesh);
67 auto const* bulk_node_ids = MeshLib::bulkNodeIDs(_bc_mesh);
68 auto const& bulk_nodes = bulk_mesh.getNodes();
69
70 auto get_bulk_element_face_id =
71 [&](auto const bulk_element_id, MeshLib::Element const* bc_elem)
72 {
73 auto const* bulk_elem = _bulk_mesh.getElement(bulk_element_id);
74 std::array<MeshLib::Node const*, 3> nodes{
75 {bulk_nodes[(*bulk_node_ids)[bc_elem->getNode(0)->getID()]],
76 bulk_nodes[(*bulk_node_ids)[bc_elem->getNode(1)->getID()]],
77 bulk_nodes[(*bulk_node_ids)[bc_elem->getNode(2)->getID()]]}};
78 return bulk_elem->identifyFace(nodes.data());
79 };
80
81 _bulk_ids.reserve(bc_elements.size());
82 std::transform(
83 begin(bc_elements), end(bc_elements), std::back_inserter(_bulk_ids),
84 [&](auto const* bc_element)
85 {
86 auto const bulk_element_id =
87 (*bulk_element_ids)[bc_element->getID()];
88 return std::make_pair(
89 bulk_element_id,
90 get_bulk_element_face_id(bulk_element_id, bc_element));
91 });
92
93 const int shape_function_order = 1;
94
96 ConstraintDirichletBoundaryConditionLocalAssembler>(
97 _bulk_mesh.getDimension(), _bc_mesh.getElements(), *_dof_table_boundary,
98 shape_function_order, _local_assemblers,
99 NumLib::IntegrationOrder{_integration_order},
100 _bc_mesh.isAxiallySymmetric(), bulk_mesh, _bulk_ids);
101}
#define OGS_FATAL(...)
Definition Error.h:19
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
std::function< Eigen::Vector3d(std::size_t const, MathLib::Point3d const &, double const, std::vector< GlobalVector * > const &)> _getFlux
The function _getFlux calculates the flux through the boundary element.
std::vector< std::unique_ptr< ConstraintDirichletBoundaryConditionLocalAssemblerInterface > > _local_assemblers
Local assemblers for each boundary element.
std::unique_ptr< NumLib::LocalToGlobalIndexMap > _dof_table_boundary
std::vector< std::pair< std::size_t, unsigned > > _bulk_ids
std::vector< double > _flux_values
Stores the results of the flux computations per boundary element.
unsigned const _integration_order
Integration order for integration over the lower-dimensional elements.
PropertyVector< std::size_t > const * bulkElementIDs(Mesh const &mesh)
Definition Mesh.cpp:290
PropertyVector< std::size_t > const * bulkNodeIDs(Mesh const &mesh)
Definition Mesh.cpp:282
void createLocalAssemblers(const unsigned dimension, std::vector< MeshLib::Element * > const &mesh_elements, NumLib::LocalToGlobalIndexMap const &dof_table, const unsigned shapefunction_order, std::vector< std::unique_ptr< LocalAssemblerInterface > > &local_assemblers, NumLib::IntegrationOrder const integration_order, ExtraCtorArgs &&... extra_ctor_args)

References _bc_mesh, _bulk_mesh, _component_id, _constraint_threshold, _dof_table_boundary, _flux_values, _getFlux, _integration_order, _local_assemblers, _lower, _parameter, _variable_id, MeshLib::bulkElementIDs(), MeshLib::bulkNodeIDs(), DBUG(), NumLib::LocalToGlobalIndexMap::deriveBoundaryConstrainedMap(), MeshLib::Mesh::getNodes(), NumLib::LocalToGlobalIndexMap::getNumberOfVariableComponents(), and NumLib::LocalToGlobalIndexMap::getNumberOfVariables().

Member Function Documentation

◆ getEssentialBCValues()

void ProcessLib::ConstraintDirichletBoundaryCondition::getEssentialBCValues ( const double ,
const GlobalVector & ,
NumLib::IndexValueVector< GlobalIndexType > &  ) const
overridevirtual

Writes the values of essential BCs to bc_values.

Reimplemented from ProcessLib::BoundaryCondition.

Definition at line 120 of file ConstraintDirichletBoundaryCondition.cpp.

123{
124 bc_values.ids.clear();
125 bc_values.values.clear();
126
127 std::vector<std::pair<GlobalIndexType, double>> tmp_bc_values;
128
129 auto isFlux = [&](const std::size_t element_id)
130 {
131 return _lower ? _flux_values[element_id] < _constraint_threshold
132 : _flux_values[element_id] > _constraint_threshold;
133 };
134
135 for (auto const* boundary_element : _bc_mesh.getElements())
136 {
137 // check if the boundary element is active
138 if (isFlux(boundary_element->getID()))
139 {
140 continue;
141 }
142
143 // loop over the boundary element nodes and set the dirichlet value
144 unsigned const number_nodes = boundary_element->getNumberOfNodes();
145 for (unsigned i = 0; i < number_nodes; ++i)
146 {
147 auto const& node = *boundary_element->getNode(i);
148 auto const id = node.getID();
149 ParameterLib::SpatialPosition const pos{
150 id, boundary_element->getID(), node};
151
152 MeshLib::Location l(_bc_mesh.getID(), MeshLib::MeshItemType::Node,
153 id);
154 // TODO: that might be slow, but only done once
155 const auto g_idx = _dof_table_boundary->getGlobalIndex(
158 {
159 continue;
160 }
161 // For the DDC approach (e.g. with PETSc option), the negative
162 // index of g_idx means that the entry by that index is a ghost one,
163 // which should be dropped. Especially for PETSc routines
164 // MatZeroRows and MatZeroRowsColumns, which are called to apply the
165 // Dirichlet BC, the negative index is not accepted like other
166 // matrix or vector PETSc routines. Therefore, the following
167 // if-condition is applied.
168 if (g_idx >= 0)
169 {
170 tmp_bc_values.emplace_back(g_idx, _parameter(t, pos).front());
171 }
172 }
173 }
174
175 if (tmp_bc_values.empty())
176 {
177 DBUG("The domain on which the boundary is defined is empty");
178 return;
179 }
180
181 // store unique pairs of node id and value with respect to the node id in
182 // the bc_values vector. The values related to the same node id are
183 // averaged.
184 // first: sort the (node id, value) pairs according to the node id
185 std::sort(tmp_bc_values.begin(), tmp_bc_values.end(),
186 [](std::pair<GlobalIndexType, double> const& a,
187 std::pair<GlobalIndexType, double> const& b)
188 { return a.first < b.first; });
189 // second: average the values over equal node id ranges
190 unsigned cnt = 1;
191 GlobalIndexType current_id = tmp_bc_values.begin()->first;
192 double sum = tmp_bc_values.begin()->second;
193 for (auto const& tmp_bc_value : tmp_bc_values)
194 {
195 if (tmp_bc_value.first == current_id)
196 {
197 cnt++;
198 sum += tmp_bc_value.second;
199 }
200 else
201 {
202 bc_values.ids.emplace_back(current_id);
203 bc_values.values.emplace_back(sum / cnt);
204 cnt = 1;
205 sum = tmp_bc_value.second;
206 current_id = tmp_bc_value.first;
207 }
208 }
209 bc_values.ids.emplace_back(current_id);
210 bc_values.values.emplace_back(sum / cnt);
211
212 DBUG("Found {:d} constraint dirichlet boundary condition values.",
213 bc_values.ids.size());
214}
GlobalMatrix::IndexType GlobalIndexType
static constexpr NUMLIB_EXPORT GlobalIndexType const nop

References _bc_mesh, _component_id, _constraint_threshold, _dof_table_boundary, _flux_values, _lower, _parameter, _variable_id, DBUG(), getEssentialBCValues(), NumLib::IndexValueVector< IndexType >::ids, MeshLib::Node, NumLib::MeshComponentMap::nop, and NumLib::IndexValueVector< IndexType >::values.

Referenced by getEssentialBCValues().

◆ preTimestep()

void ProcessLib::ConstraintDirichletBoundaryCondition::preTimestep ( double const t,
std::vector< GlobalVector * > const & x,
int const process_id )
overridevirtual

Reimplemented from ProcessLib::BoundaryCondition.

Definition at line 103 of file ConstraintDirichletBoundaryCondition.cpp.

106{
107 DBUG(
108 "ConstraintDirichletBoundaryCondition::preTimestep: computing flux "
109 "constraints");
110 for (auto const id : _bc_mesh.getElements() | MeshLib::views::ids)
111 {
112 _flux_values[id] = _local_assemblers[id]->integrate(
113 x, t,
114 [this](std::size_t const element_id, MathLib::Point3d const& pnt,
115 double const t, std::vector<GlobalVector*> const& x)
116 { return _getFlux(element_id, pnt, t, x); });
117 }
118}
constexpr ranges::views::view_closure ids
For an element of a range view return its id.
Definition Mesh.h:216

References _bc_mesh, _flux_values, _getFlux, _local_assemblers, DBUG(), MeshLib::views::ids, and preTimestep().

Referenced by preTimestep().

Member Data Documentation

◆ _bc_mesh

MeshLib::Mesh const& ProcessLib::ConstraintDirichletBoundaryCondition::_bc_mesh
private

Vector of (lower-dimensional) boundary elements on which the boundary condition is defined.

Definition at line 75 of file ConstraintDirichletBoundaryCondition.h.

Referenced by ConstraintDirichletBoundaryCondition(), getEssentialBCValues(), and preTimestep().

◆ _bulk_ids

std::vector<std::pair<std::size_t, unsigned> > ProcessLib::ConstraintDirichletBoundaryCondition::_bulk_ids
private

The first item of the pair is the element id in the bulk mesh, the second item is the face id of the bulk element that is part of the boundary

Definition at line 83 of file ConstraintDirichletBoundaryCondition.h.

◆ _bulk_mesh

MeshLib::Mesh const& ProcessLib::ConstraintDirichletBoundaryCondition::_bulk_mesh
private

The mesh _bulk_mesh is the discretized domain the process(es) are defined on. It is needed to get values for the constraint calculation.

Definition at line 105 of file ConstraintDirichletBoundaryCondition.h.

Referenced by ConstraintDirichletBoundaryCondition().

◆ _component_id

int const ProcessLib::ConstraintDirichletBoundaryCondition::_component_id
private

◆ _constraint_threshold

double const ProcessLib::ConstraintDirichletBoundaryCondition::_constraint_threshold
private

The threshold value used to the switch off/on the Dirichlet-type boundary condition.

Definition at line 95 of file ConstraintDirichletBoundaryCondition.h.

Referenced by ConstraintDirichletBoundaryCondition(), and getEssentialBCValues().

◆ _dof_table_boundary

std::unique_ptr<NumLib::LocalToGlobalIndexMap> ProcessLib::ConstraintDirichletBoundaryCondition::_dof_table_boundary
private

Local dof table, a subset of the global one restricted to the participating number of elements of the boundary condition.

Definition at line 68 of file ConstraintDirichletBoundaryCondition.h.

Referenced by ConstraintDirichletBoundaryCondition(), and getEssentialBCValues().

◆ _flux_values

std::vector<double> ProcessLib::ConstraintDirichletBoundaryCondition::_flux_values
private

Stores the results of the flux computations per boundary element.

Definition at line 86 of file ConstraintDirichletBoundaryCondition.h.

Referenced by ConstraintDirichletBoundaryCondition(), getEssentialBCValues(), and preTimestep().

◆ _getFlux

std::function<Eigen::Vector3d(std::size_t const, MathLib::Point3d const&, double const, std::vector<GlobalVector*> const&)> ProcessLib::ConstraintDirichletBoundaryCondition::_getFlux
private

The function _getFlux calculates the flux through the boundary element.

Definition at line 111 of file ConstraintDirichletBoundaryCondition.h.

Referenced by ConstraintDirichletBoundaryCondition(), and preTimestep().

◆ _integration_order

unsigned const ProcessLib::ConstraintDirichletBoundaryCondition::_integration_order
private

Integration order for integration over the lower-dimensional elements.

Definition at line 78 of file ConstraintDirichletBoundaryCondition.h.

Referenced by ConstraintDirichletBoundaryCondition().

◆ _local_assemblers

std::vector<std::unique_ptr< ConstraintDirichletBoundaryConditionLocalAssemblerInterface> > ProcessLib::ConstraintDirichletBoundaryCondition::_local_assemblers
private

Local assemblers for each boundary element.

Definition at line 91 of file ConstraintDirichletBoundaryCondition.h.

Referenced by ConstraintDirichletBoundaryCondition(), and preTimestep().

◆ _lower

bool const ProcessLib::ConstraintDirichletBoundaryCondition::_lower
private

The boolean value lower is used for the calculation of the constraint criterion, i.e., if lower is set to true the criterion 'calculated_value < constraint_threshold' is evaluated to switch on/off the boundary condition, else 'calculated_value > constraint_threshold' is evaluated.

Definition at line 101 of file ConstraintDirichletBoundaryCondition.h.

Referenced by ConstraintDirichletBoundaryCondition(), and getEssentialBCValues().

◆ _parameter

ParameterLib::Parameter<double> const& ProcessLib::ConstraintDirichletBoundaryCondition::_parameter
private

◆ _variable_id

int const ProcessLib::ConstraintDirichletBoundaryCondition::_variable_id
private

The documentation for this class was generated from the following files: