const VectorBase &b,
const PreconditionBase &preconditioner);
+ /**
+ * Solve the linear system
+ * <tt>Ax=b</tt> where <tt>A</tt>
+ * is an operator. This function
+ * can be used for matrix free
+ * computation. Depending on
+ * the information provided by
+ * derived classes and the
+ * object passed as a
+ * preconditioner, one of the
+ * linear solvers and
+ * preconditioners of Trilinos
+ * is chosen.
+ */
+ void
+ solve (Epetra_Operator &A,
+ VectorBase &x,
+ const VectorBase &b,
+ const PreconditionBase &preconditioner);
+
/**
* Solve the linear system
* <tt>Ax=b</tt>. Depending on the
const dealii::Vector<double> &b,
const PreconditionBase &preconditioner);
+ /**
+ * Solve the linear system
+ * <tt>Ax=b</tt> where <tt>A</tt>
+ * is an operator. This function can
+ * be used for matric free. Depending on the
+ * information provided by derived
+ * classes and the object passed as a
+ * preconditioner, one of the linear
+ * solvers and preconditioners of
+ * Trilinos is chosen. This class
+ * works with matrices according to
+ * the TrilinosWrappers format, but
+ * can take deal.II vectors as
+ * argument. Since deal.II are serial
+ * vectors (not distributed), this
+ * function does only what you expect
+ * in case the matrix is locally
+ * owned. Otherwise, an exception
+ * will be thrown.
+ */
+ void
+ solve (Epetra_Operator &A,
+ dealii::Vector<double> &x,
+ const dealii::Vector<double> &b,
+ const PreconditionBase &preconditioner);
+
/**
* Access to object that controls
* convergence.
private:
+ /**
+ * The solve function is used to set properly the Epetra_LinearProblem,
+ * once it is done this function solves the linear problem.
+ */
+ void execute_solve(const PreconditionBase &preconditioner);
+
/**
* A structure that collects
* the Trilinos sparse matrix,
const VectorBase &b,
const PreconditionBase &preconditioner)
{
- int ierr;
-
linear_problem.reset();
// We need an
&x.trilinos_vector(),
const_cast<Epetra_MultiVector *>(&b.trilinos_vector())));
- // Next we can allocate the
- // AztecOO solver...
- solver.SetProblem(*linear_problem);
+ execute_solve(preconditioner);
+ }
- // ... and we can specify the
- // solver to be used.
- switch (solver_name)
- {
- case cg:
- solver.SetAztecOption(AZ_solver, AZ_cg);
- break;
- case cgs:
- solver.SetAztecOption(AZ_solver, AZ_cgs);
- break;
- case gmres:
- solver.SetAztecOption(AZ_solver, AZ_gmres);
- solver.SetAztecOption(AZ_kspace, additional_data.gmres_restart_parameter);
- break;
- case bicgstab:
- solver.SetAztecOption(AZ_solver, AZ_bicgstab);
- break;
- case tfqmr:
- solver.SetAztecOption(AZ_solver, AZ_tfqmr);
- break;
- default:
- Assert (false, ExcNotImplemented());
- }
- // Introduce the
- // preconditioner, ...
- ierr = solver.SetPrecOperator (const_cast<Epetra_Operator *>
- (preconditioner.preconditioner.get()));
- AssertThrow (ierr == 0, ExcTrilinosError(ierr));
- // ... set some options, ...
- solver.SetAztecOption (AZ_output, additional_data.output_solver_details ?
- AZ_all : AZ_none);
- solver.SetAztecOption (AZ_conv, AZ_noscaled);
-
- // ... and then solve!
- ierr = solver.Iterate (solver_control.max_steps(),
- solver_control.tolerance());
-
- // report errors in more detail
- // than just by checking whether
- // the return status is zero or
- // greater. the error strings are
- // taken from the implementation
- // of the AztecOO::Iterate
- // function
- switch (ierr)
- {
- case -1:
- AssertThrow (false, ExcMessage("AztecOO::Iterate error code -1: "
- "option not implemented"));
- case -2:
- AssertThrow (false, ExcMessage("AztecOO::Iterate error code -2: "
- "numerical breakdown"));
- case -3:
- AssertThrow (false, ExcMessage("AztecOO::Iterate error code -3: "
- "loss of precision"));
- case -4:
- AssertThrow (false, ExcMessage("AztecOO::Iterate error code -4: "
- "GMRES hessenberg ill-conditioned"));
- default:
- AssertThrow (ierr >= 0, ExcTrilinosError(ierr));
- }
+ void
+ SolverBase::solve (Epetra_Operator &A,
+ VectorBase &x,
+ const VectorBase &b,
+ const PreconditionBase &preconditioner)
+ {
+ linear_problem.reset();
- // Finally, let the deal.II
- // SolverControl object know
- // what has happened. If the
- // solve succeeded, the status
- // of the solver control will
- // turn into
- // SolverControl::success.
- solver_control.check (solver.NumIters(), solver.TrueResidual());
+ // We need an
+ // Epetra_LinearProblem object
+ // to let the AztecOO solver
+ // know about the matrix and
+ // vectors.
+ linear_problem.reset
+ (new Epetra_LinearProblem(&A,
+ &x.trilinos_vector(),
+ const_cast<Epetra_MultiVector *>(&b.trilinos_vector())));
- if (solver_control.last_check() != SolverControl::success)
- throw SolverControl::NoConvergence (solver_control.last_step(),
- solver_control.last_value());
+ execute_solve(preconditioner);
}
const dealii::Vector<double> &b,
const PreconditionBase &preconditioner)
{
- int ierr;
-
linear_problem.reset();
// In case we call the solver with
(const_cast<Epetra_CrsMatrix *>(&A.trilinos_matrix()),
&ep_x, &ep_b));
+ execute_solve(preconditioner);
+ }
+
+
+
+ void
+ SolverBase::solve (Epetra_Operator &A,
+ dealii::Vector<double> &x,
+ const dealii::Vector<double> &b,
+ const PreconditionBase &preconditioner)
+ {
+ linear_problem.reset();
+
+ Epetra_Vector ep_x (View, A.OperatorDomainMap(), x.begin());
+ Epetra_Vector ep_b (View, A.OperatorRangeMap(), const_cast<double *>(b.begin()));
+
+ // We need an
+ // Epetra_LinearProblem object
+ // to let the AztecOO solver
+ // know about the matrix and
+ // vectors.
+ linear_problem.reset (new Epetra_LinearProblem(&A,&ep_x, &ep_b));
+
+ execute_solve(preconditioner);
+ }
+
+
+
+ void
+ SolverBase::execute_solve(const PreconditionBase &preconditioner)
+ {
+ int ierr;
+
// Next we can allocate the
// AztecOO solver...
solver.SetProblem(*linear_problem);
// ... and then solve!
ierr = solver.Iterate (solver_control.max_steps(),
solver_control.tolerance());
- AssertThrow (ierr >= 0, ExcTrilinosError(ierr));
+
+ // report errors in more detail
+ // than just by checking whether
+ // the return status is zero or
+ // greater. the error strings are
+ // taken from the implementation
+ // of the AztecOO::Iterate
+ // function
+ switch (ierr)
+ {
+ case -1:
+ AssertThrow (false, ExcMessage("AztecOO::Iterate error code -1: "
+ "option not implemented"));
+ case -2:
+ AssertThrow (false, ExcMessage("AztecOO::Iterate error code -2: "
+ "numerical breakdown"));
+ case -3:
+ AssertThrow (false, ExcMessage("AztecOO::Iterate error code -3: "
+ "loss of precision"));
+ case -4:
+ AssertThrow (false, ExcMessage("AztecOO::Iterate error code -4: "
+ "GMRES hessenberg ill-conditioned"));
+ default:
+ AssertThrow (ierr >= 0, ExcTrilinosError(ierr));
+ }
// Finally, let the deal.II
// SolverControl object know