KASKADE 7 development version
icc0precond.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) 2002-2024 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
18#ifndef ICC_0_PRECOND_HH
19#define ICC_0_PRECOND_HH
20
21#include <memory>
22#include <vector>
23
24#include <boost/fusion/include/at_c.hpp>
25
26#include "dune/grid/common/grid.hh"
27#include "dune/istl/matrix.hh"
28#include "dune/istl/bcrsmatrix.hh"
29#include "dune/common/fmatrix.hh"
30#include "dune/common/fvector.hh"
31#include "dune/common/iteratorfacades.hh"
32#include "dune/istl/matrixindexset.hh"
33
34#include "dune/istl/preconditioners.hh"
35
36namespace Kaskade
37{
38
50 template <class Op>
51 class ICC_0Preconditioner: public Dune::Preconditioner<typename Op::Range, typename Op::Range>
52 {
53 public:
54 typedef typename Op::Domain Domain;
55 typedef typename Op::Range Range;
56 typedef typename Op::Scalar Scalar;
57
58 private:
61 typedef Dune::BCRSMatrix<BlockType> BCRS_Matrix;
62 typedef typename BCRS_Matrix::ConstColIterator ColIter;
63
64 BCRS_Matrix mL;
65 std::vector<std::vector<int> > mEntries;
66
67 public:
68 ICC_0Preconditioner( Op& op );
69 void pre (Domain&, Range&) {}
70 void apply (Domain& x, Range const& y);
71 void post (Domain&) {}
72
78 virtual Dune::SolverCategory::Category category() const override
79 {
80 return Dune::SolverCategory::sequential;
81 }
82 };
83
84
85template <class Op>
87{
88 BCRS_Matrix mA = op.template get<BCRS_Matrix>();
89 int N = mA.N();
90 // create kind of column iterator for BCRS
91 // and simultaneously read out the sparsity pattern of mA
92 mEntries.resize(N);
93 for(int i=0;i<N;i++)
94 for (ColIter cI=mA[i].begin(); cI!=mA[i].end() && cI.index()<i; ++cI)
95 mEntries[cI.index()].push_back(i);
96
97 // backward substitution in ICC_0Preconditioner::apply() with BCRSMatrix mL^T is not
98 // efficiently applicable, therefore create two BCRSMatrices mL and mLT := mL^T
99 // set up sparsity pattern of lower triangle of mA (upper triangle of mA^T) for mL (mLT)
100 Dune::MatrixIndexSet sparsityPattern_mL(N,N);
101 for (int i=0; i<N; ++i)
102 for (ColIter cI=mA[i].begin(); cI!=mA[i].end() && cI.index()<=i; ++cI)
103 sparsityPattern_mL.add(i,cI.index() );
104
105 sparsityPattern_mL.exportIdx( mL );
106 for(int i=0;i<N;++i)
107 for (ColIter cI=mL[i].begin(); cI!=mL[i].end(); ++cI)
108 mL[i][cI.index()] = mA[i][cI.index()];
109 //find factorization mL of mA
110 double tmp;
111 for(int k=0;k<N;k++)
112 {
113 mL[k][k] = sqrt(mL[k][k]);
114 for(std::vector<int>::iterator it = mEntries[k].begin(); it!=mEntries[k].end(); it++)
115 mL[*it][k] /= mL[k][k];
116 for(std::vector<int>::iterator it = mEntries[k].begin(); it!=mEntries[k].end(); it++)
117 {
118 tmp = mL[*it][k];
119 mL[*it][*it] -= (mL[*it][k])*(mL[*it][k]); // "mEntries" contains not diagonal indices
120 for(std::vector<int>::iterator it2 = mEntries[*it].begin(); it2!=mEntries[*it].end(); it2++)
121 if( mL.exists(*it2,k) )
122 mL[*it2][*it] -= mL[*it2][k]*tmp;
123 }
124 }
125}
126
127template <class Op>
129{
130 int N = x.dim();
131
132 CoeffVector &sol = boost::fusion::at_c<0>(x.data);
133 CoeffVector const &rhs = boost::fusion::at_c<0>(b.data);
134 // for forward substitution
135 CoeffVector forward(N); forward = 0;
136
137 double tmp;
138 // forward substitution
139 for(int i=0;i<N;i++)
140 {
141 tmp = rhs[i];
142 for (ColIter cI = mL[i].begin(); cI != mL[i].end(); ++cI)
143 if( cI.index()<i )
144 tmp -= mL[i][cI.index()]*forward[cI.index()];
145 forward[i] = tmp/mL[i][i];
146 }
147 // backward substitution
148 for(int i = N-1;i>=0;i--)
149 {
150 tmp = forward[i];
151 for(std::vector<int>::iterator it = mEntries[i].begin();it!=mEntries[i].end();it++)
152 tmp -= mL[*it][i]*sol[*it];
153 sol[i] = tmp/mL[i][i];
154 }
155}
156} // namespace Kaskade
157#endif
158
Incomplete Cholesky factorization by algorithm from book "Matrix Computations" by Gene Golub & Charle...
Definition: icc0precond.hh:52
void apply(Domain &x, Range const &y)
Definition: icc0precond.hh:128
virtual Dune::SolverCategory::Category category() const override
returns the category of the operator
Definition: icc0precond.hh:78
void pre(Domain &, Range &)
Definition: icc0precond.hh:69