22#include <boost/range/iterator_range.hpp>
23#include <boost/preprocessor/seq/for_each.hpp>
25#include "arccore/alina/BuiltinBackend.h"
26#include "arccore/alina/ValueTypeComplex.h"
27#include "arccore/alina/StaticMatrix.h"
28#include "arccore/alina/Adapters.h"
30#include "arccore/alina/SolverRuntime.h"
31#include "arccore/alina/CoarseningRuntime.h"
32#include "arccore/alina/RelaxationRuntime.h"
33#include "arccore/alina/PreconditionerRuntime.h"
34#include "arccore/alina/PreconditionedSolver.h"
35#include "arccore/alina/AMG.h"
36#include "arccore/alina/IO.h"
38#include "arccore/alina/Profiler.h"
40#include "arccore/common/internal/ProgramOptions.h"
42#include "SampleProblemCommon.h"
44#ifndef ARCCORE_ALINA_BLOCK_SIZES
45#define ARCCORE_ALINA_BLOCK_SIZES (2)(3)(4)
48using namespace Arcane::Alina;
50using Alina::precondition;
53template <
class Precond,
class Matrix>
58 std::vector<std::complex<double>>
const& f,
59 std::vector<std::complex<double>>& x)
61 auto& prof = Alina::Profiler::globalProfiler();
63 typedef typename Precond::backend_type Backend;
65 typedef typename Alina::math::rhs_of<typename Backend::value_type>::type rhs_type;
66 size_t n = Alina::backend::nbRow(A);
68 rhs_type
const* fptr =
reinterpret_cast<rhs_type const*
>(&f[0]);
69 rhs_type* xptr =
reinterpret_cast<rhs_type*
>(&x[0]);
76 Solver solve(context, A, prm);
79 std::cout << solve << std::endl;
82 auto t = prof.scoped_tic(
"solve");
83 return solve(frng, xrng);
88int main(
int argc,
char* argv[])
90 auto& prof = Alina::Profiler::globalProfiler();
91 namespace po = Arcane::ProgramOptions;
92 namespace io = Alina::IO;
99 desc.add_options()(
"help,h",
"Show this help.");
100 desc.add_options()(
"prm-file,P",
102 "Fichier de paramètres au format json. ");
103 desc.add_options()(
"prm,p",
104 po::value<vector<string>>()->multitoken(),
105 "Paramètres spécifiés sous forme de paires nom=valeur. "
106 "Peut être fourni plusieurs fois. Exemples:\n"
107 " -p solver.tol=1e-3\n"
108 " -p precond.coarse_enough=300");
109 desc.add_options()(
"matrix,A",
111 "Matrice du système au format MatrixMarket. "
112 "Si non spécifié, résout un problème de Poisson dans un cube unitaire 3D. ");
113 desc.add_options()(
"rhs,f",
115 "Le vecteur du membre de droite (RHS) au format MatrixMarket. "
116 "Si omis, un vecteur de uns est utilisé par défaut. "
117 "Ne doit être fourni qu'avec une matrice de système. ");
118 desc.add_options()(
"null,N",
120 "Les vecteurs de l'espace nul proche au format MatrixMarket. "
121 "Doit être une matrice dense de taille N*M, où N est le nombre de "
122 "variables inconnues et M est le nombre de vecteurs de l'espace nul. "
123 "Ne doit être fourni qu'avec une matrice de système. ");
124 desc.add_options()(
"binary,B",
125 po::bool_switch()->default_value(
false),
126 "Lorsqu'il est spécifié, traite les fichiers d'entrée comme binaires au lieu de MatrixMarket. "
127 "Il est supposé que les fichiers ont été convertis au format binaire avec l'utilitaire mm2bin. ");
128 desc.add_options()(
"block-size,b",
129 po::value<int>()->default_value(1),
130 "La taille de bloc de la matrice du système. "
131 "Lorsqu'il est spécifié, la matrice du système est supposée avoir une structure par blocs. "
132 "C'est généralement le cas pour les problèmes en élasticité, en mécanique des structures, "
133 "pour les systèmes couplés d'EDP (tels que les équations de Navier-Stokes), etc. ");
134 desc.add_options()(
"size,n",
135 po::value<int>()->default_value(32),
136 "La taille du problème de Poisson à résoudre si aucune matrice de système n'est donnée. "
137 "Spécifié comme le nombre de nœuds de grille le long de chaque dimension d'un cube unitaire. "
138 "Le système résultant aura n*n*n inconnues. ");
139 desc.add_options()(
"single-level,1",
140 po::bool_switch()->default_value(
false),
141 "Lorsqu'il est spécifié, la hiérarchie AMG n'est pas construite. "
142 "Au lieu de cela, le problème est résolu en utilisant un lisseur de niveau unique comme préconditionneur. ");
143 desc.add_options()(
"initial,x",
144 po::value<double>()->default_value(0),
145 "Valeur à utiliser comme approximation initiale. ");
146 desc.add_options()(
"output,o",
148 "Fichier de sortie. Sera enregistré au format MatrixMarket. "
149 "Lorsqu'il est omis, la solution n'est pas sauvegardée. ");
152 po::store(po::parse_command_line(argc, argv, desc), vm);
155 if (vm.count(
"help")) {
156 std::cout << desc << std::endl;
161 if (vm.count(
"prm-file")) {
162 prm.read_json(vm[
"prm-file"].as<string>());
165 if (vm.count(
"prm")) {
175 if (vm.count(
"matrix")) {
176 auto t = prof.scoped_tic(
"reading");
178 string Afile = vm[
"matrix"].as<
string>();
179 bool binary = vm[
"binary"].as<
bool>();
182 io::read_crs(Afile, rows, ptr, col, val);
186 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
187 precondition(rows == cols,
"Matrice de système non carrée");
190 if (vm.count(
"rhs")) {
191 string bfile = vm[
"rhs"].as<
string>();
195 io::read_dense(bfile, n, m, rhs);
198 std::tie(n, m) = io::mm_reader(bfile)(rhs);
201 precondition(n == rows && m == 1,
"Le vecteur RHS a une taille incorrecte");
204 rhs.resize(rows, 1.0);
207 if (vm.count(
"null")) {
208 string nfile = vm[
"null"].as<
string>();
213 io::read_dense(nfile, m, nv, null);
216 std::tie(m, nv) = io::mm_reader(nfile)(null);
219 precondition(m == rows,
"Les vecteurs de l'espace nul proche ont une taille incorrecte");
221 prm.put(
"precond.coarsening.nullspace.cols", nv);
222 prm.put(
"precond.coarsening.nullspace.rows", rows);
223 prm.put(
"precond.coarsening.nullspace.B", &null[0]);
227 auto t = prof.scoped_tic(
"assembling");
228 rows = Alina::PoissonProblemGenerator::createSequentialMatrix(vm[
"size"].as<int>(), val, col, ptr, rhs);
231 x.resize(rows, vm[
"initial"].as<double>());
233 if (vm[
"single-level"].as<bool>())
234 prm.put(
"precond.class",
"relaxation");
236 int block_size = vm[
"block-size"].as<
int>();
238#define CALL_BLOCK_SOLVER(z, data, B) \
240 typedef StaticMatrix<std::complex<double>, B, B> value_type; \
241 typedef ::Arcane::Alina::BuiltinBackend<value_type> Backend; \
242 r = solve<::Arcane::Alina::PreconditionerRuntime<Backend>>(context, \
243 ::Arcane::Alina::adapter::block_matrix<value_type>( \
244 std::tie(rows, ptr, col, val)), \
248 switch (block_size) {
251 r = solve<PreconditionerRuntime<Backend>>(context, std::tie(rows, ptr, col, val), prm, rhs, x);
253 BOOST_PP_SEQ_FOR_EACH(CALL_BLOCK_SOLVER, ~, ARCCORE_ALINA_BLOCK_SIZES)
256#undef CALL_BLOCK_SOLVER
258 if (vm.count(
"output")) {
259 auto t = prof.scoped_tic(
"write");
260 Alina::IO::mm_write(vm[
"output"].as<string>(), &x[0], x.size());
263 std::cout <<
"Iterations: " << r.nbIteration() << std::endl
264 <<
"Error: " << r.residual() << std::endl
265 << prof << std::endl;
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.
Matrix class, to be used by user.
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.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --