Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
SolverRuntime.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* SolverRuntime.h (C) 2000-2026 */
9/* */
10/* Runtime-configurable solvers. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_SOLVERRUNTIME_H
13#define ARCCORE_ALINA_SOLVERRUNTIME_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16/*
17 * This file is based on the work on AMGCL library (version march 2026)
18 * which can be found at https://github.com/ddemidov/amgcl.
19 *
20 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
21 * SPDX-License-Identifier: MIT
22 */
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26#include <iostream>
27#include <stdexcept>
28#include <type_traits>
29
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"
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
44namespace Arcane::Alina
45{
46
47/*---------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------*/
49
50enum class eSolverType
51{
52 cg,
53 ConjugateGradientSolver = cg,
54 bicgstab,
55 BiCGStabSolver = bicgstab,
56 bicgstabl,
57 BiCGStabLSolver = bicgstabl,
58 gmres,
59 GMRESSolver = gmres,
60 lgmres,
61 LooseGMRESSolver = lgmres,
62 fgmres,
63 FlexibleGMRESSolver = fgmres,
64 idrs,
65 IDRSSolver = idrs,
66 richardson,
67 RichardsonSolver = richardson,
68 preonly,
69 PreconditionerOnlySolver = preonly
70};
71
72inline std::ostream& operator<<(std::ostream& os, eSolverType s)
73{
74 switch (s) {
75 case eSolverType::cg:
76 return os << "cg";
77 case eSolverType::bicgstab:
78 return os << "bicgstab";
79 case eSolverType::bicgstabl:
80 return os << "bicgstabl";
81 case eSolverType::gmres:
82 return os << "gmres";
83 case eSolverType::lgmres:
84 return os << "lgmres";
85 case eSolverType::fgmres:
86 return os << "fgmres";
87 case eSolverType::idrs:
88 return os << "idrs";
89 case eSolverType::richardson:
90 return os << "richardson";
91 case eSolverType::preonly:
92 return os << "preonly";
93 default:
94 return os << "???";
95 }
96}
97
98inline std::istream& operator>>(std::istream& in, eSolverType& s)
99{
100 std::string val;
101 in >> val;
102
103 if (val == "cg")
104 s = eSolverType::cg;
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;
121 else
122 throw std::invalid_argument("Invalid solver value. Valid choices are: "
123 "cg, bicgstab, bicgstabl, gmres, lgmres, fgmres, idrs, richardson, preonly.");
124
125 return in;
126}
127
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)
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
144template <class Backend, class InnerProduct = detail::default_inner_product>
145struct SolverRuntime
146{
147 typedef PropertyTree params;
148 typedef typename Backend::params backend_params;
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;
153
154 eSolverType m_solver_type;
155 SolverBase* m_solver = nullptr;
156
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))
161 {
162 if (!prm.erase("type"))
163 ARCCORE_ALINA_PARAM_MISSING("type");
164
165 switch (m_solver_type) {
166
167#define ARCCORE_ALINA_RUNTIME_SOLVER(type) \
168 case eSolverType::type: \
169 m_solver = new type<Backend, InnerProduct>(n, prm, bprm, inner_product); \
170 break
171
172 ARCCORE_ALINA_ALL_RUNTIME_SOLVER();
173
174#undef ARCCORE_ALINA_RUNTIME_SOLVER
175
176 default:
177 ARCCORE_FATAL("Unsupported solver type type={0}", m_solver_type);
178 }
179 }
180
181 ~SolverRuntime()
182 {
183 delete m_solver;
184 }
185
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
188 {
189 switch (m_solver_type) {
190
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)
194
195 ARCCORE_ALINA_ALL_RUNTIME_SOLVER();
196
197#undef ARCCORE_ALINA_RUNTIME_SOLVER
198
199 default:
200 ARCCORE_FATAL("Unsupported solver type type={0}", m_solver_type);
201 }
202 }
203
204 template <class Precond, class Vec1, class Vec2>
205 SolverResult operator()(const Precond& P, const Vec1& rhs, Vec2&& x) const
206 {
207 return (*this)(P.system_matrix(), P, rhs, x);
208 }
209
210 friend std::ostream& operator<<(std::ostream& os, const SolverRuntime& w)
211 {
212 switch (w.m_solver_type) {
213
214#define ARCCORE_ALINA_RUNTIME_SOLVER(type) \
215 case eSolverType::type: \
216 return os << *static_cast<type<Backend, InnerProduct>*>(w.m_solver)
217
218 ARCCORE_ALINA_ALL_RUNTIME_SOLVER();
219
220#undef ARCCORE_ALINA_RUNTIME_SOLVER
221
222 default:
223 ARCCORE_FATAL("Unsupported solver type type={0}", w.m_solver_type);
224 }
225 }
226
227 size_t bytes() const
228 {
229 return m_solver->bytes();
230 }
231};
232
233#undef ARCCORE_ALINA_ALL_RUNTIME_SOLVER
234
235/*---------------------------------------------------------------------------*/
236/*---------------------------------------------------------------------------*/
237
238} // namespace Arcane::Alina
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
243#endif
#define ARCCORE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Base class for solvers.
Definition SolverBase.h:31
Result of a solving.
Definition AlinaUtils.h:52
Matrix class, to be used by user.
Alina::detail::empty_params params