Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
RelaxationRuntime.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/* RelaxationRuntime.h (C) 2000-2026 */
9/* */
10/* Runtime configurable relaxation. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_RELAXATIONRUNTIME_H
13#define ARCCORE_ALINA_RELAXATIONRUNTIME_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/AlinaGlobal.h"
27
28#include <type_traits>
29
30#include "arccore/alina/AlinaUtils.h"
31#include "arccore/alina/Relaxation.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::Alina
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
43enum class eRelaxationType
44{
45 gauss_seidel,
46 GaussSeidelRelaxation = gauss_seidel,
47 ilu0,
48 ILU0Relaxation = ilu0,
49 iluk,
50 ILUKRelaxation = iluk,
51 ilup,
52 ILUPRelaxation = ilup,
53 ilut,
54 ILUTRelaxation = ilut,
55 damped_jacobi,
56 DampedJacobiRelaxation = damped_jacobi,
57 spai0,
58 SPAI0Relaxation = spai0,
59 spai1,
60 SPAI1Relaxation = spai1,
61 chebyshev,
62 ChebyshevRelaxation = chebyshev
63};
64
65extern "C++" ARCCORE_ALINA_EXPORT
66std::ostream& operator<<(std::ostream& os, eRelaxationType r);
67
68extern "C++" ARCCORE_ALINA_EXPORT
69std::istream& operator>>(std::istream& in, eRelaxationType& r);
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
74#define ARCCORE_ALINA_ALL_RUNTIME_RELAXATION() \
75 ARCCORE_ALINA_RUNTIME_RELAXATION(GaussSeidelRelaxation); \
76 ARCCORE_ALINA_RUNTIME_RELAXATION(ILU0Relaxation); \
77 ARCCORE_ALINA_RUNTIME_RELAXATION(ILUKRelaxation); \
78 ARCCORE_ALINA_RUNTIME_RELAXATION(ILUPRelaxation); \
79 ARCCORE_ALINA_RUNTIME_RELAXATION(ILUTRelaxation); \
80 ARCCORE_ALINA_RUNTIME_RELAXATION(DampedJacobiRelaxation); \
81 ARCCORE_ALINA_RUNTIME_RELAXATION(SPAI0Relaxation); \
82 ARCCORE_ALINA_RUNTIME_RELAXATION(SPAI1Relaxation); \
83 ARCCORE_ALINA_RUNTIME_RELAXATION(ChebyshevRelaxation)
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
90template <class Backend>
91struct RelaxationRuntime
92{
93 typedef Alina::PropertyTree params;
94 typedef typename Backend::params backend_params;
95
96 template <class Matrix>
97 explicit RelaxationRuntime(const Matrix& A, params prm = params(),
98 const backend_params& bprm = backend_params())
99 : m_relaxation_type(prm.get("type", eRelaxationType::spai0))
100 {
101 if (!prm.erase("type"))
102 ARCCORE_ALINA_PARAM_MISSING("type");
103 switch (m_relaxation_type) {
104
105#define ARCCORE_ALINA_RUNTIME_RELAXATION(type) \
106 case eRelaxationType::type: \
107 m_relaxation = call_constructor<type>(A, prm, bprm); \
108 break
109
110 ARCCORE_ALINA_ALL_RUNTIME_RELAXATION();
111
112#undef ARCCORE_ALINA_RUNTIME_RELAXATION
113
114 default:
115 _throwBadTypeType();
116 }
117 }
118
119 ~RelaxationRuntime()
120 {
121 delete m_relaxation;
122 }
123
124 template <class Matrix, class VectorRHS, class VectorX, class VectorTMP>
125 void apply_pre(const Matrix& A, const VectorRHS& rhs, VectorX& x, VectorTMP& tmp) const
126 {
127 switch (m_relaxation_type) {
128
129#define ARCCORE_ALINA_RUNTIME_RELAXATION(type) \
130 case eRelaxationType::type: \
131 call_apply_pre<type>(A, rhs, x, tmp); \
132 break
133
134 ARCCORE_ALINA_ALL_RUNTIME_RELAXATION();
135
136#undef ARCCORE_ALINA_RUNTIME_RELAXATION
137
138 default:
139 _throwBadTypeType();
140 }
141 }
142
143 template <class Matrix, class VectorRHS, class VectorX, class VectorTMP>
144 void apply_post(const Matrix& A, const VectorRHS& rhs, VectorX& x, VectorTMP& tmp) const
145 {
146 switch (m_relaxation_type) {
147
148#define ARCCORE_ALINA_RUNTIME_RELAXATION(type) \
149 case eRelaxationType::type: \
150 call_apply_post<type>(A, rhs, x, tmp); \
151 break
152
153 ARCCORE_ALINA_ALL_RUNTIME_RELAXATION();
154
155#undef ARCCORE_ALINA_RUNTIME_RELAXATION
156
157 default:
158 _throwBadTypeType();
159 }
160 }
161
162 template <class Matrix, class VectorRHS, class VectorX>
163 void apply(const Matrix& A, const VectorRHS& rhs, VectorX& x) const
164 {
165 switch (m_relaxation_type) {
166
167#define ARCCORE_ALINA_RUNTIME_RELAXATION(type) \
168 case eRelaxationType::type: \
169 call_apply<type>(A, rhs, x); \
170 break
171
172 ARCCORE_ALINA_ALL_RUNTIME_RELAXATION();
173
174#undef ARCCORE_ALINA_RUNTIME_RELAXATION
175
176 default:
177 _throwBadTypeType();
178 }
179 }
180
181 size_t bytes() const
182 {
183 return m_relaxation->bytes();
184 }
185
186 template <template <class> class Relaxation, class Matrix>
187 typename std::enable_if_t<backend::relaxation_is_supported<Backend, Relaxation>::value, RelaxationBase*>
188 call_constructor(const Matrix& A, const params& prm, const backend_params& bprm)
189 {
190 return new Relaxation<Backend>(A, prm, bprm);
191 }
192
193 template <template <class> class Relaxation, class Matrix>
194 typename std::enable_if_t<!backend::relaxation_is_supported<Backend, Relaxation>::value, RelaxationBase*>
195 call_constructor(const Matrix&, const params&, const backend_params&)
196 {
197 _throwUnsupportedBackendType();
198 }
199
200 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX, class VectorTMP>
201 typename std::enable_if<backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
202 call_apply_pre(const Matrix& A, const VectorRHS& rhs, VectorX& x, VectorTMP& tmp) const
203 {
204 static_cast<Relaxation<Backend>*>(m_relaxation)->apply_pre(A, rhs, x, tmp);
205 }
206
207 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX, class VectorTMP>
208 typename std::enable_if<!backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
209 call_apply_pre(const Matrix&, const VectorRHS&, VectorX&, VectorTMP&) const
210 {
211 _throwUnsupportedBackendType();
212 }
213
214 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX, class VectorTMP>
215 typename std::enable_if<backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
216 call_apply_post(const Matrix& A, const VectorRHS& rhs, VectorX& x, VectorTMP& tmp) const
217 {
218 static_cast<Relaxation<Backend>*>(m_relaxation)->apply_post(A, rhs, x, tmp);
219 }
220
221 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX, class VectorTMP>
222 typename std::enable_if<!backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
223 call_apply_post(const Matrix&, const VectorRHS&, VectorX&, VectorTMP&) const
224 {
225 _throwUnsupportedBackendType();
226 }
227
228 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX>
229 typename std::enable_if<backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
230 call_apply(const Matrix& A, const VectorRHS& rhs, VectorX& x) const
231 {
232 static_cast<Relaxation<Backend>*>(m_relaxation)->apply(A, rhs, x);
233 }
234
235 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX>
236 typename std::enable_if<!backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
237 call_apply(const Matrix&, const VectorRHS&, VectorX&) const
238 {
239 _throwUnsupportedBackendType();
240 }
241
242 void _throwBadTypeType [[noreturn]] () const
243 {
244 int v = static_cast<int>(m_relaxation_type);
245 ARCANE_FATAL("Unsupported relaxation type '{0}'", v);
246 }
247 void _throwUnsupportedBackendType [[noreturn]] () const
248 {
249 String err_message = String::format("The relaxation '{0}' is not supported by the backend", m_relaxation_type);
250 //NOTE: We need to do a 'logic_error' because this is catched is some tests
251 throw std::logic_error(err_message.localstr());
252 }
253
254 private:
255
256 eRelaxationType m_relaxation_type = eRelaxationType::SPAI0Relaxation;
257 RelaxationBase* m_relaxation = nullptr;
258};
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
262
263} // namespace Arcane::Alina
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267
268#endif
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Base class for solvers.
Matrix class, to be used by user.
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:228