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