include/meltpooldg/linear_algebra/linear_solver.hpp Source File

Developer Documentation: include/meltpooldg/linear_algebra/linear_solver.hpp Source File
Developer Documentation
linear_solver.hpp
Go to the documentation of this file.
1#pragma once
2// for distributed vectors/matrices
3#include <deal.II/lac/precondition.h>
4#include <deal.II/lac/trilinos_sparse_matrix.h>
5// solvers
6#include <deal.II/lac/solver_bicgstab.h>
7#include <deal.II/lac/solver_cg.h> // only for symmetric matrices
8#include <deal.II/lac/solver_gmres.h>
9
10// preconditioner
11#include <deal.II/base/index_set.h>
12#include <deal.II/base/mpi.h>
13
16
17namespace MeltPoolDG
18{
20 {
21 public:
22 template <typename VectorType,
23 typename OperatorType = dealii::TrilinosWrappers::SparseMatrix,
24 typename PreconditionerType = dealii::PreconditionIdentity,
25 typename number = double>
26 static int
27 solve(const OperatorType &system_matrix,
28 VectorType &solution,
29 const VectorType &rhs,
30 const LinearSolverData<number> &data,
31 const PreconditionerType &preconditioner = dealii::PreconditionIdentity(),
32 const std::string identifier = "")
33 {
34 const bool monitor_history = data.monitor_type != LinearSolverMonitorType::none;
35
36 dealii::ReductionControl solver_control(data.max_iterations,
37 data.abs_tolerance,
38 data.rel_tolerance);
39
40 if (monitor_history)
41 solver_control.enable_history_data();
42
43 const auto finalize = [&](const bool failed_step = false) {
44 // TODO: introduce get_mpi_communicator() in BlockVector in deal.II
45 std::unique_ptr<dealii::ConditionalOStream> pcout;
46 if constexpr (dealii::internal::is_block_vector<VectorType>)
47 pcout = std::make_unique<dealii::ConditionalOStream>(
48 std::cout,
49 dealii::Utilities::MPI::this_mpi_process(solution.block(0).get_mpi_communicator()) ==
50 0);
51 else
52 pcout =
53 std::make_unique<dealii::ConditionalOStream>(std::cout,
54 dealii::Utilities::MPI::this_mpi_process(
55 solution.get_mpi_communicator()) == 0);
56
57 if (monitor_history)
58 {
59 const auto &history_data = solver_control.get_history_data();
60
62 {
63 std::ostringstream str;
64 str << std::setw(5) << "# iter" << std::setw(20) << std::scientific
65 << std::setprecision(5) << "|Res| ";
66 Journal::print_line(*pcout, str.str(), "linear solver");
67 }
69
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;
74 Journal::print_line(*pcout, str.str(), "linear solver");
75 };
76
77 if (data.monitor_type == LinearSolverMonitorType::all)
78 {
79 for (unsigned int i = 0; i < history_data.size(); ++i)
80 print_value(i, history_data[i]);
81 }
82 else if (data.monitor_type == LinearSolverMonitorType::reduced)
83 {
84 print_value(0, history_data[0]);
85 if (history_data.size() >= 2)
86 print_value(history_data.size() - 1, history_data.back());
87 }
88 else
89 {
90 AssertThrow(false, dealii::ExcNotImplemented());
91 }
93 }
94
95 if (!identifier.empty() && failed_step)
97 "Exception with ID >> " + identifier + " << occured.",
98 "linear solver");
99 };
100
101
102 try
103 {
104 switch (data.solver_type)
105 {
106 case (LinearSolverType::CG): {
107 dealii::SolverCG<VectorType> solver(solver_control);
108
109 solver.solve(system_matrix, solution, rhs, preconditioner);
110 break;
111 }
112 case (LinearSolverType::GMRES): {
113 typename dealii::SolverGMRES<VectorType>::AdditionalData additional_data;
114 additional_data.right_preconditioning = true;
115
116 dealii::SolverGMRES<VectorType> solver(solver_control, additional_data);
117 solver.solve(system_matrix, solution, rhs, preconditioner);
118 break;
119 }
120 default:
121 AssertThrow(false, dealii::ExcNotImplemented());
122 }
123 }
124 catch (const dealii::SolverControl::NoConvergence &e)
125 {
126 finalize(true /*failed_step*/);
127
128 AssertThrow(false, e);
129 }
130
131 finalize();
132
133 return solver_control.last_step();
134 }
135 };
136} // namespace MeltPoolDG
Definition linear_solver.hpp:20
static int solve(const OperatorType &system_matrix, VectorType &solution, const VectorType &rhs, const LinearSolverData< number > &data, const PreconditionerType &preconditioner=dealii::PreconditionIdentity(), const std::string identifier="")
Definition linear_solver.hpp:27
void print_decoration_line(const ConditionalOStream &pcout)
Definition journal.hpp:19
void print_line(const ConditionalOStream &pcout, const std::string &text="", const std::string &operation_name="", const unsigned int extra_size=0)
Definition journal.cpp:11
Interface for a general preconditioner.
Definition boundary_condition_functions.hpp:17