21 unsigned const integration_order,
MeshLib::Mesh const& bulk_mesh,
22 double const constraint_threshold,
bool const lower,
25 std::vector<GlobalVector*>
const&)>
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));
49 std::vector<MeshLib::Node*>
const& bc_nodes =
_bc_mesh.getNodes();
51 "Found {:d} nodes for constraint Dirichlet BCs for the variable {:d} "
53 bc_nodes.size(), variable_id, component_id);
60 variable_id, {component_id}, std::move(bc_mesh_subset));
62 auto const& bc_elements(
_bc_mesh.getElements());
68 auto const& bulk_nodes = bulk_mesh.
getNodes();
70 auto get_bulk_element_face_id =
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());
81 _bulk_ids.reserve(bc_elements.size());
83 begin(bc_elements), end(bc_elements), std::back_inserter(_bulk_ids),
84 [&](
auto const* bc_element)
86 auto const bulk_element_id =
87 (*bulk_element_ids)[bc_element->getID()];
88 return std::make_pair(
90 get_bulk_element_face_id(bulk_element_id, bc_element));
93 const int shape_function_order = 1;
96 ConstraintDirichletBoundaryConditionLocalAssembler>(
97 _bulk_mesh.getDimension(), _bc_mesh.getElements(), *_dof_table_boundary,
98 shape_function_order, _local_assemblers,
100 _bc_mesh.isAxiallySymmetric(), bulk_mesh, _bulk_ids);
104 double const t, std::vector<GlobalVector*>
const& x,
108 "ConstraintDirichletBoundaryCondition::preTimestep: computing flux "
115 double const t, std::vector<GlobalVector*>
const& x)
116 {
return _getFlux(element_id, pnt, t, x); });
124 bc_values.
ids.clear();
127 std::vector<std::pair<GlobalIndexType, double>> tmp_bc_values;
129 auto isFlux = [&](
const std::size_t element_id)
135 for (
auto const* boundary_element :
_bc_mesh.getElements())
138 if (isFlux(boundary_element->getID()))
144 unsigned const number_nodes = boundary_element->getNumberOfNodes();
145 for (
unsigned i = 0; i < number_nodes; ++i)
147 auto const& node = *boundary_element->getNode(i);
148 auto const id = node.getID();
150 id, boundary_element->getID(), node};
170 tmp_bc_values.emplace_back(g_idx,
_parameter(t, pos).front());
175 if (tmp_bc_values.empty())
177 DBUG(
"The domain on which the boundary is defined is empty");
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; });
192 double sum = tmp_bc_values.begin()->second;
193 for (
auto const& tmp_bc_value : tmp_bc_values)
195 if (tmp_bc_value.first == current_id)
198 sum += tmp_bc_value.second;
202 bc_values.
ids.emplace_back(current_id);
203 bc_values.
values.emplace_back(sum / cnt);
205 sum = tmp_bc_value.second;
206 current_id = tmp_bc_value.first;
209 bc_values.
ids.emplace_back(current_id);
210 bc_values.
values.emplace_back(sum / cnt);
212 DBUG(
"Found {:d} constraint dirichlet boundary condition values.",
213 bc_values.
ids.size());
219 DBUG(
"Parsing ConstraintDirichletBoundaryCondition from config.");
229 auto const process_variable =
233 auto const threshold =
237 auto const direction_string =
243 DBUG(
"parameter name {:s}", name);
245 return {type, process_variable, threshold, direction_string, name};
248std::unique_ptr<ConstraintDirichletBoundaryCondition>
253 unsigned const integration_order,
int const component_id,
254 std::vector<std::unique_ptr<ParameterLib::ParameterBase>>
const& parameters,
255 Process const& constraining_process)
257 DBUG(
"Constructing ConstraintDirichletBoundaryCondition");
261 OGS_FATAL(
"The constraint type is '{:s}', but has to be 'Flux'.",
268 "The constraint dirichlet boundary condition is implemented only "
269 "for monolithic implemented processes.");
271 const int process_id = 0;
272 auto process_variables =
274 auto constraining_pv = std::find_if(
275 process_variables.cbegin(), process_variables.cend(),
277 { return pv.getName() == config.constraining_process_variable; });
278 if (constraining_pv == std::end(process_variables))
280 auto const& constraining_process_variable_name =
281 process_variables[variable_id].get().getName();
283 "<constraining_process_variable> in process variable name '{:s}' "
284 "at geometry 'TODO' : The constraining process variable is set as "
285 "'{:s}', but this is not specified in the project file.",
286 constraining_process_variable_name,
294 "The constraint direction is '{:s}', but has to be either "
295 "'greater' or 'lower'.",
301 parameters, 1, &bc_mesh);
317 return std::make_unique<ConstraintDirichletBoundaryCondition>(
318 param, dof_table_bulk, variable_id, component_id, bc_mesh,
319 integration_order, constraining_process.
getMesh(),
321 [&constraining_process](std::size_t
const element_id,
323 std::vector<GlobalVector*>
const& x)
324 { return constraining_process.getFlux(element_id, pnt, t, x); });
MathLib::EigenVector GlobalVector
GlobalMatrix::IndexType GlobalIndexType
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
T getConfigParameter(std::string const ¶m) const
void checkConfigParameter(std::string const ¶m, std::string_view const value) const
A subset of nodes on a single mesh.
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
unsigned getDimension() const
Returns the dimension of the mesh (determined by the maximum dimension over all elements).
std::size_t getNumberOfNodes() const
Get the number of nodes.
std::size_t getNumberOfElements() const
Get the number of elements.
int getNumberOfVariables() const
int getNumberOfVariableComponents(int variable_id) const
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
ParameterLib::Parameter< double > const & _parameter
void getEssentialBCValues(const double t, const GlobalVector &x, NumLib::IndexValueVector< GlobalIndexType > &bc_values) const override
Writes the values of essential BCs to bc_values.
double const _constraint_threshold
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
void preTimestep(double const t, std::vector< GlobalVector * > const &x, int const process_id) override
MeshLib::Mesh const & _bc_mesh
MeshLib::Mesh const & _bulk_mesh
std::vector< double > _flux_values
Stores the results of the flux computations per boundary element.
ConstraintDirichletBoundaryCondition(ParameterLib::Parameter< double > const ¶meter, 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)
unsigned const _integration_order
Integration order for integration over the lower-dimensional elements.
MeshLib::Mesh & getMesh() const
virtual bool isMonolithicSchemeUsed() const
std::vector< std::vector< std::reference_wrapper< ProcessVariable > > > const & getProcessVariables() const
constexpr ranges::views::view_closure ids
For an element of a range view return its id.
PropertyVector< std::size_t > const * bulkElementIDs(Mesh const &mesh)
PropertyVector< std::size_t > const * bulkNodeIDs(Mesh const &mesh)
OGS_NO_DANGLING Parameter< ParameterDataType > & findParameter(std::string const ¶meter_name, std::vector< std::unique_ptr< ParameterBase > > const ¶meters, int const num_components, MeshLib::Mesh const *const mesh=nullptr)
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)
std::unique_ptr< ConstraintDirichletBoundaryCondition > createConstraintDirichletBoundaryCondition(ConstraintDirichletBoundaryConditionConfig const &config, MeshLib::Mesh const &bc_mesh, NumLib::LocalToGlobalIndexMap const &dof_table_bulk, int const variable_id, unsigned const integration_order, int const component_id, std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const ¶meters, Process const &constraining_process)
ConstraintDirichletBoundaryConditionConfig parseConstraintDirichletBoundaryCondition(BaseLib::ConfigTree const &config)
std::vector< IndexType > ids
std::vector< double > values
std::string parameter_name
std::string constraining_process_variable
std::string constraint_direction
std::string constraint_type
double constraint_threshold