KASKADE 7 development version
GaussSeidelPreconditioner.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2020-2020 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef GAUSS_SEIDEL_PRECONDITIONER_HH
14#define GAUSS_SEIDEL_PRECONDITIONER_HH
15
16#include "dune/istl/preconditioners.hh"
17#include "dune/istl/solvercategory.hh"
18
19#include "fem/fixdune.hh"
20#include "fem/istlinterface.hh"
21
24
26
27namespace Kaskade
28{
29
30
31 // ----------------------------------------------------------------------------------------------
32 // ----------------------------------------------------------------------------------------------
33
35
48 template <class Matrix,
49 class Domain=typename MatrixTraits<Matrix>::NaturalDomain,
50 class Range=typename MatrixTraits<Matrix>::NaturalRange>
52 {
54 using field_type = typename Base::field_type;
55
56 public:
65 GaussSeidelPreconditioner(Matrix const& A_,
66 field_type w_ = 1.0,
68 : A(A_)
69 , w(w_)
70 , mode(mode_)
71 {
72 static_assert(std::is_same_v<Domain,Range>,
73 "Gauss Seidel works only for square matrices with coinciding domain and range types.");
75 }
76
77 void apply(Domain& x, Range const& y) override
78 {
79 Domain z = y;
80
81 // forward sweep if requested: (L+D) z = y
82 if ((int)mode & (int)GaussSeidelPreconditionerMode::FORWARD)
83 for (int i=0; i<A.N(); ++i)
84 {
85 auto const& row = A[i];
86 auto rhs = y[i];
87 auto ci = row.begin();
88 for (; ci!=row.end() && ci.index()<i; ++ci) // update right hand side entry
89 ci->usmv(-1.0,z[ci.index()],rhs); // with L*z
90 assert(ci!=row.end()); // make sure D exists
91 ci->solve(z[i],rhs); // solve with D
92 z[i] *= w;
93 }
94
95 // backward sweep if requested: (D+R) x = z
96 if ((int)mode & (int)GaussSeidelPreconditionerMode::BACKWARD)
97 for (int i=A.N()-1; i>=0; --i)
98 {
99 auto const& row = A[i];
100 auto rhs = z[i];
101 auto ci = row.begin(); // move to D by skipping over L
102 while (ci.index()<i && ci!=row.end())
103 ++ci;
104 assert(ci.index()==i); // and make sure D exists
105 auto a = *ci;
106 for (; ci!=row.end(); ++ci) // update right hand side entry
107 ci->usmv(-1.0,x[ci.index()],rhs); // with R*x
108 a.solve(x[i],rhs); // solve with D
109 x[i] *= w;
110 }
111 }
112
113 field_type applyDp(Domain& x, Range const& y) override
114 {
115 apply(x,y);
116 return x*y;
117 }
118
119 bool requiresInitializedInput() const override { return true; }
120
121 private:
122 Matrix A;
123 field_type w;
125 };
126
127
128
129} // namespace Kaskade
130#endif
A simple single-level symmetric Gauss-Seidel preconditioner.
bool requiresInitializedInput() const override
Returns true if the target vector x has to be initialized to zero before calling apply or applyDp.
field_type applyDp(Domain &x, Range const &y) override
GaussSeidelPreconditioner(Matrix const &A_, field_type w_=1.0, GaussSeidelPreconditionerMode mode_=GaussSeidelPreconditionerMode::SYMMETRIC)
Constructor.
void apply(Domain &x, Range const &y) override
Interface for symmetric preconditioners.
This file contains various utility functions that augment the basic functionality of Dune.
Defines domain and range types for matrix classes.
Definition: matrixTraits.hh:41
void NaturalDomain
The natural domain type.
Definition: matrixTraits.hh:50
void NaturalRange
The natural range type.
Definition: matrixTraits.hh:58