12#ifndef ARCCORE_ALINA_SOLVERRUNTIME_H
13#define ARCCORE_ALINA_SOLVERRUNTIME_H
30#include "arccore/alina/AlinaUtils.h"
31#include "arccore/alina/ConjugateGradientSolver.h"
32#include "arccore/alina/BiCGStabSolver.h"
33#include "arccore/alina/BiCGStabLSolver.h"
34#include "arccore/alina/GMRESSolver.h"
35#include "arccore/alina/LooseGMRESSolver.h"
36#include "arccore/alina/FlexibleGMRESSolver.h"
37#include "arccore/alina/IDRSSolver.h"
38#include "arccore/alina/RichardsonSolver.h"
39#include "arccore/alina/PreconditionerOnlySolver.h"
44namespace Arcane::Alina
53 ConjugateGradientSolver = cg,
55 BiCGStabSolver = bicgstab,
57 BiCGStabLSolver = bicgstabl,
61 LooseGMRESSolver = lgmres,
63 FlexibleGMRESSolver = fgmres,
67 RichardsonSolver = richardson,
69 PreconditionerOnlySolver = preonly
72inline std::ostream& operator<<(std::ostream& os, eSolverType s)
77 case eSolverType::bicgstab:
78 return os <<
"bicgstab";
79 case eSolverType::bicgstabl:
80 return os <<
"bicgstabl";
81 case eSolverType::gmres:
83 case eSolverType::lgmres:
84 return os <<
"lgmres";
85 case eSolverType::fgmres:
86 return os <<
"fgmres";
87 case eSolverType::idrs:
89 case eSolverType::richardson:
90 return os <<
"richardson";
91 case eSolverType::preonly:
92 return os <<
"preonly";
98inline std::istream& operator>>(std::istream& in, eSolverType& s)
105 else if (val ==
"bicgstab")
106 s = eSolverType::bicgstab;
107 else if (val ==
"bicgstabl")
108 s = eSolverType::bicgstabl;
109 else if (val ==
"gmres")
110 s = eSolverType::gmres;
111 else if (val ==
"lgmres")
112 s = eSolverType::lgmres;
113 else if (val ==
"fgmres")
114 s = eSolverType::fgmres;
115 else if (val ==
"idrs")
116 s = eSolverType::idrs;
117 else if (val ==
"richardson")
118 s = eSolverType::richardson;
119 else if (val ==
"preonly")
120 s = eSolverType::preonly;
122 throw std::invalid_argument(
"Invalid solver value. Valid choices are: "
123 "cg, bicgstab, bicgstabl, gmres, lgmres, fgmres, idrs, richardson, preonly.");
128#define ARCCORE_ALINA_ALL_RUNTIME_SOLVER() \
129 ARCCORE_ALINA_RUNTIME_SOLVER(ConjugateGradientSolver); \
130 ARCCORE_ALINA_RUNTIME_SOLVER(BiCGStabSolver); \
131 ARCCORE_ALINA_RUNTIME_SOLVER(BiCGStabLSolver); \
132 ARCCORE_ALINA_RUNTIME_SOLVER(GMRESSolver); \
133 ARCCORE_ALINA_RUNTIME_SOLVER(LooseGMRESSolver); \
134 ARCCORE_ALINA_RUNTIME_SOLVER(FlexibleGMRESSolver); \
135 ARCCORE_ALINA_RUNTIME_SOLVER(IDRSSolver); \
136 ARCCORE_ALINA_RUNTIME_SOLVER(RichardsonSolver); \
137 ARCCORE_ALINA_RUNTIME_SOLVER(PreconditionerOnlySolver)
144template <
class Backend,
class InnerProduct = detail::default_inner_product>
149 typedef typename Backend::value_type value_type;
150 typedef typename math::scalar_of<value_type>::type scalar_type;
151 typedef Backend backend_type;
152 using BackendType = backend_type;
154 eSolverType m_solver_type;
157 explicit SolverRuntime(
size_t n, params prm = params(),
158 const backend_params& bprm = backend_params(),
159 const InnerProduct& inner_product = InnerProduct())
160 : m_solver_type(prm.get(
"type", eSolverType::bicgstab))
162 if (!prm.erase(
"type"))
163 ARCCORE_ALINA_PARAM_MISSING(
"type");
165 switch (m_solver_type) {
167#define ARCCORE_ALINA_RUNTIME_SOLVER(type) \
168 case eSolverType::type: \
169 m_solver = new type<Backend, InnerProduct>(n, prm, bprm, inner_product); \
172 ARCCORE_ALINA_ALL_RUNTIME_SOLVER();
174#undef ARCCORE_ALINA_RUNTIME_SOLVER
177 ARCCORE_FATAL(
"Unsupported solver type type={0}", m_solver_type);
186 template <
class Matrix,
class Precond,
class Vec1,
class Vec2>
187 SolverResult operator()(
const Matrix& A,
const Precond& P,
const Vec1& rhs, Vec2&& x)
const
189 switch (m_solver_type) {
191#define ARCCORE_ALINA_RUNTIME_SOLVER(type) \
192 case eSolverType::type: \
193 return static_cast<type<Backend, InnerProduct>*>(m_solver)->operator()(A, P, rhs, x)
195 ARCCORE_ALINA_ALL_RUNTIME_SOLVER();
197#undef ARCCORE_ALINA_RUNTIME_SOLVER
200 ARCCORE_FATAL(
"Unsupported solver type type={0}", m_solver_type);
204 template <
class Precond,
class Vec1,
class Vec2>
205 SolverResult operator()(
const Precond& P,
const Vec1& rhs, Vec2&& x)
const
207 return (*
this)(P.system_matrix(), P, rhs, x);
210 friend std::ostream& operator<<(std::ostream& os,
const SolverRuntime& w)
212 switch (w.m_solver_type) {
214#define ARCCORE_ALINA_RUNTIME_SOLVER(type) \
215 case eSolverType::type: \
216 return os << *static_cast<type<Backend, InnerProduct>*>(w.m_solver)
218 ARCCORE_ALINA_ALL_RUNTIME_SOLVER();
220#undef ARCCORE_ALINA_RUNTIME_SOLVER
223 ARCCORE_FATAL(
"Unsupported solver type type={0}", w.m_solver_type);
229 return m_solver->bytes();
233#undef ARCCORE_ALINA_ALL_RUNTIME_SOLVER
#define ARCCORE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Matrix class, to be used by user.
Alina::detail::empty_params params