13#ifndef BLOCK_DIAGONAL_SCHUR_PRECONDITIONER_HH
14#define BLOCK_DIAGONAL_SCHUR_PRECONDITIONER_HH
19#include <boost/fusion/include/at_c.hpp>
21#include <dune/istl/solvers.hh>
22#include <dune/istl/preconditioners.hh>
23#include <dune/istl/solvercategory.hh>
34 namespace SchurPreconditionerDetail
36 template <
class Operator,
class Block>
39 typedef typename Operator::Assembler::AnsatzVariableSetDescription::template CoefficientVectorRepresentation<Block::firstCol,Block::lastCol>::type
Domain;
40 typedef typename Operator::Assembler::TestVariableSetDescription::template CoefficientVectorRepresentation<Block::firstRow,Block::lastRow>::type
Range;
44 template <
class Scalar_>
47 typedef Scalar_ Scalar;
53 template <
class Operator>
55 : A(A_.template get<
Matrix>(false)), diag(A.nrows(),0)
61 : A(A_), diag(A.nrows(),0)
66 template <
class Domain,
class Range>
67 void apply(Domain& x, Range
const& y,
size_t nIter = 1)
const
69 std::vector<Scalar> tmpx(x.dim()), tmpy;
70 IstlInterfaceDetail::toVector(y,tmpy);
71 for(
size_t i=0; i<diag.size(); ++i) tmpx[i] = tmpy[i]/diag[i];
73 for(
size_t iter=0; iter < nIter; ++iter)
76 for(
size_t i=0; i<diag.size(); ++i) tmpx[i] += tmpy[i]/diag[i];
78 IstlInterfaceDetail::fromVector(tmpx,x);
83 std::vector<Scalar> diag;
86 template <
class Scalar_>
89 typedef Scalar_ Scalar;
95 template <
class Operator,
typename... Args>
98 Matrix A = A_.template get<Matrix>();
99 diag.resize(A.
nrows());
103 template <
typename... Args>
110 template <
class Domain,
class Range>
111 void apply(Domain& x, Range
const& y)
const
113 tmpx.resize(x.dim());
114 IstlInterfaceDetail::toVector(y,tmpy);
115 for(
size_t i=0; i<diag.size(); ++i) tmpx[i] = tmpy[i]/diag[i];
116 IstlInterfaceDetail::fromVector(tmpx,x);
120 std::vector<Scalar> diag;
121 mutable std::vector<Scalar> tmpx, tmpy;
125 template <
class Domain,
class Range>
132 template <
class Operator>
134 : solver(
DirectSolver<Domain,Range>(A,directType,property))
138 : solver(
DirectSolver<Domain,Range>(A,directType,property))
141 void apply(Domain& x, Range
const& y)
const
157 template <
class Scalar_,
class Domain_,
class Range_,
158 class BlockK = IstlInterfaceDetail::BlockInfo<2,3,0,1>,
159 class BlockM = IstlInterfaceDetail::BlockInfo<0,1,0,1>,
160 class LinearSolver = SchurPreconditionerDetail::ApplyDirectSolver<Domain_,Range_>
175 template <
class Assembler>
183 template <
class Matrix>
185 : sqrtOfAlpha(sqrt(alpha)), symmetricK(symmetricK_ && symmetricM_), symmetricM(symmetricM_),
197 template <
class Assembler>
200 sqrtOfAlpha = sqrt(alpha);
201 M = assembler.template get<Matrix,BlockM::firstRow,BlockM::lastRow,BlockM::firstCol,BlockM::lastCol>(symmetricM);
204 K = assembler.template get<Matrix,BlockK::firstRow,BlockK::lastRow,BlockK::firstCol,BlockK::lastCol>(symmetricK);
210 template <
class Matrix>
243 solver = LinearSolver(N,directType,property);
248 bool symmetricK, symmetricM;
253 MatrixAsTriplet<Scalar> K;
271 template <
class Scalar_,
272 class BlockK = IstlInterfaceDetail::BlockInfo<2,3,0,1>,
273 class BlockM = IstlInterfaceDetail::BlockInfo<0,1,0,1>
286 template <
class Assembler>
296 template <
class Assembler>
299 M = assembler.template get<Matrix,BlockM::firstRow,BlockM::lastRow,BlockM::firstCol,BlockM::lastCol>(symmetricM);
301 K = assembler.template get<Matrix,BlockK::firstRow,BlockK::lastRow,BlockK::firstCol,BlockK::lastCol>(symmetricK);
306 template <
class Domain,
class Range>
307 void solve(Domain& x, Range
const& y,
size_t nIter)
const
313 std::vector<Scalar> tmpx, tmpy;
314 IstlInterfaceDetail::toVector(x,tmpx);
317 IstlInterfaceDetail::fromVector(tmpy,tmp);
339 bool symmetricK, symmetricM;
350 template <
class Operator,
template <
class,
class,
class,
class,
class,
class>
class SchurComplement = ApproximateSchurComplement,
351 class BlockK = IstlInterfaceDetail::BlockInfo<2,3,0,1>,
352 class BlockM = IstlInterfaceDetail::BlockInfo<0,1,0,1>,
354 class LinearSolver_SchurComplement = LinearSolver
360 typedef typename Operator::Assembler Assembler;
364 typedef typename Operator::Scalar
Scalar;
365 typedef typename Operator::Domain
Domain;
366 typedef typename Operator::Range
Range;
368 static int const category = Dune::SolverCategory::sequential;
371 : A(A_), alpha(alpha_), schurComplement(A.getAssembler(), alpha, symmetricK, symmetricM),
381 Range0 y0(at_c<0>(y.data));
382 Domain0 x0(at_c<0>(x.data));
384 std::cout << at_c<0>(x.data).dim() << std::endl;
387 at_c<0>(x.data) = at_c<0>(x0.data);
389 at_c<0>(y0.data) = at_c<1>(y.data);
392 at_c<1>(x.data) = at_c<0>(x0.data);
394 at_c<0>(y0.data) = at_c<2>(y.data);
395 schurComplement.solve(x0,y0);
396 at_c<2>(x.data) = at_c<0>(x0.data);
405 SchurComplement<Scalar,Domain0,Range0,BlockK,BlockM,LinearSolver_SchurComplement> schurComplement;
Approximation of the schur complement.
ApproximateSchurComplement2(Assembler const &assembler, Scalar, bool symmetricK_=false, bool symmetricM_=false)
MatrixAsTriplet< Scalar > const & massMatrix() const
void updateMatrices(Assembler const &assembler)
MatrixAsTriplet< Scalar > const & stiffnessMatrix() const
void solve(Domain &x, Range const &y, size_t nIter) const
MatrixAsTriplet< Scalar > Matrix
Approximation of the schur complement according to Pearson/Wathen '10.
ApproximateSchurComplement(Matrix const &M_, Matrix const &K_, Scalar alpha, bool symmetricK_=false, bool symmetricM_=false)
MatrixAsTriplet< Scalar > Matrix
Matrix const & getMassMatrix() const
void solve(Domain &x, Range &y) const
compute , overrides y
void updateMatrices(Assembler const &assembler, Scalar alpha)
ApproximateSchurComplement(Assembler const &assembler, Scalar alpha, bool symmetricK_=false, bool symmetricM_=false)
Matrix const & getStiffnessMatrix() const
void updateMatrices(Matrix const &M_, Matrix const &K_, Scalar alpha)
virtual ~BlockDiagonalSchurPreconditioner()
virtual void apply(Domain &x, Range const &y)
static int const category
BlockDiagonalSchurPreconditioner(Operator const &A_, Scalar alpha_, bool symmetricK=false, bool symmetricM=false)
virtual void pre(Domain &, Range &)
virtual void post(Domain &)
Dune::LinearOperator interface for inverse operators.
virtual void apply(Domain const &x, Range &y) const
SparseIndexInt nrows() const
Returns number of rows (computes them, if not known)
std::vector< SparseIndexInt > ridx
row indices
std::vector< SparseIndexInt > cidx
column indices
std::vector< Scalar > data
data
void apply(Domain &x, Range const &y) const
ApplyDirectSolver(MatrixAsTriplet< typename Domain::Scalar > const &A, DirectType directType=DirectType::MUMPS, MatrixProperties property=MatrixProperties::GENERAL)
ApplyDirectSolver(Operator const &A, DirectType directType=DirectType::MUMPS, MatrixProperties property=MatrixProperties::GENERAL)
ApplyDirectSolver()=default
InvertLumpedMatrix()=default
InvertLumpedMatrix(Operator const &A_, Args...)
InvertLumpedMatrix(Matrix const &A, Args...)
void apply(Domain &x, Range const &y) const
JacobiIteration()=default
void apply(Domain &x, Range const &y, size_t nIter=1) const
JacobiIteration(Operator const &A_)
JacobiIteration(Matrix const &A_)
Defines a linear operator with matrix representation .
DirectType
Available direct solvers for linear equation systems.
@ MUMPS
MUMPS sparse solver.
MatrixProperties
Characterizations of sparse matrix properties.
Operator::Assembler::TestVariableSetDescription::template CoefficientVectorRepresentation< Block::firstRow, Block::lastRow >::type Range
Operator::Assembler::AnsatzVariableSetDescription::template CoefficientVectorRepresentation< Block::firstCol, Block::lastCol >::type Domain