8#ifndef JACOBISOLVER_HH_
9#define JACOBISOLVER_HH_
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> > >
25 static int const category = Dune::SolverCategory::sequential;
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_)
45 assert(solution.N()==rhs.N());
48 for(
size_t i=0; i<maxSteps; ++i)
52 auto riter = A.begin(), rend = A.end();
53 for(;riter!=rend; ++riter)
55 size_t row = riter.index();
56 auto citer = riter->begin(), cend = riter->end();
57 for(;citer!=cend; ++citer)
59 size_t col = citer.index();
60 if(row!=col) tmp[row] -= *citer * solution[col];
64 solution *= (1.-relaxation);
65 for(
size_t i=0; i<solution.N(); ++i)
67 solution[i] += relaxation * diag[i] * tmp[i];
74 void extractDiagonal()
76 auto riter = A.begin(), rend = A.end();
77 for(;riter!=rend; ++riter)
79 size_t row = riter.index();
80 auto citer = riter->begin(), cend = riter->end();
81 for(;citer!=cend && row!=citer.index(); ++citer)
83 if(row==citer.index())
90 std::cout <<
"WARNING! Singular diagonal block found in jacobi solver" << std::endl;
96 Dune::BCRSMatrix<MatrixBlock>
const& A;
97 std::vector<MatrixBlock> diag;
108 template <
class Scalar,
class Domain,
class Range,
class SparseIndexInt =
int>
115 static int const category = Dune::SolverCategory::sequential;
117 : A(A_), invDiag(A.N()), maxSteps(maxSteps_), relaxation(relaxation_)
122 template <
class Assembler,
int row,
int rend,
int col,
int cend>
124 : A(A_.getTriplet()), invDiag(A.N()), maxSteps(maxSteps_), relaxation(relaxation_)
127 template <
class Assembler,
int row,
int rend,
int col,
int cend>
129 : A(A_.getTriplet()), invDiag(A.N()), maxSteps(maxSteps_), relaxation(relaxation_)
134 void pre(Domain&,Range&){}
137 void apply(Domain& solution, Range
const& rhs)
139 assert(solution.dim()==rhs.dim());
140 std::vector<Scalar> rhsVec, solVec;
141 IstlInterfaceDetail::toVector(rhs,rhsVec);
142 IstlInterfaceDetail::toVector(solution,solVec);
146 for(
size_t step=0; step<maxSteps; ++step)
150 for(
size_t i=0; i<A.data.size(); ++i)
152 if(A.ridx[i] != A.cidx[i])
156 tmp[A.ridx[i]] -= solVec[A.cidx[i]] * A.data[i];
159 for(
double& d : solVec ) d *= (1. - relaxation);
161 for(
size_t i=0; i<invDiag.size(); ++i)
163 solVec[i] += relaxation * invDiag[i] * tmp[i];
166 IstlInterfaceDetail::fromVector(solVec,solution);
171 void extractDiagonal()
173 for(
size_t i=0; i<A.data.size(); ++i)
174 if(A.ridx[i] == A.cidx[i])
176 if(std::fabs(A.data[i]) > 1e-12)
177 invDiag[A.ridx[i]] = 1./A.data[i];
179 invDiag[A.ridx[i]] = 0;
183 MatrixAsTriplet<Scalar,SparseIndexInt>
const& A;
184 std::vector<Scalar> invDiag;
189 template <
class Scalar,
class Domain,
class Range,
class SparseIndexInt =
int>
196 static int const category = Dune::SolverCategory::sequential;
203 template <
class Assembler,
int row,
int rend,
int col,
int cend>
208 template <
class Assembler,
int row,
int rend,
int col,
int cend>
215 void pre(Domain&,Range&){}
218 void apply(Domain& solution, Range
const& rhs)
220 assert(solution.dim()==rhs.dim());
221 std::vector<Scalar> rhsVec, solVec;
222 IstlInterfaceDetail::toVector(rhs,rhsVec);
223 IstlInterfaceDetail::toVector(solution,solVec);
225 for(
size_t i=0; i<invDiag.size(); ++i)
226 solVec[i] += invDiag[i] * rhsVec[i];
228 IstlInterfaceDetail::fromVector(solVec,solution);
235 for(
size_t i=0; i<A.
data.size(); ++i)
238 if(std::fabs(A.
data[i]) > 1e-12)
241 invDiag[A.
ridx[i]] = 0;
245 std::vector<Scalar> invDiag;
An adaptor presenting a Dune::LinearOperator <domain_type,range_type> interface to a contiguous sub-b...
JacobiPreconditionerForTriplets(MatrixAsTriplet< Scalar, SparseIndexInt > const &A)
static int const category
virtual ~JacobiPreconditionerForTriplets()
Dune::FieldMatrix< Scalar, 1, 1 > MatrixBlock
JacobiPreconditionerForTriplets(TransposedOperator< AssembledGalerkinOperator< Assembler, row, rend, col, cend > > const &A)
void apply(Domain &solution, Range const &rhs)
void pre(Domain &, Range &)
JacobiPreconditionerForTriplets(AssembledGalerkinOperator< Assembler, row, rend, col, cend > const &A)
Dune::FieldVector< Scalar, 1 > VectorBlock
static int const category
void apply(Domain &solution, Range const &rhs)
virtual ~JacobiSolverForTriplets()
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
void apply(Dune::BlockVector< VectorBlock > &solution, Dune::BlockVector< VectorBlock > const &rhs)
Dune::FieldMatrix< Scalar, nComponents, nComponents > MatrixBlock
Dune::FieldVector< Scalar, nComponents > VectorBlock
void pre(Dune::BlockVector< VectorBlock > &, Dune::BlockVector< VectorBlock > &)
void post(Dune::BlockVector< VectorBlock > &)
JacobiSolver(Dune::BCRSMatrix< MatrixBlock > const &A_, size_t maxSteps_=100, double relaxation_=1.0)
Constructor taking a reference to a bcrs matrix.
std::vector< SparseIndexInt > ridx
row indices
std::vector< SparseIndexInt > cidx
column indices
std::vector< Scalar > data
data