Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
CoarseningRuntime.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/* CoarseningRuntime.h (C) 2000-2026 */
9/* */
10/*---------------------------------------------------------------------------*/
11#ifndef ARCCORE_ALINA_COARSENINGRUNTIME_H
12#define ARCCORE_ALINA_COARSENINGRUNTIME_H
13/*---------------------------------------------------------------------------*/
14/*---------------------------------------------------------------------------*/
15/*
16 * This file is based on the work on AMGCL library (version march 2026)
17 * which can be found at https://github.com/ddemidov/amgcl.
18 *
19 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
20 * SPDX-License-Identifier: MIT
21 */
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24
25#include <iostream>
26#include <stdexcept>
27#include <type_traits>
28
29#include "arccore/alina/AlinaUtils.h"
30#include "arccore/alina/ValueTypeInterface.h"
31#include "arccore/alina/Coarsening.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::Alina
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
42enum class eCoarserningType
43{
44 ruge_stuben,
45 RugeStubenCoarsening = ruge_stuben,
46 aggregation,
47 AggregationCoarsening = aggregation,
48 smoothed_aggregation,
49 SmoothedAggregationCoarserning = smoothed_aggregation,
50 smoothed_aggr_emin,
51 SmoothedAggregationEnergyMinCoarsening = smoothed_aggr_emin
52};
53
54inline std::ostream& operator<<(std::ostream& os, eCoarserningType c)
55{
56 switch (c) {
57 case eCoarserningType::ruge_stuben:
58 return os << "ruge_stuben";
59 case eCoarserningType::aggregation:
60 return os << "aggregation";
61 case eCoarserningType::smoothed_aggregation:
62 return os << "smoothed_aggregation";
63 case eCoarserningType::smoothed_aggr_emin:
64 return os << "smoothed_aggr_emin";
65 default:
66 return os << "???";
67 }
68}
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
73inline std::istream& operator>>(std::istream& in, eCoarserningType& c)
74{
75 std::string val;
76 in >> val;
77
78 if (val == "ruge_stuben")
79 c = eCoarserningType::ruge_stuben;
80 else if (val == "aggregation")
81 c = eCoarserningType::aggregation;
82 else if (val == "smoothed_aggregation")
83 c = eCoarserningType::smoothed_aggregation;
84 else if (val == "smoothed_aggr_emin")
85 c = eCoarserningType::smoothed_aggr_emin;
86 else
87 throw std::invalid_argument("Invalid coarsening value. Valid choices are: "
88 "ruge_stuben, aggregation, smoothed_aggregation, smoothed_aggr_emin.");
89
90 return in;
91}
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96template <class Backend>
97struct CoarseningRuntime
98{
99 typedef Alina::PropertyTree params;
100 eCoarserningType c;
101 bool as_scalar;
102 void* handle = nullptr;
103
104 explicit CoarseningRuntime(params prm = params())
105 : c(prm.get("type", eCoarserningType::smoothed_aggregation))
106 {
107 if (!prm.erase("type"))
108 ARCCORE_ALINA_PARAM_MISSING("type");
109
110 typedef typename backend::value_type<Backend>::type value_type;
111 const bool block_value_type = math::static_rows<value_type>::value > 1;
112
113 as_scalar = (block_value_type &&
114 c != eCoarserningType::ruge_stuben &&
115 prm.get("nullspace.cols", 0) > 0);
116 std::cout << "PreconditionerCoarseningType=" << c << "\n";
117 switch (c) {
118
119#define ARCCORE_ALINA_RUNTIME_COARSENING(t) \
120 case eCoarserningType::t: \
121 if (as_scalar) { \
122 handle = call_constructor<AsScalarCoarsening<t>::type>(prm); \
123 } \
124 else { \
125 handle = call_constructor<t>(prm); \
126 } \
127 break
128
129 ARCCORE_ALINA_RUNTIME_COARSENING(RugeStubenCoarsening);
130 ARCCORE_ALINA_RUNTIME_COARSENING(AggregationCoarsening);
131 ARCCORE_ALINA_RUNTIME_COARSENING(SmoothedAggregationCoarserning);
132 ARCCORE_ALINA_RUNTIME_COARSENING(SmoothedAggregationEnergyMinCoarsening);
133
134#undef ARCCORE_ALINA_RUNTIME_COARSENING
135
136 default:
137 throw std::invalid_argument("Unsupported coarsening type");
138 }
139 }
140
141 ~CoarseningRuntime()
142 {
143 switch (c) {
144
145#define ARCCORE_ALINA_RUNTIME_COARSENING(t) \
146 case eCoarserningType::t: \
147 if (as_scalar) { \
148 call_destructor<AsScalarCoarsening<t>::type>(); \
149 } \
150 else { \
151 call_destructor<t>(); \
152 } \
153 break
154
155 ARCCORE_ALINA_RUNTIME_COARSENING(RugeStubenCoarsening);
156 ARCCORE_ALINA_RUNTIME_COARSENING(AggregationCoarsening);
157 ARCCORE_ALINA_RUNTIME_COARSENING(SmoothedAggregationCoarserning);
158 ARCCORE_ALINA_RUNTIME_COARSENING(SmoothedAggregationEnergyMinCoarsening);
159
160#undef ARCCORE_ALINA_RUNTIME_COARSENING
161 }
162 }
163
164 template <class Matrix>
165 std::tuple<std::shared_ptr<Matrix>, std::shared_ptr<Matrix>>
166 transfer_operators(const Matrix& A)
167 {
168 switch (c) {
169
170#define ARCCORE_ALINA_RUNTIME_COARSENING(t) \
171 case eCoarserningType::t: \
172 if (as_scalar) { \
173 return make_operators<AsScalarCoarsening<t>::type>(A); \
174 } \
175 return make_operators<t>(A)
176
177 ARCCORE_ALINA_RUNTIME_COARSENING(RugeStubenCoarsening);
178 ARCCORE_ALINA_RUNTIME_COARSENING(AggregationCoarsening);
179 ARCCORE_ALINA_RUNTIME_COARSENING(SmoothedAggregationCoarserning);
180 ARCCORE_ALINA_RUNTIME_COARSENING(SmoothedAggregationEnergyMinCoarsening);
181
182#undef ARCCORE_ALINA_RUNTIME_COARSENING
183
184 default:
185 throw std::invalid_argument("Unsupported coarsening type");
186 }
187 }
188
189 template <class Matrix> std::shared_ptr<Matrix>
190 coarse_operator(const Matrix& A, const Matrix& P, const Matrix& R) const
191 {
192 switch (c) {
193
194#define ARCCORE_ALINA_RUNTIME_COARSENING(t) \
195 case eCoarserningType::t: \
196 if (as_scalar) { \
197 return make_coarse<AsScalarCoarsening<t>::type>(A, P, R); \
198 } \
199 return make_coarse<t>(A, P, R)
200
201 ARCCORE_ALINA_RUNTIME_COARSENING(RugeStubenCoarsening);
202 ARCCORE_ALINA_RUNTIME_COARSENING(AggregationCoarsening);
203 ARCCORE_ALINA_RUNTIME_COARSENING(SmoothedAggregationCoarserning);
204 ARCCORE_ALINA_RUNTIME_COARSENING(SmoothedAggregationEnergyMinCoarsening);
205
206#undef ARCCORE_ALINA_RUNTIME_COARSENING
207
208 default:
209 throw std::invalid_argument("Unsupported coarsening type");
210 }
211 }
212
213 template <template <class> class Coarsening>
214 std::enable_if_t<backend::coarsening_is_supported<Backend, Coarsening>::value, void*>
215 call_constructor(const params& prm)
216 {
217 return static_cast<void*>(new Coarsening<Backend>(prm));
218 }
219
220 template <template <class> class Coarsening>
221 std::enable_if_t<!backend::coarsening_is_supported<Backend, Coarsening>::value, void*>
222 call_constructor(const params&)
223 {
224 throw std::logic_error("The coarsening is not supported by the backend");
225 }
226
227 template <template <class> class Coarsening>
228 std::enable_if_t<backend::coarsening_is_supported<Backend, Coarsening>::value, void>
229 call_destructor()
230 {
231 delete static_cast<Coarsening<Backend>*>(handle);
232 }
233
234 template <template <class> class Coarsening>
235 std::enable_if_t<!backend::coarsening_is_supported<Backend, Coarsening>::value, void>
236 call_destructor()
237 {
238 }
239
240 template <template <class> class Coarsening, class Matrix>
241 std::enable_if_t<backend::coarsening_is_supported<Backend, Coarsening>::value,
242 std::tuple<std::shared_ptr<Matrix>, std::shared_ptr<Matrix>>>
243 make_operators(const Matrix& A) const
244 {
245 return static_cast<Coarsening<Backend>*>(handle)->transfer_operators(A);
246 }
247
248 template <template <class> class Coarsening, class Matrix>
249 std::enable_if_t<!backend::coarsening_is_supported<Backend, Coarsening>::value,
250 std::tuple<
251 std::shared_ptr<Matrix>,
252 std::shared_ptr<Matrix>>>
253 make_operators(const Matrix&)
254 {
255 throw std::logic_error("The coarsening is not supported by the backend");
256 }
257
258 template <template <class> class Coarsening, class Matrix>
259 std::enable_if_t<backend::coarsening_is_supported<Backend, Coarsening>::value,
260 std::shared_ptr<Matrix>>
261 make_coarse(const Matrix& A, const Matrix& P, const Matrix& R) const
262 {
263 return static_cast<Coarsening<Backend>*>(handle)->coarse_operator(A, P, R);
264 }
265
266 template <template <class> class Coarsening, class Matrix>
267 std::enable_if_t<!backend::coarsening_is_supported<Backend, Coarsening>::value,
268 std::shared_ptr<Matrix>>
269 make_coarse(const Matrix&, const Matrix&, const Matrix&) const
270 {
271 throw std::logic_error("The coarsening is not supported by the backend");
272 }
273};
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
278} // namespace Arcane::Alina
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
282
283#endif
Matrix class, to be used by user.
Non-smoothed aggregation.
Definition Coarsening.h:639
Classic Ruge-Stuben coarsening with direct interpolation.
Definition Coarsening.h:909
Smoothed aggregation coarsening.
Smoothed aggregation with energy minimization.
Number of rows for statically sized matrix types.