Newer
Older
#ifndef LEVEL_PATCH_PRECONDITIONER_HH
#define LEVEL_PATCH_PRECONDITIONER_HH
#include <string>
#include <dune/common/timer.hh>
#include <dune/common/fvector.hh>
#include <dune/common/bitsetvector.hh>
#include <dune/solvers/iterationsteps/lineariterationstep.hh>
#include <dune/faultnetworks/assemblers/globalfaultassembler.hh>
#include <dune/faultnetworks/localproblem.hh>
#include <dune/faultnetworks/levelinterfacenetwork.hh>
#include <dune/faultnetworks/utils/debugutils.hh>
#include <dune/fufem/boundarypatch.hh>
#include <dune/fufem/functiontools/boundarydofs.hh>
template <class BasisType, class LocalAssembler, class LocalInterfaceAssembler, class MatrixType, class VectorType>
class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorType> {
public:
typedef typename BasisType::GridView GridView;
typedef typename GridView::Grid GridType;
const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork_;
const LocalAssembler& localAssembler_;
const std::vector<std::shared_ptr<LocalInterfaceAssembler>>& localInterfaceAssemblers_;
const GridType& grid_;
const int level_;
const BasisType basis_;
size_t patchDepth_;
BoundaryMode boundaryMode_;
MatrixType matrix_;
std::vector<std::shared_ptr<OscLocalProblem<MatrixType, VectorType>> > localProblems_;
public:
LevelPatchPreconditioner(const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork,
const LocalAssembler& localAssembler,
const std::vector<std::shared_ptr<LocalInterfaceAssembler>>& localInterfaceAssemblers,
localAssembler_(localAssembler),
localInterfaceAssemblers_(localInterfaceAssemblers),
mode_(mode),
grid_(levelInterfaceNetwork_.grid()),
level_(levelInterfaceNetwork_.level()),
basis_(levelInterfaceNetwork_)
{
void setPatchDepth(const size_t patchDepth = 0) {
patchDepth_ = patchDepth;
}
void setBoundaryMode(const BoundaryMode boundaryMode = LevelPatchPreconditioner::BoundaryMode::homogeneous) {
boundaryMode_ = boundaryMode;
}
virtual void setProblem(const MatrixType& mat, VectorType& x, const VectorType& rhs) {
this->x_ = &x;
this->rhs_ = &rhs;
this->mat_ = Dune::stackobject_to_shared_ptr(mat);
for (size_t i=0; i<localProblems_.size(); i++) {
if (boundaryMode_ == BoundaryMode::homogeneous)
localProblems_[i]->updateRhs(rhs);
else
localProblems_[i]->updateRhsAndBoundary(rhs, x);
}
}
void setDirection(Direction dir = SYMMETRIC) {
multDirection_ = dir;
}
virtual void iterate() {
}
const BasisType& basis() const {
return basis_;
}
const GridView& gridView() const {
return basis_.getGridView();
}
const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork() const {
return levelInterfaceNetwork_;
}
size_t size() const {
return localProblems_.size();
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
void setup() {
// assemble stiffness matrix for entire level including all faults
GlobalFaultAssembler<BasisType, BasisType> globalFaultAssembler(basis_, basis_, levelInterfaceNetwork_);
globalFaultAssembler.assembleOperator(localAssembler_, localInterfaceAssemblers_, matrix_);
// set boundary conditions
Dune::BitSetVector<1> globalBoundaryDofs;
BoundaryPatch<GridView> boundaryPatch(levelInterfaceNetwork_.levelGridView(), true);
constructBoundaryDofs(boundaryPatch, basis_, globalBoundaryDofs);
typedef typename MatrixType::row_type RowType;
typedef typename RowType::ConstIterator ColumnIterator;
for(size_t i=0; i<globalBoundaryDofs.size(); i++) {
if(!globalBoundaryDofs[i][0])
continue;
RowType& row = matrix_[i];
ColumnIterator cIt = row.begin();
ColumnIterator cEndIt = row.end();
for(; cIt!=cEndIt; ++cIt) {
row[cIt.index()] = 0;
}
row[i] = 1;
}
}
VectorType it, x;
for (size_t i=0; i<localProblems_.size(); i++) {
localProblems_[i]->solve(it);
localProblems_[i]->prolong(it, x);
/*if (i==5) {
writeToVTK(basis_, x, "/storage/mi/podlesny/data/faultnetworks/iterates/", "exactvertexdata_patchDepth_"+std::to_string(patchDepth_));
}*/
*(this->x_) += x;
}
}
for (size_t i=0; i<localProblems_.size(); i++)
iterateStep(i);
}
for (size_t i=localProblems_.size()-1; i>=0 && i<localProblems_.size(); i--)
iterateStep(i);
}
void iterateStep(size_t i) {
v1.resize(localProblem.getLocalMat().N());
localProblem.getLocalMat().mv(v, v1);
v3.resize(matrix_.N());
matrix_.mv(*(this->x_), v3);
localProblem.restrict(v3, v2);
//print(v1, "v1");
//print(v2, "v2");
VectorType r1;
localProblem.restrict(*(this->rhs_), r1);
Dune::MatrixVector::subtractProduct(r1, localProblem.getLocalMat(), v);
/*localProblem.updateLocalRhs(r);
localProblem.updateVector(v, *(this->x_));*/
VectorType localR;
VectorType r = *(this->rhs_);
Dune::MatrixVector::subtractProduct(r, matrix_, *(this->x_));
localProblem.restrict(r, localR);
// print(r1, "r1");
// print(localR, "localR");
localProblem.updateLocalRhs(localR);
VectorType x;
localProblem.solve(x);
//VectorType v;
localProblem.prolong(x, v);
*(this->x_) += v;