Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
RichardsonSolver.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/* solver_gmres.h (C) 2000-2026 */
9/* */
10/* Richardson iteration. . */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_RICHARDSONSOLVER_H
13#define ARCCORE_ALINA_RICHARDSONSOLVER_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16/*
17 * This file is based on the work on AMGCL library (version march 2026)
18 * which can be found at https://github.com/ddemidov/amgcl.
19 *
20 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
21 * SPDX-License-Identifier: MIT
22 */
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26#include "arccore/alina/SolverUtils.h"
27#include "arccore/alina/SolverBase.h"
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32namespace Arcane::Alina
33{
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
40struct RichardsonSolverParams
41{
42 using params = RichardsonSolverParams;
43
45 double damping = 1.0;
46
49
51 double tol = 1.0e-8;
52
54 double abstol = std::numeric_limits<double>::min();
55
57 //** Useful for searching for the null-space vectors of the system */
58 bool ns_search = false;
59
61 bool verbose = false;
62
63 RichardsonSolverParams() = default;
64
65 RichardsonSolverParams(const PropertyTree& p)
66 : ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p, damping)
67 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p, maxiter)
68 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p, tol)
69 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p, abstol)
70 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p, ns_search)
71 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p, verbose)
72 {
73 p.check_params({ "damping", "maxiter", "tol", "abstol", "ns_search", "verbose" });
74 }
75
76 void get(PropertyTree& p, const std::string& path) const
77 {
78 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path, damping);
79 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path, maxiter);
80 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path, tol);
81 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path, abstol);
82 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path, ns_search);
83 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path, verbose);
84 }
85};
86
87/*---------------------------------------------------------------------------*/
88/*---------------------------------------------------------------------------*/
92template <class Backend, class InnerProduct = detail::default_inner_product>
94: public SolverBase
95{
96 public:
97
98 typedef Backend backend_type;
99
100 typedef typename Backend::vector vector;
101 typedef typename Backend::value_type value_type;
102 typedef typename Backend::params backend_params;
103
104 typedef typename math::scalar_of<value_type>::type scalar_type;
105
106 typedef typename math::inner_product_impl<
107 typename math::rhs_of<value_type>::type>::return_type coef_type;
108
109 using params = RichardsonSolverParams;
110
111 public:
112
115 const params& prm = params(),
116 const backend_params& backend_prm = backend_params(),
117 const InnerProduct& inner_product = InnerProduct())
118 : prm(prm)
119 , n(n)
120 , r(Backend::create_vector(n, backend_prm))
121 , s(Backend::create_vector(n, backend_prm))
122 , inner_product(inner_product)
123 {}
124
140 template <class Matrix, class Precond, class Vec1, class Vec2>
141 SolverResult operator()(const Matrix& A, const Precond& P, const Vec1& rhs, Vec2&& x) const
142 {
143 static const coef_type one = math::identity<coef_type>();
144
145 ScopedStreamModifier ss(std::cout);
146
147 scalar_type norm_rhs = norm(rhs);
148 if (norm_rhs < Alina::detail::eps<scalar_type>(1)) {
149 if (prm.ns_search) {
150 norm_rhs = math::identity<scalar_type>();
151 }
152 else {
153 backend::clear(x);
154 return SolverResult(0, norm_rhs);
155 }
156 }
157
158 scalar_type eps = std::max(prm.tol * norm_rhs, prm.abstol);
159
160 backend::residual(rhs, A, x, *r);
161 scalar_type res_norm = norm(*r);
162
163 size_t iter = 0;
164 for (; iter < prm.maxiter && math::norm(res_norm) > eps; ++iter) {
165 P.apply(*r, *s);
166 backend::axpby(prm.damping, *s, one, x);
167 backend::residual(rhs, A, x, *r);
168 res_norm = norm(*r);
169
170 if (prm.verbose && iter % 5 == 0)
171 std::cout << iter << "\t" << std::scientific << res_norm / norm_rhs << std::endl;
172 }
173
174 return SolverResult(iter, res_norm / norm_rhs);
175 }
176
187 template <class Precond, class Vec1, class Vec2>
188 SolverResult operator()(const Precond& P, const Vec1& rhs, Vec2&& x) const
189 {
190 return (*this)(P.system_matrix(), P, rhs, x);
191 }
192
193 size_t bytes() const
194 {
195 return backend::bytes(*r) +
196 backend::bytes(*s);
197 }
198
199 friend std::ostream& operator<<(std::ostream& os, const RichardsonSolver& s)
200 {
201 return os << "Type: Richardson"
202 << "\nUnknowns: " << s.n
203 << "\nMemory footprint: " << human_readable_memory(s.bytes())
204 << std::endl;
205 }
206
207 public:
208
209 params prm;
210
211 private:
212
213 size_t n;
214
215 std::shared_ptr<vector> r;
216 std::shared_ptr<vector> s;
217
218 InnerProduct inner_product;
219
220 template <class Vec>
221 scalar_type norm(const Vec& x) const
222 {
223 return sqrt(math::norm(inner_product(x, x)));
224 }
225};
226
227/*---------------------------------------------------------------------------*/
228/*---------------------------------------------------------------------------*/
229
230} // namespace Arcane::Alina
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
234
235#endif
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
SolverResult operator()(const Precond &P, const Vec1 &rhs, Vec2 &&x) const
Computes the solution for the given right-hand side.
size_t bytes() const
Memory used in bytes.
RichardsonSolver(size_t n, const params &prm=params(), const backend_params &backend_prm=backend_params(), const InnerProduct &inner_product=InnerProduct())
Preallocates necessary data structures for the system of size n.
SolverResult operator()(const Matrix &A, const Precond &P, const Vec1 &rhs, Vec2 &&x) const
Computes the solution for the given system matrix.
Save ostream flags in constructor, restore in destructor.
Base class for solvers.
Definition SolverBase.h:31
Result of a solving.
Definition AlinaUtils.h:52
Matrix class, to be used by user.
std::int32_t Int32
Type entier signé sur 32 bits.
Alina::detail::empty_params params
Parameters for Richardson solver.
double abstol
Target absolute residual error.
Int32 maxiter
Maximum number of iterations.
bool ns_search
Ignore the trivial solution x=0 when rhs is zero.
double tol
Target relative residual error.
bool verbose
Verbose output (show iterations and error)
Default implementation for inner product.