19#include "arccore/alina/BuiltinBackend.h"
20#include "arccore/alina/RelaxationRuntime.h"
21#include "arccore/alina/CoarseningRuntime.h"
22#include "arccore/alina/SolverRuntime.h"
23#include "arccore/alina/PreconditionerRuntime.h"
24#include "arccore/alina/DeflatedSolver.h"
25#include "arccore/alina/AMG.h"
26#include "arccore/alina/Adapters.h"
27#include "arccore/alina/IO.h"
28#include "arccore/alina/Profiler.h"
30#include "arccore/common/internal/ProgramOptions.h"
37using Alina::precondition;
40int main(
int argc,
char* argv[])
42 auto& prof = Alina::Profiler::globalProfiler();
44 namespace po = Arcane::ProgramOptions;
45 namespace io = Alina::IO;
53 desc.add_options()(
"help,h",
"Affiche cette aide.");
54 desc.add_options()(
"prm-file,P",
56 "Fichier de paramètres au format json. ");
57 desc.add_options()(
"prm,p",
58 po::value<vector<string>>()->multitoken(),
59 "Paramètres spécifiés sous forme de paires nom=valeur. "
60 "Peut être fourni plusieurs fois. Exemples:\n"
61 " -p solver.tol=1e-3\n"
62 " -p precond.coarse_enough=300");
63 desc.add_options()(
"matrix,A",
64 po::value<string>()->required(),
65 "Matrice du système au format MatrixMarket.");
66 desc.add_options()(
"rhs,f",
68 "Le vecteur du membre de droite (RHS) au format MatrixMarket. "
69 "Lorsqu'il est omis, un vecteur de uns est utilisé par défaut. "
70 "Ne doit être fourni qu'avec une matrice de système. ");
71 desc.add_options()(
"scale,s",
72 po::bool_switch()->default_value(
false),
73 "Mettre à l'échelle la matrice de sorte que la diagonale soit unitaire. ");
74 desc.add_options()(
"null,N",
76 "Vecteurs nuls de départ au format MatrixMarket. ");
77 desc.add_options()(
"numvec,n",
78 po::value<int>()->default_value(3),
79 "Le nombre de vecteurs proches de l'espace nul à rechercher. ");
80 desc.add_options()(
"binary,B",
81 po::bool_switch()->default_value(
false),
82 "Lorsqu'il est spécifié, traiter les fichiers d'entrée comme binaires au lieu de MatrixMarket. "
83 "Il est supposé que les fichiers ont été convertis au format binaire avec l'utilitaire mm2bin. ");
84 desc.add_options()(
"output,o",
86 "Sortir l'espace nul calculé dans le fichier MatrixMarket.");
95 if (vm.count(
"help")) {
96 std::cout << desc << std::endl;
100 for (
int i = 0; i < argc; ++i) {
103 std::cout << argv[i];
105 std::cout << std::endl;
108 if (vm.count(
"prm-file")) {
109 prm.read_json(vm[
"prm-file"].as<string>());
112 if (vm.count(
"prm")) {
113 for (
const string& v : vm[
"prm"].as<vector<string>>()) {
118 ptrdiff_t rows, nv = 0, numvec = vm[
"numvec"].as<
int>();
119 vector<ptrdiff_t> ptr, col;
120 vector<double> val, rhs;
121 std::list<std::vector<double>> Z;
124 auto t = prof.scoped_tic(
"read");
126 string Afile = vm[
"matrix"].as<
string>();
127 bool binary = vm[
"binary"].as<
bool>();
130 io::read_crs(Afile, rows, ptr, col, val);
134 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
135 precondition(rows == cols,
"Matrice de système non carrée");
138 if (vm.count(
"rhs")) {
139 string bfile = vm[
"rhs"].as<
string>();
144 io::read_dense(bfile, n, m, rhs);
147 std::tie(n, m) = io::mm_reader(bfile)(rhs);
150 precondition(n == rows && m == 1,
"Le vecteur RHS a la mauvaise taille");
153 rhs.resize(rows, 1.0);
156 if (vm.count(
"null")) {
157 string nfile = vm[
"null"].as<
string>();
159 std::vector<double> null;
163 io::read_dense(nfile, m, nv, null);
166 std::tie(m, nv) = io::mm_reader(nfile)(null);
169 precondition(m == rows,
"Les vecteurs proches de l'espace nul ont la mauvaise taille");
171 for (ptrdiff_t i = 0; i < nv; ++i) {
172 Z.emplace_back(rows);
173 for (ptrdiff_t j = 0; j < rows; ++j) {
174 Z.back()[j] = null[j * nv + i];
180 if (vm[
"scale"].as<bool>()) {
181 auto t = prof.scoped_tic(
"scaling");
182 std::vector<double> dia(rows, 1.0);
184 for (ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(rows); ++i) {
186 for (ptrdiff_t j = ptr[i], e = ptr[i + 1]; j < e; ++j) {
188 d = 1 /
sqrt(val[j]);
195 for (ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(rows); ++i) {
197 for (ptrdiff_t j = ptr[i], e = ptr[i + 1]; j < e; ++j) {
198 val[j] *= dia[i] * dia[col[j]];
208 std::uniform_real_distribution<double> rnd(-1, 1);
209 std::vector<double> x(rows), zero(rows, 0.0);
211 auto A = std::tie(rows, ptr, col, val);
213 prm.put(
"solver.ns_search",
true);
216 for (
int k = nv; k < numvec; ++k) {
217 auto t = prof.scoped_tic(std::string(
"vector ") + std::to_string(k));
218 std::vector<double> N;
223 for (
const auto& z : Z) {
224 for (ptrdiff_t i = 0; i < rows; ++i) {
230 prm.put(
"precond.coarsening.nullspace.rows", rows);
231 prm.put(
"precond.coarsening.nullspace.cols", k);
232 prm.put(
"precond.coarsening.nullspace.B", N.data());
236 Solver S(context, A, prm);
239 std::cout << std::endl
240 <<
"-------------------------" << std::endl
241 <<
"-- Recherche du vecteur " << k << std::endl
242 <<
"-------------------------" << std::endl
252 std::cout <<
"Itérations: " << r.nbIteration() << std::endl
253 <<
"Erreur: " << r.residual() << std::endl;
256 for (
const auto& z : Z) {
257 double c = Alina::backend::inner_product(x, z) / Alina::backend::inner_product(z, z);
258 Alina::backend::axpby(-c, z, 1, x);
261 double nx =
sqrt(Alina::backend::inner_product(x, x));
269 std::vector<double> N(numvec * rows);
271 auto t = prof.scoped_tic(
"apply");
274 for (
const auto& z : Z) {
275 for (ptrdiff_t i = 0; i < rows; ++i) {
276 N[i * numvec + j] = z[i];
281 prm.put(
"precond.coarsening.nullspace.rows", rows);
282 prm.put(
"precond.coarsening.nullspace.cols", numvec);
283 prm.put(
"precond.coarsening.nullspace.B", N.data());
286 Solver S(context, A, prm);
289 std::cout << std::endl
290 <<
"-------------------------" << std::endl
291 <<
"-- Résolution du système " << std::endl
292 <<
"-------------------------" << std::endl
295 Alina::backend::clear(x);
301 std::cout <<
"Itérations: " << r.nbIteration() << std::endl
302 <<
"Erreur: " << r.residual() << std::endl;
305 if (vm.count(
"output")) {
306 auto t = prof.scoped_tic(
"write");
307 Alina::IO::mm_write(vm[
"output"].as<string>(), N.data(), rows, numvec);
310 std::cout << 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.
Constructeur d'analyseur d'arguments en ligne de commande fluide.
Décrit un ensemble d'options en ligne de commande.
Décrit les arguments positionnels (non-options).
Stocke les valeurs d'options analysées.
apfloat sqrt(apfloat v)
Racine carrée de v.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Runtime-configurable wrappers around iterative solvers.