Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
PreconditionerRuntime.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/* PreconditionerRuntime.h (C) 2000-2026 */
9/* */
10/* Runtime-configurable preconditioners. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_PRECONDITIONERRUNTIME_H
13#define ARCCORE_ALINA_PRECONDITIONERRUNTIME_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 "arccore/alina/AlinaUtils.h"
27#include "arccore/alina/SolverRuntime.h"
28#include "arccore/alina/CoarseningRuntime.h"
29#include "arccore/alina/RelaxationRuntime.h"
30#include "arccore/alina/Relaxation.h"
31#include "arccore/alina/DummyPreconditioner.h"
32#include "arccore/alina/PreconditionedSolver.h"
33#include "arccore/alina/AMG.h"
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38namespace Arcane::Alina
39{
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
45enum class ePreconditionerType
46{
47 amg,
48 relaxation,
49 dummy,
50 nested
51};
52
53inline std::ostream& operator<<(std::ostream& os, ePreconditionerType p)
54{
55 switch (p) {
56 case ePreconditionerType::amg:
57 return os << "amg";
58 case ePreconditionerType::relaxation:
59 return os << "relaxation";
60 case ePreconditionerType::dummy:
61 return os << "dummy";
62 case ePreconditionerType::nested:
63 return os << "nested";
64 default:
65 return os << "???";
66 }
67}
68
69inline std::istream& operator>>(std::istream& in, ePreconditionerType& p)
70{
71 std::string val;
72 in >> val;
73
74 if (val == "amg")
75 p = ePreconditionerType::amg;
76 else if (val == "relaxation")
77 p = ePreconditionerType::relaxation;
78 else if (val == "dummy")
79 p = ePreconditionerType::dummy;
80 else if (val == "nested")
81 p = ePreconditionerType::nested;
82 else
83 throw std::invalid_argument("Invalid preconditioner class. Valid choices are: "
84 "amg, relaxation, dummy, nested");
85
86 return in;
87}
88
89/*---------------------------------------------------------------------------*/
90/*---------------------------------------------------------------------------*/
94template <class Backend>
95class PreconditionerRuntime
96{
97 public:
98
99 using backend_type = Backend;
100 using BackendType = Backend;
101
102 typedef typename Backend::value_type value_type;
103 typedef typename Backend::matrix matrix;
104 typedef typename Backend::vector vector;
105 typedef typename Backend::params backend_params;
106
107 typedef Alina::PropertyTree params;
108
109 template <class Matrix>
110 PreconditionerRuntime(const Matrix& A,
111 params prm = params(),
112 const backend_params& bprm = backend_params())
113 : _class(prm.get("class", ePreconditionerType::amg))
114 , handle(0)
115 {
116 if (!prm.erase("class"))
117 ARCCORE_ALINA_PARAM_MISSING("class");
118 std::cout << "PreconditionerClass=" << _class << "\n";
119 switch (_class) {
120 case ePreconditionerType::amg: {
122 handle = static_cast<void*>(new Precond(A, prm, bprm));
123 } break;
124 case ePreconditionerType::relaxation: {
126 handle = static_cast<void*>(new Precond(A, prm, bprm));
127 } break;
128 case ePreconditionerType::dummy: {
130 handle = static_cast<void*>(new Precond(A, prm, bprm));
131 } break;
132 case ePreconditionerType::nested: {
134 handle = static_cast<void*>(new Precond(A, prm, bprm));
135 } break;
136 default:
137 throw std::invalid_argument("Unsupported preconditioner class");
138 }
139 }
140
141 ~PreconditionerRuntime()
142 {
143 switch (_class) {
144 case ePreconditionerType::amg: {
146 delete static_cast<Precond*>(handle);
147 } break;
148 case ePreconditionerType::relaxation: {
150 delete static_cast<Precond*>(handle);
151 } break;
152 case ePreconditionerType::dummy: {
154 delete static_cast<Precond*>(handle);
155 } break;
156 case ePreconditionerType::nested: {
158 delete static_cast<Precond*>(handle);
159 } break;
160 default:
161 break;
162 }
163 }
164
165 template <class Matrix>
166 void rebuild(const Matrix& A, const backend_params& bprm = backend_params())
167 {
168 switch (_class) {
169 case ePreconditionerType::amg: {
171 static_cast<Precond*>(handle)->rebuild(A, bprm);
172 } break;
173 default:
174 std::cerr << "rebuild is a noop unless the preconditioner is AMG" << std::endl;
175 return;
176 }
177 }
178
179 template <class Vec1, class Vec2>
180 void apply(const Vec1& rhs, Vec2& x) const
181 {
182 switch (_class) {
183 case ePreconditionerType::amg: {
185 static_cast<Precond*>(handle)->apply(rhs, x);
186 } break;
187 case ePreconditionerType::relaxation: {
189 static_cast<Precond*>(handle)->apply(rhs, x);
190 } break;
191 case ePreconditionerType::dummy: {
193 static_cast<Precond*>(handle)->apply(rhs, x);
194 } break;
195 case ePreconditionerType::nested: {
197 static_cast<Precond*>(handle)->apply(rhs, x);
198 } break;
199 default:
200 throw std::invalid_argument("Unsupported preconditioner class");
201 }
202 }
203
204 std::shared_ptr<matrix> system_matrix_ptr() const
205 {
206 switch (_class) {
207 case ePreconditionerType::amg: {
209 return static_cast<Precond*>(handle)->system_matrix_ptr();
210 }
211 case ePreconditionerType::relaxation: {
213 return static_cast<Precond*>(handle)->system_matrix_ptr();
214 }
215 case ePreconditionerType::dummy: {
217 return static_cast<Precond*>(handle)->system_matrix_ptr();
218 }
219 case ePreconditionerType::nested: {
221 return static_cast<Precond*>(handle)->system_matrix_ptr();
222 }
223 default:
224 throw std::invalid_argument("Unsupported preconditioner class");
225 }
226 }
227
228 const matrix& system_matrix() const
229 {
230 return *system_matrix_ptr();
231 }
232
233 size_t size() const
234 {
235 return backend::nbRow(system_matrix());
236 }
237
238 size_t bytes() const
239 {
240 switch (_class) {
241 case ePreconditionerType::amg: {
243 return backend::bytes(*static_cast<Precond*>(handle));
244 }
245 case ePreconditionerType::relaxation: {
247 return backend::bytes(*static_cast<Precond*>(handle));
248 }
249 case ePreconditionerType::dummy: {
251 return backend::bytes(*static_cast<Precond*>(handle));
252 }
253 case ePreconditionerType::nested: {
255 return backend::bytes(*static_cast<Precond*>(handle));
256 }
257 default:
258 throw std::invalid_argument("Unsupported preconditioner class");
259 }
260 }
261
262 friend std::ostream& operator<<(std::ostream& os, const PreconditionerRuntime& p)
263 {
264 switch (p._class) {
265 case ePreconditionerType::amg: {
267 return os << *static_cast<Precond*>(p.handle);
268 }
269 case ePreconditionerType::relaxation: {
271 return os << *static_cast<Precond*>(p.handle);
272 }
273 case ePreconditionerType::dummy: {
275 return os << *static_cast<Precond*>(p.handle);
276 }
277 case ePreconditionerType::nested: {
279 return os << *static_cast<Precond*>(p.handle);
280 }
281 default:
282 throw std::invalid_argument("Unsupported preconditioner class");
283 }
284 }
285
286 private:
287
288 const ePreconditionerType _class;
289
290 void* handle = nullptr;
291};
292
293/*---------------------------------------------------------------------------*/
294/*---------------------------------------------------------------------------*/
295
296} // namespace Arcane::Alina
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
300
301#endif
Algebraic multigrid method.
Definition AMG.h:71
Convenience class that bundles together a preconditioner and an iterative solver.
Allows to use an AMG smoother as standalone preconditioner.
Definition Relaxation.h:144
Dummy preconditioner using identity matrix.
Matrix class, to be used by user.