diff --git a/dune/faultnetworks/dgmgtransfer.hh b/dune/faultnetworks/dgmgtransfer.hh index 641d3f8cdba07d63535d73a50687811b09603737..7201df5e094cd43045cebb355064cc7b23af1fc7 100644 --- a/dune/faultnetworks/dgmgtransfer.hh +++ b/dune/faultnetworks/dgmgtransfer.hh @@ -218,6 +218,24 @@ public: { GenericMultigridTransfer::restrict(prolongationMatrix_, f, t, -1); } + + template< class OperatorType> + void galerkinRestrictSetOccupation(const OperatorType& fineMat, OperatorType& coarseMat) + { + GenericMultigridTransfer::galerkinRestrictSetOccupation(prolongationMatrix_, fineMat, coarseMat); + } + + template<class FineMatrixType, class CoarseMatrixType> + void galerkinRestrict(const FineMatrixType& fineMat, CoarseMatrixType& coarseMat) + { + GenericMultigridTransfer::galerkinRestrict(prolongationMatrix_, fineMat, coarseMat); + } + + template <class BitVectorType> + void restrictToFathers(const BitVectorType& f, BitVectorType& t) const + { + GenericMultigridTransfer::restrictBitFieldToFathers(prolongationMatrix_, f, t, -1); + } }; #endif diff --git a/dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh b/dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh index c4c2b04fa72c2ee04a0c0e48140516f913575d7c..a14f005352084a4c1dd86aa6a47c6fa60e08b2c0 100644 --- a/dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh +++ b/dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh @@ -21,14 +21,14 @@ public: const Mode mode = Mode::additive) : Base(levelInterfaceNetwork, patchLevelBasis, localAssembler, localInterfaceAssemblers, mode) {} - void build() { + void preprocess() { const int patchLevel = this->patchLevelBasis_.faultNetwork().level(); CellPatchFactory<BasisType> patchFactory(this->patchLevelBasis_, this->basis_, patchLevel, this->level_); const auto& localToGlobal = patchFactory.getLocalToGlobal(); const auto& boundaryDofs = patchFactory.getBoundaryDofs(); VectorType rhs; - rhs.resize(this->matrix_.N()); + rhs.resize(this->mat_->N()); rhs = 0; std::cout << "CellPatchPreconditioner::build() level: " << this->level_ << std::endl; @@ -38,7 +38,7 @@ public: for (size_t i=0; i<cellCount; i++) { using LocalProblemType = typename std::remove_reference<decltype(*(this->localProblems_[i]))>::type; - this->localProblems_[i] = std::make_shared<LocalProblemType>(this->matrix_, rhs, localToGlobal[i], boundaryDofs[i]); + this->localProblems_[i] = std::make_shared<LocalProblemType>(*this->mat_, rhs, localToGlobal[i], boundaryDofs[i]); } } }; diff --git a/dune/faultnetworks/preconditioners/levelglobalpreconditioner.hh b/dune/faultnetworks/preconditioners/levelglobalpreconditioner.hh index 2b7b4e2bb80f6ad5ec302097654dbb5bc320deb4..b831764cdbadc6bd7d6c55ea7a8c40e949ca8e03 100644 --- a/dune/faultnetworks/preconditioners/levelglobalpreconditioner.hh +++ b/dune/faultnetworks/preconditioners/levelglobalpreconditioner.hh @@ -57,7 +57,7 @@ public: assert(localInterfaceAssemblers_.size() == levelInterfaceNetwork_.size()); } - void build() { + void preprocess() { //printBasisDofLocation(basis_); GlobalFaultAssembler<BasisType, BasisType> globalFaultAssembler(basis_, basis_, levelInterfaceNetwork_); diff --git a/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh b/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh index c9fb33fdb8fce847ece8f595310aa741c60733e6..3d9a9526ad7f09db9d610e7a35cf8ad96625679a 100644 --- a/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh +++ b/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh @@ -44,7 +44,6 @@ protected: size_t patchDepth_; BoundaryMode boundaryMode_; - MatrixType matrix_; std::vector<std::shared_ptr<OscLocalProblem<MatrixType, VectorType>> > localProblems_; public: @@ -66,11 +65,10 @@ public: setPatchDepth(); setBoundaryMode(); setDirection(); - setup(); } // has to setup localProblems_ - virtual void build() = 0; + virtual void preprocess() = 0; void setPatchDepth(const size_t patchDepth = 0) { patchDepth_ = patchDepth; @@ -98,6 +96,8 @@ public: } virtual void iterate() { + *(this->x_) = 0; + if (mode_ == ADDITIVE) iterateAdd(); else @@ -121,47 +121,12 @@ public: } private: - 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; - } - } - void iterateAdd() { - //*(this->x_) = 0; - 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; } } @@ -178,48 +143,22 @@ private: } void iterateStep(size_t i) { - //*(this->x_) = 0; - auto& localProblem = *localProblems_[i]; - VectorType v, v1, v2, v3; - localProblem.restrict(*(this->x_), v); - - v1.resize(localProblem.getLocalMat().N()); - localProblem.getLocalMat().mv(v, v1); - v3.resize(matrix_.N()); - matrix_.mv(*(this->x_), v3); - localProblem.restrict(v3, v2); + // compute residual + VectorType residual = *this->rhs_; + this->mat_->mmv(*this->x_, residual); - //print(v1, "v1"); - //print(v2, "v2"); + // restrict residual + VectorType localResidual; + localProblem.restrict(residual, localResidual); - VectorType r1; - localProblem.restrict(*(this->rhs_), r1); - Dune::MatrixVector::subtractProduct(r1, localProblem.getLocalMat(), v); + // solve local problem + localProblem.updateLocalRhs(localResidual); - /*localProblem.updateLocalRhs(r); - - VectorType x; + // prolong + VectorType x, v; localProblem.solve(x); - v += x; - - 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; } diff --git a/dune/faultnetworks/preconditioners/levelpatchpreconditioner_working.hh b/dune/faultnetworks/preconditioners/levelpatchpreconditioner_working.hh new file mode 100644 index 0000000000000000000000000000000000000000..c9fb33fdb8fce847ece8f595310aa741c60733e6 --- /dev/null +++ b/dune/faultnetworks/preconditioners/levelpatchpreconditioner_working.hh @@ -0,0 +1,229 @@ +#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: + enum Mode {ADDITIVE, MULTIPLICATIVE}; + enum BoundaryMode {homogeneous, fromIterate}; + enum Direction {FORWARD, BACKWARD, SYMMETRIC}; + +protected: + typedef typename BasisType::GridView GridView; + typedef typename GridView::Grid GridType; + + const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork_; + const BasisType& patchLevelBasis_; + const LocalAssembler& localAssembler_; + const std::vector<std::shared_ptr<LocalInterfaceAssembler>>& localInterfaceAssemblers_; + + const Mode mode_; + Direction multDirection_; + + 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 BasisType& patchLevelBasis, + const LocalAssembler& localAssembler, + const std::vector<std::shared_ptr<LocalInterfaceAssembler>>& localInterfaceAssemblers, + const Mode mode = LevelPatchPreconditioner::Mode::ADDITIVE) : + levelInterfaceNetwork_(levelInterfaceNetwork), + patchLevelBasis_(patchLevelBasis), + localAssembler_(localAssembler), + localInterfaceAssemblers_(localInterfaceAssemblers), + mode_(mode), + grid_(levelInterfaceNetwork_.grid()), + level_(levelInterfaceNetwork_.level()), + basis_(levelInterfaceNetwork_) + { + assert(localInterfaceAssemblers_.size() == levelInterfaceNetwork_.size()); + setPatchDepth(); + setBoundaryMode(); + setDirection(); + setup(); + } + + // has to setup localProblems_ + virtual void build() = 0; + + 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() { + if (mode_ == ADDITIVE) + iterateAdd(); + else + iterateMult(); + } + + 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(); + } + +private: + 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; + } + } + + void iterateAdd() { + //*(this->x_) = 0; + + 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; + } + } + + void iterateMult() { + if (multDirection_ != BACKWARD) { + for (size_t i=0; i<localProblems_.size(); i++) + iterateStep(i); + } + + if (multDirection_ != Direction::FORWARD) + for (size_t i=localProblems_.size()-1; i>=0 && i<localProblems_.size(); i--) + iterateStep(i); + } + + void iterateStep(size_t i) { + //*(this->x_) = 0; + + auto& localProblem = *localProblems_[i]; + + VectorType v, v1, v2, v3; + localProblem.restrict(*(this->x_), v); + + 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); + + VectorType x; + localProblem.solve(x); + v += x; + + 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; + } +}; + +#endif + diff --git a/dune/faultnetworks/preconditioners/multilevelpatchpreconditioner.hh b/dune/faultnetworks/preconditioners/multilevelpatchpreconditioner.hh index e4bf038e631ba11dc8f103e985b782ead0f786b6..2f12d043cca61bef96032619c7d7be320341b462 100644 --- a/dune/faultnetworks/preconditioners/multilevelpatchpreconditioner.hh +++ b/dune/faultnetworks/preconditioners/multilevelpatchpreconditioner.hh @@ -10,6 +10,9 @@ #include <dune/solvers/iterationsteps/lineariterationstep.hh> +#include <dune/matrix-vector/genericvectortools.hh> +#include <dune/matrix-vector/resize.hh> + #include <dune/faultnetworks/preconditioners/levelglobalpreconditioner.hh> #include <dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh> #include <dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh> @@ -45,19 +48,24 @@ private: using MultDirection = typename LevelPatchPreconditionerType::Direction; MultDirection multDirection_; - int itCounter_; std::shared_ptr<LevelGlobalPreconditionerType> coarseGlobalPreconditioner_; std::vector<std::shared_ptr<LevelPatchPreconditionerType>> levelPatchPreconditioners_; - std::vector<VectorType> levelX_; - std::vector<VectorType> levelRhs_; std::shared_ptr<LevelInterfaceNetwork<GridView>> allFaultLevelInterfaceNetwork_; std::shared_ptr<BasisType> allFaultBasis_; + // data hierarchy + std::vector<std::shared_ptr<const MatrixType> > matrixHierarchy_; + std::vector<BitVector*> ignoreNodesHierarchy_; + std::vector<std::shared_ptr<VectorType> > xHierarchy_; + std::vector<VectorType> rhsHierarchy_; + std::vector<std::shared_ptr<DGMGTransfer<BasisType>>> mgTransfer_; + bool preprocessCalled_; + public: MultilevelPatchPreconditioner(const InterfaceNetwork<GridType>& interfaceNetwork, const BitVector& activeLevels, @@ -68,7 +76,8 @@ public: activeLevels_(activeLevels), localAssemblers_(localAssemblers), localInterfaceAssemblers_(localInterfaceAssemblers), - parset_(parset) + parset_(parset), + preprocessCalled_(false) { parseSettings(); @@ -77,14 +86,13 @@ public: assert(activeLevels.size() == localAssemblers_.size() && activeLevels.size() == localInterfaceAssemblers_.size()); - // init level fault preconditioners and multigrid transfer + // init level patch preconditioners levelPatchPreconditioners_.resize(0); - mgTransfer_.resize(0); for (size_t i=0; i<activeLevels_.size(); i++) { if (activeLevels_[i][0]) { // init global problem on coarsest level - const LevelInterfaceNetwork<GridView>& levelNetwork = interfaceNetwork.levelInterfaceNetwork(i); + const LevelInterfaceNetwork<GridView>& levelNetwork = interfaceNetwork_.levelInterfaceNetwork(i); coarseGlobalPreconditioner_ = std::make_shared<LevelGlobalPreconditionerType>(levelNetwork, *localAssemblers_[i], localInterfaceAssemblers_[i]); break; @@ -92,41 +100,93 @@ public: } auto maxLevel = setupLevelPreconditioners(); - - levelX_.resize(levelPatchPreconditioners_.size()+1); - levelRhs_.resize(levelPatchPreconditioners_.size()+1); - allFaultBasis_ = std::make_shared<BasisType>(interfaceNetwork_.levelInterfaceNetwork(maxLevel)); - // init multigrid transfer - for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { - mgTransfer_.push_back(std::make_shared<DGMGTransfer<BasisType>>(levelPatchPreconditioners_[i]->basis(), *allFaultBasis_)); - } - mgTransfer_.push_back(std::make_shared<DGMGTransfer<BasisType>>(coarseGlobalPreconditioner_->basis(), *allFaultBasis_)); - itCounter_ = 0; } + virtual ~MultilevelPatchPreconditioner() { + for (int i=0; i<int(ignoreNodesHierarchy_.size()-1); i++) { + if (ignoreNodesHierarchy_[i]) + delete(ignoreNodesHierarchy_[i]); + } + } + + virtual void setProblem(const MatrixType& mat,VectorType& x, const VectorType& rhs) { + LinearIterationStep<MatrixType, VectorType>::setProblem(mat, x, rhs); + + preprocessCalled_ = false; + } - virtual void setProblem(const MatrixType& mat, VectorType& x, const VectorType& rhs) { - this->x_ = &x; + void setRhs(const VectorType& rhs) { this->rhs_ = &rhs; - this->mat_ = Dune::stackobject_to_shared_ptr(mat); + rhsHierarchy_.back() = rhs; + } - for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { - mgTransfer_[i]->restrict(x, levelX_[i]); - mgTransfer_[i]->restrict(rhs, levelRhs_[i]); + virtual void preprocess() { + if (preprocessCalled_) + std::cout << "Warning: Preprocess has already been called without calling iterate afterwards!" << std::endl; + + preprocessCalled_ = true; + + const int numLevels = levelPatchPreconditioners_.size()+1; - levelPatchPreconditioners_[i]->setProblem(mat, levelX_[i], levelRhs_[i]); + // init transfer operators + mgTransfer_.resize(numLevels-1); + mgTransfer_[0] = std::make_shared<DGMGTransfer<BasisType>>(coarseGlobalPreconditioner_->basis(), levelPatchPreconditioners_[0]->basis()); + for (size_t i=1; i<mgTransfer_.size(); i++) { + mgTransfer_[i] = std::make_shared<DGMGTransfer<BasisType>>(levelPatchPreconditioners_[i-1]->basis(), levelPatchPreconditioners_[i]->basis()); } - size_t j = levelPatchPreconditioners_.size(); - mgTransfer_[j]->restrict(x, levelX_[j]); - mgTransfer_[j]->restrict(rhs, levelRhs_[j]); + // resize hierarchy containers to number of levels + xHierarchy_.resize(numLevels); + rhsHierarchy_.resize(numLevels); + matrixHierarchy_.resize(numLevels); + ignoreNodesHierarchy_.resize(numLevels); + + for (int i=0; i<numLevels-1; i++) { + matrixHierarchy_[i].reset(); + xHierarchy_[i].reset(); + ignoreNodesHierarchy_[i] = NULL; + } + + matrixHierarchy_.back() = this->mat_; + xHierarchy_.back() = Dune::stackobject_to_shared_ptr(*(this->x_)); + rhsHierarchy_.back() = *(this->rhs_); + + // assemble hierarchy of matrices + for (int i=numLevels-2; i>=0; i--) { + matrixHierarchy_[i] = std::shared_ptr<MatrixType>(new MatrixType); + xHierarchy_[i] = std::shared_ptr<VectorType>(new VectorType); + + mgTransfer_[i]->galerkinRestrictSetOccupation(*matrixHierarchy_[i+1], *std::const_pointer_cast<MatrixType>(matrixHierarchy_[i])); + mgTransfer_[i]->galerkinRestrict(*matrixHierarchy_[i+1], *std::const_pointer_cast<MatrixType>(matrixHierarchy_[i])); + + // Set solution vector sizes for the lower levels + Dune::MatrixVector::resize(*xHierarchy_[i], *matrixHierarchy_[i]); + } + + // set dirichlet bitfields + if (this->ignoreNodes_!=0) { + ignoreNodesHierarchy_[numLevels-1] = const_cast<BitVector*>(this->ignoreNodes_); - coarseGlobalPreconditioner_->setProblem(mat, levelX_[j], levelRhs_[j]); + for (int i=numLevels-2; i>=0; --i) { + ignoreNodesHierarchy_[i] = new BitVector(); + mgTransfer_[i]->restrictToFathers(*ignoreNodesHierarchy_[i+1], *ignoreNodesHierarchy_[i]); + } + } else + DUNE_THROW(SolverError, "We need a set of nodes to ignore"); + + coarseGlobalPreconditioner_->setProblem(*matrixHierarchy_[0], *xHierarchy_[0], rhsHierarchy_[0]); + coarseGlobalPreconditioner_->preprocess(); + + for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { + levelPatchPreconditioners_[i]->setProblem(*matrixHierarchy_[i+1], *xHierarchy_[i+1], rhsHierarchy_[i+1]); + levelPatchPreconditioners_[i]->preprocess(); + } } + virtual void iterate() { if (mode_ == Mode::ADDITIVE) iterateAdd(); @@ -134,14 +194,6 @@ public: iterateMult(); } - void build() { - coarseGlobalPreconditioner_->build(); - - for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { - levelPatchPreconditioners_[i]->build(); - } - } - std::shared_ptr<LevelPatchPreconditionerType> levelPatchPreconditioner(const int level) { return levelPatchPreconditioners_[level]; } @@ -178,32 +230,31 @@ private: } void iterateAdd() { - VectorType x; + *(this->x_) = 0; + + for (int i=mgTransfer_.size()-1; i>=0; i--) { + *xHierarchy_[i] = 0; + mgTransfer_[i]->restrict(rhsHierarchy_[i+1], rhsHierarchy_[i]); + } + + // coarseGlobalPreconditioner_->setProblem(*matrixHierarchy_[0], *xHierarchy_[0], rhsHierarchy_[0]); + coarseGlobalPreconditioner_->iterate(); for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { + // levelPatchPreconditioners_[i]->setProblem(*matrixHierarchy_[i+1], *xHierarchy_[i+1], rhsHierarchy_[i+1]); levelPatchPreconditioners_[i]->iterate(); - const VectorType& it = levelPatchPreconditioners_[i]->getSol(); - - mgTransfer_[i]->prolong(it, x); - //writeToVTK(*allFaultBasis_, x, "/home/mi/podlesny/data/faultnetworks/sol/", "preconditioner_step_"+std::to_string(i)); + VectorType x(xHierarchy_[i+1]->size()); + mgTransfer_[i]->prolong(*xHierarchy_[i], x); - *(this->x_) += x; + *xHierarchy_[i+1] += x; } - - coarseGlobalPreconditioner_->iterate(); - const VectorType& it = coarseGlobalPreconditioner_->getSol(); - - mgTransfer_[levelPatchPreconditioners_.size()]->prolong(it, x); - *(this->x_) += x; } void iterateMult() { - if (multDirection_ != MultDirection::FORWARD) - for (size_t i=levelPatchPreconditioners_.size()-1; i>=0 && i<levelPatchPreconditioners_.size(); i--) - iterateStep(i, MultDirection::BACKWARD); +/* size_t j = levelPatchPreconditioners_.size(); mgTransfer_[j]->restrict(*(this->x_), levelX_[j]); @@ -232,31 +283,82 @@ private: } itCounter_++; + + preprocessCalled_ = false; + + if (multDirection_ != MultDirection::FORWARD) + for (size_t i=levelPatchPreconditioners_.size()-1; i>=0 && i<levelPatchPreconditioners_.size(); i--) + iterateStep(i, MultDirection::BACKWARD); + + //presmoother_[level]->setProblem(*(this->matrixHierarchy_[level]), *x[level], rhs[level]); + //presmoother_[level]->ignoreNodes_ = ignoreNodesHierarchy_[level]; + + // restriction + + // compute residual + /* // fineResidual = rhs[level] - mat[level] * x[level]; + VectorType fineResidual = rhs[level]; + mat[level]->mmv(*x[level], fineResidual); + + // restrict residual + this->mgTransfer_[level-1]->restrict(fineResidual, rhs[level-1]); + + + // Set Dirichlet values. + MatrixVector::Generic::truncate(rhs[level-1], *ignoreNodesHierarchy_[level-1]); + + // Choose all zeros as the initial correction + *x[level-1] = 0; + + // /////////////////////////////////////// + // Recursively solve the coarser system + level--; + for (int i=0; i<mu_; i++) + iterate(); + level++; + + // //////////////////////////////////////// + // Prolong + + // add correction to the presmoothed solution + VectorType tmp; + this->mgTransfer_[level-1]->prolong(*x[level-1], tmp); + *x[level] += tmp; + } + + // Postsmoothing + postsmoother_[level]->setProblem(*(mat[level]), *x[level], rhs[level]); + postsmoother_[level]->ignoreNodes_ = ignoreNodesHierarchy_[level]; */ } - void iterateStep(const size_t i, const MultDirection dir) { - //mgTransfer_[i]->restrict(*(this->x_), levelX_[i]); + void iterateStep(const size_t level, const MultDirection dir) { + /* levelPatchPreconditioners_[level]->setProblem(*matrixHierarchy_[level], *xHierarchy_[level], rhsHierarchy_[level]); + levelPatchPreconditioners_[level]->ignoreNodes_ = ignoreNodesHierarchy_[level]; + levelPatchPreconditioners_[level]->setDirection(dir); - VectorType residual = *(this->rhs_); - Dune::MatrixVector::subtractProduct(residual, *(this->mat_), *(this->x_)); + // compute residual + // fineResidual = rhs[level] - mat[level] * x[level]; + VectorType fineResidual = rhsHierarchy_[level]; + matrixHierarchy_[level]->mmv(*xHierarchy_[level], fineResidual); - VectorType localResidual; - mgTransfer_[i]->restrict(residual, localResidual); - //print(levelRhs_[i], "levelLocalCoarseRhs: "); - //writeToVTK(levelPatchPreconditioners_[i]->basis(), levelRhs_[i], "/storage/mi/podlesny/data/faultnetworks/rhs/fine", "exactvertexdata_step_"+std::to_string(itCounter_)); + // restrict residual + mgTransfer_[level-1]->restrict(fineResidual, rhsHierarchy_[level-1]); + + // set dirichlet values + Dune::MatrixVector::Generic::truncate(rhs[level-1], *ignoreNodesHierarchy_[level-1]); + // initial correction + *xHierarchy_[level-1] = 0; - levelPatchPreconditioners_[i]->setProblem(*(this->mat_), levelX_[i], localResidual); - levelPatchPreconditioners_[i]->setDirection(dir); - levelPatchPreconditioners_[i]->iterate(); - const VectorType& it = levelPatchPreconditioners_[i]->getSol(); + levelPatchPreconditioners_[level]->iterate(); + const VectorType& it = levelPatchPreconditioners_[level]->getSol(); VectorType x; mgTransfer_[i]->prolong(it, x); *(this->x_) += x; - //writeToVTK(*allFaultBasis_, x, "/storage/mi/podlesny/data/faultnetworks/fineIterates/multilevel", "exactvertexdata_step_"+std::to_string(itCounter_)); + //writeToVTK(*allFaultBasis_, x, "/storage/mi/podlesny/data/faultnetworks/fineIterates/multilevel", "exactvertexdata_step_"+std::to_string(itCounter_)); */ } auto setupLevelPreconditioners() { diff --git a/dune/faultnetworks/preconditioners/multilevelpatchpreconditioner_working.hh b/dune/faultnetworks/preconditioners/multilevelpatchpreconditioner_working.hh new file mode 100644 index 0000000000000000000000000000000000000000..e4bf038e631ba11dc8f103e985b782ead0f786b6 --- /dev/null +++ b/dune/faultnetworks/preconditioners/multilevelpatchpreconditioner_working.hh @@ -0,0 +1,337 @@ +#ifndef MULTILEVEL_PATCH_PRECONDITIONER_HH +#define MULTILEVEL_PATCH_PRECONDITIONER_HH + +#include <string> + +#include <dune/common/timer.hh> +#include <dune/common/fvector.hh> +#include <dune/common/bitsetvector.hh> +#include <dune/common/parametertree.hh> + +#include <dune/solvers/iterationsteps/lineariterationstep.hh> + +#include <dune/faultnetworks/preconditioners/levelglobalpreconditioner.hh> +#include <dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh> +#include <dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh> +#include <dune/faultnetworks/preconditioners/supportpatchpreconditioner.hh> +#include <dune/faultnetworks/levelinterfacenetwork.hh> +#include <dune/faultnetworks/interfacenetwork.hh> +#include <dune/faultnetworks/dgmgtransfer.hh> + +#include <dune/faultnetworks/utils/debugutils.hh> + +template <class BasisType, class LocalOperatorAssembler, class LocalInterfaceAssembler, class MatrixType, class VectorType> +class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorType> { + +public: + using LevelPatchPreconditionerType = LevelPatchPreconditioner<BasisType, LocalOperatorAssembler, LocalInterfaceAssembler, MatrixType, VectorType>; + using LevelGlobalPreconditionerType = LevelGlobalPreconditioner<BasisType, LocalOperatorAssembler, LocalInterfaceAssembler, MatrixType, VectorType>; + +private: + using GridView = typename BasisType::GridView; + using GridType = typename GridView::Grid ; + using BitVector = typename Dune::BitSetVector<1>; + + const InterfaceNetwork<GridType>& interfaceNetwork_; + const BitVector& activeLevels_; + const std::vector<std::shared_ptr<LocalOperatorAssembler>>& localAssemblers_; + const std::vector<std::vector<std::shared_ptr<LocalInterfaceAssembler>>>& localInterfaceAssemblers_; + + // preconditioner parset settings + const Dune::ParameterTree& parset_; + using Mode = typename LevelPatchPreconditionerType::Mode; + Mode mode_; + + using MultDirection = typename LevelPatchPreconditionerType::Direction; + MultDirection multDirection_; + + + int itCounter_; + + std::shared_ptr<LevelGlobalPreconditionerType> coarseGlobalPreconditioner_; + std::vector<std::shared_ptr<LevelPatchPreconditionerType>> levelPatchPreconditioners_; + std::vector<VectorType> levelX_; + std::vector<VectorType> levelRhs_; + + std::shared_ptr<LevelInterfaceNetwork<GridView>> allFaultLevelInterfaceNetwork_; + std::shared_ptr<BasisType> allFaultBasis_; + + std::vector<std::shared_ptr<DGMGTransfer<BasisType>>> mgTransfer_; + +public: + MultilevelPatchPreconditioner(const InterfaceNetwork<GridType>& interfaceNetwork, + const BitVector& activeLevels, + const std::vector<std::shared_ptr<LocalOperatorAssembler>>& localAssemblers, + const std::vector<std::vector<std::shared_ptr<LocalInterfaceAssembler>>>& localInterfaceAssemblers, + const Dune::ParameterTree& parset) : + interfaceNetwork_(interfaceNetwork), + activeLevels_(activeLevels), + localAssemblers_(localAssemblers), + localInterfaceAssemblers_(localInterfaceAssemblers), + parset_(parset) + { + parseSettings(); + + if (activeLevels_.size() > (size_t) interfaceNetwork.maxLevel() +1) + DUNE_THROW(Dune::Exception, "MultilevelFaultPreconditioner: too many active levels; preconditioner supports at most (grid.maxLevel + 1) levels!"); + + assert(activeLevels.size() == localAssemblers_.size() && activeLevels.size() == localInterfaceAssemblers_.size()); + + // init level fault preconditioners and multigrid transfer + levelPatchPreconditioners_.resize(0); + mgTransfer_.resize(0); + + for (size_t i=0; i<activeLevels_.size(); i++) { + if (activeLevels_[i][0]) { + // init global problem on coarsest level + const LevelInterfaceNetwork<GridView>& levelNetwork = interfaceNetwork.levelInterfaceNetwork(i); + coarseGlobalPreconditioner_ = std::make_shared<LevelGlobalPreconditionerType>(levelNetwork, *localAssemblers_[i], localInterfaceAssemblers_[i]); + + break; + } + } + + auto maxLevel = setupLevelPreconditioners(); + + levelX_.resize(levelPatchPreconditioners_.size()+1); + levelRhs_.resize(levelPatchPreconditioners_.size()+1); + + allFaultBasis_ = std::make_shared<BasisType>(interfaceNetwork_.levelInterfaceNetwork(maxLevel)); + + // init multigrid transfer + for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { + mgTransfer_.push_back(std::make_shared<DGMGTransfer<BasisType>>(levelPatchPreconditioners_[i]->basis(), *allFaultBasis_)); + } + mgTransfer_.push_back(std::make_shared<DGMGTransfer<BasisType>>(coarseGlobalPreconditioner_->basis(), *allFaultBasis_)); + + itCounter_ = 0; + } + + + 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<levelPatchPreconditioners_.size(); i++) { + mgTransfer_[i]->restrict(x, levelX_[i]); + mgTransfer_[i]->restrict(rhs, levelRhs_[i]); + + levelPatchPreconditioners_[i]->setProblem(mat, levelX_[i], levelRhs_[i]); + } + + size_t j = levelPatchPreconditioners_.size(); + mgTransfer_[j]->restrict(x, levelX_[j]); + mgTransfer_[j]->restrict(rhs, levelRhs_[j]); + + coarseGlobalPreconditioner_->setProblem(mat, levelX_[j], levelRhs_[j]); + } + + virtual void iterate() { + if (mode_ == Mode::ADDITIVE) + iterateAdd(); + else + iterateMult(); + } + + void build() { + coarseGlobalPreconditioner_->build(); + + for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { + levelPatchPreconditioners_[i]->build(); + } + } + + std::shared_ptr<LevelPatchPreconditionerType> levelPatchPreconditioner(const int level) { + return levelPatchPreconditioners_[level]; + } + + const BasisType& basis() const { + return *allFaultBasis_; + } + + size_t size() const { + return levelPatchPreconditioners_.size()+1; + } + +private: + void parseSettings() { + const auto mode = parset_.get<std::string>("mode"); + if (mode == "ADDITIVE") { + mode_ = Mode::ADDITIVE; + } else if (mode == "MULTIPLICATIVE") { + mode_ = Mode::MULTIPLICATIVE; + } else { + DUNE_THROW(Dune::Exception, "MultilevelFaultPreconditioner::parseSettings unknown mode! Possible options: ADDITIVE , MULTIPLICATIVE"); + } + + auto multDirection = parset_.get<std::string>("multDirection"); + if (multDirection == "FORWARD") { + multDirection_ = MultDirection::FORWARD; + } else if (multDirection == "BACKWARD") { + multDirection_ = MultDirection::BACKWARD; + } else if (multDirection == "SYMMETRIC") { + multDirection_ = MultDirection::SYMMETRIC; + } else { + DUNE_THROW(Dune::Exception, "MultilevelFaultPreconditioner::parseSettings unknown multDirection! Possible options: FORWARD , BACKWARD, SYMMETRIC"); + } + } + + void iterateAdd() { + VectorType x; + + for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { + levelPatchPreconditioners_[i]->iterate(); + const VectorType& it = levelPatchPreconditioners_[i]->getSol(); + + mgTransfer_[i]->prolong(it, x); + + //writeToVTK(*allFaultBasis_, x, "/home/mi/podlesny/data/faultnetworks/sol/", "preconditioner_step_"+std::to_string(i)); + + *(this->x_) += x; + } + + coarseGlobalPreconditioner_->iterate(); + const VectorType& it = coarseGlobalPreconditioner_->getSol(); + + mgTransfer_[levelPatchPreconditioners_.size()]->prolong(it, x); + *(this->x_) += x; + } + + + void iterateMult() { + + if (multDirection_ != MultDirection::FORWARD) + for (size_t i=levelPatchPreconditioners_.size()-1; i>=0 && i<levelPatchPreconditioners_.size(); i--) + iterateStep(i, MultDirection::BACKWARD); + + size_t j = levelPatchPreconditioners_.size(); + mgTransfer_[j]->restrict(*(this->x_), levelX_[j]); + + //print(levelRhs_[j], "localCoarseRhs: "); + //writeToVTK(coarseGlobalPreconditioner_->basis(), levelRhs_[j], "/storage/mi/podlesny/data/faultnetworks/rhs/coarse", "exactvertexdata_step_"+std::to_string(itCounter_)); + + VectorType residual = *(this->rhs_); + Dune::MatrixVector::subtractProduct(residual, *(this->mat_), *(this->x_)); + + VectorType localResidual; + mgTransfer_[j]->restrict(residual, localResidual); + + coarseGlobalPreconditioner_->setProblem(*(this->mat_), levelX_[j], localResidual); + coarseGlobalPreconditioner_->iterate(); + const VectorType& it = coarseGlobalPreconditioner_->getSol(); + + VectorType x; + mgTransfer_[j]->prolong(it, x); + *(this->x_) += x; + //writeToVTK(*allFaultBasis_, x, "/storage/mi/podlesny/data/faultnetworks/coarseIterates/multilevel", "exactvertexdata_step_"+std::to_string(itCounter_)); + + if (multDirection_ != MultDirection::BACKWARD) { + for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) + iterateStep(i, MultDirection::FORWARD); + } + + itCounter_++; + } + + void iterateStep(const size_t i, const MultDirection dir) { + //mgTransfer_[i]->restrict(*(this->x_), levelX_[i]); + + VectorType residual = *(this->rhs_); + Dune::MatrixVector::subtractProduct(residual, *(this->mat_), *(this->x_)); + + VectorType localResidual; + mgTransfer_[i]->restrict(residual, localResidual); + //print(levelRhs_[i], "levelLocalCoarseRhs: "); + //writeToVTK(levelPatchPreconditioners_[i]->basis(), levelRhs_[i], "/storage/mi/podlesny/data/faultnetworks/rhs/fine", "exactvertexdata_step_"+std::to_string(itCounter_)); + + + levelPatchPreconditioners_[i]->setProblem(*(this->mat_), levelX_[i], localResidual); + + levelPatchPreconditioners_[i]->setDirection(dir); + levelPatchPreconditioners_[i]->iterate(); + const VectorType& it = levelPatchPreconditioners_[i]->getSol(); + + VectorType x; + mgTransfer_[i]->prolong(it, x); + *(this->x_) += x; + + //writeToVTK(*allFaultBasis_, x, "/storage/mi/podlesny/data/faultnetworks/fineIterates/multilevel", "exactvertexdata_step_"+std::to_string(itCounter_)); + } + + auto setupLevelPreconditioners() { + const auto preconditionerType = parset_.get<std::string>("patch"); + if (preconditionerType == "CELL") { + return setupCellPreconditioner(); + } else if (preconditionerType == "SUPPORT") { + return setupSupportPreconditioner(); + } else { + DUNE_THROW(Dune::Exception, "MultilevelFaultPreconditioner: unknown levelpatchpreconditioner type! Possible options: CELL , SUPPORT"); + } + } + + auto setupCellPreconditioner() { + using CellPreconditioner = CellPatchPreconditioner<BasisType, LocalOperatorAssembler, LocalInterfaceAssembler, MatrixType, VectorType>; + + int maxLevel = 0; + + bool skip = true; + for (size_t i=0; i<activeLevels_.size(); i++) { + if (activeLevels_[i][0] && skip) { + skip = false; + continue; + } + + if (activeLevels_[i][0]) { + const LevelInterfaceNetwork<GridView>& levelNetwork = interfaceNetwork_.levelInterfaceNetwork(i); + + if (levelPatchPreconditioners_.size() == 0) { + levelPatchPreconditioners_.push_back(std::make_shared<CellPreconditioner>(levelNetwork, coarseGlobalPreconditioner_->basis(), *localAssemblers_[i], localInterfaceAssemblers_[i], mode_)); + } else { + levelPatchPreconditioners_.push_back(std::make_shared<CellPreconditioner>(levelNetwork, levelPatchPreconditioners_.back()->basis(), *localAssemblers_[i], localInterfaceAssemblers_[i], mode_)); + levelPatchPreconditioners_.back()->setBoundaryMode(LevelPatchPreconditionerType::BoundaryMode::homogeneous); + } + + maxLevel = i; + } + } + + return maxLevel; + } + + auto setupSupportPreconditioner() { + using SupportPreconditioner = SupportPatchPreconditioner<BasisType, LocalOperatorAssembler, LocalInterfaceAssembler, MatrixType, VectorType>; + + const auto patchDepth = parset_.get<size_t>("patchDepth"); + + int maxLevel = 0; + + bool skip = true; + for (size_t i=0; i<activeLevels_.size(); i++) { + if (skip && activeLevels_[i][0]) { + skip = false; + continue; + } + + if (activeLevels_[i][0]) { + // init local patch preconditioners on each level + const LevelInterfaceNetwork<GridView>& levelNetwork = interfaceNetwork_.levelInterfaceNetwork(i); + + if (levelPatchPreconditioners_.size() == 0) { + levelPatchPreconditioners_.push_back(std::make_shared<SupportPreconditioner>(levelNetwork, coarseGlobalPreconditioner_->basis(), *localAssemblers_[i], localInterfaceAssemblers_[i], mode_)); + } else { + levelPatchPreconditioners_.push_back(std::make_shared<SupportPreconditioner>(levelNetwork, levelPatchPreconditioners_.back()->basis(), *localAssemblers_[i], localInterfaceAssemblers_[i], mode_)); + levelPatchPreconditioners_.back()->setPatchDepth(patchDepth); + levelPatchPreconditioners_.back()->setBoundaryMode(LevelPatchPreconditionerType::BoundaryMode::homogeneous); + } + + maxLevel = i; + } + } + + return maxLevel; + } +}; + +#endif + diff --git a/dune/faultnetworks/preconditioners/supportpatchpreconditioner.hh b/dune/faultnetworks/preconditioners/supportpatchpreconditioner.hh index 68f544cabfcd176529da1164c9b1749f4a74389e..dc4064e81981890575975847ab157993829b3c0f 100644 --- a/dune/faultnetworks/preconditioners/supportpatchpreconditioner.hh +++ b/dune/faultnetworks/preconditioners/supportpatchpreconditioner.hh @@ -26,7 +26,7 @@ public: Base(levelInterfaceNetwork, patchLevelBasis, localAssembler, localInterfaceAssemblers, mode) {} - void build() { + void preprocess() { // init vertexInElements const int dim = GridType::dimension; using Element = typename GridType::template Codim<0>::Entity; @@ -60,11 +60,11 @@ public: const auto& boundaryDofs = patchFactory.getBoundaryDofs(); VectorType rhs; - rhs.resize(this->matrix_.N()); + rhs.resize(this->mat_->N()); rhs = 0; using LocalProblemType = typename std::remove_reference<decltype(*(this->localProblems_[i]))>::type; - this->localProblems_[i] = std::make_shared<LocalProblemType>(this->matrix_, rhs, localToGlobal, boundaryDofs); + this->localProblems_[i] = std::make_shared<LocalProblemType>(*this->mat_, rhs, localToGlobal, boundaryDofs); } } }; diff --git a/src/cantorfaultnetworks/cantorfaultnetwork.cc b/src/cantorfaultnetworks/cantorfaultnetwork.cc index e2ed377d029c7229d6f8ff5125a8c3b088b26ecf..90a9b2b9a97e37b4e5e625b4c1311e15ab5fc85d 100644 --- a/src/cantorfaultnetworks/cantorfaultnetwork.cc +++ b/src/cantorfaultnetworks/cantorfaultnetwork.cc @@ -317,7 +317,6 @@ int main(int argc, char** argv) { try levelFaultPreconditioner.setPatchDepth(patchDepth); levelFaultPreconditioner.setBoundaryMode(LevelPatchPreconditioner::BoundaryMode::homogeneous); }*/ - preconditioner.build(); std::cout << "Setup complete, starting preconditioned cg iteration!" << std::endl; std::cout << std::endl << std::endl; diff --git a/src/cantorfaultnetworks/cantorfaultnetwork.parset b/src/cantorfaultnetworks/cantorfaultnetwork.parset index fe8182cf83ad0868dc2354c936de20b271a04bac..0af54c6260ea293ff2e6e68bb3eb56d8c2c31744 100644 --- a/src/cantorfaultnetworks/cantorfaultnetwork.parset +++ b/src/cantorfaultnetworks/cantorfaultnetwork.parset @@ -3,19 +3,19 @@ resultPath = ../cantorfaultnetworks/results/ [preconditioner] patch = SUPPORT # CELL , SUPPORT -mode = MULTIPLICATIVE # ADDITIVE , MULTIPLICATIVE +mode = ADDITIVE # ADDITIVE , MULTIPLICATIVE multDirection = SYMMETRIC # SYMMETRIC , FORWARD , BACKWARD patchDepth = 1 ########################################### [problem0] -oscDataFile = oscDataLaplace32.mat +oscDataFile = oscDataLaplace16.mat # level resolution in 2^(-...) -coarseResolution = 0 -fineResolution = 5 -exactResolution = 8 +coarseResolution = 3 +fineResolution = 4 +exactResolution = 5 minCantorResolution = 0 penaltyFactor = 1 diff --git a/src/cantorfaultnetworks/results/sparse/compare.txt b/src/cantorfaultnetworks/results/sparse/compare.txt new file mode 100644 index 0000000000000000000000000000000000000000..7202b5a59ffa6ce289ec4968d8f27b4d49415495 --- /dev/null +++ b/src/cantorfaultnetworks/results/sparse/compare.txt @@ -0,0 +1,114 @@ +[problem0] + +local Cantor-type network + +coarseCantorLevel = 1 +fineCantorLevel = 2 +maxCantorLevel = 3 + +grid resolutions: 4^{-k}, k = 1, 2, 3 + +K = 2 (fineCantorLevel) +iterate in step \nu: u_K^{(\nu)} +exact solutions: u_{K+1}, u_{K} + +in iteration step \nu: +---------------------- +discError: || u_{K+1} - u_{K}^{(\nu)} || / || u_{K+1} - u_{K}^{(*)} ||, where u_{K}^{(*)} is initial iterate given by u_{K-1} +rate: \rho^{(\nu)} = || u_K - u_K^{(\nu)} || / || u_K - u_K^{(\nu-1)} || +criterion: || u_{K} - u_{K}^{(\nu)} || \leq || u_{K+1} - u_{K} || + +totalConvRate in step \nu: \delta^{(\nu)} = (\Pi_{i=0}^{\nu} \rho^{(i)})^{1/ \nu} + +maxTotalConvRate: max{\delta^{(\nu)} : 0 \leq \nu \leq 7} +totalConvRate: \delta^{(7)} + + +2-level methods: + + +-------------------------------------------------------------------------------------- +[preconditioner] +patch = SUPPORT +mode = ADDITIVE +patchDepth = 1 + +--- CGSolver --- + iter discError rate criterion +---------------------------------------- + 0 4.4748610e-01 0.38363 0 + 1 2.6385601e-01 0.23138 1 + 2 2.5082680e-01 0.30402 1 + 3 2.4957306e-01 0.28518 1 + 4 2.4947130e-01 0.29271 1 + 5 2.4946257e-01 0.29074 1 + 6 2.4946183e-01 0.29931 1 + 7 2.4946177e-01 0.25816 1 +maxTotalConvRate: 0.3836291, totalConvRate: 0.2904196, 8 iterations performed +-------------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------------- +[preconditioner] +patch = SUPPORT +mode = MULTIPLICATIVE +multDirection = SYMMETRIC + +--- CGSolver --- + iter discError rate criterion +---------------------------------------- + 0 2.6563220e-01 0.09424 1 + 1 2.4973859e-01 0.12881 1 + 2 2.4947325e-01 0.20368 1 + 3 2.4946253e-01 0.25855 1 + 4 2.4946184e-01 0.32400 1 + 5 2.4946177e-01 0.37774 1 + 6 2.4946176e-01 0.42970 1 + 7 2.4946176e-01 0.47934 1 +maxTotalConvRate: 0.2517121, totalConvRate: 0.2517121, 8 iterations performed +-------------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------------- +[preconditioner] +patch = CELL +mode = ADDITIVE +patchDepth = 1 + +--- CGSolver --- + iter discError rate criterion +---------------------------------------- + 0 3.6789829e-01 0.27923 0 + 1 2.9049278e-01 0.55046 1 + 2 2.6631671e-01 0.62641 1 + 3 2.5254058e-01 0.42165 1 + 4 2.5012727e-01 0.46381 1 + 5 2.4953864e-01 0.33968 1 + 6 2.4948824e-01 0.58679 1 + 7 2.4946635e-01 0.41623 1 +maxTotalConvRate: 0.4583344, totalConvRate: 0.4458779, 8 iterations performed +-------------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------------- +[preconditioner] +patch = CELL +mode = MULTIPLICATIVE +multDirection = SYMMETRIC + +--- CGSolver --- + iter discError rate criterion +---------------------------------------- + 0 2.8217734e-01 0.13619 1 + 1 2.5034252e-01 0.15909 1 + 2 2.4948254e-01 0.15347 1 + 3 2.4946213e-01 0.13378 1 + 4 2.4946178e-01 0.19682 1 + 5 2.4946176e-01 0.10302 1 + 6 2.4946176e-01 0.13350 1 + 7 2.4946176e-01 0.15741 1 +maxTotalConvRate: 0.1543307, totalConvRate: 0.1444492, 8 iterations performed +-------------------------------------------------------------------------------------- diff --git a/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc b/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc index 8c1da5ba1b467ba14f6d0460745484a40cfd8bf9..8e7ece9cb6a1510149ae0cbab36b8f078e6b83d9 100644 --- a/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc +++ b/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc @@ -314,7 +314,6 @@ int main(int argc, char** argv) { try levelFaultPreconditioner.setPatchDepth(patchDepth); levelFaultPreconditioner.setBoundaryMode(LevelPatchPreconditioner::BoundaryMode::homogeneous); }*/ - preconditioner.build(); std::cout << "Setup complete, starting preconditioned cg iteration!" << std::endl; std::cout << std::endl << std::endl; diff --git a/src/cantorfaultnetworks/sparsecantorfaultnetwork.parset b/src/cantorfaultnetworks/sparsecantorfaultnetwork.parset index 456c5bfc2935601ddc4e07e80fd4070fd2f9aff7..95857a7b236331928f4af765f5326e537a5e5d01 100644 --- a/src/cantorfaultnetworks/sparsecantorfaultnetwork.parset +++ b/src/cantorfaultnetworks/sparsecantorfaultnetwork.parset @@ -3,7 +3,7 @@ resultPath = ../cantorfaultnetworks/results/sparse/ [preconditioner] patch = SUPPORT # CELL , SUPPORT -mode = MULTIPLICATIVE # ADDITIVE , MULTIPLICATIVE +mode = ADDITIVE # ADDITIVE , MULTIPLICATIVE multDirection = SYMMETRIC # SYMMETRIC , FORWARD , BACKWARD patchDepth = 1 diff --git a/src/geofaultnetworks/geofaultnetwork.cc b/src/geofaultnetworks/geofaultnetwork.cc index ddad719dd1e090bb824d67e40fcd2e11c6d71755..03f1b84e7debcfbbaf6007cb68450f3e9878d159 100644 --- a/src/geofaultnetworks/geofaultnetwork.cc +++ b/src/geofaultnetworks/geofaultnetwork.cc @@ -350,7 +350,6 @@ int main(int argc, char** argv) { try levelFaultPreconditioner.setPatchDepth(patchDepth); levelFaultPreconditioner.setBoundaryMode(LevelPatchPreconditioner::BoundaryMode::homogeneous); }*/ - preconditioner.build(); std::cout << "Setup complete, starting preconditioned cg iteration!" << std::endl; std::cout << std::endl << std::endl; diff --git a/src/geofaultnetworks/rockfaultnetwork.cc b/src/geofaultnetworks/rockfaultnetwork.cc index cf0c2c3f91d020daeff3d5a0f66e42caf5d847f5..777b2e11cbfbb32089f955dfd0dee024c8fbd301 100644 --- a/src/geofaultnetworks/rockfaultnetwork.cc +++ b/src/geofaultnetworks/rockfaultnetwork.cc @@ -324,7 +324,6 @@ int main(int argc, char** argv) { try levelFaultPreconditioner.setPatchDepth(patchDepth); levelFaultPreconditioner.setBoundaryMode(LevelPatchPreconditioner::BoundaryMode::homogeneous); }*/ - preconditioner.build(); std::cout << "Setup complete, starting preconditioned cg iteration!" << std::endl; std::cout << std::endl << std::endl; diff --git a/src/geofaultnetworks/rockfaultnetwork.parset b/src/geofaultnetworks/rockfaultnetwork.parset index a977724af639b1d266215f4e4b1775f592515c43..7c93947185ff266288b8af4fd7ef2ce274843c89 100644 --- a/src/geofaultnetworks/rockfaultnetwork.parset +++ b/src/geofaultnetworks/rockfaultnetwork.parset @@ -17,9 +17,9 @@ patchDepth = 1 oscDataFile = oscDataLaplace4.mat # level resolution in 2^(-...) -coarseResolution = 5 -fineResolution = 8 -exactResolution = 9 +coarseResolution = 3 +fineResolution = 4 +exactResolution = 5 penaltyFactor = 1