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