27 solve(
const OperatorType &system_matrix,
29 const VectorType &rhs,
30 const LinearSolverData<number> &data,
31 const PreconditionerType &preconditioner = dealii::PreconditionIdentity(),
32 const std::string identifier =
"")
34 const bool monitor_history = data.monitor_type != LinearSolverMonitorType::none;
36 dealii::ReductionControl solver_control(data.max_iterations,
41 solver_control.enable_history_data();
43 const auto finalize = [&](
const bool failed_step =
false) {
45 std::unique_ptr<dealii::ConditionalOStream> pcout;
46 if constexpr (dealii::internal::is_block_vector<VectorType>)
47 pcout = std::make_unique<dealii::ConditionalOStream>(
49 dealii::Utilities::MPI::this_mpi_process(solution.block(0).get_mpi_communicator()) ==
53 std::make_unique<dealii::ConditionalOStream>(std::cout,
54 dealii::Utilities::MPI::this_mpi_process(
55 solution.get_mpi_communicator()) == 0);
59 const auto &history_data = solver_control.get_history_data();
63 std::ostringstream str;
64 str << std::setw(5) <<
"# iter" << std::setw(20) << std::scientific
65 << std::setprecision(5) <<
"|Res| ";
70 const auto print_value = [&](
const unsigned int iteration,
const number value) {
71 std::ostringstream str;
72 str << std::setw(5) << iteration << std::setw(20) << std::scientific
73 << std::setprecision(5) << value;
77 if (data.monitor_type == LinearSolverMonitorType::all)
79 for (
unsigned int i = 0; i < history_data.size(); ++i)
80 print_value(i, history_data[i]);
82 else if (data.monitor_type == LinearSolverMonitorType::reduced)
84 print_value(0, history_data[0]);
85 if (history_data.size() >= 2)
86 print_value(history_data.size() - 1, history_data.back());
90 AssertThrow(
false, dealii::ExcNotImplemented());
95 if (!identifier.empty() && failed_step)
97 "Exception with ID >> " + identifier +
" << occured.",
104 switch (data.solver_type)
106 case (LinearSolverType::CG): {
107 dealii::SolverCG<VectorType> solver(solver_control);
109 solver.solve(system_matrix, solution, rhs, preconditioner);
112 case (LinearSolverType::GMRES): {
113 typename dealii::SolverGMRES<VectorType>::AdditionalData additional_data;
114 additional_data.right_preconditioning =
true;
116 dealii::SolverGMRES<VectorType> solver(solver_control, additional_data);
117 solver.solve(system_matrix, solution, rhs, preconditioner);
121 AssertThrow(
false, dealii::ExcNotImplemented());
124 catch (
const dealii::SolverControl::NoConvergence &e)
128 AssertThrow(
false, e);
133 return solver_control.last_step();