20#pragma GCC diagnostic ignored "-Wdeprecated-copy"
21#pragma GCC diagnostic ignored "-Wint-in-bool-context"
26#include <boost/preprocessor/seq/for_each.hpp>
28#include "arccore/alina/PreconditionedSolver.h"
29#include "arccore/alina/make_block_solver.h"
30#include "arccore/alina/StaticMatrix.h"
31#include "arccore/alina/Adapters.h"
32#include "arccore/alina/AMG.h"
33#include "arccore/alina/SolverRuntime.h"
34#include "arccore/alina/CoarseningRuntime.h"
35#include "arccore/alina/RelaxationRuntime.h"
36#include "arccore/alina/SchurPressureCorrectionPreconditioner.h"
37#include "arccore/alina/PreconditionerRuntime.h"
38#include "arccore/alina/Adapters.h"
40#if defined(SOLVER_BACKEND_VEXCL)
42# ifndef SOLVER_BACKEND_BUILTIN
43# define SOLVER_BACKEND_BUILTIN
45#include "arccore/alina/BuiltinBackend.h"
46#ifdef BLOCK_TYPE_EIGEN
47#include "arccore/alina/ValueTypeEigen.h"
48template <
class T,
int N,
int M>
49using BlockMatrix = Eigen::Matrix<T, N, M>;
51 template <
class T,
int N,
int M>
57#include "arccore/alina/IO.h"
58#include "arccore/alina/Profiler.h"
59#include "arccore/common/internal/ProgramOptions.h"
61#ifndef ARCCORE_ALINA_BLOCK_SIZES
62# define ARCCORE_ALINA_BLOCK_SIZES (3)(4)
67using Alina::precondition;
70template <
class USolver,
class PSolver,
class Matrix>
73 auto& prof = Alina::Profiler::globalProfiler();
74 typedef Backend<double> SBackend;
75 SBackend::params bprm;
77 auto t1 = prof.scoped_tic(
"schur_complement");
82 solve(context, K, prm, bprm);
85 std::cout << solve << std::endl;
88 auto f = SBackend::copy_vector(rhs, bprm);
89 auto x = SBackend::create_vector(rhs.size(), bprm);
90 Alina::backend::clear(*x);
96 std::cout <<
"Iterations: " << r.nbIteration() << std::endl
97 <<
"Error: " << r.residual() << std::endl;
100#define ARCCORE_ALINA_BLOCK_PSOLVER(z, data, B) \
102 typedef Backend<BlockMatrix<float, B, B>> BBackend; \
103 typedef ::Arcane::Alina::make_block_solver< \
104 ::Arcane::Alina::PreconditionerRuntime<BBackend>, \
105 ::Arcane::Alina::SolverRuntime<BBackend>> \
107 solve_schur<USolver, PSolver>(context, K, rhs, prm); \
111template <
class USolver,
class Matrix>
void
119 solve_schur<USolver, PSolver>(context, K, rhs, prm);
121#if defined(SOLVER_BACKEND_BUILTIN)
122 BOOST_PP_SEQ_FOR_EACH(ARCCORE_ALINA_BLOCK_PSOLVER, ~, ARCCORE_ALINA_BLOCK_SIZES)
125 precondition(
false,
"Unsupported block size for pressure");
129#define ARCCORE_ALINA_BLOCK_USOLVER(z, data, B) \
131 typedef Backend<BlockMatrix<float, B, B>> BBackend; \
132 typedef ::Arcane::Alina::make_block_solver< \
133 ::Arcane::Alina::PreconditionerRuntime<BBackend>, \
134 ::Arcane::Alina::SolverRuntime<BBackend>> \
136 solve_schur<USolver>(context, pb, K, rhs, prm); \
140template <
class Matrix>
void
142 int ub,
int pb,
const Matrix& K,
143 const std::vector<double>& rhs,
150 solve_schur<USolver>(context, pb, K, rhs, prm);
152#if defined(SOLVER_BACKEND_BUILTIN) || defined(SOLVER_BACKEND_VEXCL)
153 BOOST_PP_SEQ_FOR_EACH(ARCCORE_ALINA_BLOCK_USOLVER, ~, ARCCORE_ALINA_BLOCK_SIZES)
156 precondition(
false,
"Unsupported block size for flow");
162int main(
int argc,
char* argv[])
164 auto& prof = Alina::Profiler::globalProfiler();
169 namespace po = Arcane::ProgramOptions;
170 namespace io = Alina::IO;
174 desc.add_options()(
"help,h",
"show help");
175 desc.add_options()(
"binary,B",
176 po::bool_switch()->default_value(
false),
177 "When specified, treat input files as binary instead of as MatrixMarket. "
178 "It is assumed the files were converted to binary format with mm2bin utility. ");
179 desc.add_options()(
"scale,s", po::bool_switch()->default_value(
false),
180 "Scale the matrix so that the diagonal is unit. ");
181 desc.add_options()(
"matrix,A", po::value<string>()->required(),
182 "The system matrix in MatrixMarket format");
183 desc.add_options()(
"rhs,f", po::value<string>(),
184 "The right-hand side in MatrixMarket format");
185 desc.add_options()(
"pmask,m", po::value<string>(),
186 "The pressure mask in MatrixMarket format. Or, if the parameter has "
187 "the form '%n:m', then each (n+i*m)-th variable is treated as pressure.");
188 desc.add_options()(
"ub", po::value<int>()->default_value(1),
189 "Block-size of the 'flow'/'non-pressure' part of the matrix");
190 desc.add_options()(
"pb",
191 po::value<int>()->default_value(1),
192 "Block-size of the 'pressure' part of the matrix");
193 desc.add_options()(
"params,P", po::value<string>(),
194 "parameter file in json format");
195 desc.add_options()(
"prm,p",
196 po::value<vector<string>>()->multitoken(),
197 "Parameters specified as name=value pairs. "
198 "May be provided multiple times. Examples:\n"
199 " -p solver.tol=1e-3\n"
200 " -p precond.coarse_enough=300");
203 po::store(po::parse_command_line(argc, argv, desc), vm);
205 if (vm.count(
"help")) {
206 std::cout << desc << std::endl;
213 if (vm.count(
"params"))
214 prm.read_json(vm[
"params"].as<string>());
216 if (vm.count(
"prm")) {
217 for (
const string& v : vm[
"prm"].as<vector<string>>()) {
223 vector<ptrdiff_t> ptr, col;
224 vector<double> val, rhs;
225 std::vector<char> pm;
228 auto t = prof.scoped_tic(
"reading");
230 string Afile = vm[
"matrix"].as<
string>();
231 bool binary = vm[
"binary"].as<
bool>();
234 io::read_crs(Afile, rows, ptr, col, val);
238 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
239 precondition(rows == cols,
"Non-square system matrix");
242 if (vm.count(
"rhs")) {
243 string bfile = vm[
"rhs"].as<
string>();
248 io::read_dense(bfile, n, m, rhs);
251 std::tie(n, m) = io::mm_reader(bfile)(rhs);
254 precondition(n == rows && m == 1,
"The RHS vector has wrong size");
257 rhs.resize(rows, 1.0);
260 if (vm.count(
"pmask")) {
261 std::string pmask = vm[
"pmask"].as<
string>();
262 prm.put(
"precond.pmask_size", rows);
268 prm.put(
"precond.pmask_pattern", pmask);
273 precondition(n == rows && m == 1,
"Mask file has wrong size");
274 prm.put(
"precond.pmask",
static_cast<void*
>(&pm[0]));
280 if (vm[
"scale"].as<bool>()) {
281 std::vector<double> dia(rows, 1.0);
283 for (ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(rows); ++i) {
285 for (ptrdiff_t j = ptr[i], e = ptr[i + 1]; j < e; ++j) {
287 d = 1 /
sqrt(val[j]);
294 for (ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(rows); ++i) {
296 for (ptrdiff_t j = ptr[i], e = ptr[i + 1]; j < e; ++j) {
297 val[j] *= dia[i] * dia[col[j]];
302 solve_schur(context, vm[
"ub"].as<int>(), vm[
"pb"].as<int>(),
303 std::tie(rows, ptr, col, val), rhs, prm);
305 std::cout << prof << std::endl;
Convenience class that bundles together a preconditioner and an iterative solver.
Class to store parameters as a hierarchical key/value tree.
Matrix class, to be used by user.
Describes a set of command-line options.
Stores parsed option values.
apfloat sqrt(apfloat v)
Square root of v.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Sparse matrix stored in CSR (Compressed Sparse Row) format.
Runtime-configurable wrappers around iterative solvers.