Arcane  4.2.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
DeflatedSolver.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 effectué sur la bibliothèque AMGCL (version Mars 2026)
11 * qui peut être trouvé à 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 <string>
21
22#include "arccore/alina/BuiltinBackend.h"
23#include "arccore/alina/RelaxationRuntime.h"
24#include "arccore/alina/CoarseningRuntime.h"
25#include "arccore/alina/SolverRuntime.h"
26#include "arccore/alina/PreconditionerRuntime.h"
27#include "arccore/alina/DeflatedSolver.h"
28#include "arccore/alina/AMG.h"
29#include "arccore/alina/Adapters.h"
30#include "arccore/alina/IO.h"
31#include "arccore/alina/Profiler.h"
32
33#include "arccore/common/internal/ProgramOptions.h"
34
35using namespace Arcane;
36
37using Alina::precondition;
38
39//---------------------------------------------------------------------------
40int main(int argc, char* argv[])
41{
42 auto& prof = Alina::Profiler::globalProfiler();
43
44 namespace po = Arcane::ProgramOptions;
45 namespace io = Alina::IO;
46
47 using std::string;
48 using std::vector;
49
50 po::options_description desc("Options");
51
52 desc.add_options()("help,h", "Affiche cette aide.")("prm-file,P",
53 po::value<string>(),
54 "Fichier de paramètres au format json. ")(
55 "prm,p",
56 po::value<vector<string>>()->multitoken(),
57 "Paramètres spécifiés sous forme de paires nom=valeur. "
58 "Peut être fourni plusieurs fois. Exemples:\n"
59 " -p solver.tol=1e-3\n"
60 " -p precond.coarse_enough=300")("matrix,A",
61 po::value<string>()->required(),
62 "Matrice du système au format MatrixMarket.")(
63 "rhs,f",
64 po::value<string>(),
65 "Le vecteur RHS au format MatrixMarket. "
66 "S'il est omis, un vecteur de uns est utilisé par défaut. "
67 "Ne doit être fourni qu'avec une matrice de système. ")(
68 "defvec,D",
69 po::value<string>(),
70 "Les vecteurs de l'espace nul proche au format MatrixMarket. ")(
71 "coords,C",
72 po::value<string>(),
73 "Matrice de coordonnées où le nombre de lignes correspond au nombre de nœuds de grille "
74 "et le nombre de colonnes correspond à la dimensionnalité du problème (2 ou 3). "
75 "Sera utilisée pour construire des vecteurs de l'espace nul proche en tant que modes de corps rigide. ")(
76 "binary,B",
77 po::bool_switch()->default_value(false),
78 "Lorsqu'il est spécifié, traite les fichiers d'entrée comme binaires au lieu de MatrixMarket. "
79 "Il est supposé que les fichiers ont été convertis au format binaire avec l'utilitaire mm2bin. ")(
80 "single-level,1",
81 po::bool_switch()->default_value(false),
82 "Lorsqu'il est spécifié, la hiérarchie AMG n'est pas construite. "
83 "Au lieu de cela, le problème est résolu en utilisant un lisseur de niveau unique comme préconditionneur. ")(
84 "output,o",
85 po::value<string>(),
86 "Fichier de sortie. Sera enregistré au format MatrixMarket. "
87 "S'il est omis, la solution n'est pas enregistrée. ");
88
90 p.add("prm", -1);
91
93 po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
94 po::notify(vm);
95
96 if (vm.count("help")) {
97 std::cout << desc << std::endl;
98 return 0;
99 }
100
101 for (int i = 0; i < argc; ++i) {
102 if (i)
103 std::cout << " ";
104 std::cout << argv[i];
105 }
106 std::cout << std::endl;
107
109 if (vm.count("prm-file")) {
110 prm.read_json(vm["prm-file"].as<string>());
111 }
112
113 if (vm.count("prm")) {
114 for (const string& v : vm["prm"].as<vector<string>>()) {
115 prm.putKeyValue(v);
116 }
117 }
118
119 if (!vm.count("defvec") && !vm.count("coords")) {
120 std::cerr << "Soit defvec soit coords doit être fourni" << std::endl;
121 return 1;
122 }
123
124 ptrdiff_t rows, nv;
125 vector<ptrdiff_t> ptr, col;
126 vector<double> val, rhs, z;
127
128 {
129 auto t = prof.scoped_tic("reading");
130
131 string Afile = vm["matrix"].as<string>();
132 bool binary = vm["binary"].as<bool>();
133
134 if (binary) {
135 io::read_crs(Afile, rows, ptr, col, val);
136 }
137 else {
138 ptrdiff_t cols;
139 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
140 precondition(rows == cols, "Matrice de système non carrée");
141 }
142
143 if (vm.count("rhs")) {
144 string bfile = vm["rhs"].as<string>();
145
146 ptrdiff_t n, m;
147
148 if (binary) {
149 io::read_dense(bfile, n, m, rhs);
150 }
151 else {
152 std::tie(n, m) = io::mm_reader(bfile)(rhs);
153 }
154
155 precondition(n == rows && m == 1, "Le vecteur RHS a une taille incorrecte");
156 }
157 else {
158 rhs.resize(rows, 1.0);
159 }
160
161 if (vm.count("defvec")) {
162 string nfile = vm["defvec"].as<string>();
163 std::vector<double> N;
164
165 ptrdiff_t m;
166
167 if (binary) {
168 io::read_dense(nfile, m, nv, N);
169 }
170 else {
171 std::tie(m, nv) = io::mm_reader(nfile)(N);
172 }
173
174 precondition(m == rows, "Les vecteurs de déflation ont une taille incorrecte");
175
176 z.resize(N.size());
177 for (ptrdiff_t i = 0; i < rows; ++i)
178 for (ptrdiff_t j = 0; j < nv; ++j)
179 z[i + j * rows] = N[i * nv + j];
180 }
181 else if (vm.count("coords")) {
182 string cfile = vm["coords"].as<string>();
183 std::vector<double> coo;
184
185 ptrdiff_t m, ndim;
186
187 if (binary) {
188 io::read_dense(cfile, m, ndim, coo);
189 }
190 else {
191 std::tie(m, ndim) = io::mm_reader(cfile)(coo);
192 }
193
194 precondition(m * ndim == rows && (ndim == 2 || ndim == 3), "La matrice de coordonnées a une taille incorrecte");
195
196 nv = Alina::rigid_body_modes(ndim, coo, z, /*transpose = */ true);
197 }
198
199 prm.put("nvec", nv);
200 prm.put("vec", z.data());
201 }
202
203 std::vector<double> x(rows, 0);
204
205 if (vm["single-level"].as<bool>())
206 prm.put("precond.class", "relaxation");
207
208 typedef Alina::BuiltinBackend<double> Backend;
211 Solver;
212
213 auto A = std::tie(rows, ptr, col, val);
214
215 prof.tic("setup");
216 Solver solve(A, prm);
217 prof.toc("setup");
218
219 prof.tic("solve");
220 Alina::SolverResult result = solve(rhs, x);
221 prof.toc("solve");
222
223 if (vm.count("output")) {
224 auto t = prof.scoped_tic("write");
225 Alina::IO::mm_write(vm["output"].as<string>(), x.data(), x.size());
226 }
227
228 std::vector<double> r(rows);
229 Alina::backend::residual(rhs, A, x, r);
230
231 std::cout << "Itérations: " << result.nbIteration() << std::endl
232 << "Erreur: " << result.residual() << std::endl
233 << "Erreur réelle: " << sqrt(Alina::backend::inner_product(r, r)) / sqrt(Alina::backend::inner_product(rhs, rhs))
234 << prof << std::endl;
235}
Iterative preconditioned solver with deflation.
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
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.
Definition MathApfloat.h:65
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Runtime-configurable wrappers around iterative solvers.