15#ifdef DEAL_II_TRILINOS_WITH_EPETRA
25# include <AztecOO_StatusTest.h>
26# include <AztecOO_StatusTestCombo.h>
27# include <AztecOO_StatusTestMaxIters.h>
28# include <AztecOO_StatusTestResNorm.h>
29# include <AztecOO_StatusType.h>
42#ifdef DEAL_II_TRILINOS_WITH_EPETRA
47 const bool output_solver_details,
48 const unsigned int gmres_restart_parameter)
49 : output_solver_details(output_solver_details)
50 , gmres_restart_parameter(gmres_restart_parameter)
66 : solver_name(solver_name)
68 , additional_data(
data)
90 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()),
92 const_cast<Epetra_MultiVector *
>(&b.trilinos_vector()));
110 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
112 const_cast<Epetra_MultiVector *
>(
113 &b.trilinos_vector()));
131 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
133 const_cast<Epetra_MultiVector *
>(
134 &b.trilinos_vector()));
145 Epetra_MultiVector &x,
146 const Epetra_MultiVector &b,
152 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
154 const_cast<Epetra_MultiVector *
>(
166 Epetra_MultiVector &x,
167 const Epetra_MultiVector &b,
173 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
175 const_cast<Epetra_MultiVector *
>(
186 const ::Vector<double> &b,
193 Assert(A.local_range().second == A.m(),
194 ExcMessage(
"Can only work in serial when using deal.II vectors."));
195 Assert(A.trilinos_matrix().Filled(),
196 ExcMessage(
"Matrix is not compressed. Call compress() method."));
198 Epetra_Vector ep_x(View, A.trilinos_matrix().DomainMap(), x.
begin());
199 Epetra_Vector ep_b(View,
200 A.trilinos_matrix().RangeMap(),
201 const_cast<double *
>(b.begin()));
206 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()), &ep_x, &ep_b);
216 const ::Vector<double> &b,
219 Epetra_Vector ep_x(View, A.OperatorDomainMap(), x.
begin());
220 Epetra_Vector ep_b(View,
221 A.OperatorRangeMap(),
222 const_cast<double *
>(b.begin()));
226 linear_problem = std::make_unique<Epetra_LinearProblem>(&A, &ep_x, &ep_b);
236 const ::LinearAlgebra::distributed::Vector<double> &b,
242 A.trilinos_matrix().DomainMap().NumMyElements());
244 A.trilinos_matrix().RangeMap().NumMyElements());
246 Epetra_Vector ep_x(View, A.trilinos_matrix().DomainMap(), x.
begin());
247 Epetra_Vector ep_b(View,
248 A.trilinos_matrix().RangeMap(),
249 const_cast<double *
>(b.begin()));
254 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()), &ep_x, &ep_b);
264 const ::LinearAlgebra::distributed::Vector<double> &b,
265 const PreconditionBase &preconditioner)
268 A.OperatorDomainMap().NumMyElements());
270 A.OperatorRangeMap().NumMyElements());
272 Epetra_Vector ep_x(View, A.OperatorDomainMap(), x.
begin());
273 Epetra_Vector ep_b(View,
274 A.OperatorRangeMap(),
275 const_cast<double *
>(b.begin()));
279 linear_problem = std::make_unique<Epetra_LinearProblem>(&A, &ep_x, &ep_b);
290 compute_residual(
const Epetra_MultiVector *
const residual_vector)
292 Assert(residual_vector->NumVectors() == 1,
293 ExcMessage(
"Residual multivector holds more than one vector"));
295 const int ierr = residual_vector->Norm2(&res_l2_norm);
300 class TrilinosReductionControl :
public AztecOO_StatusTest
303 TrilinosReductionControl(
const int max_steps,
304 const double tolerance,
305 const double reduction,
306 const Epetra_LinearProblem &linear_problem);
308 virtual ~TrilinosReductionControl()
override =
default;
311 ResidualVectorRequired()
const override
316 virtual AztecOO_StatusType
317 CheckStatus(
int CurrentIter,
318 Epetra_MultiVector *CurrentResVector,
319 double CurrentResNormEst,
320 bool SolutionUpdated)
override
325 (CurrentResNormEst < 0.0 ? compute_residual(CurrentResVector) :
327 if (CurrentIter == 0)
336 virtual AztecOO_StatusType
337 GetStatus()
const override
342 virtual std::ostream &
343 Print(std::ostream &stream,
int indent = 0)
const override
349 get_initial_residual()
const
355 get_current_residual()
const
370 TrilinosReductionControl::TrilinosReductionControl(
372 const double tolerance,
373 const double reduction,
374 const Epetra_LinearProblem &linear_problem)
380 AztecOO_StatusTestCombo::OR))
385 std::make_unique<AztecOO_StatusTestMaxIters>(max_steps);
388 Assert(linear_problem.GetRHS()->NumVectors() == 1,
389 ExcMessage(
"RHS multivector holds more than one vector"));
393 *linear_problem.GetOperator(),
394 *(linear_problem.GetLHS()->operator()(0)),
395 *(linear_problem.GetRHS()->operator()(0)),
398 AztecOO_StatusTestResNorm::TwoNorm);
400 AztecOO_StatusTestResNorm::None, AztecOO_StatusTestResNorm::TwoNorm);
405 *linear_problem.GetOperator(),
406 *(linear_problem.GetLHS()->operator()(0)),
407 *(linear_problem.GetRHS()->operator()(0)),
410 AztecOO_StatusTestResNorm::TwoNorm);
412 AztecOO_StatusTestResNorm::NormOfInitRes,
413 AztecOO_StatusTestResNorm::TwoNorm);
421 template <
typename Preconditioner>
423 SolverBase::do_solve(
const Preconditioner &preconditioner)
428 solver.SetProblem(*linear_problem);
434 solver.SetAztecOption(AZ_solver, AZ_cg);
437 solver.SetAztecOption(AZ_solver, AZ_cgs);
440 solver.SetAztecOption(AZ_solver, AZ_gmres);
441 solver.SetAztecOption(AZ_kspace,
442 additional_data.gmres_restart_parameter);
445 solver.SetAztecOption(AZ_solver, AZ_bicgstab);
448 solver.SetAztecOption(AZ_solver, AZ_tfqmr);
455 set_preconditioner(solver, preconditioner);
458 solver.SetAztecOption(AZ_output,
459 additional_data.output_solver_details ? AZ_all :
461 solver.SetAztecOption(AZ_conv, AZ_noscaled);
481 status_test = std::make_unique<internal::TrilinosReductionControl>(
482 reduction_control->max_steps(),
483 reduction_control->tolerance(),
484 reduction_control->reduction(),
486 solver.SetStatusTest(status_test.get());
492 solver.Iterate(solver_control.max_steps(), solver_control.tolerance());
502 "option not implemented"));
507 "numerical breakdown"));
512 "loss of precision"));
517 "GMRES Hessenberg ill-conditioned"));
530 if (
const internal::TrilinosReductionControl
531 *
const reduction_control_status =
532 dynamic_cast<const internal::TrilinosReductionControl *
>(
541 if (solver.NumIters() > 0)
546 solver_control.check(
547 0, reduction_control_status->get_initial_residual());
548 solver_control.check(
550 reduction_control_status->get_current_residual());
553 solver_control.check(
555 reduction_control_status->get_current_residual());
560 solver_control.check(solver.NumIters(), solver.TrueResidual());
566 solver_control.last_value()));
573 SolverBase::set_preconditioner(AztecOO &solver,
580 const int ierr = solver.SetPrecOperator(
585 solver.SetAztecOption(AZ_precond, AZ_none);
591 SolverBase::set_preconditioner(AztecOO &solver,
595 solver.SetPrecOperator(
const_cast<Epetra_Operator *
>(&preconditioner));
639 const std::string &solver_type)
640 : output_solver_details(output_solver_details)
641 , solver_type(solver_type)
655 , additional_data(
data.output_solver_details,
data.solver_type)
677 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()));
694 "You tried to select the solver type <" +
696 "> but this solver is not supported by Trilinos either "
697 "because it does not exist, or because Trilinos was not "
698 "configured for its use."));
703 verbose_cout <<
"Starting symbolic factorization" << std::endl;
704 ierr =
solver->SymbolicFactorization();
707 verbose_cout <<
"Starting numeric factorization" << std::endl;
708 ierr =
solver->NumericFactorization();
734 const ::LinearAlgebra::distributed::Vector<double> &b)
748 const_cast<Epetra_MultiVector *
>(&b.trilinos_vector()));
756 verbose_cout <<
"Starting solve" << std::endl;
759 int ierr =
solver->Solve();
771 const ::LinearAlgebra::distributed::Vector<double> &b)
const
773 Epetra_Vector ep_x(View,
776 Epetra_Vector ep_b(View,
778 const_cast<double *
>(b.begin()));
791 verbose_cout <<
"Starting solve" << std::endl;
794 int ierr =
solver->Solve();
821 "You tried to select the solver type <" +
823 "> but this solver is not supported by Trilinos either "
824 "because it does not exist, or because Trilinos was not "
825 "configured for its use."));
830 verbose_cout <<
"Starting symbolic factorization" << std::endl;
831 ierr =
solver->SymbolicFactorization();
834 verbose_cout <<
"Starting numeric factorization" << std::endl;
835 ierr =
solver->NumericFactorization();
838 verbose_cout <<
"Starting solve" << std::endl;
856 Epetra_MultiVector &x,
857 const Epetra_MultiVector &b)
862 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
864 const_cast<Epetra_MultiVector *
>(
881 const unsigned int m = rhs.
m();
882 const unsigned int n = rhs.
n();
890 std::vector<double *> rhs_ptrs(n);
891 std::vector<double *> sultion_ptrs(n);
893 for (
unsigned int i = 0; i < n; ++i)
895 rhs_ptrs[i] = &rhs_t[i][0];
896 sultion_ptrs[i] = &solution_t[i][0];
901 Epetra_MultiVector trilinos_dst(View,
902 mat.OperatorRangeMap(),
904 sultion_ptrs.size());
905 Epetra_MultiVector trilinos_src(View,
906 mat.OperatorDomainMap(),
911 this->
solve(mat, trilinos_dst, trilinos_src);
925 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()),
927 const_cast<Epetra_MultiVector *
>(&b.trilinos_vector()));
937 const ::Vector<double> &b)
943 Assert(A.local_range().second == A.m(),
944 ExcMessage(
"Can only work in serial when using deal.II vectors."));
945 Epetra_Vector ep_x(View, A.trilinos_matrix().DomainMap(), x.
begin());
946 Epetra_Vector ep_b(View,
947 A.trilinos_matrix().RangeMap(),
948 const_cast<double *
>(b.begin()));
953 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()), &ep_x, &ep_b);
964 const ::LinearAlgebra::distributed::Vector<double> &b)
967 A.trilinos_matrix().DomainMap().NumMyElements());
969 A.trilinos_matrix().RangeMap().NumMyElements());
970 Epetra_Vector ep_x(View, A.trilinos_matrix().DomainMap(), x.
begin());
971 Epetra_Vector ep_b(View,
972 A.trilinos_matrix().RangeMap(),
973 const_cast<double *
>(b.begin()));
978 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()), &ep_x, &ep_b);
void copy_transposed(const MatrixType &)
size_type locally_owned_size() const
SolverCG(SolverControl &cn, VectorMemory< VectorType > &mem, const AdditionalData &data=AdditionalData())
unsigned int last_step() const
double last_value() const
virtual State check(const unsigned int step, const double check_value)
@ success
Stop iteration, goal reached.
const Epetra_MultiVector & trilinos_vector() const
Teuchos::RCP< Epetra_Operator > preconditioner
SolverControl & control() const
void solve(const SparseMatrix &A, MPI::Vector &x, const MPI::Vector &b, const PreconditionBase &preconditioner)
const AdditionalData additional_data
SolverControl & solver_control
void do_solve(const Preconditioner &preconditioner)
std::unique_ptr< Epetra_LinearProblem > linear_problem
SolverBase(SolverControl &cn, const AdditionalData &data=AdditionalData())
enum TrilinosWrappers::SolverBase::SolverName solver_name
SolverBicgstab(SolverControl &cn, const AdditionalData &data=AdditionalData())
SolverCGS(SolverControl &cn, const AdditionalData &data=AdditionalData())
void initialize(const SparseMatrix &A)
void vmult(MPI::Vector &x, const MPI::Vector &b) const
std::unique_ptr< Amesos_BaseSolver > solver
SolverControl & solver_control
void solve(MPI::Vector &x, const MPI::Vector &b)
std::unique_ptr< Epetra_LinearProblem > linear_problem
AdditionalData additional_data
SolverControl solver_control_own
SolverControl & control() const
SolverDirect(const AdditionalData &data=AdditionalData())
SolverGMRES(SolverControl &cn, const AdditionalData &data=AdditionalData())
SolverTFQMR(SolverControl &cn, const AdditionalData &data=AdditionalData())
const Epetra_CrsMatrix & trilinos_matrix() const
virtual size_type size() const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcTrilinosError(int arg1)
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcTrilinosError(int arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::vector< index_type > data
AdditionalData(const bool output_solver_details=false, const unsigned int gmres_restart_parameter=30)
AdditionalData(const bool output_solver_details=false, const std::string &solver_type="Amesos_Klu")
bool output_solver_details
std::unique_ptr< AztecOO_StatusTestResNorm > status_test_abs_tol
std::unique_ptr< AztecOO_StatusTestResNorm > status_test_rel_tol
std::unique_ptr< AztecOO_StatusTestMaxIters > status_test_max_steps
std::unique_ptr< AztecOO_StatusTestCombo > status_test_collection