* @f[
* (C^T A C + Id_c) \tilde x = C^T (b - A\,k)
* @f]
- * instead [1] (M. S. Shephard: Linear multipoint constraints applied via
- * transformation as part of a direct stiffness assembly process, 1985).
- *
- * Here, $A$ is a given (unconstrained) system matrix and $b$
- * the corresponding right hand side of a system of linear equations
- * $A\,x=b$. The matrix $C$ describes the homogeneous part of the linear
- * constraints stored in a ConstraintMatrix and the vector $k$ is the
- * vector of corresponding inhomogeneities. More precisely, the
- * ConstraintMatrix::distribute() operation applied on a vector $x$ is the
- * operation
+ * instead [1] (M. S. Shephard. Linear multipoint constraints applied via
+ * transformation as part of a direct stiffness assembly process.
+ * <i>International Journal for Numerical Methods in Engineering</i>
+ * 20(11):2107-2112, 1985).
+ *
+ * Here, $A$ is a given (unconstrained) system matrix for wich we only
+ * assume that we can apply it to a vector but can not necessarily access
+ * individual matrix entries. $b$ is the corresponding right hand side of a
+ * system of linear equations $A\,x=b$. The matrix $C$ describes the
+ * homogeneous part of the linear constraints stored in a ConstraintMatrix
+ * and the vector $k$ is the vector of corresponding inhomogeneities. More
+ * precisely, the ConstraintMatrix::distribute() operation applied on a
+ * vector $x$ is the operation
* @f[
x \leftarrow C\,x+k.
* @f]
/**
* This function takes a ConstraintMatrix @p constraint_matrix and an
* operator exemplar @p exemplar (this exemplar is usually a linear
- * operator that describes the system matrix) and returns a LinearOperator
- * object associated with the "homogeneous action" of the underlying
- * ConstraintMatrix object:
+ * operator that describes the system matrix - it is only used to create
+ * domain and range vectors of appropriate sizes, its action <tt>vmult</tt>
+ * is never used). A LinearOperator object associated with the "homogeneous
+ * action" of the underlying ConstraintMatrix object is returned:
*
* Applying the LinearOperator object on a vector <code>u</code> results in
* a vector <code>v</code> that stores the result of calling
*
* @author Mauro Bardelloni, Matthias Maier, 2015
*
+ * @note Currently, this function may not work correctly for distributed data
+ * structures.
+ *
* @relates LinearOperator
* @ingroup constraints
*/
return_op.vmult_add = [&constraint_matrix](Range &v, const Domain &u)
{
+ Assert(!dealii::PointerComparison::equal(&v, &u),
+ dealii::ExcMessage("The domain and range vectors must be different "
+ "storage locations"));
+
for (auto i : v.locally_owned_elements())
{
if (constraint_matrix.is_constrained(i))
{
- const auto *entries = constraint_matrix.get_constraint_entries (i);
+ const auto *entries = constraint_matrix.get_constraint_entries(i);
for (types::global_dof_index j = 0; j < entries->size(); ++j)
{
const auto pos = (*entries)[j].first;
- v(i) += u(pos) * (*entries)[j].second;
+ v(i) += u(pos) * (*entries)[j].second;
}
}
else
return_op.Tvmult_add = [&constraint_matrix](Domain &v, const Range &u)
{
+ Assert(!dealii::PointerComparison::equal(&v, &u),
+ dealii::ExcMessage("The domain and range vectors must be different "
+ "storage locations"));
+
for (auto i : v.locally_owned_elements())
{
if (constraint_matrix.is_constrained(i))
/**
* Given a ConstraintMatrix @p constraint_matrix and an operator exemplar
- * @p exemplar, return an LinearOperator that is the projection to the
- * subspace of constrained degrees of freedom.
+ * @p exemplar, return a LinearOperator that is the projection to the
+ * subspace of constrained degrees of freedom, i.e. all entries of the
+ * result vector that correspond to unconstrained degrees of freedom are
+ * set to zero.
*
* @author Mauro Bardelloni, Matthias Maier, 2015
*
return_op.vmult = [&constraint_matrix](Range &v, const Domain &u)
{
+ Assert(!dealii::PointerComparison::equal(&v, &u),
+ dealii::ExcMessage("The domain and range vectors must be different "
+ "storage locations"));
+
v = 0.;
for (auto i : v.locally_owned_elements())
if (constraint_matrix.is_constrained(i))
return_op.Tvmult = [&constraint_matrix](Domain &v, const Range &u)
{
+ Assert(!dealii::PointerComparison::equal(&v, &u),
+ dealii::ExcMessage("The domain and range vectors must be different "
+ "storage locations"));
v = 0.;
for (auto i : v.locally_owned_elements())
if (constraint_matrix.is_constrained(i))
*
* @author Mauro Bardelloni, Matthias Maier, 2015
*
+ * @note Currently, this function may not work correctly for distributed data
+ * structures.
+ *
* @relates LinearOperator
* @ingroup constraints
*/
*
* @author Mauro Bardelloni, Matthias Maier, 2015
*
+ * @note Currently, this function may not work correctly for distributed data
+ * structures.
+ *
* @relates LinearOperator
* @ingroup constraints
*/