22#include <boost/program_options.hpp>
23#include <boost/preprocessor/seq/for_each.hpp>
25#if defined(SOLVER_BACKEND_CUDA)
26# include "arccore/alina/CudaBackend.h"
27# include "arccore/alina/relaxation_cusparse_ilu0.h"
30# ifndef SOLVER_BACKEND_BUILTIN
31# define SOLVER_BACKEND_BUILTIN
33#include "arccore/alina/BuiltinBackend.h"
37#include "arccore/alina/PreconditionedSolver.h"
38#include "arccore/alina/make_block_solver.h"
39#include "arccore/alina/StaticMatrix.h"
40#include "arccore/alina/Adapters.h"
41#include "arccore/alina/AMG.h"
42#include "arccore/alina/SolverRuntime.h"
43#include "arccore/alina/CoarseningRuntime.h"
44#include "arccore/alina/RelaxationRuntime.h"
45#include "arccore/alina/SchurPressureCorrectionPreconditioner.h"
46#include "arccore/alina/PreconditionerRuntime.h"
47#include "arccore/alina/Adapters.h"
49#include "arccore/alina/IO.h"
50#include "arccore/alina/Profiler.h"
53using namespace Arcane::Alina;
55#ifndef ARCCORE_ALINA_BLOCK_SIZES
56# define ARCCORE_ALINA_BLOCK_SIZES (3)(4)
59using Alina::precondition;
63template <
class USolver,
class PSolver,
class Matrix>
66 auto& prof = Alina::Profiler::globalProfiler();
69#if defined(SOLVER_BACKEND_CUDA)
70 cusparseCreate(&bprm.cusparse_handle);
76 cudaGetDeviceProperties(&prop, dev);
77 std::cout << prop.name << std::endl
82 auto t1 = prof.scoped_tic(
"schur_complement");
90 std::cout << solve << std::endl;
92 auto f = Backend<double>::copy_vector(rhs, bprm);
93 auto x = Backend<double>::create_vector(rhs.size(), bprm);
94 Alina::backend::clear(*x);
100 std::cout <<
"Iterations: " << r.nbIteration() << std::endl
101 <<
"Error: " << r.residual() << std::endl;
104#define ARCCORE_ALINA_BLOCK_PSOLVER(z, data, B) \
106 typedef Backend<StaticMatrix<double, B, B>> BBackend; \
107 typedef ::Arcane::Alina::make_block_solver< \
108 PreconditionerRuntime<BBackend>, SolverRuntime<BBackend>> PSolver; \
109 solve_schur<USolver, PSolver>(K, rhs, prm); \
113template <
class USolver,
class Matrix>
void
119 solve_schur<USolver, PSolver>(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<StaticMatrix<double, B, B>> BBackend; \
132 typedef make_block_solver< PreconditionerRuntime<BBackend>, SolverRuntime<BBackend>> USolver; \
133 solve_schur<USolver>(pb, K, rhs, prm); \
137template <
class Matrix>
143 solve_schur<USolver>(pb, K, rhs, prm);
145#if defined(SOLVER_BACKEND_BUILTIN)
146 BOOST_PP_SEQ_FOR_EACH(ARCCORE_ALINA_BLOCK_USOLVER, ~, ARCCORE_ALINA_BLOCK_SIZES)
149 precondition(
false,
"Unsupported block size for flow");
154int main(
int argc,
char* argv[])
156 auto& prof = Alina::Profiler::globalProfiler();
160 namespace po = boost::program_options;
161 namespace io = Alina::IO;
163 po::options_description desc(
"Options");
165 desc.add_options()(
"help,h",
"show help")(
167 po::bool_switch()->default_value(
false),
168 "When specified, treat input files as binary instead of as MatrixMarket. "
169 "It is assumed the files were converted to binary format with mm2bin utility. ")(
171 po::value<string>()->required(),
172 "The system matrix in MatrixMarket format")(
175 "The right-hand side in MatrixMarket format")(
178 "The pressure mask in MatrixMarket format. Or, if the parameter has "
179 "the form '%n:m', then each (n+i*m)-th variable is treated as pressure.")(
181 po::value<int>()->default_value(1),
182 "Block-size of the 'flow'/'non-pressure' part of the matrix")(
184 po::value<int>()->default_value(1),
185 "Block-size of the 'pressure' part of the matrix")(
188 "parameter file in json format")(
190 po::value<vector<string>>()->multitoken(),
191 "Parameters specified as name=value pairs. "
192 "May be provided multiple times. Examples:\n"
193 " -p solver.tol=1e-3\n"
194 " -p precond.coarse_enough=300");
196 po::variables_map vm;
197 po::store(po::parse_command_line(argc, argv, desc), vm);
199 if (vm.count(
"help")) {
200 std::cout << desc << std::endl;
207 if (vm.count(
"params"))
208 prm.read_json(vm[
"params"].as<string>());
210 if (vm.count(
"prm")) {
219 std::vector<char> pm;
222 auto t = prof.scoped_tic(
"reading");
224 string Afile = vm[
"matrix"].as<
string>();
225 bool binary = vm[
"binary"].as<
bool>();
228 io::read_crs(Afile, rows, ptr, col, val);
232 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
233 precondition(rows == cols,
"Non-square system matrix");
236 if (vm.count(
"rhs")) {
237 string bfile = vm[
"rhs"].as<
string>();
242 io::read_dense(bfile, n, m, rhs);
245 std::tie(n, m) = io::mm_reader(bfile)(rhs);
248 precondition(n == rows && m == 1,
"The RHS vector has wrong size");
251 rhs.resize(rows, 1.0);
254 if (vm.count(
"pmask")) {
255 std::string pmask = vm[
"pmask"].as<
string>();
256 prm.put(
"precond.pmask_size", rows);
262 prm.put(
"precond.pmask_pattern", pmask);
267 precondition(n == rows && m == 1,
"Mask file has wrong size");
268 prm.put(
"precond.pmask",
static_cast<void*
>(&pm[0]));
274 solve_schur(vm[
"ub"].as<int>(), vm[
"pb"].as<int>(),
275 std::tie(rows, ptr, col, val), rhs, prm);
277 std::cout << prof << std::endl;
Convenience class that bundles together a preconditioner and an iterative solver.
Matrix class, to be used by user.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Alina::detail::empty_params params
Runtime-configurable wrappers around iterative solvers.