From 24d606deb2fb47db8af31951818fcadf594564e6 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 5 Oct 2023 15:38:28 -0600 Subject: [PATCH] Add AffineConstraint::add_constraint(). --- include/deal.II/lac/affine_constraints.h | 70 ++++++++++++++++++++---- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/include/deal.II/lac/affine_constraints.h b/include/deal.II/lac/affine_constraints.h index e683d2d8c4..ddac49df82 100644 --- a/include/deal.II/lac/affine_constraints.h +++ b/include/deal.II/lac/affine_constraints.h @@ -246,9 +246,10 @@ namespace internal const size_type index_in_constraint) const; /** - * Return whether there is one row with indirect contributions (i.e., - * there has been at least one constraint with non-trivial - * ConstraintLine). + * Return whether this object stores a constraint in which one degree + * of freedom is constrained against another degree of freedom (as + * opposed to having only constraints of the form $x_i=42$ where + * no other degree of freedom appears on the right side). */ bool have_indirect_rows() const; @@ -428,14 +429,7 @@ namespace internal } // namespace internal #endif -// TODO[WB]: We should have a function of the kind -// AffineConstraints::add_constraint (const size_type constrained_dof, -// const std::vector > &entries, -// const number inhomogeneity = 0); -// rather than building up constraints piecemeal through add_line/add_entry -// etc. This would also eliminate the possibility of accidentally changing -// existing constraints into something pointless, see the discussion on the -// mailing list on "Tiny bug in interpolate_boundary_values" in Sept. 2010. + /** * This class implements dealing with linear (possibly inhomogeneous) @@ -760,6 +754,41 @@ public: * @{ */ + /** + * Add a constraint to this object. This function adds a constraint + * of the form + * @f[ + * x_i = \sum_{j=1}^n w_j x_{k_j} + b + * @f] + * where $i$ is the number of the degree of freedom to be constrained + * and is provided by the @p constrained_dofs argument. The weights + * $w_j$ and indices $k_j$ are provided as pairs in the + * @p dependencies argument, and the inhomogeneity $b$ is + * provided by the last argument. + * + * As an example, if you want to add the constraint + * @f[ + * x_{42} = 0.5 x_{12} + 0.5 x_{36} + 27 + * @f] + * you would call this function as follows: + * @code + * constraints.add_constraint (42, {{12, 0.5}, {36, 0.5}}, 27.0); + * @endcode + * On the other hand, if (as one often wants to) you need a constraint + * of the kind + * @f[ + * x_{42} = 27 + * @f] + * you would call this function as follows: + * @code + * constraints.add_constraint (42, {}, 27.0); + * @endcode + */ + void + add_constraint(const size_type constrained_dof, + const std::vector> &dependencies, + const number inhomogeneity = 0); + /** * Add a new line to the matrix. If the line already exists, then the * function simply returns without doing anything. @@ -2203,6 +2232,25 @@ inline AffineConstraints::AffineConstraints( +template +inline void +AffineConstraints::add_constraint( + const size_type constrained_dof, + const std::vector> &dependencies, + const number inhomogeneity) +{ + Assert(is_constrained(constrained_dof) == false, + ExcMessage("You cannot add a constraint for a degree of freedom " + "that is already constrained.")); + + add_line(constrained_dof); + for (const auto &dep : dependencies) + add_entry(constrained_dof, dep.first, dep.second); + set_inhomogeneity(constrained_dof, inhomogeneity); +} + + + template inline void AffineConstraints::add_line(const size_type line_n) -- 2.39.5