/**
* @{
*/
-
+
/**
* This function does nothing. It is only here to provide a interface
* consistent with other sparse direct solvers.
/**
* @{
*/
-
+
/**
* Preconditioner interface function. Usually, given the source vector,
- * this method returns an approximated solution of <i>Ax = b</i>. As this
+ * this method returns an approximate solution of <i>Ax = b</i>. As this
* class provides a wrapper to a direct solver, here it is actually the
* exact solution (exact within the range of numerical accuracy of
* course).
const BlockVector<double> &src) const;
/**
- * Not implemented but necessary for compiling certain other classes.
+ * Same as before, but uses the transpose of the matrix, i.e. this
+ * function multiplies with $A^{-T}$.
*/
void Tvmult (Vector<double> &dst,
const Vector<double> &src) const;
+ /**
+ * Same as before, but for block vectors
+ */
+ void Tvmult (BlockVector<double> &dst,
+ const BlockVector<double> &src) const;
+
/**
* Same as vmult(), but adding to the previous solution. Not implemented
* yet but necessary for compiling certain other classes.
const Vector<double> &src) const;
/**
- * Not implemented but necessary for compiling certain other classes.
+ * Same as before, but uses the transpose of the matrix, i.e. this
+ * function multiplies with $A^{-T}$.
*/
void Tvmult_add (Vector<double> &dst,
const Vector<double> &src) const;
-
+
/**
* @}
*/
* happen. Note that we can't actually call the factorize() function from
* here if it has not yet been called, since we have no access to the
* actual matrix.
+ *
+ * If @p transpose is set to true this function solves for the transpose
+ * of the matrix, i.e. $x=A^{-T}b$.
*/
- void solve (Vector<double> &rhs_and_solution) const;
+ void solve (Vector<double> &rhs_and_solution, bool transpose = false) const;
/**
* Same as before, but for block vectors.
*/
- void solve (BlockVector<double> &rhs_and_solution) const;
-
+ void solve (BlockVector<double> &rhs_and_solution, bool transpose = false) const;
+
/**
* Call the two functions factorize() and solve() in that order, i.e. perform
* the whole solution process for the given right hand side vector.
*/
template <class Matrix>
void solve (const Matrix &matrix,
- Vector<double> &rhs_and_solution);
+ Vector<double> &rhs_and_solution,
+ bool transpose = false);
/**
* Same as before, but for block vectors.
*/
template <class Matrix>
void solve (const Matrix &matrix,
- BlockVector<double> &rhs_and_solution);
+ BlockVector<double> &rhs_and_solution,
+ bool transpose = false);
/**
* @}
void
-SparseDirectUMFPACK::solve (Vector<double> &rhs_and_solution) const
+SparseDirectUMFPACK::solve (Vector<double> &rhs_and_solution,
+ bool transpose /*=false*/) const
{
// make sure that some kind of factorize() call has happened before
Assert (Ap.size() != 0, ExcNotInitialized());
// solve the system. note that since UMFPACK wants compressed column
// storage instead of the compressed row storage format we use in
// deal.II's SparsityPattern classes, we solve for UMFPACK's A^T instead
+
+ // Conversely, if we solve for the transpose, we have to use UMFPACK_A
+ // instead.
const int status
- = umfpack_dl_solve (UMFPACK_At,
+ = umfpack_dl_solve (transpose ? UMFPACK_A : UMFPACK_At,
&Ap[0], &Ai[0], &Ax[0],
rhs_and_solution.begin(), rhs.begin(),
numeric_decomposition,
void
-SparseDirectUMFPACK::solve (BlockVector<double> &rhs_and_solution) const
+SparseDirectUMFPACK::solve (BlockVector<double> &rhs_and_solution,
+ bool transpose /*=false*/) const
{
// the UMFPACK functions want a contiguous array of elements, so
// there is no way around copying data around. thus, just copy the
// data into a regular vector and back
Vector<double> tmp (rhs_and_solution.size());
tmp = rhs_and_solution;
- solve (tmp);
+ solve (tmp, transpose);
rhs_and_solution = tmp;
}
template <class Matrix>
void
SparseDirectUMFPACK::solve (const Matrix &matrix,
- Vector<double> &rhs_and_solution)
+ Vector<double> &rhs_and_solution,
+ bool transpose /*=false*/)
{
factorize (matrix);
- solve (rhs_and_solution);
+ solve (rhs_and_solution, transpose);
}
template <class Matrix>
void
-SparseDirectUMFPACK::solve (const Matrix &matrix,
- BlockVector<double> &rhs_and_solution)
+SparseDirectUMFPACK::solve (const Matrix &matrix,
+ BlockVector<double> &rhs_and_solution,
+ bool transpose /*=false*/)
{
factorize (matrix);
- solve (rhs_and_solution);
+ solve (rhs_and_solution, transpose);
}
void
SparseDirectUMFPACK::Tvmult (
- Vector<double> &,
- const Vector<double> &) const
+ Vector<double> &dst,
+ const Vector<double> &src) const
{
- Assert(false, ExcNotImplemented());
+ dst = src;
+ this->solve(dst, /*transpose=*/ true);
+}
+
+
+
+void
+SparseDirectUMFPACK::Tvmult (
+ BlockVector<double> &dst,
+ const BlockVector<double> &src) const
+{
+ dst = src;
+ this->solve(dst, /*transpose=*/ true);
}
+
#ifdef DEAL_II_WITH_MUMPS
SparseDirectMUMPS::SparseDirectMUMPS ()
// explicit instantiations for SparseMatrixUMFPACK
-#define InstantiateUMFPACK(MATRIX) \
- template \
- void SparseDirectUMFPACK::factorize (const MATRIX &); \
- template \
- void SparseDirectUMFPACK::solve (const MATRIX &, \
- Vector<double> &); \
- template \
- void SparseDirectUMFPACK::solve (const MATRIX &, \
- BlockVector<double> &); \
- template \
- void SparseDirectUMFPACK::initialize (const MATRIX &, \
+#define InstantiateUMFPACK(MATRIX) \
+ template \
+ void SparseDirectUMFPACK::factorize (const MATRIX &); \
+ template \
+ void SparseDirectUMFPACK::solve (const MATRIX &, \
+ Vector<double> &, \
+ bool); \
+ template \
+ void SparseDirectUMFPACK::solve (const MATRIX &, \
+ BlockVector<double> &, \
+ bool); \
+ template \
+ void SparseDirectUMFPACK::initialize (const MATRIX &, \
const AdditionalData);
InstantiateUMFPACK(SparseMatrix<double>)
// explicit instantiations for SparseDirectMUMPS
#ifdef DEAL_II_WITH_MUMPS
-#define InstantiateMUMPS(MATRIX) \
- template \
+#define InstantiateMUMPS(MATRIX) \
+ template \
void SparseDirectMUMPS::initialize (const MATRIX &, const Vector<double> &);
InstantiateMUMPS(SparseMatrix<double>)