KASKADE 7 development version
jacobiSolver.hh
Go to the documentation of this file.
1/*
2 * jacobiSolver.hh
3 *
4 * Created on: 21.08.2013
5 * Author: bzflubko
6 */
7
8#ifndef JACOBISOLVER_HH_
9#define JACOBISOLVER_HH_
10
11namespace Kaskade
12{
18 template <class Scalar, int nComponents=1>
19 class JacobiSolver : public Dune::Preconditioner<Dune::BlockVector<Dune::FieldVector<Scalar,nComponents> >,Dune::BlockVector<Dune::FieldVector<Scalar,nComponents> > >
20 {
21 public:
24
25 static int const category = Dune::SolverCategory::sequential;
26
28
32 explicit JacobiSolver(Dune::BCRSMatrix<MatrixBlock> const& A_, size_t maxSteps_ = 100, double relaxation_=1.0)
33 : A(A_), diag(A.N()), maxSteps(maxSteps_), relaxation(relaxation_)
34 {
35 extractDiagonal();
36 }
37
38 virtual ~JacobiSolver(){}
39
42
44 {
45 assert(solution.N()==rhs.N());
47
48 for(size_t i=0; i<maxSteps; ++i)
49 {
50 tmp = rhs;
51 // apply non diagonal
52 auto riter = A.begin(), rend = A.end();
53 for(;riter!=rend; ++riter) // iterate over rows
54 {
55 size_t row = riter.index();
56 auto citer = riter->begin(), cend = riter->end();
57 for(;citer!=cend; ++citer) // iterate over cols
58 {
59 size_t col = citer.index();
60 if(row!=col) tmp[row] -= *citer * solution[col];
61 }
62 }
63
64 solution *= (1.-relaxation);
65 for(size_t i=0; i<solution.N(); ++i)
66 {
67 solution[i] += relaxation * diag[i] * tmp[i];
68 }
69 }
70 }
71
72 private:
74 void extractDiagonal()
75 {
76 auto riter = A.begin(), rend = A.end();
77 for(;riter!=rend; ++riter)
78 {
79 size_t row = riter.index();
80 auto citer = riter->begin(), cend = riter->end();
81 for(;citer!=cend && row!=citer.index(); ++citer)
82 ;
83 if(row==citer.index())
84 {
85 diag[row] = *citer;
86 diag[row].invert();
87 }
88 else
89 {
90 std::cout << "WARNING! Singular diagonal block found in jacobi solver" << std::endl;
91 diag[row] = 0;
92 }
93 }
94 }
95
96 Dune::BCRSMatrix<MatrixBlock> const& A;
97 std::vector<MatrixBlock> diag;
98 size_t maxSteps;
99 double relaxation;
100 };
101
102
108 template <class Scalar, class Domain, class Range, class SparseIndexInt = int>
109 class JacobiSolverForTriplets : public Dune::Preconditioner<Domain,Range>
110 {
111 public:
114
115 static int const category = Dune::SolverCategory::sequential;
116 explicit JacobiSolverForTriplets(MatrixAsTriplet<Scalar,SparseIndexInt> const& A_, size_t maxSteps_ = 100, double relaxation_=1.0)
117 : A(A_), invDiag(A.N()), maxSteps(maxSteps_), relaxation(relaxation_)
118 {
119 extractDiagonal();
120 }
121
122 template <class Assembler, int row, int rend, int col, int cend>
123 explicit JacobiSolverForTriplets(AssembledGalerkinOperator<Assembler,row,rend,col,cend> const& A_, size_t maxSteps_ = 100, double relaxation_=1.0)
124 : A(A_.getTriplet()), invDiag(A.N()), maxSteps(maxSteps_), relaxation(relaxation_)
125 {}
126
127 template <class Assembler, int row, int rend, int col, int cend>
128 explicit JacobiSolverForTriplets(TransposedOperator<AssembledGalerkinOperator<Assembler,row,rend,col,cend> > const& A_, size_t maxSteps_ = 100, double relaxation_=1.0)
129 : A(A_.getTriplet()), invDiag(A.N()), maxSteps(maxSteps_), relaxation(relaxation_)
130 {}
131
133
134 void pre(Domain&,Range&){}
135 void post(Domain&){}
136
137 void apply(Domain& solution, Range const& rhs)
138 {
139 assert(solution.dim()==rhs.dim());
140 std::vector<Scalar> rhsVec, solVec;
141 IstlInterfaceDetail::toVector(rhs,rhsVec);
142 IstlInterfaceDetail::toVector(solution,solVec);
143 // for( size_t i=0; i<solVec.size(); ++i)
144 //std::cout << i << ": " << solVec[i] << std::endl;
145
146 for(size_t step=0; step<maxSteps; ++step)
147 {
148 auto tmp = rhsVec;
149 // apply non-diagonal
150 for(size_t i=0; i<A.data.size(); ++i)
151 {
152 if(A.ridx[i] != A.cidx[i])
153 {
154 // std::cout << "index: " << A.ridx[i] << ", " << A.cidx[i] << std::endl;
155 //std::cout << "subtracting: " << solVec[A.cidx[i]] << " * " << A.data[i] << std::endl;
156 tmp[A.ridx[i]] -= solVec[A.cidx[i]] * A.data[i];
157 }
158 }
159 for( double& d : solVec ) d *= (1. - relaxation);
160// solVec *= (1.-relaxation);
161 for(size_t i=0; i<invDiag.size(); ++i)
162 {
163 solVec[i] += relaxation * invDiag[i] * tmp[i];
164 }
165 }
166 IstlInterfaceDetail::fromVector(solVec,solution);
167 }
168
169 private:
171 void extractDiagonal()
172 {
173 for(size_t i=0; i<A.data.size(); ++i)
174 if(A.ridx[i] == A.cidx[i])
175 {
176 if(std::fabs(A.data[i]) > 1e-12)
177 invDiag[A.ridx[i]] = 1./A.data[i];
178 else
179 invDiag[A.ridx[i]] = 0;
180 }
181 }
182
183 MatrixAsTriplet<Scalar,SparseIndexInt> const& A;
184 std::vector<Scalar> invDiag;
185 size_t maxSteps;
186 double relaxation;
187 };
188
189 template <class Scalar, class Domain, class Range, class SparseIndexInt = int>
190 class JacobiPreconditionerForTriplets : public Dune::Preconditioner<Domain,Range>
191 {
192 public:
195
196 static int const category = Dune::SolverCategory::sequential;
198 : invDiag(A.N())
199 {
200 extractDiagonal(A);
201 }
202
203 template <class Assembler, int row, int rend, int col, int cend>
205 : JacobiPreconditionerForTriplets(A.template getTriplet())
206 {}
207
208 template <class Assembler, int row, int rend, int col, int cend>
210 : JacobiPreconditionerForTriplets(A.template getTriplet())
211 {}
212
214
215 void pre(Domain&,Range&){}
216 void post(Domain&){}
217
218 void apply(Domain& solution, Range const& rhs)
219 {
220 assert(solution.dim()==rhs.dim());
221 std::vector<Scalar> rhsVec, solVec;
222 IstlInterfaceDetail::toVector(rhs,rhsVec);
223 IstlInterfaceDetail::toVector(solution,solVec);
224
225 for(size_t i=0; i<invDiag.size(); ++i)
226 solVec[i] += invDiag[i] * rhsVec[i];
227
228 IstlInterfaceDetail::fromVector(solVec,solution);
229 }
230
231 private:
233 void extractDiagonal(MatrixAsTriplet<Scalar,SparseIndexInt> const& A)
234 {
235 for(size_t i=0; i<A.data.size(); ++i)
236 if(A.ridx[i] == A.cidx[i])
237 {
238 if(std::fabs(A.data[i]) > 1e-12)
239 invDiag[A.ridx[i]] = 1./A.data[i];
240 else
241 invDiag[A.ridx[i]] = 0;
242 }
243 }
244
245 std::vector<Scalar> invDiag;
246 };
247}
248
249
250#endif /* JACOBISOLVER_HH_ */
An adaptor presenting a Dune::LinearOperator <domain_type,range_type> interface to a contiguous sub-b...
JacobiPreconditionerForTriplets(MatrixAsTriplet< Scalar, SparseIndexInt > const &A)
Dune::FieldMatrix< Scalar, 1, 1 > MatrixBlock
JacobiPreconditionerForTriplets(TransposedOperator< AssembledGalerkinOperator< Assembler, row, rend, col, cend > > const &A)
void apply(Domain &solution, Range const &rhs)
JacobiPreconditionerForTriplets(AssembledGalerkinOperator< Assembler, row, rend, col, cend > const &A)
Dune::FieldVector< Scalar, 1 > VectorBlock
void apply(Domain &solution, Range const &rhs)
Dune::FieldMatrix< Scalar, 1, 1 > MatrixBlock
Dune::FieldVector< Scalar, 1 > VectorBlock
void pre(Domain &, Range &)
JacobiSolverForTriplets(TransposedOperator< AssembledGalerkinOperator< Assembler, row, rend, col, cend > > const &A_, size_t maxSteps_=100, double relaxation_=1.0)
JacobiSolverForTriplets(AssembledGalerkinOperator< Assembler, row, rend, col, cend > const &A_, size_t maxSteps_=100, double relaxation_=1.0)
JacobiSolverForTriplets(MatrixAsTriplet< Scalar, SparseIndexInt > const &A_, size_t maxSteps_=100, double relaxation_=1.0)
static int const category
Definition: jacobiSolver.hh:25
void apply(Dune::BlockVector< VectorBlock > &solution, Dune::BlockVector< VectorBlock > const &rhs)
Definition: jacobiSolver.hh:43
Dune::FieldMatrix< Scalar, nComponents, nComponents > MatrixBlock
Definition: jacobiSolver.hh:22
Dune::FieldVector< Scalar, nComponents > VectorBlock
Definition: jacobiSolver.hh:23
void pre(Dune::BlockVector< VectorBlock > &, Dune::BlockVector< VectorBlock > &)
Definition: jacobiSolver.hh:40
void post(Dune::BlockVector< VectorBlock > &)
Definition: jacobiSolver.hh:41
JacobiSolver(Dune::BCRSMatrix< MatrixBlock > const &A_, size_t maxSteps_=100, double relaxation_=1.0)
Constructor taking a reference to a bcrs matrix.
Definition: jacobiSolver.hh:32
std::vector< SparseIndexInt > ridx
row indices
Definition: triplet.hh:669
std::vector< SparseIndexInt > cidx
column indices
Definition: triplet.hh:671
std::vector< Scalar > data
data
Definition: triplet.hh:673