Arcane  4.1.11.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
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 <iostream>
26
27using namespace Arcane;
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32using Backend = Alina::BuiltinBackend<double>;
33//using Backend = Alina::BuiltinBackend<double,Int32,Int32>;
36typedef Alina::PropertyTree Params;
37
38//---------------------------------------------------------------------------
39
40using DistributedSolverType = Alina::DistributedSubDomainDeflation<PreconditionerType,
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
48{
49 Params m_properties;
50};
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
55struct AlinaPreconditioner
56{
57 explicit AlinaPreconditioner(PreconditionerType* preconditioner)
58 : m_preconditioner(preconditioner)
59 {}
60 ~AlinaPreconditioner()
61
62 {
63 delete m_preconditioner;
64 }
65 PreconditionerType* m_preconditioner = nullptr;
66};
67
68/*---------------------------------------------------------------------------*/
69/*---------------------------------------------------------------------------*/
70
71struct AlinaSequentialSolver
72{
73 explicit AlinaSequentialSolver(SequentialSolverType* solver)
74 : m_solver(solver)
75 {}
76 ~AlinaSequentialSolver()
77 {
78 delete m_solver;
79 }
80 SequentialSolverType* m_solver = nullptr;
81};
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86struct AlinaDistributedSolver
87{
88 explicit AlinaDistributedSolver(DistributedSolverType* solver)
89 : m_solver(solver)
90 {}
91 ~AlinaDistributedSolver()
92 {
93 delete m_solver;
94 }
95 DistributedSolverType* m_solver = nullptr;
96};
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
102_toConvInfo(const Alina::SolverResult& r)
103{
105 x.iterations = r.nbIteration();
106 x.residual = r.residual();
107 return x;
108}
109
110/*---------------------------------------------------------------------------*/
111/*---------------------------------------------------------------------------*/
112
113AlinaParameters* AlinaLib::
114params_create()
115{
116 return new AlinaParameters();
117}
118
119/*---------------------------------------------------------------------------*/
120/*---------------------------------------------------------------------------*/
121
122void AlinaLib::
123params_set_int(AlinaParameters* prm, const char* name, int value)
124{
125 prm->m_properties.put(name, value);
126}
127
128/*---------------------------------------------------------------------------*/
129/*---------------------------------------------------------------------------*/
130
131void AlinaLib::
132params_set_float(AlinaParameters* prm, const char* name, float value)
133{
134 prm->m_properties.put(name, value);
135}
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139
140void AlinaLib::
141params_set_string(AlinaParameters* prm, const char* name, const char* value)
142{
143 prm->m_properties.put(name, value);
144}
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
148
149void AlinaLib::
150params_read_json(AlinaParameters* prm, const char* fname)
151{
152 Params& p = prm->m_properties;
153 p.read_json(fname);
154}
155
156/*---------------------------------------------------------------------------*/
157/*---------------------------------------------------------------------------*/
158
159void AlinaLib::
160params_destroy(AlinaParameters* prm)
161{
162 delete prm;
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
167
168AlinaPreconditioner* AlinaLib::
169preconditioner_create(int n,
170 const int* ptr,
171 const int* col,
172 const double* val,
173 AlinaParameters* prm)
174{
175 SmallSpan<const int> ptr_range(ptr, n + 1);
176 SmallSpan<const int> col_range(col, ptr[n]);
177 SmallSpan<const double> val_range(val, ptr[n]);
178
179 auto A = std::make_tuple(n, ptr_range, col_range, val_range);
180
181 PreconditionerType* amg = nullptr;
182 if (prm)
183 amg = new PreconditionerType(A, prm->m_properties);
184 else
185 amg = new PreconditionerType(A);
186 return new AlinaPreconditioner(amg);
187}
188
189/*---------------------------------------------------------------------------*/
190/*---------------------------------------------------------------------------*/
191
192void AlinaLib::
193preconditioner_apply(AlinaPreconditioner* handle, const double* rhs, double* x)
194{
195 PreconditionerType* amg = handle->m_preconditioner;
196
197 size_t n = Alina::backend::nbRow(amg->system_matrix());
198
199 SmallSpan<double> x_range(x, n);
200 SmallSpan<const double> rhs_range(rhs, n);
201
202 amg->apply(rhs_range, x_range);
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208void AlinaLib::
209preconditioner_report(AlinaPreconditioner* handle)
210{
211 std::cout << *(handle->m_preconditioner) << std::endl;
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
216
217void AlinaLib::
218preconditioner_destroy(AlinaPreconditioner* handle)
219{
220 delete handle;
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
226AlinaSequentialSolver* AlinaLib::
227solver_create(int n, const int* ptr,
228 const int* col,
229 const double* val,
230 AlinaParameters* prm)
231{
232 SmallSpan<const int> ptr_range(ptr, n + 1);
233 SmallSpan<const int> col_range(col, ptr[n]);
234 SmallSpan<const double> val_range(val, ptr[n]);
235
236 auto A = std::make_tuple(n, ptr_range, col_range, val_range);
237
238 SequentialSolverType* solver = new SequentialSolverType(A);
239 if (prm)
240 solver = new SequentialSolverType(A, prm->m_properties);
241 else
242 solver = new SequentialSolverType(A);
243 std::cout << "Printing solver infos\n";
244 std::cout << (*solver) << std::endl;
245 Alina::PropertyTree ptree;
246 solver->prm.get(ptree);
247 std::cout << "SOLVER_PARAMS: " << ptree << "\n";
248 return new AlinaSequentialSolver(solver);
249}
250
251/*---------------------------------------------------------------------------*/
252/*---------------------------------------------------------------------------*/
253
254void AlinaLib::
255solver_report(AlinaSequentialSolver* handle)
256{
257 SequentialSolverType* slv = handle->m_solver;
258
259 std::cout << slv->precond() << std::endl;
260}
261
262/*---------------------------------------------------------------------------*/
263/*---------------------------------------------------------------------------*/
264
265void AlinaLib::
266solver_destroy(AlinaSequentialSolver* handle)
267{
268 delete handle;
269}
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
273
274AlinaConvergenceInfo AlinaLib::
275solver_solve(AlinaSequentialSolver* handle,
276 const double* rhs,
277 double* x)
278{
279 SequentialSolverType* slv = handle->m_solver;
280
281 size_t n = slv->size();
282
283 SmallSpan<double> x_range(x, n);
284 SmallSpan<const double> rhs_range(rhs, n);
285
286 Alina::SolverResult r = (*slv)(rhs_range, x_range);
287
288 return _toConvInfo(r);
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
294AlinaConvergenceInfo AlinaLib::
295solver_solve_matrix(AlinaSequentialSolver* handle,
296 int const* A_ptr,
297 int const* A_col,
298 double const* A_val,
299 const double* rhs,
300 double* x)
301{
302 SequentialSolverType* slv = handle->m_solver;
303
304 size_t n = slv->size();
305
306 SmallSpan<double> x_range(x, n);
307 SmallSpan<const double> rhs_range(rhs, n);
308
309 SmallSpan<const int> ptr_range(A_ptr, n + 1);
310 SmallSpan<const int> col_range(A_col, A_ptr[n]);
311 SmallSpan<const double> val_range(A_val, A_ptr[n]);
312
313 auto A = std::make_tuple(n, ptr_range, col_range, val_range);
314
315 Alina::SolverResult r = (*slv)(A, rhs_range, x_range);
316
317 return _toConvInfo(r);
318}
319
320/*---------------------------------------------------------------------------*/
321/*---------------------------------------------------------------------------*/
322
323struct deflation_vectors
324{
325 int n;
326 AlinaDefVecFunction user_func;
327 void* user_data;
328
329 deflation_vectors(int n, AlinaDefVecFunction user_func, void* user_data)
330 : n(n)
331 , user_func(user_func)
332 , user_data(user_data)
333 {}
334
335 int dim() const { return n; }
336
337 double operator()(int i, ptrdiff_t j) const
338 {
339 return user_func(i, j, user_data);
340 }
341};
342
343//---------------------------------------------------------------------------
344AlinaDistributedSolver* AlinaLib::
345solver_mpi_create(MPI_Comm comm,
346 ptrdiff_t n,
347 const ptrdiff_t* ptr,
348 const ptrdiff_t* col,
349 const double* val,
350 int n_def_vec,
351 AlinaDefVecFunction def_vec_func,
352 void* def_vec_data,
353 AlinaParameters* params)
354{
355 std::function<double(ptrdiff_t, unsigned)> dv = deflation_vectors(n_def_vec, def_vec_func, def_vec_data);
356 Alina::PropertyTree prm = params->m_properties;
357 prm.put("num_def_vec", n_def_vec);
358 prm.put("def_vec", &dv);
359
360 SmallSpan<const ptrdiff_t> ptr_range(ptr, n + 1);
361 SmallSpan<const ptrdiff_t> col_range(col, ptr[n]);
362 SmallSpan<const double> val_range(val, ptr[n]);
363
364 auto A = std::make_tuple(n, ptr_range, col_range, val_range);
365 Alina::mpi_communicator mpi_comm(comm);
366 auto* p = new DistributedSolverType(mpi_comm, A, prm);
367
368 return new AlinaDistributedSolver(p);
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
373
374AlinaConvergenceInfo AlinaLib::
375solver_mpi_solve(AlinaDistributedSolver* handle,
376 double const* rhs,
377 double* x)
378{
379 DistributedSolverType* solver = handle->m_solver;
380
381 size_t n = solver->size();
382
383 SmallSpan<double> x_range(x, n);
384 SmallSpan<const double> rhs_range(rhs, n);
385
386 AlinaConvergenceInfo cnv;
387
388 std::tie(cnv.iterations, cnv.residual) = (*solver)(rhs_range, x_range);
389
390 return cnv;
391}
392
393/*---------------------------------------------------------------------------*/
394/*---------------------------------------------------------------------------*/
395
396void AlinaLib::
397solver_mpi_destroy(AlinaDistributedSolver* handle)
398{
399 delete handle;
400}
401
402/*---------------------------------------------------------------------------*/
403/*---------------------------------------------------------------------------*/
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.
Result of a solving.
Definition AlinaUtils.h:52
Vue d'un tableau d'éléments de type T.
Definition Span.h:801
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Convenience wrapper around MPI_Comm.