Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
TestSolverCommon.h
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 * This file is based on the work on AMGCL library (version march 2026)
11 * which can be found at 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#ifndef TESTS_TEST_SOLVER_HPP
20#define TESTS_TEST_SOLVER_HPP
21
22#include "arccore/alina/AMG.h"
23#include "arccore/alina/SolverRuntime.h"
24#include "arccore/alina/CoarseningRuntime.h"
25#include "arccore/alina/RelaxationRuntime.h"
26#include "arccore/alina/Relaxation.h"
27#include "arccore/alina/PreconditionedSolver.h"
28#include "arccore/alina/Adapters.h"
29#include "arccore/alina/Profiler.h"
30
31#include <boost/assign/std/vector.hpp>
32using namespace boost::assign;
33
34#include "SampleProblemCommon.h"
35
36using namespace Arcane;
37
38namespace
39{
41}
42
43//---------------------------------------------------------------------------
44
45template <class Backend, class Matrix>
46void test_solver(const Matrix& A,
47 std::shared_ptr<typename Backend::vector> const& f,
48 std::shared_ptr<typename Backend::vector>& x,
49 Alina::eSolverType solver,
50 Alina::eRelaxationType relaxation,
51 Alina::eCoarserningType coarsening,
52 typename Backend::params const& bprm,
53 bool test_null_space = false)
54{
56 prm.put("precond.coarse_enough", 500);
57 prm.put("precond.coarsening.type", coarsening);
58 prm.put("precond.relax.type", relaxation);
59 prm.put("solver.type", solver);
60
61 typedef typename Backend::value_type value_type;
62 std::vector<double> null;
63
64 if (test_null_space && Alina::math::static_rows<value_type>::value == 1) {
65 Int64 n = Alina::backend::nbRow(*A);
66 null.resize(n, 1.0);
67
68 prm.put("precond.coarsening.nullspace.cols", 1);
69 prm.put("precond.coarsening.nullspace.rows", n);
70 prm.put("precond.coarsening.nullspace.B", &null[0]);
71 }
72
75 solve(A, prm, bprm);
76
77 std::cout << solve.precond() << std::endl;
78
79 Alina::backend::clear(*x);
80
81 Alina::SolverResult r = solve(*f, *x);
82
83 std::cout << "Iterations: " << r.nbIteration() << std::endl
84 << "Error: " << r.residual() << std::endl
85 << std::endl;
86
87 ASSERT_NEAR(r.residual(), 0.0, 1e-4);
88}
89
90//---------------------------------------------------------------------------
91template <class Backend, class Matrix>
92void test_rap(const Matrix& A,
93 std::shared_ptr<typename Backend::vector> const& f,
94 std::shared_ptr<typename Backend::vector>& x,
95 Alina::eSolverType solver,
96 Alina::eRelaxationType relaxation,
97 typename Backend::params const& bprm)
98{
100 prm.put("precond.type", relaxation);
101 prm.put("solver.type", solver);
102
105 solve(A, prm, bprm);
106
107 std::cout << "Using " << relaxation << " as preconditioner" << std::endl;
108
109 Alina::backend::clear(*x);
110
111 Alina::SolverResult r = solve(*f, *x);
112
113 std::cout << "Iterations: " << r.nbIteration() << std::endl
114 << "Error: " << r.residual() << std::endl;
115
116 ASSERT_NEAR(r.residual(), 0.0, 1e-4);
117}
118
119template <class Backend, class value_type, class col_type, class ptr_type, class rhs_type>
120void test_problem(size_t n,
121 std::vector<ptr_type> ptr,
122 std::vector<col_type> col,
123 std::vector<value_type> val,
124 std::vector<rhs_type> rhs,
125 typename Backend::params const& bprm)
126{
127 Alina::eCoarserningType coarsening[] = {
128 Alina::eCoarserningType::aggregation,
129 Alina::eCoarserningType::smoothed_aggregation,
130 Alina::eCoarserningType::smoothed_aggr_emin,
131 Alina::eCoarserningType::ruge_stuben
132 };
133
134 Alina::eRelaxationType relaxation[] = {
135 Alina::eRelaxationType::spai0,
136 Alina::eRelaxationType::spai1,
137 Alina::eRelaxationType::damped_jacobi,
138 Alina::eRelaxationType::gauss_seidel,
139 Alina::eRelaxationType::ilu0,
140 Alina::eRelaxationType::iluk,
141 Alina::eRelaxationType::ilup,
142 Alina::eRelaxationType::ilut,
143 Alina::eRelaxationType::chebyshev
144 };
145
146 Alina::eSolverType solver[] = {
147 Alina::eSolverType::cg,
148 Alina::eSolverType::bicgstab,
149 Alina::eSolverType::bicgstabl,
150 Alina::eSolverType::gmres,
151 Alina::eSolverType::lgmres,
152 Alina::eSolverType::fgmres,
153 Alina::eSolverType::idrs
154 };
155
156 typename Backend::params prm;
157
158 auto y = Backend::copy_vector(rhs, prm);
159 auto x = Backend::create_vector(n, prm);
160
161 // Test solvers
162 for (Alina::eSolverType s : solver) {
163 std::cout << "Solver: " << s << std::endl;
164 try {
165 test_solver<Backend>(Alina::adapter::zero_copy_direct(n, ptr.data(), col.data(), val.data()),
166 y, x, s, relaxation[0], coarsening[0], bprm);
167 }
168 catch (const std::logic_error&) {
169 }
170 }
171
172 // Test smoothers
173 for (Alina::eRelaxationType r : relaxation) {
174 std::cout << "Relaxation: " << r << std::endl;
175 try {
176 test_solver<Backend>(Alina::adapter::zero_copy_direct(n, ptr.data(), col.data(), val.data()),
177 y, x, solver[0], r, coarsening[0], bprm);
178 }
179 catch (const std::logic_error&) {
180 }
181
182 try {
183 std::cout << "Relaxation as preconditioner: " << r << std::endl;
184
185 test_rap<Backend>(Alina::adapter::zero_copy_direct(n, ptr.data(), col.data(), val.data()),
186 y, x, solver[0], r, bprm);
187 }
188 catch (const std::logic_error&) {
189 }
190 }
191
192 // Test coarsening
193 for (Alina::eCoarserningType c : coarsening) {
194 std::cout << "Coarsening: " << c << std::endl;
195
196 try {
197 test_solver<Backend>(Alina::adapter::zero_copy_direct(n, ptr.data(), col.data(), val.data()),
198 y, x, solver[0], relaxation[0], c, bprm);
199 }
200 catch (const std::logic_error&) {
201 }
202
203 switch (c) {
204 case Alina::eCoarserningType::aggregation:
205 case Alina::eCoarserningType::smoothed_aggregation:
206 case Alina::eCoarserningType::smoothed_aggr_emin:
207 test_solver<Backend>(Alina::adapter::zero_copy_direct(n, ptr.data(), col.data(), val.data()),
208 y, x, solver[0], relaxation[0], c, bprm, /*test_null_space*/ true);
209 break;
210 default:
211 break;
212 }
213 }
214}
215
216template <class Backend>
217void test_backend(typename Backend::params const& bprm = typename Backend::params())
218{
219 typedef typename Backend::value_type value_type;
220 typedef typename Backend::col_type col_type;
221 typedef typename Backend::ptr_type ptr_type;
222 typedef typename Alina::math::rhs_of<value_type>::type rhs_type;
223
224 // Poisson 3D
225 {
226 std::vector<ptr_type> ptr;
227 std::vector<col_type> col;
228 std::vector<value_type> val;
229 std::vector<rhs_type> rhs;
230
231 size_t n = sample_problem(24, val, col, ptr, rhs);
232
233 test_problem<Backend>(n, ptr, col, val, rhs, bprm);
234 }
235
236 // Trivial problem
237 {
238 std::vector<ptr_type> ptr;
239 std::vector<col_type> col;
240 std::vector<value_type> val;
241 std::vector<rhs_type> rhs;
242
243 val += Alina::math::identity<value_type>(), Alina::math::identity<value_type>();
244 col += 0, 1;
245 ptr += 0, 1, 2;
246 rhs += Alina::math::constant<rhs_type>(1.0), Alina::math::zero<rhs_type>();
247
248 size_t n = rhs.size();
249
250 test_problem<Backend>(n, ptr, col, val, rhs, bprm);
251 }
252}
253
254/*---------------------------------------------------------------------------*/
255/*---------------------------------------------------------------------------*/
256
257#if defined(ARCCORE_HAS_ACCELERATOR_THREAD)
258#define ARCCORE_ALINA_TEST_DO_TEST_TASK(name1, name2, func) \
259 TEST(name1, name2##_task4) \
260 { \
261 func(false, 4); \
262 }
263#else
264#define ARCCORE_ALINA_TEST_DO_TEST_TASK(name1, name2, func)
265#endif
266
267#define ARCCORE_ALINA_TEST_DO_TEST_SEQUENTIAL(name1, name2, func) \
268 TEST(name1, name2) \
269 { \
270 func(false, 0); \
271 }
272
274#define ARCCORE_ALINA_TEST_DO_TEST_ACCELERATOR(name1, name2, func) \
275 ARCCORE_ALINA_TEST_DO_TEST_TASK(name1, name2, func); \
276 ARCCORE_ALINA_TEST_DO_TEST_SEQUENTIAL(name1, name2, func);
277
278/*---------------------------------------------------------------------------*/
279/*---------------------------------------------------------------------------*/
280
281#endif
Convenience class that bundles together a preconditioner and an iterative solver.
Profiler class.
Definition Profiler.h:50
Result of a solving.
Definition AlinaUtils.h:52
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.
Number of rows for statically sized matrix types.