1 #include <deal.II/base/conditional_ostream.h> 3 #include <deal.II/lac/solver_control.h> 4 #include <deal.II/lac/trilinos_precondition.h> 5 #include <deal.II/lac/trilinos_solver.h> 8 #include <Ifpack_ILU.h> 10 #include <deal.II/lac/solver_gmres.h> 12 #include "linear_solver.h" 14 #include "global_counter.hpp" 20 using dealii::TrilinosWrappers::PreconditionILU::AdditionalData;
23 void initialize(
const dealii::TrilinosWrappers::SparseMatrix &matrix,
const AdditionalData &additional_data)
25 preconditioner.reset();
27 matrix.trilinos_matrix().Print(std::cout);
29 Epetra_CrsMatrix * epetra_matrix =
const_cast<Epetra_CrsMatrix *
>(&(matrix.trilinos_matrix()));
31 Ifpack_Preconditioner *ifpack =
dynamic_cast<Ifpack_Preconditioner *
>(preconditioner.get());
33 preconditioner.reset(Ifpack().Create(
"ILU", epetra_matrix, additional_data.overlap));
35 std::cout << ifpack << std::endl;
36 ifpack =
dynamic_cast<Ifpack_Preconditioner *
>(preconditioner.get());
37 std::cout << ifpack << std::endl;
39 Assert(ifpack !=
nullptr, dealii::ExcMessage(
"Trilinos could not create this " "preconditioner"));
43 Teuchos::ParameterList parameter_list;
44 parameter_list.set(
"fact: level-of-fill", static_cast<int>(additional_data.ilu_fill));
45 parameter_list.set(
"fact: absolute threshold", additional_data.ilu_atol);
46 parameter_list.set(
"fact: relative threshold", additional_data.ilu_rtol);
48 parameter_list.set(
"schwarz: reordering type",
"rcm");
50 ierr = ifpack->SetParameters(parameter_list);
51 AssertThrow(ierr == 0, dealii::ExcTrilinosError(ierr));
53 ierr = ifpack->Initialize();
54 AssertThrow(ierr == 0, dealii::ExcTrilinosError(ierr));
56 ierr = ifpack->Compute();
57 AssertThrow(ierr == 0, dealii::ExcTrilinosError(ierr));
59 ifpack->Print(std::cout);
61 Ifpack_ILU *ifpack_ilu =
dynamic_cast<Ifpack_ILU *
>(ifpack);
64 const Epetra_CrsMatrix &L = ifpack_ilu->L();
65 const Epetra_Vector &D = ifpack_ilu->D();
66 const Epetra_CrsMatrix &U = ifpack_ilu->U();
76 Teuchos::ParameterList List;
78 const std::string PrecType =
"ILU";
79 List.set(
"fact: level-of-fill", 0);
81 List.set(
"schwarz: reordering type",
"rcm");
82 const int OverlapLevel = 1;
83 Ifpack_Preconditioner *jacobian_prec = Factory.Create(PrecType, epetra_matrix, OverlapLevel);
84 jacobian_prec->Print(std::cout);
85 assert (jacobian_prec != 0);
88 ierr = jacobian_prec->SetParameters(List);
89 AssertThrow(ierr == 0, dealii::ExcTrilinosError(ierr));
90 ierr = jacobian_prec->Initialize();
91 AssertThrow(ierr == 0, dealii::ExcTrilinosError(ierr));
92 ierr = jacobian_prec->Compute();
93 AssertThrow(ierr == 0, dealii::ExcTrilinosError(ierr));
95 preconditioner.reset(jacobian_prec);
99 ifpack =
dynamic_cast<Ifpack_Preconditioner *
>(preconditioner.get());
100 ifpack_ilu =
dynamic_cast<Ifpack_ILU *
>(ifpack);
101 const Epetra_CrsMatrix &L = ifpack_ilu->L();
102 const Epetra_Vector &D = ifpack_ilu->D();
103 const Epetra_CrsMatrix &U = ifpack_ilu->U();
112 std::pair<unsigned int, double>
114 const dealii::TrilinosWrappers::SparseMatrix &system_matrix,
115 dealii::LinearAlgebra::distributed::Vector<double> &right_hand_side,
116 dealii::LinearAlgebra::distributed::Vector<double> &solution,
119 std::shared_ptr<dealii::TrilinosWrappers::PreconditionBase> preconditioner;
122 typedef dealii::TrilinosWrappers::PreconditionILU::AdditionalData AddiData_ILU;
123 const unsigned int overlap = 1;
126 std::shared_ptr<dealii::TrilinosWrappers::PreconditionILU> ilu_preconditioner = std::make_shared<dealii::TrilinosWrappers::PreconditionILU> ();
127 ilu_preconditioner->initialize(system_matrix, precond_settings);
129 preconditioner = ilu_preconditioner;
131 typedef dealii::TrilinosWrappers::PreconditionILUT::AdditionalData AddiData_ILUT;
132 const unsigned int overlap = 1;
135 std::shared_ptr<dealii::TrilinosWrappers::PreconditionILUT> ilut_preconditioner = std::make_shared<dealii::TrilinosWrappers::PreconditionILUT> ();
136 ilut_preconditioner->initialize(system_matrix, precond_settings);
138 preconditioner = ilut_preconditioner;
142 const double rhs_norm = right_hand_side.l2_norm();
143 const double linear_residual_tolerance = param.
linear_residual * rhs_norm;
147 const bool log_result =
true;
148 dealii::SolverControl solver_control(max_iterations, linear_residual_tolerance, log_history, log_result);
149 if (log_history) solver_control.enable_history_data();
151 const bool right_preconditioning =
false;
152 const bool use_default_residual =
true;
153 const bool force_re_orthogonalization =
false;
154 using VectorType = dealii::LinearAlgebra::distributed::Vector<double>;
155 typedef typename dealii::SolverGMRES<VectorType>::AdditionalData AddiData_GMRES;
156 AddiData_GMRES add_data_gmres( param.
restart_number, right_preconditioning, use_default_residual, force_re_orthogonalization);
157 dealii::SolverGMRES<VectorType> solver_gmres(solver_control, add_data_gmres);
160 solver_gmres.solve(system_matrix, solution, right_hand_side, *preconditioner);
162 return {solver_control.last_step(), solver_control.last_value()};
166 std::pair<unsigned int, double>
168 const dealii::TrilinosWrappers::SparseMatrix &system_matrix,
169 dealii::LinearAlgebra::distributed::Vector<double> &right_hand_side,
170 dealii::LinearAlgebra::distributed::Vector<double> &solution,
191 dealii::SolverControl solver_control(1, 0);
192 dealii::TrilinosWrappers::SolverDirect::AdditionalData data(
false);
194 dealii::TrilinosWrappers::SolverDirect direct(solver_control, data);
196 direct.solve(system_matrix, solution, right_hand_side);
197 return {solver_control.last_step(), solver_control.last_value()};
202 Epetra_Vector x(View,
203 system_matrix.trilinos_matrix().DomainMap(),
205 Epetra_Vector b(View,
206 system_matrix.trilinos_matrix().RangeMap(),
207 right_hand_side.begin());
210 solver.SetAztecOption(AZ_solver, AZ_gmres);
218 const double rhs_norm = right_hand_side.l2_norm();
221 solver.SetUserMatrix(const_cast<Epetra_CrsMatrix *>(&system_matrix.trilinos_matrix()));
222 dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0);
223 pcout <<
" Solving linear system with max_iterations = " << max_iterations
224 <<
" and linear residual tolerance: " << linear_residual << std::endl;
228 solver.SetAztecOption(AZ_orthog, AZ_classic);
229 solver.SetAztecOption(AZ_conv, AZ_rhs);
231 solver.SetAztecOption(AZ_precond, AZ_dom_decomp);
232 solver.SetAztecOption(AZ_overlap, 1);
233 solver.SetAztecOption(AZ_reorder, 1);
235 if (ilut_fill < -99) {
241 solver.SetAztecOption(AZ_precond, AZ_none);
242 }
else if (ilut_fill < 1) {
243 solver.SetAztecOption(AZ_subdomain_solve, AZ_ilu);
244 solver.SetAztecOption(AZ_graph_fill, std::abs(ilut_fill));
248 solver.SetAztecParam(AZ_athresh, ilut_atol);
249 solver.SetAztecParam(AZ_rthresh, ilut_rtol);
251 const double ilut_drop = param.
ilut_drop;
254 solver.SetAztecOption(AZ_subdomain_solve, AZ_ilut);
256 solver.SetAztecParam(AZ_drop, ilut_drop);
257 solver.SetAztecParam(AZ_ilut_fill, ilut_fill);
258 solver.SetAztecParam(AZ_athresh, ilut_atol);
259 solver.SetAztecParam(AZ_rthresh, ilut_rtol);
262 unsigned int n_iterations = 0;
263 const int n_solves = 2;
264 for (
int i_solve = 0; i_solve < n_solves; ++i_solve) {
265 solver.Iterate(max_iterations,
267 n_iterations += solver.NumIters();
268 pcout <<
" Solve #" << i_solve + 1 <<
" out of " << n_solves <<
"." 269 <<
" Linear solver took " << solver.NumIters()
270 <<
" iterations resulting in a linear residual of " << solver.ScaledResidual()
274 pcout <<
" Totalling " << n_iterations
275 <<
" iterations resulting in a linear residual of " << solver.ScaledResidual() << std::endl
276 <<
" Current RHS norm: " << right_hand_side.l2_norm()
277 <<
" Linear solution norm: " << solution.l2_norm() << std::endl;
281 n_vmult += 7*solver.NumIters();
282 dRdW_mult += 7*solver.NumIters();
285 return {solver.NumIters(), solver.TrueResidual()};
double ilut_drop
Threshold to drop terms close to zero.
Parameters related to the linear solver.
LinearSolverEnum
Types of linear solvers available.
std::pair< unsigned int, double > solve_linear(const dealii::TrilinosWrappers::SparseMatrix &system_matrix, dealii::LinearAlgebra::distributed::Vector< double > &right_hand_side, dealii::LinearAlgebra::distributed::Vector< double > &solution, const Parameters::LinearSolverParam ¶m)
double ilut_atol
Add ilu_rtol to diagonal for more diagonal dominance.
Files for the baseline physics.
int restart_number
Number of iterations before restarting GMRES.
double linear_residual
Tolerance for linear residual.
LinearSolverEnum linear_solver_type
direct or gmres.
double ilut_rtol
Multiplies diagonal by ilut_rtol for more diagonal dominance.
int max_iterations
Maximum number of linear iteration.
int ilut_fill
ILU fill-in.
OutputEnum linear_solver_output
Can either be verbose or quiet.