deal.II version GIT relicensing-6842-g793a97d2aa 2026-10-02 14:00:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
solver_richardson.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 1999 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_solver_richardson_h
14#define dealii_solver_richardson_h
15
16
17#include <deal.II/base/config.h>
18
22
23#include <deal.II/lac/solver.h>
25
26#include <limits>
27
29
61template <typename VectorType = Vector<double>>
63class SolverRichardson : public SolverBase<VectorType>
64{
65public:
70 {
74 explicit AdditionalData(const double omega = 1,
75 const bool use_preconditioned_residual = false);
76
80 double omega;
81
86 };
87
94
101
105 virtual ~SolverRichardson() override = default;
106
110 template <typename MatrixType, typename PreconditionerType>
114 void solve(const MatrixType &A,
115 VectorType &x,
116 const VectorType &b,
117 const PreconditionerType &preconditioner);
118
122 template <typename MatrixType, typename PreconditionerType>
124 (concepts::is_transpose_linear_operator_on<MatrixType, VectorType> &&
125 concepts::is_transpose_linear_operator_on<PreconditionerType, VectorType>))
126 void Tsolve(const MatrixType &A,
127 VectorType &x,
128 const VectorType &b,
129 const PreconditionerType &preconditioner);
130
134 void
135 set_omega(const double om = 1.);
136
142 virtual void
143 print_vectors(const unsigned int step,
144 const VectorType &x,
145 const VectorType &r,
146 const VectorType &d) const;
147
148protected:
155 virtual typename VectorType::value_type
156 criterion(const VectorType &r, const VectorType &d) const;
157
161 AdditionalData additional_data;
162};
163
165/*----------------- Implementation of the Richardson Method ------------------*/
166
167#ifndef DOXYGEN
168
169template <typename VectorType>
172 const double omega,
173 const bool use_preconditioned_residual)
174 : omega(omega)
175 , use_preconditioned_residual(use_preconditioned_residual)
176{}
177
178
179template <typename VectorType>
183 const AdditionalData &data)
184 : SolverBase<VectorType>(cn, mem)
185 , additional_data(data)
186{}
187
188
189
190template <typename VectorType>
193 const AdditionalData &data)
195 , additional_data(data)
196{}
197
198
199
200template <typename VectorType>
202template <typename MatrixType, typename PreconditionerType>
207 const MatrixType &A,
208 VectorType &x,
209 const VectorType &b,
210 const PreconditionerType &preconditioner)
211{
213
214 double last_criterion = std::numeric_limits<double>::lowest();
215
216 unsigned int iter = 0;
217
218 // Memory allocation.
219 // 'Vr' holds the residual, 'Vd' the preconditioned residual
220 typename VectorMemory<VectorType>::Pointer Vr(this->memory);
221 typename VectorMemory<VectorType>::Pointer Vd(this->memory);
222
223 VectorType &r = *Vr;
224 r.reinit(x);
225
226 VectorType &d = *Vd;
227 d.reinit(x);
228
229 LogStream::Prefix prefix("Richardson");
230
231 // Main loop
232 while (conv == SolverControl::iterate)
233 {
234 // Compute the residual:
235 A.vmult(r, x);
236 r.sadd(-1., 1., b);
237
238 preconditioner.vmult(d, r);
239
240 // get the required norm of the (possibly preconditioned)
241 // residual
242 last_criterion = criterion(r, d);
243 conv = this->iteration_status(iter, last_criterion, x);
244 if (conv != SolverControl::iterate)
245 break;
246
247 // Add the correction to the current iterate. In many cases, one runs
248 // Richardson's iteration with a step length (damping factor) of one,
249 // in which case we can optimize the addition.
250 if (additional_data.omega != 1.0)
251 x.add(additional_data.omega, d);
252 else
253 x += d;
254
255 print_vectors(iter, x, r, d);
256
257 ++iter;
258 }
259
260 // in case of failure: throw exception
261 if (conv != SolverControl::success)
262 AssertThrow(false, SolverControl::NoConvergence(iter, last_criterion));
263 // otherwise exit as normal
264}
265
266
267
268template <typename VectorType>
270template <typename MatrixType, typename PreconditionerType>
275 const MatrixType &A,
276 VectorType &x,
277 const VectorType &b,
278 const PreconditionerType &preconditioner)
279{
281 double last_criterion = std::numeric_limits<double>::lowest();
282
283 unsigned int iter = 0;
284
285 // Memory allocation.
286 // 'Vr' holds the residual, 'Vd' the preconditioned residual
287 typename VectorMemory<VectorType>::Pointer Vr(this->memory);
288 typename VectorMemory<VectorType>::Pointer Vd(this->memory);
289
290 VectorType &r = *Vr;
291 r.reinit(x);
292
293 VectorType &d = *Vd;
294 d.reinit(x);
295
296 LogStream::Prefix prefix("RichardsonT");
297
298 // Main loop
299 while (conv == SolverControl::iterate)
300 {
301 // Do not use Tresidual,
302 // but do it in 2 steps
303 A.Tvmult(r, x);
304 r.sadd(-1., 1., b);
305 preconditioner.Tvmult(d, r);
306
307 last_criterion = criterion(r, d);
308 conv = this->iteration_status(iter, last_criterion, x);
309 if (conv != SolverControl::iterate)
310 break;
311
312 x.add(additional_data.omega, d);
313 print_vectors(iter, x, r, d);
314
315 ++iter;
316 }
317
318 // in case of failure: throw exception
319 if (conv != SolverControl::success)
320 AssertThrow(false, SolverControl::NoConvergence(iter, last_criterion));
321
322 // otherwise exit as normal
323}
324
325
326
327template <typename VectorType>
329void SolverRichardson<VectorType>::print_vectors(const unsigned int,
330 const VectorType &,
331 const VectorType &,
332 const VectorType &) const
333{}
334
335
336
337template <typename VectorType>
339inline typename VectorType::value_type
340 SolverRichardson<VectorType>::criterion(const VectorType &r,
341 const VectorType &d) const
342{
343 if (!additional_data.use_preconditioned_residual)
344 return r.l2_norm();
345 else
346 return d.l2_norm();
347}
348
349
350template <typename VectorType>
352inline void SolverRichardson<VectorType>::set_omega(const double om)
353{
354 additional_data.omega = om;
355}
356
357#endif // DOXYGEN
358
360
361#endif
@ iterate
Continue iteration.
@ success
Stop iteration, goal reached.
virtual void print_vectors(const unsigned int step, const VectorType &x, const VectorType &r, const VectorType &d) const
void solve(const MatrixType &A, VectorType &x, const VectorType &b, const PreconditionerType &preconditioner)
void set_omega(const double om=1.)
SolverRichardson(SolverControl &cn, VectorMemory< VectorType > &mem, const AdditionalData &data=AdditionalData())
void Tsolve(const MatrixType &A, VectorType &x, const VectorType &b, const PreconditionerType &preconditioner)
virtual ~SolverRichardson() override=default
virtual VectorType::value_type criterion(const VectorType &r, const VectorType &d) const
SolverRichardson(SolverControl &cn, const AdditionalData &data=AdditionalData())
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:249
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define AssertThrow(cond, exc)
std::vector< index_type > data
Definition mpi.cc:734
constexpr char A
Tpetra::Vector< Number, LO, GO, NodeType< MemorySpace > > VectorType
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
AdditionalData(const double omega=1, const bool use_preconditioned_residual=false)