Arcane  4.2.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
SolverComplex.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 <boost/range/iterator_range.hpp>
23#include <boost/preprocessor/seq/for_each.hpp>
24
25#include "arccore/alina/BuiltinBackend.h"
26#include "arccore/alina/ValueTypeComplex.h"
27#include "arccore/alina/StaticMatrix.h"
28#include "arccore/alina/Adapters.h"
29
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"
37
38#include "arccore/alina/Profiler.h"
39
40#include "arccore/common/internal/ProgramOptions.h"
41
42#include "SampleProblemCommon.h"
43
44#ifndef ARCCORE_ALINA_BLOCK_SIZES
45#define ARCCORE_ALINA_BLOCK_SIZES (2)(3)(4)
46#endif
47using namespace Arcane;
48using namespace Arcane::Alina;
49
50using Alina::precondition;
51
52//---------------------------------------------------------------------------
53template <class Precond, class Matrix>
55solve(const Matrix& A,
56 const Alina::PropertyTree& prm,
57 std::vector<std::complex<double>> const& f,
58 std::vector<std::complex<double>>& x)
59{
60 auto& prof = Alina::Profiler::globalProfiler();
61
62 typedef typename Precond::backend_type Backend;
63
64 typedef typename Alina::math::rhs_of<typename Backend::value_type>::type rhs_type;
65 size_t n = Alina::backend::nbRow(A);
66
67 rhs_type const* fptr = reinterpret_cast<rhs_type const*>(&f[0]);
68 rhs_type* xptr = reinterpret_cast<rhs_type*>(&x[0]);
69 SmallSpan<const rhs_type> frng(fptr, n);
70 SmallSpan<rhs_type> xrng(xptr, n);
71
73
74 prof.tic("setup");
75 Solver solve(A, prm);
76 prof.toc("setup");
77
78 std::cout << solve << std::endl;
79
80 {
81 auto t = prof.scoped_tic("solve");
82 return solve(frng, xrng);
83 }
84}
85
86//---------------------------------------------------------------------------
87int main(int argc, char* argv[])
88{
89 auto& prof = Alina::Profiler::globalProfiler();
90 namespace po = Arcane::ProgramOptions;
91 namespace io = Alina::IO;
92
93 using std::string;
94 using std::vector;
95
96 po::options_description desc("Options");
97
98 desc.add_options()("help,h", "Show this help.")("prm-file,P",
99 po::value<string>(),
100 "Fichier de paramètres au format json. ")(
101 "prm,p",
102 po::value<vector<string>>()->multitoken(),
103 "Paramètres spécifiés sous forme de paires nom=valeur. "
104 "Peut être fourni plusieurs fois. Exemples:\n"
105 " -p solver.tol=1e-3\n"
106 " -p precond.coarse_enough=300")("matrix,A",
107 po::value<string>(),
108 "Matrice du système au format MatrixMarket. "
109 "Si non spécifié, résout un problème de Poisson dans un cube unitaire 3D. ")(
110 "rhs,f",
111 po::value<string>(),
112 "Le vecteur du membre de droite (RHS) au format MatrixMarket. "
113 "Si omis, un vecteur de uns est utilisé par défaut. "
114 "Ne doit être fourni qu'avec une matrice de système. ")(
115 "null,N",
116 po::value<string>(),
117 "Les vecteurs de l'espace nul proche au format MatrixMarket. "
118 "Doit être une matrice dense de taille N*M, où N est le nombre de "
119 "variables inconnues et M est le nombre de vecteurs de l'espace nul. "
120 "Ne doit être fourni qu'avec une matrice de système. ")(
121 "binary,B",
122 po::bool_switch()->default_value(false),
123 "Lorsqu'il est spécifié, traite les fichiers d'entrée comme binaires au lieu de MatrixMarket. "
124 "Il est supposé que les fichiers ont été convertis au format binaire avec l'utilitaire mm2bin. ")(
125 "block-size,b",
126 po::value<int>()->default_value(1),
127 "La taille de bloc de la matrice du système. "
128 "Lorsqu'il est spécifié, la matrice du système est supposée avoir une structure par blocs. "
129 "C'est généralement le cas pour les problèmes en élasticité, en mécanique des structures, "
130 "pour les systèmes couplés d'EDP (tels que les équations de Navier-Stokes), etc. ")(
131 "size,n",
132 po::value<int>()->default_value(32),
133 "La taille du problème de Poisson à résoudre si aucune matrice de système n'est donnée. "
134 "Spécifié comme le nombre de nœuds de grille le long de chaque dimension d'un cube unitaire. "
135 "Le système résultant aura n*n*n inconnues. ")(
136 "single-level,1",
137 po::bool_switch()->default_value(false),
138 "Lorsqu'il est spécifié, la hiérarchie AMG n'est pas construite. "
139 "Au lieu de cela, le problème est résolu en utilisant un lisseur de niveau unique comme préconditionneur. ")(
140 "initial,x",
141 po::value<double>()->default_value(0),
142 "Valeur à utiliser comme approximation initiale. ")(
143 "output,o",
144 po::value<string>(),
145 "Fichier de sortie. Sera enregistré au format MatrixMarket. "
146 "Lorsqu'il est omis, la solution n'est pas sauvegardée. ");
147
149 po::store(po::parse_command_line(argc, argv, desc), vm);
150 po::notify(vm);
151
152 if (vm.count("help")) {
153 std::cout << desc << std::endl;
154 return 0;
155 }
156
158 if (vm.count("prm-file")) {
159 prm.read_json(vm["prm-file"].as<string>());
160 }
161
162 if (vm.count("prm")) {
163 for (const string& v : vm["prm"].as<vector<string>>()) {
164 prm.putKeyValue(v);
165 }
166 }
167
168 size_t rows;
169 vector<ptrdiff_t> ptr, col;
170 vector<std::complex<double>> val, rhs, null, x;
171
172 if (vm.count("matrix")) {
173 auto t = prof.scoped_tic("reading");
174
175 string Afile = vm["matrix"].as<string>();
176 bool binary = vm["binary"].as<bool>();
177
178 if (binary) {
179 io::read_crs(Afile, rows, ptr, col, val);
180 }
181 else {
182 size_t cols;
183 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
184 precondition(rows == cols, "Matrice de système non carrée");
185 }
186
187 if (vm.count("rhs")) {
188 string bfile = vm["rhs"].as<string>();
189
190 size_t n, m;
191 if (binary) {
192 io::read_dense(bfile, n, m, rhs);
193 }
194 else {
195 std::tie(n, m) = io::mm_reader(bfile)(rhs);
196 }
197
198 precondition(n == rows && m == 1, "Le vecteur RHS a une taille incorrecte");
199 }
200 else {
201 rhs.resize(rows, 1.0);
202 }
203
204 if (vm.count("null")) {
205 string nfile = vm["null"].as<string>();
206
207 size_t m, nv;
208
209 if (binary) {
210 io::read_dense(nfile, m, nv, null);
211 }
212 else {
213 std::tie(m, nv) = io::mm_reader(nfile)(null);
214 }
215
216 precondition(m == rows, "Les vecteurs de l'espace nul proche ont une taille incorrecte");
217
218 prm.put("precond.coarsening.nullspace.cols", nv);
219 prm.put("precond.coarsening.nullspace.rows", rows);
220 prm.put("precond.coarsening.nullspace.B", &null[0]);
221 }
222 }
223 else {
224 auto t = prof.scoped_tic("assembling");
225 rows = sample_problem(vm["size"].as<int>(), val, col, ptr, rhs);
226 }
227
228 x.resize(rows, vm["initial"].as<double>());
229
230 if (vm["single-level"].as<bool>())
231 prm.put("precond.class", "relaxation");
232
233 int block_size = vm["block-size"].as<int>();
235#define CALL_BLOCK_SOLVER(z, data, B) \
236 case B: { \
237 typedef StaticMatrix<std::complex<double>, B, B> value_type; \
238 typedef ::Arcane::Alina::BuiltinBackend<value_type> Backend; \
239 r = solve<::Arcane::Alina::PreconditionerRuntime<Backend>>( \
240 ::Arcane::Alina::adapter::block_matrix<value_type>( \
241 std::tie(rows, ptr, col, val)), \
242 prm, rhs, x); \
243 } break;
244
245 switch (block_size) {
246 case 1: {
248 r = solve<PreconditionerRuntime<Backend>>(
249 std::tie(rows, ptr, col, val), prm, rhs, x);
250 } break;
251 BOOST_PP_SEQ_FOR_EACH(CALL_BLOCK_SOLVER, ~, ARCCORE_ALINA_BLOCK_SIZES)
252 }
253
254#undef CALL_BLOCK_SOLVER
255
256 if (vm.count("output")) {
257 auto t = prof.scoped_tic("write");
258 Alina::IO::mm_write(vm["output"].as<string>(), &x[0], x.size());
259 }
260
261 std::cout << "Iterations: " << r.nbIteration() << std::endl
262 << "Error: " << r.residual() << std::endl
263 << prof << std::endl;
264}
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
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.
Definition Span.h:802
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --