Arcane  4.2.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
DistributedRuntimeSDD.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/*---------------------------------------------------------------------------*/
9/*
10 * Ce fichier est basé sur le travail sur la bibliothèque AMGCL (version mars 2026)
11 * qui peut être trouvée à https://github.com/ddemidov/amgcl.
12 *
13 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
14 * SPDX-License-Identifier: MIT
15 */
16/*---------------------------------------------------------------------------*/
17/*---------------------------------------------------------------------------*/
18
19#include <iostream>
20#include <iomanip>
21#include <fstream>
22#include <vector>
23#include <numeric>
24#include <cmath>
25#include <stdexcept>
26
27#if defined(SOLVER_BACKEND_CUDA)
28// Cela ne semble pas défini avec CUDA
29namespace boost::math
30{
31class rounding_error
32{};
33} // namespace boost::math
34#endif
35
36#include "DomainPartition.h"
37
38#include "MBA.h"
39
40#include <memory>
41
42#include <boost/multi_array.hpp>
43#if defined(SOLVER_BACKEND_CUDA)
44#include "arccore/alina/CudaBackend.h"
45#include "arccore/alina/relaxation_cusparse_ilu0.h"
47#else
48#ifndef SOLVER_BACKEND_BUILTIN
49#define SOLVER_BACKEND_BUILTIN
50#endif
51#include "arccore/alina/BuiltinBackend.h"
53#endif
54
55#include "arccore/alina/PreconditionedSolver.h"
56#include "arccore/alina/AMG.h"
57#include "arccore/alina/CoarseningRuntime.h"
58#include "arccore/alina/RelaxationRuntime.h"
59#include "arccore/alina/PreconditionerRuntime.h"
60#include "arccore/alina/DistributedDirectSolverRuntime.h"
61#include "arccore/alina/DistributedSolverRuntime.h"
62#include "arccore/alina/DistributedSubDomainDeflation.h"
63#include "arccore/alina/Adapters.h"
64#include "arccore/alina/Profiler.h"
65
66#include "arccore/common/internal/ProgramOptions.h"
67
68#include "AlinaSamplesCommon.h"
69
70using namespace Arcane;
71
72struct partitioned_deflation
73{
74 unsigned nparts;
75 std::vector<unsigned> domain;
76
77 partitioned_deflation(boost::array<ptrdiff_t, 2> LO,
78 boost::array<ptrdiff_t, 2> HI,
79 unsigned nparts)
80 : nparts(nparts)
81 {
82 DomainPartition<2> part(LO, HI, nparts);
83
84 ptrdiff_t nx = HI[0] - LO[0] + 1;
85 ptrdiff_t ny = HI[1] - LO[1] + 1;
86
87 domain.resize(nx * ny);
88 for (unsigned p = 0; p < nparts; ++p) {
89 boost::array<ptrdiff_t, 2> lo = part.domain(p).min_corner();
90 boost::array<ptrdiff_t, 2> hi = part.domain(p).max_corner();
91
92 for (int j = lo[1]; j <= hi[1]; ++j) {
93 for (int i = lo[0]; i <= hi[0]; ++i) {
94 domain[(j - LO[1]) * nx + (i - LO[0])] = p;
95 }
96 }
97 }
98 }
99
100 size_t dim() const { return nparts; }
101
102 double operator()(ptrdiff_t i, unsigned j) const
103 {
104 return domain[i] == j;
105 }
106};
107
108struct linear_deflation
109{
110 std::vector<double> x;
111 std::vector<double> y;
112
113 linear_deflation(ptrdiff_t chunk,
114 boost::array<ptrdiff_t, 2> lo,
115 boost::array<ptrdiff_t, 2> hi)
116 {
117 double hx = 1.0 / (hi[0] - lo[0]);
118 double hy = 1.0 / (hi[1] - lo[1]);
119
120 ptrdiff_t nx = hi[0] - lo[0] + 1;
121 ptrdiff_t ny = hi[1] - lo[1] + 1;
122
123 x.reserve(chunk);
124 y.reserve(chunk);
125
126 for (ptrdiff_t j = 0; j < ny; ++j) {
127 for (ptrdiff_t i = 0; i < nx; ++i) {
128 x.push_back(i * hx - 0.5);
129 y.push_back(j * hy - 0.5);
130 }
131 }
132 }
133
134 size_t dim() const { return 3; }
135
136 double operator()(ptrdiff_t i, unsigned j) const
137 {
138 switch (j) {
139 default:
140 case 0:
141 return 1;
142 case 1:
143 return x[i];
144 case 2:
145 return y[i];
146 }
147 }
148};
149
150struct bilinear_deflation
151{
152 size_t nv, chunk;
153 std::vector<double> v;
154
155 bilinear_deflation(ptrdiff_t n,
156 ptrdiff_t chunk,
157 boost::array<ptrdiff_t, 2> lo,
158 boost::array<ptrdiff_t, 2> hi)
159 : nv(0)
160 , chunk(chunk)
161 {
162 // Voir quels voisins nous avons.
163 int neib[2][2] = {
164 { lo[0] > 0 || lo[1] > 0, hi[0] + 1 < n || lo[1] > 0 },
165 { lo[0] > 0 || hi[1] + 1 < n, hi[0] + 1 < n || hi[1] + 1 < n }
166 };
167
168 for (int j = 0; j < 2; ++j)
169 for (int i = 0; i < 2; ++i)
170 if (neib[j][i])
171 ++nv;
172
173 if (nv == 0) {
174 // Processus MPI unique ?
175 nv = 1;
176 v.resize(chunk, 1);
177 return;
178 }
179
180 v.resize(chunk * nv, 0);
181
182 double* dv = v.data();
183
184 ptrdiff_t nx = hi[0] - lo[0] + 1;
185 ptrdiff_t ny = hi[1] - lo[1] + 1;
186
187 double hx = 1.0 / (nx - 1);
188 double hy = 1.0 / (ny - 1);
189
190 for (int j = 0; j < 2; ++j) {
191 for (int i = 0; i < 2; ++i) {
192 if (!neib[j][i])
193 continue;
194
195 boost::multi_array_ref<double, 2> V(dv, boost::extents[ny][nx]);
196
197 for (ptrdiff_t jj = 0; jj < ny; ++jj) {
198 double y = jj * hy;
199 double b = std::abs((1 - j) - y);
200 for (ptrdiff_t ii = 0; ii < nx; ++ii) {
201 double x = ii * hx;
202
203 double a = std::abs((1 - i) - x);
204 V[jj][ii] = a * b;
205 }
206 }
207
208 dv += chunk;
209 }
210 }
211 }
212
213 size_t dim() const { return nv; }
214
215 double operator()(ptrdiff_t i, unsigned j) const
216 {
217 return v[j * chunk + i];
218 }
219};
220
221#ifndef SOLVER_BACKEND_CUDA
222struct mba_deflation
223{
224 size_t chunk, nv;
225 std::vector<double> v;
226
227 mba_deflation(ptrdiff_t n,
228 ptrdiff_t chunk,
229 boost::array<ptrdiff_t, 2> lo,
230 boost::array<ptrdiff_t, 2> hi)
231 : chunk(chunk)
232 , nv(1)
233 {
234 // Voir quels voisins nous avons.
235 int neib[2][2] = {
236 { lo[0] > 0 || lo[1] > 0, hi[0] + 1 < n || lo[1] > 0 },
237 { lo[0] > 0 || hi[1] + 1 < n, hi[0] + 1 < n || hi[1] + 1 < n }
238 };
239
240 for (int j = 0; j < 2; ++j)
241 for (int i = 0; i < 2; ++i)
242 if (neib[j][i])
243 ++nv;
244
245 v.resize(chunk * nv, 0);
246
247 double* dv = v.data();
248 std::fill(dv, dv + chunk, 1.0);
249 dv += chunk;
250
251 ptrdiff_t nx = hi[0] - lo[0] + 1;
252 ptrdiff_t ny = hi[1] - lo[1] + 1;
253
254 double hx = 1.0 / (nx - 1);
255 double hy = 1.0 / (ny - 1);
256
257 std::array<double, 2> cmin = { -0.01, -0.01 };
258 std::array<double, 2> cmax = { 1.01, 1.01 };
259 std::array<size_t, 2> grid = { 3, 3 };
260
261 std::array<std::array<double, 2>, 4> coo;
262 std::array<double, 4> val;
263
264 for (int j = 0, idx = 0; j < 2; ++j) {
265 for (int i = 0; i < 2; ++i, ++idx) {
266 coo[idx][0] = i;
267 coo[idx][1] = j;
268 }
269 }
270
271 for (int j = 0, idx = 0; j < 2; ++j) {
272 for (int i = 0; i < 2; ++i, ++idx) {
273 if (!neib[j][i])
274 continue;
275
276 std::fill(val.begin(), val.end(), 0.0);
277 val[idx] = 1.0;
278
279 mba::MBA<2> interp(cmin, cmax, grid, coo, val, 8, 1e-8, 0.5, zero);
280
281 boost::multi_array_ref<double, 2> V(dv, boost::extents[ny][nx]);
282
283 for (int jj = 0; jj < ny; ++jj)
284 for (int ii = 0; ii < nx; ++ii) {
285 std::array<double, 2> p = { ii * hx, jj * hy };
286 V[jj][ii] = interp(p);
287 }
288
289 dv += chunk;
290 }
291 }
292 }
293
294 size_t dim() const { return nv; }
295
296 double operator()(ptrdiff_t i, unsigned j) const
297 {
298 return v[j * chunk + i];
299 }
300
301 static double zero(const std::array<double, 2>&)
302 {
303 return 0;
304 }
305};
306#endif
307
308struct harmonic_deflation
309{
310 size_t nv, chunk;
311 std::vector<double> v;
312
313 harmonic_deflation(ptrdiff_t n,
314 ptrdiff_t chunk,
315 boost::array<ptrdiff_t, 2> lo,
316 boost::array<ptrdiff_t, 2> hi)
317 : nv(0)
318 , chunk(chunk)
319 {
320 Alina::AlinaContext context;
321
322 // Voir quels voisins nous avons.
323 int neib[2][2] = {
324 { lo[0] > 0 || lo[1] > 0, hi[0] + 1 < n || lo[1] > 0 },
325 { lo[0] > 0 || hi[1] + 1 < n, hi[0] + 1 < n || hi[1] + 1 < n }
326 };
327
328 for (int j = 0; j < 2; ++j)
329 for (int i = 0; i < 2; ++i)
330 if (neib[j][i])
331 ++nv;
332
333 if (nv == 0) {
334 // Processus MPI unique ?
335 nv = 1;
336 v.resize(chunk, 1);
337 return;
338 }
339
340 v.resize(chunk * nv, 0);
341 double* dv = v.data();
342
343 ptrdiff_t nx = hi[0] - lo[0] + 1;
344 ptrdiff_t ny = hi[1] - lo[1] + 1;
345
346 std::vector<Int32> ptr;
347 std::vector<Int32> col;
348 std::vector<double> val;
349 std::vector<double> rhs(chunk, 0.0);
350
351 ptr.reserve(chunk + 1);
352 col.reserve(chunk * 5);
353 val.reserve(chunk * 5);
354
355 ptr.push_back(0);
356
357 for (int j = 0, k = 0; j < ny; ++j) {
358 for (int i = 0; i < nx; ++i, ++k) {
359 if (
360 (i == 0 && j == 0) ||
361 (i == 0 && j == ny - 1) ||
362 (i == nx - 1 && j == 0) ||
363 (i == nx - 1 && j == ny - 1)) {
364 col.push_back(k);
365 val.push_back(1);
366 }
367 else {
368 col.push_back(k);
369 val.push_back(1.0);
370
371 if (j == 0) {
372 col.push_back(k + nx);
373 val.push_back(-0.5);
374 }
375 else if (j == ny - 1) {
376 col.push_back(k - nx);
377 val.push_back(-0.5);
378 }
379 else {
380 col.push_back(k - nx);
381 val.push_back(-0.25);
382
383 col.push_back(k + nx);
384 val.push_back(-0.25);
385 }
386
387 if (i == 0) {
388 col.push_back(k + 1);
389 val.push_back(-0.5);
390 }
391 else if (i == nx - 1) {
392 col.push_back(k - 1);
393 val.push_back(-0.5);
394 }
395 else {
396 col.push_back(k - 1);
397 val.push_back(-0.25);
398
399 col.push_back(k + 1);
400 val.push_back(-0.25);
401 }
402 }
403
404 ptr.push_back(col.size());
405 }
406 }
407
413 solve(context, Alina::adapter::zero_copy(chunk, ptr.data(), col.data(), val.data()));
414
415 for (int j = 0; j < 2; ++j) {
416 for (int i = 0; i < 2; ++i) {
417 if (!neib[j][i])
418 continue;
419
420 ptrdiff_t idx = i * (nx - 1) + j * (ny - 1) * nx;
421 rhs[idx] = 1.0;
422
423 SmallSpan<double> x(dv, chunk);
424 solve(rhs, x);
425
426 rhs[idx] = 0.0;
427
428 dv += chunk;
429 }
430 }
431 }
432
433 size_t dim() const { return nv; }
434
435 double operator()(ptrdiff_t i, unsigned j) const
436 {
437 return v[j * chunk + i];
438 }
439};
440
441struct renumbering
442{
443 const DomainPartition<2>& part;
444 const std::vector<ptrdiff_t>& dom;
445
446 renumbering(const DomainPartition<2>& p,
447 const std::vector<ptrdiff_t>& d)
448 : part(p)
449 , dom(d)
450 {}
451
452 ptrdiff_t operator()(ptrdiff_t i, ptrdiff_t j) const
453 {
454 boost::array<ptrdiff_t, 2> p = { { i, j } };
455 std::pair<int, ptrdiff_t> v = part.index(p);
456 return dom[v.first] + v.second;
457 }
458};
459
460int main2(const Alina::SampleMainContext& ctx, int argc, char* argv[])
461{
462 auto& prof = Alina::Profiler::globalProfiler();
463
464 Alina::AlinaCommunicator world(ctx.messagePassingMng());
465 if (world.rank == 0)
466 std::cout << "World size: " << world.size << std::endl;
467 Alina::AlinaContext context;
468
469 // Lire la configuration à partir de la ligne de commande
470 ptrdiff_t n = 1024;
471 std::string deflation_type = "bilinear";
472
473 auto coarsening = Alina::eCoarserningType::smoothed_aggregation;
474 auto relaxation = Alina::eRelaxationType::spai0;
475 auto iterative_solver = Alina::eSolverType::bicgstabl;
476 auto direct_solver = Alina::eDistributedDirectSolverType::skyline_lu;
477
478 bool just_relax = false;
479 bool symm_dirichlet = true;
480 std::string problem = "laplace2d";
481 std::string parameter_file;
482 std::string out_file;
483
484 namespace po = Arcane::ProgramOptions;
485 po::options_description desc("Options");
486
487 desc.add_options()("help,h", "show help")(
488 "problem",
489 po::value<std::string>(&problem)->default_value(problem),
490 "laplace2d, recirc2d")(
491 "symbc",
492 po::value<bool>(&symm_dirichlet)->default_value(symm_dirichlet),
493 "Utiliser des conditions de Dirichlet symétriques dans laplace2d")(
494 "size,n",
495 po::value<ptrdiff_t>(&n)->default_value(n),
496 "taille du domaine")(
497 "coarsening,c",
498 po::value<Alina::eCoarserningType>(&coarsening)->default_value(coarsening),
499 "ruge_stuben, aggregation, smoothed_aggregation, smoothed_aggr_emin")(
500 "relaxation,r",
501 po::value<Alina::eRelaxationType>(&relaxation)->default_value(relaxation),
502 "gauss_seidel, ilu0, iluk, ilut, damped_jacobi, spai0, spai1, chebyshev")(
503 "iter_solver,i",
504 po::value<Alina::eSolverType>(&iterative_solver)->default_value(iterative_solver),
505 "cg, bicgstab, bicgstabl, gmres")(
506 "dir_solver,d",
507 po::value<Alina::eDistributedDirectSolverType>(&direct_solver)->default_value(direct_solver),
508 "skyline_lu"
509#ifdef ARCCORE_ALINA_HAVE_PASTIX
510 ", pastix"
511#endif
512 )(
513 "deflation,v",
514 po::value<std::string>(&deflation_type)->default_value(deflation_type),
515 "constant, partitioned, linear, bilinear, mba, harmonic")(
516 "subparts",
517 po::value<int>()->default_value(16),
518 "nombre de partitions pour la déflation partitionnée")(
519 "params,P",
520 po::value<std::string>(&parameter_file),
521 "fichier de paramètres au format json")(
522 "prm,p",
523 po::value<std::vector<std::string>>()->multitoken(),
524 "Paramètres spécifiés sous forme de paires nom=valeur. "
525 "Peut être fourni plusieurs fois. Exemples :\n"
526 " -p solver.tol=1e-3\n"
527 " -p precond.coarse_enough=300")(
528 "just-relax,0",
529 po::bool_switch(&just_relax),
530 "Ne pas créer la hiérarchie AMG, utiliser la relaxation comme préconditionneur")(
531 "out,o",
532 po::value<std::string>(&out_file),
533 "fichier de sortie");
534
536 po::store(po::parse_command_line(argc, argv, desc), vm);
537 po::notify(vm);
538
539 if (vm.count("help")) {
540 std::cout << desc << std::endl;
541 return 0;
542 }
543
545 if (vm.count("params"))
546 prm.read_json(parameter_file);
547
548 if (vm.count("prm")) {
549 for (const std::string& v : vm["prm"].as<std::vector<std::string>>()) {
550 prm.putKeyValue(v);
551 }
552 }
553
554 prm.put("isolver.type", iterative_solver);
555 prm.put("dsolver.type", direct_solver);
556
557 const ptrdiff_t n2 = n * n;
558 const double hinv = (n - 1);
559 const double h2i = (n - 1) * (n - 1);
560 const double h = 1 / hinv;
561
562 boost::array<ptrdiff_t, 2> lo = { { 0, 0 } };
563 boost::array<ptrdiff_t, 2> hi = { { n - 1, n - 1 } };
564
565 prof.tic("partition");
566 DomainPartition<2> part(lo, hi, world.size);
567 ptrdiff_t chunk = part.size(world.rank);
568
569 std::vector<ptrdiff_t> domain(world.size + 1);
570 ConstArrayView<ptrdiff_t> send_buf(1, &chunk);
571 ArrayView<ptrdiff_t> receive_buf(world.size, &domain[1]);
572 mpAllGather(world.m_message_passing_mng.get(), send_buf, receive_buf);
573 std::partial_sum(domain.begin(), domain.end(), domain.begin());
574
575 lo = part.domain(world.rank).min_corner();
576 hi = part.domain(world.rank).max_corner();
577 prof.toc("partition");
578
579 renumbering renum(part, domain);
580
581 prof.tic("deflation");
582 std::function<double(ptrdiff_t, unsigned)> dv;
583 Int32 ndv = 1;
584
585 if (deflation_type == "constant") {
587 }
588 else if (deflation_type == "partitioned") {
589 ndv = vm["subparts"].as<int>();
590 dv = partitioned_deflation(lo, hi, ndv);
591 }
592 else if (deflation_type == "linear") {
593 ndv = 3;
594 dv = linear_deflation(chunk, lo, hi);
595 }
596 else if (deflation_type == "bilinear") {
597 bilinear_deflation bld(n, chunk, lo, hi);
598 ndv = bld.dim();
599 dv = bld;
600#ifndef SOLVER_BACKEND_CUDA
601 }
602 else if (deflation_type == "mba") {
603 mba_deflation mba(n, chunk, lo, hi);
604 ndv = mba.dim();
605 dv = mba;
606#endif
607 }
608 else if (deflation_type == "harmonic") {
609 harmonic_deflation hd(n, chunk, lo, hi);
610 ndv = hd.dim();
611 dv = hd;
612 }
613 else {
614 throw std::runtime_error("Unsupported deflation type");
615 }
616
617 prm.put("num_def_vec", ndv);
618 prm.put("def_vec", &dv);
619 prof.toc("deflation");
620
621 prof.tic("assemble");
622 std::vector<ptrdiff_t> ptr;
623 std::vector<ptrdiff_t> col;
624 std::vector<double> val;
625 std::vector<double> rhs;
626
627 ptr.reserve(chunk + 1);
628 col.reserve(chunk * 5);
629 val.reserve(chunk * 5);
630 rhs.reserve(chunk);
631
632 ptr.push_back(0);
633
634 if (problem == "recirc2d") {
635 const double eps = 1e-5;
636
637 for (ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
638 double y = h * j;
639 for (ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
640 double x = h * i;
641
642 if (i == 0 || j == 0 || i + 1 == n || j + 1 == n) {
643 col.push_back(renum(i, j));
644 val.push_back(1);
645 rhs.push_back(
646 sin(M_PI * x) + sin(M_PI * y) +
647 sin(13 * M_PI * x) + sin(13 * M_PI * y));
648 }
649 else {
650 double a = -sin(M_PI * x) * cos(M_PI * y) * hinv;
651 double b = sin(M_PI * y) * cos(M_PI * x) * hinv;
652
653 if (j > 0) {
654 col.push_back(renum(i, j - 1));
655 val.push_back(-eps * h2i - std::max(b, 0.0));
656 }
657
658 if (i > 0) {
659 col.push_back(renum(i - 1, j));
660 val.push_back(-eps * h2i - std::max(a, 0.0));
661 }
662
663 col.push_back(renum(i, j));
664 val.push_back(4 * eps * h2i + fabs(a) + fabs(b));
665
666 if (i + 1 < n) {
667 col.push_back(renum(i + 1, j));
668 val.push_back(-eps * h2i + std::min(a, 0.0));
669 }
670
671 if (j + 1 < n) {
672 col.push_back(renum(i, j + 1));
673 val.push_back(-eps * h2i + std::min(b, 0.0));
674 }
675
676 rhs.push_back(1.0);
677 }
678 ptr.push_back(col.size());
679 }
680 }
681 }
682 else {
683 for (ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
684 for (ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
685 if (!symm_dirichlet && (i == 0 || j == 0 || i + 1 == n || j + 1 == n)) {
686 col.push_back(renum(i, j));
687 val.push_back(1);
688 rhs.push_back(0);
689 }
690 else {
691 if (j > 0) {
692 col.push_back(renum(i, j - 1));
693 val.push_back(-h2i);
694 }
695
696 if (i > 0) {
697 col.push_back(renum(i - 1, j));
698 val.push_back(-h2i);
699 }
700
701 col.push_back(renum(i, j));
702 val.push_back(4 * h2i);
703
704 if (i + 1 < n) {
705 col.push_back(renum(i + 1, j));
706 val.push_back(-h2i);
707 }
708
709 if (j + 1 < n) {
710 col.push_back(renum(i, j + 1));
711 val.push_back(-h2i);
712 }
713
714 rhs.push_back(1);
715 }
716 ptr.push_back(col.size());
717 }
718 }
719 }
720 prof.toc("assemble");
721
722 Backend::params bprm;
723
724#if defined(SOLVER_BACKEND_CUDA)
725 cusparseCreate(&bprm.cusparse_handle);
726#endif
727
728 auto f = Backend::copy_vector(rhs, bprm);
729 auto x = Backend::create_vector(chunk, bprm);
730
731 Alina::backend::clear(*x);
732
733 if (just_relax) {
734 prm.put("local.class", "relaxation");
735 prm.put("local.type", relaxation);
736 }
737 else {
738 prm.put("local.coarsening.type", coarsening);
739 prm.put("local.relax.type", relaxation);
740 }
741
742 prof.tic("setup");
746
747 SDD solve(context, world, std::tie(chunk, ptr, col, val), prm, bprm);
748 prof.toc("setup");
749
750 prof.tic("solve");
751 Alina::SolverResult r = solve(*f, *x);
752 prof.toc("solve");
753
754 if (world.rank == 0) {
755 std::cout << "Itérations : " << r.nbIteration() << std::endl
756 << "Erreur : " << r.residual() << std::endl
757 << prof << std::endl;
758 }
759 return 0;
760}
761
762int main(int argc, char* argv[])
763{
764 return Arcane::Alina::SampleMainContext::execMain(main2, argc, argv);
765}
Runtime wrapper for distributed direct solvers.
Solveur distribué basé sur la déflation de sous-domaines.
Generalized Minimal Residual (GMRES) method.
Convenience class that bundles together a preconditioner and an iterative solver.
Classe pour stocker les paramètres sous forme d'arbre hiérarchique clé/valeur.
Definition AlinaUtils.h:113
Résultat d'une solution.
Definition AlinaUtils.h:56
Vue modifiable d'un tableau d'un type T.
Vue constante d'un tableau de type T.
Décrit un ensemble d'options en ligne de commande.
Stocke les valeurs d'options analysées.
Vue d'un tableau d'éléments de type T.
Definition Span.h:802
void mpAllGather(IMessagePassingMng *pm, const ISerializer *send_serializer, ISerializer *receive_serialize)
Message allGather() pour une sérialisation.
Definition Messages.cc:318
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Wrapper de commodité autour de MPI_Comm.
Gauss-Seidel relaxation.
Definition Relaxation.h:512
Raffinement par agrégation lissée.
Vecteurs de déflation constants ponctuels.