Arcane  4.2.1.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 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(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 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(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 po::options_description desc("Options");
122
123 desc.add_options()("help,h", "show help")(
124 "binary,B",
125 po::bool_switch()->default_value(false),
126 "When specified, treat input files as binary instead of as MatrixMarket. "
127 "It is assumed the files were converted to binary format with mm2bin utility. ")(
128 "matrix,A",
129 po::value<string>()->required(),
130 "The system matrix in MatrixMarket format")(
131 "rhs,f",
132 po::value<string>(),
133 "The right-hand side in MatrixMarket format")(
134 "runtime-block-size,b",
135 po::value<int>(),
136 "The block size of the system matrix set at runtime")(
137 "static-block-size,c",
138 po::value<int>()->default_value(1),
139 "The block size of the system matrix set at compiletime")(
140 "params,P",
141 po::value<string>(),
142 "parameter file in json format")(
143 "prm,p",
144 po::value<vector<string>>()->multitoken(),
145 "Parameters specified as name=value pairs. "
146 "May be provided multiple times. Examples:\n"
147 " -p solver.tol=1e-3\n"
148 " -p precond.coarse_enough=300");
149
151 po::store(po::parse_command_line(argc, argv, desc), vm);
152
153 if (vm.count("help")) {
154 std::cout << desc << std::endl;
155 return 0;
156 }
157
158 po::notify(vm);
159
161 if (vm.count("params"))
162 prm.read_json(vm["params"].as<string>());
163
164 if (vm.count("prm")) {
165 for (const string& v : vm["prm"].as<vector<string>>()) {
166 prm.putKeyValue(v);
167 }
168 }
169
170 int cb = vm["static-block-size"].as<int>();
171
172 if (vm.count("runtime-block-size"))
173 prm.put("precond.block_size", vm["runtime-block-size"].as<int>());
174 else
175 prm.put("precond.block_size", cb);
176
177 size_t rows;
178 vector<ptrdiff_t> ptr, col;
179 vector<double> val, rhs;
180 std::vector<char> pm;
181
182 {
183 auto t = prof.scoped_tic("reading");
184
185 string Afile = vm["matrix"].as<string>();
186 bool binary = vm["binary"].as<bool>();
187
188 if (binary) {
189 io::read_crs(Afile, rows, ptr, col, val);
190 }
191 else {
192 size_t cols;
193 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
194 precondition(rows == cols, "Non-square system matrix");
195 }
196
197 if (vm.count("rhs")) {
198 string bfile = vm["rhs"].as<string>();
199
200 size_t n, m;
201
202 if (binary) {
203 io::read_dense(bfile, n, m, rhs);
204 }
205 else {
206 std::tie(n, m) = io::mm_reader(bfile)(rhs);
207 }
208
209 precondition(n == rows && m == 1, "The RHS vector has wrong size");
210 }
211 else {
212 rhs.resize(rows, 1.0);
213 }
214 }
215
216#define CALL_BLOCK_SOLVER(z, data, B) \
217 case B: \
218 solve_block_cpr<B>(std::tie(rows, ptr, col, val), rhs, prm); \
219 break;
220
221 switch (cb) {
222 case 1:
223 solve_cpr(std::tie(rows, ptr, col, val), rhs, prm);
224 break;
225
226 BOOST_PP_SEQ_FOR_EACH(CALL_BLOCK_SOLVER, ~, ARCCORE_ALINA_BLOCK_SIZES)
227
228 default:
229 precondition(false, "Unsupported block size");
230 break;
231 }
232
233 std::cout << prof << std::endl;
234}
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:112
Allows to use an AMG smoother as standalone preconditioner.
Definition Relaxation.h:144
Résultat d'une solution.
Definition AlinaUtils.h:53
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.