Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
DistributedRelaxationRuntime.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/* DistributedRelaxationRuntime.h (C) 2000-2026 */
9/* */
10/* Distributed memory sparse approximate inverse relaxation scheme. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_MPI_DISTRIBUTEDRELAXATIONRUNTIME_H
13#define ARCCORE_ALINA_MPI_DISTRIBUTEDRELAXATIONRUNTIME_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/BackendInterface.h"
27#include "arccore/alina/RelaxationRuntime.h"
28#include "arccore/alina/DistributedRelaxation.h"
29#include "arccore/alina/DistributedMatrix.h"
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane::Alina
35{
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
42template <class Backend>
43struct DistributedRelaxationRuntime
44{
45 typedef Backend backend_type;
46 using BackendType = backend_type;
47 typedef typename Backend::params backend_params;
48 typedef Alina::PropertyTree params;
49
50 eRelaxationType r;
51 void* handle = nullptr;
52
53 DistributedRelaxationRuntime(const DistributedMatrix<Backend>& A,
54 params prm, const backend_params& bprm = backend_params())
55 : r(prm.get("type", eRelaxationType::spai0))
56 {
57 if (!prm.erase("type"))
58 ARCCORE_ALINA_PARAM_MISSING("type");
59
60 switch (r) {
61
62#define ARCCORE_ALINA_RELAX_DISTR(type) \
63 case eRelaxationType::type: \
64 handle = static_cast<void*>(new ::Arcane::Alina::Distributed##type<Backend>(A, prm, bprm)); \
65 break
66
67#define ARCCORE_ALINA_RELAX_LOCAL_DISTR(type) \
68 case eRelaxationType::type: \
69 handle = call_constructor<type>(A, prm, bprm); \
70 break;
71
72#define ARCCORE_ALINA_RELAX_LOCAL_LOCAL(type) \
73 case eRelaxationType::type: \
74 handle = call_constructor<type>(*A.local(), prm, bprm); \
75 break;
76
77 ARCCORE_ALINA_RELAX_DISTR(SPAI0Relaxation);
78 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ChebyshevRelaxation);
79 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(DampedJacobiRelaxation);
80 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(ILU0Relaxation);
81 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(ILUKRelaxation);
82 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(ILUPRelaxation);
83 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(ILUTRelaxation);
84 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(SPAI1Relaxation);
85 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(GaussSeidelRelaxation);
86
87#undef ARCCORE_ALINA_RELAX_LOCAL_LOCAL
88#undef ARCCORE_ALINA_RELAX_LOCAL_DISTR
89#undef ARCCORE_ALINA_RELAX_DISTR
90
91 default:
92 throw std::invalid_argument("Unsupported relaxation type");
93 }
94 }
95
96 ~DistributedRelaxationRuntime()
97 {
98 switch (r) {
99#define ARCCORE_ALINA_RELAX_DISTR(type) \
100 case eRelaxationType::type: \
101 delete static_cast<Distributed##type<Backend>*>(handle); \
102 break
103
104#define ARCCORE_ALINA_RELAX_LOCAL(type) \
105 case eRelaxationType::type: \
106 delete static_cast<type<Backend>*>(handle); \
107 break;
108
109 ARCCORE_ALINA_RELAX_DISTR(SPAI0Relaxation);
110 ARCCORE_ALINA_RELAX_LOCAL(DampedJacobiRelaxation);
111 ARCCORE_ALINA_RELAX_LOCAL(ILU0Relaxation);
112 ARCCORE_ALINA_RELAX_LOCAL(ILUKRelaxation);
113 ARCCORE_ALINA_RELAX_LOCAL(ILUPRelaxation);
114 ARCCORE_ALINA_RELAX_LOCAL(ILUTRelaxation);
115 ARCCORE_ALINA_RELAX_LOCAL(SPAI1Relaxation);
116 ARCCORE_ALINA_RELAX_LOCAL(ChebyshevRelaxation);
117 ARCCORE_ALINA_RELAX_LOCAL(GaussSeidelRelaxation);
118
119#undef ARCCORE_ALINA_RELAX_LOCAL
120#undef ARCCORE_ALINA_RELAX_DISTR
121
122 default:
123 break;
124 }
125 }
126
127 template <class Matrix, class VectorRHS, class VectorX, class VectorTMP>
128 void apply_pre(const Matrix& A, const VectorRHS& rhs, VectorX& x, VectorTMP& tmp) const
129 {
130 switch (r) {
131
132#define ARCCORE_ALINA_RELAX_DISTR(type) \
133 case eRelaxationType::type: \
134 static_cast<const Distributed##type<Backend>*>(handle)->apply_pre(A, rhs, x, tmp); \
135 break
136
137#define ARCCORE_ALINA_RELAX_LOCAL_DISTR(type) \
138 case eRelaxationType::type: \
139 call_apply_pre<type>(A, rhs, x, tmp); \
140 break;
141
142#define ARCCORE_ALINA_RELAX_LOCAL_LOCAL(type) \
143 case eRelaxationType::type: \
144 call_apply_pre<type>(*A.local_backend(), rhs, x, tmp); \
145 break;
146
147 ARCCORE_ALINA_RELAX_DISTR(SPAI0Relaxation);
148 ARCCORE_ALINA_RELAX_LOCAL_DISTR(DampedJacobiRelaxation);
149 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILU0Relaxation);
150 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILUKRelaxation);
151 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILUPRelaxation);
152 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILUTRelaxation);
153 ARCCORE_ALINA_RELAX_LOCAL_DISTR(SPAI1Relaxation);
154 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ChebyshevRelaxation);
155 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(GaussSeidelRelaxation);
156
157#undef ARCCORE_ALINA_RELAX_LOCAL_LOCAL
158#undef ARCCORE_ALINA_RELAX_LOCAL_DISTR
159#undef ARCCORE_ALINA_RELAX_DISTR
160
161 default:
162 throw std::invalid_argument("Unsupported relaxation type");
163 }
164 }
165
166 template <class Matrix, class VectorRHS, class VectorX, class VectorTMP>
167 void apply_post(const Matrix& A, const VectorRHS& rhs, VectorX& x, VectorTMP& tmp) const
168 {
169 switch (r) {
170
171#define ARCCORE_ALINA_RELAX_DISTR(type) \
172 case eRelaxationType::type: \
173 static_cast<const ::Arcane::Alina::Distributed##type<Backend>*>(handle)->apply_post(A, rhs, x, tmp); \
174 break
175
176#define ARCCORE_ALINA_RELAX_LOCAL_DISTR(type) \
177 case eRelaxationType::type: \
178 call_apply_post<type>(A, rhs, x, tmp); \
179 break;
180
181#define ARCCORE_ALINA_RELAX_LOCAL_LOCAL(type) \
182 case eRelaxationType::type: \
183 call_apply_post<type>(*A.local_backend(), rhs, x, tmp); \
184 break;
185
186 ARCCORE_ALINA_RELAX_DISTR(SPAI0Relaxation);
187 ARCCORE_ALINA_RELAX_LOCAL_DISTR(DampedJacobiRelaxation);
188 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILU0Relaxation);
189 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILUKRelaxation);
190 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILUPRelaxation);
191 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILUTRelaxation);
192 ARCCORE_ALINA_RELAX_LOCAL_DISTR(SPAI1Relaxation);
193 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ChebyshevRelaxation);
194 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(GaussSeidelRelaxation);
195
196#undef ARCCORE_ALINA_RELAX_LOCAL_LOCAL
197#undef ARCCORE_ALINA_RELAX_LOCAL_DISTR
198#undef ARCCORE_ALINA_RELAX_DISTR
199
200 default:
201 throw std::invalid_argument("Unsupported relaxation type");
202 }
203 }
204
205 template <class Matrix, class VectorRHS, class VectorX>
206 void apply(const Matrix& A, const VectorRHS& rhs, VectorX& x) const
207 {
208 switch (r) {
209
210#define ARCCORE_ALINA_RELAX_DISTR(type) \
211 case eRelaxationType::type: \
212 static_cast<const Distributed##type<Backend>*>(handle)->apply(A, rhs, x); \
213 break
214
215#define ARCCORE_ALINA_RELAX_LOCAL_DISTR(type) \
216 case eRelaxationType::type: \
217 call_apply<type>(A, rhs, x); \
218 break;
219
220#define ARCCORE_ALINA_RELAX_LOCAL_LOCAL(type) \
221 case eRelaxationType::type: \
222 call_apply<type>(*A.local_backend(), rhs, x); \
223 break;
224
225 ARCCORE_ALINA_RELAX_DISTR(SPAI0Relaxation);
226 ARCCORE_ALINA_RELAX_LOCAL_DISTR(DampedJacobiRelaxation);
227 ARCCORE_ALINA_RELAX_LOCAL_LOCAL(GaussSeidelRelaxation);
228 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILU0Relaxation);
229 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILUKRelaxation);
230 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILUPRelaxation);
231 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ILUTRelaxation);
232 ARCCORE_ALINA_RELAX_LOCAL_DISTR(SPAI1Relaxation);
233 ARCCORE_ALINA_RELAX_LOCAL_DISTR(ChebyshevRelaxation);
234
235#undef ARCCORE_ALINA_RELAX_LOCAL_LOCAL
236#undef ARCCORE_ALINA_RELAX_LOCAL_DISTR
237#undef ARCCORE_ALINA_RELAX_DISTR
238
239 default:
240 throw std::invalid_argument("Unsupported relaxation type");
241 }
242 }
243
244 template <template <class> class Relaxation, class Matrix>
245 typename std::enable_if<backend::relaxation_is_supported<Backend, Relaxation>::value, void*>::type
246 call_constructor(const Matrix& A, const params& prm, const backend_params& bprm)
247 {
248 return static_cast<void*>(new Relaxation<Backend>(A, prm, bprm));
249 }
250
251 template <template <class> class Relaxation, class Matrix>
252 typename std::enable_if<!backend::relaxation_is_supported<Backend, Relaxation>::value, void*>::type
253 call_constructor(const Matrix&, const params&, const backend_params&)
254 {
255 throw std::logic_error("The relaxation is not supported by the backend");
256 }
257
258 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX, class VectorTMP>
259 typename std::enable_if<backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
260 call_apply_pre(const Matrix& A, const VectorRHS& rhs, VectorX& x, VectorTMP& tmp) const
261 {
262 static_cast<Relaxation<Backend>*>(handle)->apply_pre(A, rhs, x, tmp);
263 }
264
265 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX, class VectorTMP>
266 typename std::enable_if<!backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
267 call_apply_pre(const Matrix&, const VectorRHS&, VectorX&, VectorTMP&) const
268 {
269 throw std::logic_error("The relaxation is not supported by the backend");
270 }
271
272 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX, class VectorTMP>
273 typename std::enable_if<backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
274 call_apply_post(const Matrix& A, const VectorRHS& rhs, VectorX& x, VectorTMP& tmp) const
275 {
276 static_cast<Relaxation<Backend>*>(handle)->apply_post(A, rhs, x, tmp);
277 }
278
279 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX, class VectorTMP>
280 typename std::enable_if<!backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
281 call_apply_post(const Matrix&, const VectorRHS&, VectorX&, VectorTMP&) const
282 {
283 throw std::logic_error("The relaxation is not supported by the backend");
284 }
285
286 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX>
287 typename std::enable_if<backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
288 call_apply(const Matrix& A, const VectorRHS& rhs, VectorX& x) const
289 {
290 static_cast<Relaxation<Backend>*>(handle)->apply(A, rhs, x);
291 }
292
293 template <template <class> class Relaxation, class Matrix, class VectorRHS, class VectorX>
294 typename std::enable_if<!backend::relaxation_is_supported<Backend, Relaxation>::value, void>::type
295 call_apply(const Matrix&, const VectorRHS&, VectorX&) const
296 {
297 throw std::logic_error("The relaxation is not supported by the backend");
298 }
299};
300
301/*---------------------------------------------------------------------------*/
302/*---------------------------------------------------------------------------*/
303
304} // namespace Arcane::Alina
305
306/*---------------------------------------------------------------------------*/
307/*---------------------------------------------------------------------------*/
308
309#endif
Chebyshev polynomial smoother.
Definition Relaxation.h:246
Distributed Matrix using message passing.
Matrix class, to be used by user.
Damped Jacobi relaxation.
Definition Relaxation.h:409
Gauss-Seidel relaxation.
Definition Relaxation.h:510
Sparse approximate interface smoother.
Sparse approximate interface smoother.