17#ifdef DEAL_II_WITH_TRILINOS
27# include <AztecOO_StatusTest.h>
28# include <AztecOO_StatusTestCombo.h>
29# include <AztecOO_StatusTestMaxIters.h>
30# include <AztecOO_StatusTestResNorm.h>
31# include <AztecOO_StatusType.h>
87 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()),
89 const_cast<Epetra_MultiVector *
>(&b.trilinos_vector()));
107 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
109 const_cast<Epetra_MultiVector *
>(
110 &b.trilinos_vector()));
128 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
130 const_cast<Epetra_MultiVector *
>(
131 &b.trilinos_vector()));
142 Epetra_MultiVector &x,
143 const Epetra_MultiVector &b,
149 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
151 const_cast<Epetra_MultiVector *
>(
163 Epetra_MultiVector &x,
164 const Epetra_MultiVector &b,
170 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
172 const_cast<Epetra_MultiVector *
>(
183 const ::Vector<double> &b,
190 Assert(A.local_range().second == A.m(),
191 ExcMessage(
"Can only work in serial when using deal.II vectors."));
192 Assert(A.trilinos_matrix().Filled(),
193 ExcMessage(
"Matrix is not compressed. Call compress() method."));
195 Epetra_Vector ep_x(View, A.trilinos_matrix().DomainMap(), x.
begin());
196 Epetra_Vector ep_b(View,
197 A.trilinos_matrix().RangeMap(),
198 const_cast<double *
>(b.begin()));
203 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()), &ep_x, &ep_b);
213 const ::Vector<double> &b,
216 Epetra_Vector ep_x(View, A.OperatorDomainMap(), x.
begin());
217 Epetra_Vector ep_b(View,
218 A.OperatorRangeMap(),
219 const_cast<double *
>(b.begin()));
223 linear_problem = std::make_unique<Epetra_LinearProblem>(&A, &ep_x, &ep_b);
233 const ::LinearAlgebra::distributed::Vector<double> &b,
239 A.trilinos_matrix().DomainMap().NumMyElements());
241 A.trilinos_matrix().RangeMap().NumMyElements());
243 Epetra_Vector ep_x(View, A.trilinos_matrix().DomainMap(), x.
begin());
244 Epetra_Vector ep_b(View,
245 A.trilinos_matrix().RangeMap(),
246 const_cast<double *
>(b.begin()));
251 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()), &ep_x, &ep_b);
261 const ::LinearAlgebra::distributed::Vector<double> &b,
265 A.OperatorDomainMap().NumMyElements());
267 A.OperatorRangeMap().NumMyElements());
269 Epetra_Vector ep_x(View, A.OperatorDomainMap(), x.
begin());
270 Epetra_Vector ep_b(View,
271 A.OperatorRangeMap(),
272 const_cast<double *
>(b.begin()));
276 linear_problem = std::make_unique<Epetra_LinearProblem>(&A, &ep_x, &ep_b);
287 compute_residual(
const Epetra_MultiVector *
const residual_vector)
289 Assert(residual_vector->NumVectors() == 1,
290 ExcMessage(
"Residual multivector holds more than one vector"));
292 const int ierr = residual_vector->Norm2(&res_l2_norm);
297 class TrilinosReductionControl :
public AztecOO_StatusTest
300 TrilinosReductionControl(
const int max_steps,
301 const double tolerance,
302 const double reduction,
303 const Epetra_LinearProblem &linear_problem);
305 virtual ~TrilinosReductionControl()
override =
default;
308 ResidualVectorRequired()
const override
310 return status_test_collection->ResidualVectorRequired();
313 virtual AztecOO_StatusType
314 CheckStatus(
int CurrentIter,
315 Epetra_MultiVector *CurrentResVector,
316 double CurrentResNormEst,
317 bool SolutionUpdated)
override
322 (CurrentResNormEst < 0.0 ? compute_residual(CurrentResVector) :
324 if (CurrentIter == 0)
325 initial_residual = current_residual;
327 return status_test_collection->CheckStatus(CurrentIter,
333 virtual AztecOO_StatusType
334 GetStatus()
const override
336 return status_test_collection->GetStatus();
339 virtual std::ostream &
340 Print(std::ostream &stream,
int indent = 0)
const override
342 return status_test_collection->Print(stream, indent);
346 get_initial_residual()
const
348 return initial_residual;
352 get_current_residual()
const
354 return current_residual;
358 double initial_residual;
359 double current_residual;
360 std::unique_ptr<AztecOO_StatusTestCombo> status_test_collection;
361 std::unique_ptr<AztecOO_StatusTestMaxIters> status_test_max_steps;
362 std::unique_ptr<AztecOO_StatusTestResNorm> status_test_abs_tol;
363 std::unique_ptr<AztecOO_StatusTestResNorm> status_test_rel_tol;
367 TrilinosReductionControl::TrilinosReductionControl(
369 const double tolerance,
370 const double reduction,
371 const Epetra_LinearProblem &linear_problem)
372 : initial_residual(std::numeric_limits<double>::
max())
373 , current_residual(std::numeric_limits<double>::
max())
376 , status_test_collection(std::make_unique<AztecOO_StatusTestCombo>(
377 AztecOO_StatusTestCombo::OR))
381 status_test_max_steps =
382 std::make_unique<AztecOO_StatusTestMaxIters>(max_steps);
383 status_test_collection->AddStatusTest(*status_test_max_steps);
386 ExcMessage(
"RHS multivector holds more than one vector"));
389 status_test_abs_tol = std::make_unique<AztecOO_StatusTestResNorm>(
394 status_test_abs_tol->DefineResForm(AztecOO_StatusTestResNorm::Explicit,
395 AztecOO_StatusTestResNorm::TwoNorm);
396 status_test_abs_tol->DefineScaleForm(
397 AztecOO_StatusTestResNorm::None, AztecOO_StatusTestResNorm::TwoNorm);
398 status_test_collection->AddStatusTest(*status_test_abs_tol);
401 status_test_rel_tol = std::make_unique<AztecOO_StatusTestResNorm>(
406 status_test_rel_tol->DefineResForm(AztecOO_StatusTestResNorm::Explicit,
407 AztecOO_StatusTestResNorm::TwoNorm);
408 status_test_rel_tol->DefineScaleForm(
409 AztecOO_StatusTestResNorm::NormOfInitRes,
410 AztecOO_StatusTestResNorm::TwoNorm);
411 status_test_collection->AddStatusTest(*status_test_rel_tol);
418 template <
typename Preconditioner>
431 solver.SetAztecOption(AZ_solver, AZ_cg);
434 solver.SetAztecOption(AZ_solver, AZ_cgs);
437 solver.SetAztecOption(AZ_solver, AZ_gmres);
438 solver.SetAztecOption(AZ_kspace,
442 solver.SetAztecOption(AZ_solver, AZ_bicgstab);
445 solver.SetAztecOption(AZ_solver, AZ_tfqmr);
455 solver.SetAztecOption(AZ_output,
458 solver.SetAztecOption(AZ_conv, AZ_noscaled);
478 status_test = std::make_unique<internal::TrilinosReductionControl>(
479 reduction_control->max_steps(),
480 reduction_control->tolerance(),
481 reduction_control->reduction(),
499 "option not implemented"));
504 "numerical breakdown"));
509 "loss of precision"));
514 "GMRES Hessenberg ill-conditioned"));
527 if (
const internal::TrilinosReductionControl
528 *
const reduction_control_status =
529 dynamic_cast<const internal::TrilinosReductionControl *
>(
538 if (
solver.NumIters() > 0)
544 0, reduction_control_status->get_initial_residual());
547 reduction_control_status->get_current_residual());
552 reduction_control_status->get_current_residual());
577 const int ierr =
solver.SetPrecOperator(
582 solver.SetAztecOption(AZ_precond, AZ_none);
674 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()));
691 "You tried to select the solver type <" +
693 "> but this solver is not supported by Trilinos either "
694 "because it does not exist, or because Trilinos was not "
695 "configured for its use."));
700 verbose_cout <<
"Starting symbolic factorization" << std::endl;
701 ierr =
solver->SymbolicFactorization();
704 verbose_cout <<
"Starting numeric factorization" << std::endl;
705 ierr =
solver->NumericFactorization();
731 const ::LinearAlgebra::distributed::Vector<double> &b)
745 const_cast<Epetra_MultiVector *
>(&b.trilinos_vector()));
753 verbose_cout <<
"Starting solve" << std::endl;
756 int ierr =
solver->Solve();
768 const ::LinearAlgebra::distributed::Vector<double> &b)
const
770 Epetra_Vector ep_x(View,
773 Epetra_Vector ep_b(View,
775 const_cast<double *
>(b.begin()));
788 verbose_cout <<
"Starting solve" << std::endl;
791 int ierr =
solver->Solve();
818 "You tried to select the solver type <" +
820 "> but this solver is not supported by Trilinos either "
821 "because it does not exist, or because Trilinos was not "
822 "configured for its use."));
827 verbose_cout <<
"Starting symbolic factorization" << std::endl;
828 ierr =
solver->SymbolicFactorization();
831 verbose_cout <<
"Starting numeric factorization" << std::endl;
832 ierr =
solver->NumericFactorization();
835 verbose_cout <<
"Starting solve" << std::endl;
853 Epetra_MultiVector &x,
854 const Epetra_MultiVector &b)
859 std::make_unique<Epetra_LinearProblem>(
const_cast<Epetra_Operator *
>(&A),
861 const_cast<Epetra_MultiVector *
>(
878 const unsigned int m = rhs.
m();
879 const unsigned int n = rhs.
n();
887 std::vector<double *> rhs_ptrs(n);
888 std::vector<double *> sultion_ptrs(n);
890 for (
unsigned int i = 0; i < n; ++i)
892 rhs_ptrs[i] = &rhs_t[i][0];
893 sultion_ptrs[i] = &solution_t[i][0];
898 Epetra_MultiVector trilinos_dst(View,
899 mat.OperatorRangeMap(),
901 sultion_ptrs.size());
902 Epetra_MultiVector trilinos_src(View,
903 mat.OperatorDomainMap(),
908 this->
solve(mat, trilinos_dst, trilinos_src);
922 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()),
924 const_cast<Epetra_MultiVector *
>(&b.trilinos_vector()));
934 const ::Vector<double> &b)
940 Assert(A.local_range().second == A.m(),
941 ExcMessage(
"Can only work in serial when using deal.II vectors."));
942 Epetra_Vector ep_x(View, A.trilinos_matrix().DomainMap(), x.
begin());
943 Epetra_Vector ep_b(View,
944 A.trilinos_matrix().RangeMap(),
945 const_cast<double *
>(b.begin()));
950 const_cast<Epetra_CrsMatrix *
>(&A.trilinos_matrix()), &ep_x, &ep_b);
961 const ::LinearAlgebra::distributed::Vector<double> &b)
964 A.trilinos_matrix().DomainMap().NumMyElements());
966 A.trilinos_matrix().RangeMap().NumMyElements());
967 Epetra_Vector ep_x(View, A.trilinos_matrix().DomainMap(), x.
begin());
968 Epetra_Vector ep_b(View,
969 A.trilinos_matrix().RangeMap(),
970 const_cast<double *
>(b.begin()));
975 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())
@ 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
std::unique_ptr< AztecOO_StatusTest > status_test
void set_preconditioner(AztecOO &solver, const Preconditioner &preconditioner)
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)
const unsigned int gmres_restart_parameter
const bool output_solver_details
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