Arcane  4.2.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
CPR.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/preprocessor/seq/for_each.hpp>
23
24#include "arccore/alina/BuiltinBackend.h"
25#include "arccore/alina/StaticMatrix.h"
26#include "arccore/alina/PreconditionedSolver.h"
27#include "arccore/alina/AMG.h"
28#include "arccore/alina/SolverRuntime.h"
29#include "arccore/alina/CoarseningRuntime.h"
30#include "arccore/alina/RelaxationRuntime.h"
31#include "arccore/alina/Relaxation.h"
32#include "arccore/alina/CPRPreconditioner.h"
33#include "arccore/alina/Adapters.h"
34#include "arccore/alina/IO.h"
35#include "arccore/alina/Profiler.h"
36
37#include "arccore/common/internal/ProgramOptions.h"
38
39using namespace Arcane;
40
41using Alina::precondition;
42
43//---------------------------------------------------------------------------
44template <class Matrix>
45void solve_cpr(const Alina::AlinaContext& context, const Matrix& K, const std::vector<double>& rhs, Alina::PropertyTree& prm)
46{
47 auto& prof = Alina::Profiler::globalProfiler();
48
49 auto t1 = prof.scoped_tic("CPR");
50
51 using Backend = Alina::BuiltinBackend<double>;
54
55 prof.tic("setup");
58 solve(context, K, prm);
59 prof.toc("setup");
60
61 std::cout << solve.precond() << std::endl;
62
63 std::vector<double> x(rhs.size(), 0.0);
64
65 prof.tic("setup");
66 Alina::SolverResult r = solve(rhs, x);
67 prof.toc("setup");
68
69 std::cout << "Iterations: " << r.nbIteration() << std::endl
70 << "Error: " << r.residual() << std::endl;
71}
72
73//---------------------------------------------------------------------------
74template <int B, class Matrix>
75void solve_block_cpr(const Alina::AlinaContext& context, const Matrix& K, const std::vector<double>& rhs, Alina::PropertyTree& prm)
76{
77 auto& prof = Alina::Profiler::globalProfiler();
78 auto t1 = prof.scoped_tic("CPR");
79
80 typedef Alina::StaticMatrix<double, B, B> val_type;
81 typedef Alina::StaticMatrix<double, B, 1> rhs_type;
82 typedef Alina::BuiltinBackend<val_type> SBackend;
83 typedef Alina::BuiltinBackend<double> PBackend;
84
87
88 prof.tic("setup");
92 solve(context, Alina::adapter::block_matrix<val_type>(K), prm);
93 prof.toc("setup");
94
95 std::cout << solve.precond() << std::endl;
96
97 std::vector<rhs_type> x(rhs.size(), Alina::math::zero<rhs_type>());
98
99 auto rhs_ptr = reinterpret_cast<const rhs_type*>(rhs.data());
100 size_t n = Alina::backend::nbRow(K) / B;
101
102 prof.tic("solve");
103 Alina::SolverResult r = solve(SmallSpan<const rhs_type>(rhs_ptr, n), x);
104 prof.toc("solve");
105
106 std::cout << "Iterations: " << r.nbIteration() << std::endl
107 << "Error: " << r.residual() << std::endl;
108}
109
110//---------------------------------------------------------------------------
111int main(int argc, char* argv[])
112{
113 auto& prof = Alina::Profiler::globalProfiler();
114 using Alina::precondition;
115 using std::string;
116 using std::vector;
117
118 namespace po = Arcane::ProgramOptions;
119 namespace io = Alina::IO;
120
121 Alina::AlinaContext context;
122
123 po::options_description desc("Options");
124
125 desc.add_options()("help,h", "show help")(
126 "binary,B",
127 po::bool_switch()->default_value(false),
128 "When specified, treat input files as binary instead of as MatrixMarket. "
129 "It is assumed the files were converted to binary format with mm2bin utility. ")(
130 "matrix,A",
131 po::value<string>()->required(),
132 "The system matrix in MatrixMarket format")(
133 "rhs,f",
134 po::value<string>(),
135 "The right-hand side in MatrixMarket format")(
136 "runtime-block-size,b",
137 po::value<int>(),
138 "The block size of the system matrix set at runtime")(
139 "static-block-size,c",
140 po::value<int>()->default_value(1),
141 "The block size of the system matrix set at compiletime")(
142 "params,P",
143 po::value<string>(),
144 "parameter file in json format")(
145 "prm,p",
146 po::value<vector<string>>()->multitoken(),
147 "Parameters specified as name=value pairs. "
148 "May be provided multiple times. Examples:\n"
149 " -p solver.tol=1e-3\n"
150 " -p precond.coarse_enough=300");
151
153 po::store(po::parse_command_line(argc, argv, desc), vm);
154
155 if (vm.count("help")) {
156 std::cout << desc << std::endl;
157 return 0;
158 }
159
160 po::notify(vm);
161
163 if (vm.count("params"))
164 prm.read_json(vm["params"].as<string>());
165
166 if (vm.count("prm")) {
167 for (const string& v : vm["prm"].as<vector<string>>()) {
168 prm.putKeyValue(v);
169 }
170 }
171
172 int cb = vm["static-block-size"].as<int>();
173
174 if (vm.count("runtime-block-size"))
175 prm.put("precond.block_size", vm["runtime-block-size"].as<int>());
176 else
177 prm.put("precond.block_size", cb);
178
179 size_t rows;
180 vector<ptrdiff_t> ptr, col;
181 vector<double> val, rhs;
182 std::vector<char> pm;
183
184 {
185 auto t = prof.scoped_tic("reading");
186
187 string Afile = vm["matrix"].as<string>();
188 bool binary = vm["binary"].as<bool>();
189
190 if (binary) {
191 io::read_crs(Afile, rows, ptr, col, val);
192 }
193 else {
194 size_t cols;
195 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
196 precondition(rows == cols, "Non-square system matrix");
197 }
198
199 if (vm.count("rhs")) {
200 string bfile = vm["rhs"].as<string>();
201
202 size_t n, m;
203
204 if (binary) {
205 io::read_dense(bfile, n, m, rhs);
206 }
207 else {
208 std::tie(n, m) = io::mm_reader(bfile)(rhs);
209 }
210
211 precondition(n == rows && m == 1, "The RHS vector has wrong size");
212 }
213 else {
214 rhs.resize(rows, 1.0);
215 }
216 }
217
218#define CALL_BLOCK_SOLVER(z, data, B) \
219 case B: \
220 solve_block_cpr<B>(context, std::tie(rows, ptr, col, val), rhs, prm); \
221 break;
222
223 switch (cb) {
224 case 1:
225 solve_cpr(context, std::tie(rows, ptr, col, val), rhs, prm);
226 break;
227
228 BOOST_PP_SEQ_FOR_EACH(CALL_BLOCK_SOLVER, ~, ARCCORE_ALINA_BLOCK_SIZES)
229
230 default:
231 precondition(false, "Unsupported block size");
232 break;
233 }
234
235 std::cout << prof << std::endl;
236}
Algebraic multigrid method.
Definition AMG.h:71
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:113
Allows to use an AMG smoother as standalone preconditioner.
Definition Relaxation.h:144
Résultat d'une solution.
Definition AlinaUtils.h:56
Two stage preconditioner of the Constrained Pressure Residual type.
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 --
Runtime-configurable wrappers around iterative solvers.