From 2b058faa2a503c374978f55a66c73ad92057c084 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 19 Oct 2023 14:06:05 -0600 Subject: [PATCH] Add AffineConstraints::constrain_dof_to_zero(). --- include/deal.II/lac/affine_constraints.h | 29 +++++++++++++++ .../lac/affine_constraints.templates.h | 35 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/include/deal.II/lac/affine_constraints.h b/include/deal.II/lac/affine_constraints.h index 59a195e44b..f61b6d1897 100644 --- a/include/deal.II/lac/affine_constraints.h +++ b/include/deal.II/lac/affine_constraints.h @@ -793,6 +793,21 @@ public: * @code * constraints.add_constraint (42, {}, 27.0); * @endcode + * If you want to constrain a degree of freedom to zero, i.e., + * require that + * @f[ + * x_{42} = 0 + * @f] + * you would call this function as follows: + * @code + * constraints.add_constraint (42, {}, 0.0); + * @endcode + * That said, this special case can be achieved in a more obvious way by + * calling + * @code + * constraints.constrain_dof_to_zero (42); + * @endcode + * instead. */ void add_constraint( @@ -800,6 +815,20 @@ public: const ArrayView> &dependencies, const number inhomogeneity = 0); + /** + * Constrain the given degree of freedom to be zero, i.e., + * require a constraint like + * @f[ + * x_{42} = 0. + * @f] + * Calling this function is equivalent to, but more readable than, saying + * @code + * constraints.add_constraint (42, {}, 0.0); + * @endcode + */ + void + constrain_dof_to_zero(const size_type constrained_dof); + /** * Add a new line to the matrix. If the line already exists, then the * function simply returns without doing anything. diff --git a/include/deal.II/lac/affine_constraints.templates.h b/include/deal.II/lac/affine_constraints.templates.h index f6d5e79216..047dcd1b12 100644 --- a/include/deal.II/lac/affine_constraints.templates.h +++ b/include/deal.II/lac/affine_constraints.templates.h @@ -143,6 +143,41 @@ AffineConstraints::add_constraint( +template +void +AffineConstraints::constrain_dof_to_zero( + const size_type constrained_dof) +{ + Assert(sorted == false, ExcMatrixIsClosed()); + Assert(is_constrained(constrained_dof) == false, + ExcMessage("You cannot add a constraint for a degree of freedom " + "that is already constrained.")); + + // The following can happen when we compute with distributed meshes and dof + // handlers and we constrain a degree of freedom whose number we don't have + // locally. if we don't abort here the program will try to allocate several + // terabytes of memory to resize the various arrays below :-) + Assert(constrained_dof != numbers::invalid_size_type, ExcInternalError()); + + // if necessary enlarge vector of existing entries for cache + const size_type line_index = calculate_line_index(constrained_dof); + if (line_index >= lines_cache.size()) + lines_cache.resize(std::max(2 * static_cast(lines_cache.size()), + line_index + 1), + numbers::invalid_size_type); + + // Push a new line to the end of the list and fill it with the + // provided information: + ConstraintLine &constraint = lines.emplace_back(); + constraint.index = constrained_dof; + constraint.inhomogeneity = 0.; + + // Record the new constraint in the cache: + lines_cache[line_index] = lines.size() - 1; +} + + + template typename AffineConstraints::LineRange AffineConstraints::get_lines() const -- 2.39.5