Arcane  4.2.2.0
Developer documentation
Loading...
Searching...
No Matches
AlinaLib.cc
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/* AlinaLib.cc (C) 2000-2026 */
9/* */
10/* Public API for Alina. . */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/alina/RelaxationRuntime.h"
15#include "arccore/alina/CoarseningRuntime.h"
16#include "arccore/alina/SolverRuntime.h"
17#include "arccore/alina/PreconditionedSolver.h"
18#include "arccore/alina/DistributedSolverRuntime.h"
19#include "arccore/alina/DistributedDirectSolverRuntime.h"
20#include "arccore/alina/DistributedSubDomainDeflation.h"
21#include "arccore/alina/AMG.h"
22#include "arccore/alina/BuiltinBackend.h"
23#include "arccore/alina/AlinaLib.h"
24
25#include "arccore/concurrency/Mutex.h"
26
27#include <iostream>
28
29using namespace Arcane;
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34//using Backend = Alina::BuiltinBackend<double>;
38typedef Alina::PropertyTree Params;
39
40//---------------------------------------------------------------------------
41
42using DistributedSolverType = Alina::DistributedSubDomainDeflation<PreconditionerType,
45
46/*---------------------------------------------------------------------------*/
47/*---------------------------------------------------------------------------*/
48
49namespace
50{
52_toConvInfo(const Alina::SolverResult& r)
53{
55 x.iterations = r.nbIteration();
56 x.residual = r.residual();
57 return x;
58}
59}
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
65{
66 public:
67
68 Params m_properties;
69};
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
74AlinaParameters::
75AlinaParameters()
76: m_p(std::make_shared<AlinaParametersImpl>())
77{}
78
79/*---------------------------------------------------------------------------*/
80/*---------------------------------------------------------------------------*/
81
83setInt32(const char* name, Arcane::Int32 value)
84{
85 m_p->m_properties.put(name, value);
86}
87
89setInt64(const char* name, Arcane::Int64 value)
90{
91 m_p->m_properties.put(name, value);
92}
93
95setReal(const char* name, Arcane::Real value)
96{
97 m_p->m_properties.put(name, value);
98}
99
101setString(const char* name, const char* value)
102{
103 m_p->m_properties.put(name, value);
104}
105
107readFromJSON(const char* fname)
108{
109 Params& p = m_p->m_properties;
110 p.read_json(fname);
111}
112
113/*---------------------------------------------------------------------------*/
114/*---------------------------------------------------------------------------*/
115
117checkSizes() const
118{
119 Int32 nb_row = nbRow();
120 Int32 n1 = m_row_indexes.size();
121 if (n1 != (nb_row + 1))
122 ARCCORE_FATAL("Bad size '{0}' for rowIndexes() (expected value = {1})",n1, nb_row+1);
123 Int32 nb_value = m_row_indexes[nb_row];
124 Int32 n2 = m_columns.size();
125 Int32 n3 = m_values.size();
126 if (n2 != nb_value)
127 ARCCORE_FATAL("Bad size '{0}' for columns() (expected value = {1})",n2, nb_value);
128 if (n3 != nb_value)
129 ARCCORE_FATAL("Bad size '{0}' for values() (expected value = {1})",n3, nb_value);
130}
131
132/*---------------------------------------------------------------------------*/
133/*---------------------------------------------------------------------------*/
134
135class AlinaPreconditionerImpl
136{
137 public:
138
139 explicit AlinaPreconditionerImpl(PreconditionerType* preconditioner)
140 : m_preconditioner(preconditioner)
141 {}
142 ~AlinaPreconditionerImpl()
143 {
144 delete m_preconditioner;
145 }
146
147 PreconditionerType* m_preconditioner = nullptr;
148};
149
150/*---------------------------------------------------------------------------*/
151/*---------------------------------------------------------------------------*/
152
153AlinaPreconditioner::
154AlinaPreconditioner(int n,
155 const int* ptr,
156 const int* col,
157 const double* val,
158 const AlinaParameters* prm)
159{
160 SmallSpan<const int> ptr_range(ptr, n + 1);
161 SmallSpan<const int> col_range(col, ptr[n]);
162 SmallSpan<const double> val_range(val, ptr[n]);
163
164 auto A = std::make_tuple(n, ptr_range, col_range, val_range);
165
166 PreconditionerType* amg = nullptr;
167 if (prm)
168 amg = new PreconditionerType(A, prm->m_p->m_properties);
169 else
170 amg = new PreconditionerType(A);
171 m_p = std::make_shared<AlinaPreconditionerImpl>(amg);
172}
173
174/*---------------------------------------------------------------------------*/
175/*---------------------------------------------------------------------------*/
176
178apply(const double* rhs, double* x)
179{
180 PreconditionerType* amg = m_p->m_preconditioner;
181
182 size_t n = Alina::backend::nbRow(amg->system_matrix());
183
184 SmallSpan<double> x_range(x, n);
185 SmallSpan<const double> rhs_range(rhs, n);
186
187 amg->apply(rhs_range, x_range);
188}
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
192
194report()
195{
196 std::cout << *(m_p->m_preconditioner) << std::endl;
197}
198
199/*---------------------------------------------------------------------------*/
200/*---------------------------------------------------------------------------*/
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
205struct AlinaSequentialSolverImpl
206{
207 explicit AlinaSequentialSolverImpl(SequentialSolverType* solver)
208 : m_solver(solver)
209 {}
210 ~AlinaSequentialSolverImpl()
211 {
212 delete m_solver;
213 }
214 SequentialSolverType* m_solver = nullptr;
215};
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219
222 const AlinaParameters* prm)
223{
224 matrix_view.checkSizes();
225 auto A = std::make_tuple(matrix_view.nbRow(), matrix_view.rowIndexes(),
226 matrix_view.columns(), matrix_view.values());
227
228 auto* solver = new SequentialSolverType(A);
229 if (prm)
230 solver = new SequentialSolverType(A, prm->m_p->m_properties);
231 else
232 solver = new SequentialSolverType(A);
233 std::cout << "Printing solver infos\n";
234 std::cout << (*solver) << std::endl;
236 solver->prm.get(ptree);
237 std::cout << "SOLVER_PARAMS: " << ptree << "\n";
238 m_p = std::make_shared<AlinaSequentialSolverImpl>(solver);
239}
240
241/*---------------------------------------------------------------------------*/
242/*---------------------------------------------------------------------------*/
243
245report()
246{
247 SequentialSolverType* slv = m_p->m_solver;
248
249 std::cout << slv->precond() << std::endl;
250}
251
252/*---------------------------------------------------------------------------*/
253/*---------------------------------------------------------------------------*/
254
257{
258 SequentialSolverType* slv = m_p->m_solver;
259
260 Alina::SolverResult r = (*slv)(rhs, x);
261
262 return _toConvInfo(r);
263}
264
265/*---------------------------------------------------------------------------*/
266/*---------------------------------------------------------------------------*/
267
269solveMatrix(const AlinaCSRMatrixView& matrix_view,
272{
273 SequentialSolverType* slv = m_p->m_solver;
274
275 Int32 n = slv->size();
276 matrix_view.checkSizes();
277
278 if (n != matrix_view.nbRow())
279 ARCCORE_FATAL("Bad number of rows v={0} expected={1}", matrix_view.nbRow(), n);
280
281 auto A = std::make_tuple(matrix_view.nbRow(), matrix_view.rowIndexes(),
282 matrix_view.columns(), matrix_view.values());
283
284 Alina::SolverResult r = (*slv)(A, rhs, x);
285
286 return _toConvInfo(r);
287}
288
289/*---------------------------------------------------------------------------*/
290/*---------------------------------------------------------------------------*/
291
292struct deflation_vectors
293{
294 int n;
295 AlinaDefVecFunction user_func;
296 void* user_data;
297
298 deflation_vectors(int n, AlinaDefVecFunction user_func, void* user_data)
299 : n(n)
300 , user_func(user_func)
301 , user_data(user_data)
302 {}
303
304 int dim() const { return n; }
305
306 double operator()(int i, ptrdiff_t j) const
307 {
308 return user_func(i, j, user_data);
309 }
310};
311
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
316class AlinaDistributedSolverImpl
317{
318 public:
319
320 explicit AlinaDistributedSolverImpl(DistributedSolverType* solver)
321 : m_solver(solver)
322 {}
323 ~AlinaDistributedSolverImpl()
324 {
325 delete m_solver;
326 }
327 DistributedSolverType* m_solver = nullptr;
328};
329
330/*---------------------------------------------------------------------------*/
331/*---------------------------------------------------------------------------*/
332
334AlinaDistributedSolver(MPI_Comm comm,
335 const AlinaCSRMatrixView& matrix_view,
336 //ptrdiff_t n,
337 //const int* ptr,
338 //const int* col,
339 //const double* val,
340 int n_def_vec,
341 AlinaDefVecFunction def_vec_func,
342 void* def_vec_data,
343 const AlinaParameters& params)
344{
345 std::function<double(ptrdiff_t, unsigned)> dv = deflation_vectors(n_def_vec, def_vec_func, def_vec_data);
346 Alina::PropertyTree prm = params.m_p->m_properties;
347 prm.put("num_def_vec", n_def_vec);
348 prm.put("def_vec", &dv);
349 matrix_view.checkSizes();
350
351 auto A = std::make_tuple(matrix_view.nbRow(), matrix_view.rowIndexes(),
352 matrix_view.columns(), matrix_view.values());
353
354 Alina::mpi_communicator mpi_comm(comm);
355 auto* p = new DistributedSolverType(mpi_comm, A, prm);
356
357 m_p = std::make_shared<AlinaDistributedSolverImpl>(p);
358}
359
360/*---------------------------------------------------------------------------*/
361/*---------------------------------------------------------------------------*/
362
365{
366 DistributedSolverType* solver = m_p->m_solver;
367
368 size_t n = solver->size();
369
371
372 Alina::SolverResult r = (*solver)(rhs, x);
373
374 return _toConvInfo(r);
375}
376
377/*---------------------------------------------------------------------------*/
378/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
CSR Matrix view used in AlinaLib.
Definition AlinaLib.h:98
void checkSizes() const
Check that sizes are valid:
Definition AlinaLib.cc:117
AlinaConvergenceInfo solve(Arcane::SmallSpan< const double > rhs, Arcane::SmallSpan< double > x)
Find solution for the given RHS.
Definition AlinaLib.cc:364
AlinaDistributedSolver(MPI_Comm comm, const AlinaCSRMatrixView &matrix_view, int n_def_vec, AlinaDefVecFunction def_vec_func, void *def_vec_data, const AlinaParameters &params)
Create distributed solver.
Definition AlinaLib.cc:334
Handle parameters for Alina.
Definition AlinaLib.h:60
void setInt64(const char *name, Arcane::Int64 value)
Set Int64 parameter in the parameter list.
Definition AlinaLib.cc:89
void setInt32(const char *name, Arcane::Int32 value)
Set Int32 parameter in the parameter list.
Definition AlinaLib.cc:83
void setReal(const char *name, Arcane::Real value)
Set floating point parameter in the parameter list.
Definition AlinaLib.cc:95
void readFromJSON(const char *fname)
Read parameters from a JSON file.
Definition AlinaLib.cc:107
void setString(const char *name, const char *value)
Set floating point parameter in the parameter list.
Definition AlinaLib.cc:101
void report()
Printout preconditioner structure.
Definition AlinaLib.cc:194
void apply(const double *rhs, double *x)
Apply AMG preconditioner (x = M^(-1) * rhs).
Definition AlinaLib.cc:178
void report()
Printout solver structure.
Definition AlinaLib.cc:245
AlinaConvergenceInfo solve(Arcane::SmallSpan< const double > rhs, Arcane::SmallSpan< double > x)
Solve the problem for the given right-hand side.
Definition AlinaLib.cc:256
AlinaSequentialSolver(const AlinaCSRMatrixView &matrix_view, const AlinaParameters *parameters)
Build a solver for matrix matrix.
Definition AlinaLib.cc:221
AlinaConvergenceInfo solveMatrix(const AlinaCSRMatrixView &matrix_view, Arcane::SmallSpan< const double > rhs, Arcane::SmallSpan< double > x)
Solve the problem for the given matrix and the right-hand side.
Definition AlinaLib.cc:269
Algebraic multigrid method.
Definition AMG.h:71
Runtime wrapper for distributed direct solvers.
Distributed solver based on subdomain deflation.
Convenience class that bundles together a preconditioner and an iterative solver.
const Precond & precond() const
Returns reference to the constructed preconditioner.
size_t size() const
Returns the size of the system matrix.
Class to store parameters as a hierarchical key/value tree.
Definition AlinaUtils.h:112
Result of a solution.
Definition AlinaUtils.h:53
View of an array of elements of type T.
Definition Span.h:803
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
double Real
Type representing a real number.
std::int32_t Int32
Signed integer type of 32 bits.
Convenience wrapper around MPI_Comm.