14 const mfem::ParFiniteElementSpace& space,
const std::set<int>& attrs)
15 : coef_(coef), component_(component), attr_markers_(space.GetMesh()->bdr_attributes.Max()), space_(space)
17 if (
get_if<std::shared_ptr<mfem::VectorCoefficient>>(&coef_)) {
18 SLIC_ERROR_ROOT_IF(component_,
"A vector coefficient must be applied to all components");
23 for (
const int attr : attrs) {
24 SLIC_ASSERT_MSG(attr <= attr_markers_.Size(),
"Attribute specified larger than what is found in the mesh.");
25 attr_markers_[attr - 1] = 1;
28 setDofListsFromAttributeMarkers();
32 const mfem::ParFiniteElementSpace& space,
const mfem::Array<int>& true_dofs)
33 : coef_(coef), component_(component), attr_markers_(0), space_(space)
35 if (
get_if<std::shared_ptr<mfem::VectorCoefficient>>(&coef_)) {
36 SLIC_ERROR_IF(component_,
"A vector coefficient must be applied to all components");
38 setTrueDofList(true_dofs);
41 void BoundaryCondition::setTrueDofList(
const mfem::Array<int>& true_dofs)
43 true_dofs_ = true_dofs;
46 mfem::Array<int> true_dof_marker(space_.GetTrueVSize());
47 mfem::Array<int> local_dof_marker(space_.GetVSize());
49 mfem::FiniteElementSpace::ListToMarker(true_dofs_, space_.GetTrueVSize(), true_dof_marker);
51 space_.GetRestrictionMatrix()->BooleanMultTranspose(true_dof_marker, local_dof_marker);
53 mfem::FiniteElementSpace::MarkerToList(local_dof_marker, local_dofs_);
56 void BoundaryCondition::setLocalDofList(
const mfem::Array<int>& local_dofs)
58 local_dofs_ = local_dofs;
61 mfem::Array<int> true_dof_marker(space_.GetTrueVSize());
62 mfem::Array<int> local_dof_marker(space_.GetVSize());
64 mfem::FiniteElementSpace::ListToMarker(local_dofs_, space_.GetVSize(), local_dof_marker);
66 space_.GetRestrictionMatrix()->BooleanMult(local_dof_marker, true_dof_marker);
68 mfem::FiniteElementSpace::MarkerToList(true_dof_marker, true_dofs_);
71 void BoundaryCondition::setDofListsFromAttributeMarkers()
73 auto& mutable_space =
const_cast<mfem::ParFiniteElementSpace&
>(space_);
76 mfem::Array<int> dof_markers;
78 mutable_space.GetEssentialTrueDofs(attr_markers_, true_dofs_, *component_);
79 space_.GetEssentialVDofs(attr_markers_, dof_markers, *component_);
82 space_.MarkerToList(dof_markers, local_dofs_);
85 mfem::Array<int> dof_markers;
87 mutable_space.GetEssentialTrueDofs(attr_markers_, true_dofs_);
88 space_.GetEssentialVDofs(attr_markers_, dof_markers);
91 space_.MarkerToList(dof_markers, local_dofs_);
97 SLIC_ERROR_IF(space_.GetTrueVSize() != vector.Size(),
98 "State to project and boundary condition space are not compatible.");
103 mfem::Array<int> dof_list(local_dofs_.Size());
104 std::transform(local_dofs_.begin(), local_dofs_.end(), dof_list.begin(),
105 [&space = space_](
int ldof) { return space.VDofToDof(ldof); });
109 auto vec_coef = get<std::shared_ptr<mfem::VectorCoefficient>>(coef_);
110 vec_coef->SetTime(time);
111 state.
project(*vec_coef, dof_list);
115 auto scalar_coef = get<std::shared_ptr<mfem::Coefficient>>(coef_);
116 scalar_coef->SetTime(time);
118 state.
project(*scalar_coef, dof_list, *component_);
125 for (
int i : true_dofs_) {
126 vector(i) = state(i);
132 std::unique_ptr<mfem::HypreParMatrix> eliminated_entries(k_mat.EliminateRowsCols(true_dofs_));
133 mfem::EliminateBC(k_mat, *eliminated_entries, true_dofs_, state, rhs);
138 auto scalar_coef = get_if<std::shared_ptr<mfem::Coefficient>>(&coef_);
140 return **scalar_coef;
142 SLIC_ERROR_ROOT(
"Asking for a scalar coefficient on a BoundaryCondition that contains a vector coefficient.");
149 auto scalar_coef = get_if<std::shared_ptr<mfem::Coefficient>>(&coef_);
151 return **scalar_coef;
153 SLIC_ERROR_ROOT(
"Asking for a scalar coefficient on a BoundaryCondition that contains a vector coefficient.");
160 auto vec_coef = get_if<std::shared_ptr<mfem::VectorCoefficient>>(&coef_);
164 SLIC_ERROR_ROOT(
"Asking for a vector coefficient on a BoundaryCondition that contains a scalar coefficient.");
171 auto vec_coef = get_if<std::shared_ptr<mfem::VectorCoefficient>>(&coef_);
175 SLIC_ERROR_ROOT(
"Asking for a vector coefficient on a BoundaryCondition that contains a scalar coefficient.");
This file contains the declaration of the boundary condition class.
void setDofs(mfem::Vector &state, const double time=0.0) const
Projects the associated coefficient over a solution vector on the DOFs constrained by the boundary co...
const mfem::VectorCoefficient & vectorCoefficient() const
Accessor for the underlying vector coefficient.
const mfem::Coefficient & scalarCoefficient() const
Accessor for the underlying scalar coefficient.
BoundaryCondition(GeneralCoefficient coef, const std::optional< int > component, const mfem::ParFiniteElementSpace &space, const std::set< int > &attrs)
Constructor for setting up a boundary condition using a set of attributes.
void apply(mfem::HypreParMatrix &k_mat, mfem::Vector &rhs, mfem::Vector &state) const
Modify the system of equations by replacing equations that correspond to essential boundary conditio...
Class for encapsulating the critical MFEM components of a primal finite element field.
void projectOnBoundary(mfem::Coefficient &coef, const mfem::Array< int > &markers)
Project a coefficient on a specific set of marked boundaries.
void project(mfem::VectorCoefficient &coef, mfem::Array< int > &dof_list)
Project a vector coefficient onto a set of dofs.
Accelerator functionality.
bool is_vector_valued(const GeneralCoefficient &coef)
convenience function for querying the type stored in a GeneralCoefficient
T * get_if(variant< T0, T1 > *v)
Returns the member of requested type if it's active, otherwise nullptr.