* has already been condensed before).
*
* The use of ConstraintMatrix for implementing Dirichlet boundary conditions
- * is discussed in the step-22 tutorial program.
+ * is discussed in the step-22 tutorial program. A further example that applies
+ * the ConstraintMatrix is step-41. The situation here is little more complicated,
+ * because there we have some constraints which are not at the boundary.
+ * There are two ways to apply inhomogeneous constraints after creating the
+ * ConstraintMatrix:
+ *
+ * First:
+ * - Set the solution to zero in the inhomogeneous constrained components
+ * using the ConstraintMatrix::set_zero() function (or start with a solution
+ * vector equal to zero)
+ * - Apply the ConstraintMatrix::distribute_local_to_global() function to the
+ * system matrix and the right-hand-side with the parameter
+ * use_inhomogeneities_for_rhs = false (default)
+ * - solve() the linear system
+ * - Apply ConstraintMatrix::distribute() to the solution
+ *
+ * Second:
+ * - Set the concerning components of the solution to the inhomogeneous
+ * constrained values
+ * - Use the ConstraintMatrix::distribute_local_to_global() function with the parameter
+ * use_inhomogeneities_for_rhs = true and apply it to
+ * the system matrix and the right-hand-side
+ * - solve() the linear system
+ * - Depending on the solver now you have to apply the ConstraintMatrix::distribute()
+ * function to the solution, because the solver could change the constrained
+ * values in the solution. For a krylov based solver this should not be the
+ * case, but it is still possible that there is a difference between the
+ * inhomogeneous value and the solution value in the order of machine precision.
*
*
* <h3>Dealing with conflicting constraints</h3>
<a name="specific"></a>
<h3>Specific improvements</h3>
+<ol>
+<li> New: Implementation of an alternative handling of inhomogeneous constraints in ConstraintMatrix. This is controlled with a new parameter use_inhomogeneities_for_rhs in distribute_local_to_global() and determines whether the correct or zero values (this was the case before and still is the default) are kept in the linear system during the solution process.
+<br>
+(Jörg Frohne, 2011/11/01)
+
<ol>
<li> Fixed: SparseMatrix::mmult and SpareMatrix::Tmmult had a number of
issues that are now fixed: (i) rebuilding the sparsity pattern was allowed
* This function does much the same as
* the above one, except that it
* condenses the matrix struct
- * 'in-place'. It does not remove
+ * 'in-place'. It does not removes
* nonzero entries from the matrix but
* adds those needed for the process of
* distribution of the constrained
MatrixType &global_matrix) const;
/**
- * This function simultaneously writes
- * elements into matrix and vector,
- * according to the constraints
- * specified by the calling
- * ConstraintMatrix. This function can
- * correctly handle inhomogeneous
- * constraints as well.
+ * This function simultaneously
+ * writes elements into matrix
+ * and vector, according to the
+ * constraints specified by the
+ * calling ConstraintMatrix. This
+ * function can correctly handle
+ * inhomogeneous constraints as
+ * well. For the parameter
+ * use_inhomogeneities_for_rhs
+ * see the documentation in @ref
+ * constraints module.
*
* Note: This function is not
* thread-safe, so you will need to
const Vector<double> &local_vector,
const std::vector<unsigned int> &local_dof_indices,
MatrixType &global_matrix,
- VectorType &global_vector) const;
+ VectorType &global_vector,
+ bool use_inhomogeneities_for_rhs = false) const;
/**
* Do a similar operation as the
const std::vector<unsigned int> &local_dof_indices,
MatrixType &global_matrix,
VectorType &global_vector,
+ bool use_inhomogeneities_for_rhs,
internal::bool2type<false>) const;
/**
const std::vector<unsigned int> &local_dof_indices,
MatrixType &global_matrix,
VectorType &global_vector,
+ bool use_inhomogeneities_for_rhs,
internal::bool2type<true>) const;
/**
const Vector<double> &local_vector,
const std::vector<unsigned int> &local_dof_indices,
MatrixType &global_matrix,
- VectorType &global_vector) const
+ VectorType &global_vector,
+ bool use_inhomogeneities_for_rhs) const
{
// enter the internal function with the
// respective block information set, the
// actual implementation follows in the
// cm.templates.h file.
distribute_local_to_global (local_matrix, local_vector, local_dof_indices,
- global_matrix, global_vector,
+ global_matrix, global_vector, use_inhomogeneities_for_rhs,
internal::bool2type<IsBlockMatrix<MatrixType>::value>());
}
// hanging nodes in 3d). however, in
// the line below, we do actually do
// something with this dof
- template <typename MatrixType>
+ template <typename MatrixType, typename VectorType>
inline void
set_matrix_diagonals (const internals::GlobalRowsFromLocal &global_rows,
const std::vector<unsigned int> &local_dof_indices,
const FullMatrix<double> &local_matrix,
- MatrixType &global_matrix)
+ const ConstraintMatrix &constraints,
+ MatrixType &global_matrix,
+ VectorType &global_vector,
+ bool use_inhomogeneities_for_rhs)
{
if (global_rows.n_constraints() > 0)
{
= (std::fabs(local_matrix(local_row,local_row)) != 0 ?
std::fabs(local_matrix(local_row,local_row)) : average_diagonal);
global_matrix.add(global_row, global_row, new_diagonal);
+
+ // if the use_inhomogeneities_for_rhs flag is
+ // set to true, the inhomogeneities are used
+ // to create the global vector. instead of
+ // fill in a zero in the ith components with an
+ // inhomogeneity, we set those to:
+ // inhomogeneity(i)*global_matrix (i,i).
+ if (use_inhomogeneities_for_rhs == true)
+ global_vector(global_row) += constraints.get_inhomogeneity(global_row) * new_diagonal;
}
}
}
const std::vector<unsigned int> &local_dof_indices,
MatrixType &global_matrix,
VectorType &global_vector,
+ bool use_inhomogeneities_for_rhs,
internal::bool2type<false>) const
{
// check whether we work on real vectors
}
internals::set_matrix_diagonals (global_rows, local_dof_indices,
- local_matrix, global_matrix);
+ local_matrix, *this,
+ global_matrix, global_vector, use_inhomogeneities_for_rhs);
}
const std::vector<unsigned int> &local_dof_indices,
MatrixType &global_matrix,
VectorType &global_vector,
+ bool use_inhomogeneities_for_rhs,
internal::bool2type<true>) const
{
const bool use_vectors = (local_vector.size() == 0 &&
}
internals::set_matrix_diagonals (global_rows, local_dof_indices,
- local_matrix, global_matrix);
+ local_matrix, *this,
+ global_matrix, global_vector, use_inhomogeneities_for_rhs);
}
const std::vector<unsigned int> &, \
MatrixType &, \
VectorType &, \
+ bool , \
internal::bool2type<false>) const
#define MATRIX_FUNCTIONS(MatrixType) \
template void ConstraintMatrix:: \
const std::vector<unsigned int> &, \
MatrixType &, \
Vector<double> &, \
+ bool , \
internal::bool2type<false>) const
#define BLOCK_MATRIX_VECTOR_FUNCTIONS(MatrixType, VectorType) \
template void ConstraintMatrix:: \
const std::vector<unsigned int> &, \
MatrixType &, \
VectorType &, \
+ bool , \
internal::bool2type<true>) const
#define BLOCK_MATRIX_FUNCTIONS(MatrixType) \
template void ConstraintMatrix:: \
const std::vector<unsigned int> &, \
MatrixType &, \
Vector<double> &, \
+ bool , \
internal::bool2type<true>) const
MATRIX_FUNCTIONS(SparseMatrix<double>);