From 50340c30dbc217205f93392d64b1bcc6c0368e68 Mon Sep 17 00:00:00 2001 From: podlesny <podlesny@zedat.fu-berlin.de> Date: Sun, 31 May 2020 17:13:53 +0200 Subject: [PATCH] . --- .../patchfactories/cellpatchfactory.hh | 6 +- .../patchfactories/supportpatchfactory.hh | 24 +-- .../preconditioners/CMakeLists.txt | 4 + .../cellpatchpreconditioner.hh | 43 ++++ .../levelpatchpreconditioner.hh | 190 ++++++------------ .../supportpatchpreconditioner.hh | 70 +++++++ .../sparsecantorfaultnetwork.cc | 2 +- 7 files changed, 186 insertions(+), 153 deletions(-) create mode 100644 dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh create mode 100644 dune/faultnetworks/preconditioners/supportpatchpreconditioner.hh diff --git a/dune/faultnetworks/patchfactories/cellpatchfactory.hh b/dune/faultnetworks/patchfactories/cellpatchfactory.hh index 530c462..7b2379e 100644 --- a/dune/faultnetworks/patchfactories/cellpatchfactory.hh +++ b/dune/faultnetworks/patchfactories/cellpatchfactory.hh @@ -23,9 +23,7 @@ class CellPatchFactory typedef typename GridType::ctype ctype; static const int dim = GridType::dimension; typedef typename GridType::template Codim<0>::Entity Element; - typedef typename GridType::template Codim<dim>::Entity Vertex; - typedef HierarchicLevelIterator<GridType> HierarchicLevelIteratorType; typedef typename Dune::LevelMultipleCodimMultipleGeomTypeMapper<GridType, Dune::MCMGElementLayout > ElementMapper; private: @@ -42,13 +40,13 @@ class CellPatchFactory ElementMapper mapper; private: - void print(const Dune::BitSetVector<1>& x, std::string message){ + /*void print(const Dune::BitSetVector<1>& x, std::string message){ std::cout << message << std::endl; for (size_t i=0; i<x.size(); i++) { std::cout << x[i][0] << " "; } std::cout << std::endl << std::endl; - } + }*/ bool containsInsideSubentity(const Element& elem, const typename GridType::LevelIntersection& intersection, int subEntity, int codim) { return ReferenceElementHelper<double, dim>::subEntityContainsSubEntity(elem.type(), intersection.indexInInside(), 1, subEntity, codim); diff --git a/dune/faultnetworks/patchfactories/supportpatchfactory.hh b/dune/faultnetworks/patchfactories/supportpatchfactory.hh index 20754c0..07a297d 100644 --- a/dune/faultnetworks/patchfactories/supportpatchfactory.hh +++ b/dune/faultnetworks/patchfactories/supportpatchfactory.hh @@ -1,7 +1,8 @@ #ifndef SUPPORT_PATCH_FACTORY_HH #define SUPPORT_PATCH_FACTORY_HH -#include<queue> +#include <queue> +#include <set> #include <dune/common/bitsetvector.hh> #include <dune/common/fvector.hh> @@ -227,27 +228,6 @@ private: } } } - - /* add interior coarse level vertices to boundary dofs - for(int i=0; i<coarseGeometry.corners(); ++i) { - const auto& local = fineGeometry.local(coarseGeometry.corner(i)); - - if (!ref.checkInside(local)) - continue; - - const int localBasisSize = fineLFE.localBasis().size(); - std::vector<Dune::FieldVector<double, 1>, std::allocator<Dune::FieldVector<double, 1> > > localBasisRep(localBasisSize); - fineLFE.localBasis().evaluateFunction(local, localBasisRep); - - for(int k=0; k<localBasisSize; ++k) { - if (localBasisRep[k]==1) { - int dofIndex = fineBasis_.index(fineElem, k); - localBoundaryDofs.insert(dofIndex); - break; - } - } - } */ - } }; #endif diff --git a/dune/faultnetworks/preconditioners/CMakeLists.txt b/dune/faultnetworks/preconditioners/CMakeLists.txt index f427498..4063392 100644 --- a/dune/faultnetworks/preconditioners/CMakeLists.txt +++ b/dune/faultnetworks/preconditioners/CMakeLists.txt @@ -2,12 +2,16 @@ add_custom_target(faultnetworks_preconditioners_src SOURCES levelglobalpreconditioner.hh + cellpatchpreconditioner.hh + supportpatchpreconditioner.hh levelpatchpreconditioner.hh multilevelpatchpreconditioner.hh ) install(FILES levelglobalpreconditioner.hh + cellpatchpreconditioner.hh + supportpatchpreconditioner.hh levelpatchpreconditioner.hh multilevelpatchpreconditioner.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/faultnetworks/preconditioners) diff --git a/dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh b/dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh new file mode 100644 index 0000000..e938979 --- /dev/null +++ b/dune/faultnetworks/preconditioners/cellpatchpreconditioner.hh @@ -0,0 +1,43 @@ +#ifndef CELL_PATCH_PRECONDITIONER_HH +#define CELL_PATCH_PRECONDITIONER_HH + +#include <string> + +#include <dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh> +#include <dune/faultnetworks/patchfactories/cellpatchfactory.hh> + +template <class BasisType, class LocalAssembler, class LocalInterfaceAssembler, class MatrixType, class VectorType> +class CellPatchPreconditioner : public LevelPatchPreconditioner<BasisType, LocalAssembler, LocalInterfaceAssembler, MatrixType, VectorType> { +private: + using Base = LevelPatchPreconditioner<BasisType, LocalAssembler, LocalInterfaceAssembler, MatrixType, VectorType>; + using GridView = typename Base::GridView; + using Mode = typename Base::Mode; + +public: + CellPatchPreconditioner(const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork, + const LocalAssembler& localAssembler, + const std::vector<std::shared_ptr<LocalInterfaceAssembler>>& localInterfaceAssemblers, + const Mode mode = Mode::additive) : + Base(levelInterfaceNetwork, localAssembler, localInterfaceAssemblers, mode) {} + + void build() { + CellPatchFactory<BasisType> patchFactory(this->basis_, this->level_); + const auto& localToGlobal = patchFactory.getLocalToGlobal(); + const auto& boundaryDofs = patchFactory.getBoundaryDofs(); + + VectorType rhs; + rhs.resize(this->matrix_.N()); + rhs = 0; + + std::cout << "CellPatchPreconditioner::build() level: " << this->level_ << std::endl; + + size_t cellCount = localToGlobal.size(); + this->localProblems_.resize(cellCount); + for (size_t i=0; i<cellCount; i++) { + this->localProblems_[i] = std::make_shared<decltype(*(this->localProblems_[i]))>(this->matrix_, rhs, localToGlobal[i], boundaryDofs[i]); + } + } +}; + +#endif + diff --git a/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh b/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh index bbe464f..60a06a3 100644 --- a/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh +++ b/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh @@ -10,7 +10,6 @@ #include <dune/solvers/iterationsteps/lineariterationstep.hh> #include <dune/faultnetworks/assemblers/globalfaultassembler.hh> -#include <dune/faultnetworks/patchfactories/supportpatchfactory.hh> #include <dune/faultnetworks/localproblem.hh> #include <dune/faultnetworks/levelinterfacenetwork.hh> #include <dune/faultnetworks/utils/debugutils.hh> @@ -18,20 +17,19 @@ #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 Mode {ADDITIVE, MULTIPLICATIVE}; enum BoundaryMode {homogeneous, fromIterate}; + enum Direction {FORWARD, BACKWARD, SYMMETRIC}; private: 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_; @@ -46,30 +44,8 @@ private: MatrixType matrix_; std::vector<std::shared_ptr<OscLocalProblem<MatrixType, VectorType>> > localProblems_; -public: - - // for each coarse patch given by patchLevelBasis: set up local problem, compute local correction - 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_) - { - setPatchDepth(); - setBoundaryMode(); - - assert(localInterfaceAssemblers_.size() == levelInterfaceNetwork_.size()); - } - - void build() { +private: + void setup() { // assemble stiffness matrix for entire level including all faults GlobalFaultAssembler<BasisType, BasisType> globalFaultAssembler(basis_, basis_, levelInterfaceNetwork_); globalFaultAssembler.assembleOperator(localAssembler_, localInterfaceAssemblers_, matrix_); @@ -96,70 +72,31 @@ public: } row[i] = 1; } + } - // init vertexInElements - const int dim = GridType::dimension; - typedef typename GridType::template Codim<0>::Entity EntityType; - std::vector<std::vector<EntityType>> vertexInElements; - - const GridView& patchLevelGridView = patchLevelBasis_.getGridView(); - vertexInElements.resize(patchLevelGridView.size(dim)); - for (size_t i=0; i<vertexInElements.size(); i++) { - vertexInElements[i].resize(0); - } - - typedef typename BasisType::LocalFiniteElement FE; - typedef typename GridView::template Codim <0>::Iterator ElementLevelIterator; - ElementLevelIterator endElemIt = patchLevelGridView.template end <0>(); - for (ElementLevelIterator it = patchLevelGridView. template begin <0>(); it!=endElemIt; ++it) { - - // compute coarseGrid vertexInElements - const FE& coarseFE = patchLevelBasis_.getLocalFiniteElement(*it); - - for (size_t i=0; i<coarseFE.localBasis().size(); ++i) { - int dofIndex = patchLevelBasis_.indexInGridView(*it, i); - vertexInElements[dofIndex].push_back(*it); - } - } - - localProblems_.resize(vertexInElements.size()); - - std::cout << std::endl; - std::cout << "---------------------------------------------" << std::endl; - std::cout << "Initializing local fine grid corrections! Level: " << level_ << std::endl; - - // init local fine level corrections - Dune::Timer timer; - timer.reset(); - timer.start(); - - const int patchLevel = patchLevelBasis_.faultNetwork().level(); - for (size_t i=0; i<vertexInElements.size(); i++) { - //std::cout << i << std::endl; - //std::cout << "---------------" << std::endl; - - SupportPatchFactory<BasisType> patchFactory(patchLevelBasis_, basis_, patchLevel, level_, vertexInElements, i, patchDepth_); - std::vector<int>& localToGlobal = patchFactory.getLocalToGlobal(); - Dune::BitSetVector<1>& boundaryDofs = patchFactory.getBoundaryDofs(); - VectorType rhs; - rhs.resize(matrix_.N()); - rhs = 0; - - //print(localToGlobal, "localToGlobal: "); - //print(boundaryDofs, "boundaryDofs: "); +public: + // has to setup localProblems_ + virtual void build(); - localProblems_[i] = std::make_shared<OscLocalProblem<MatrixType, VectorType>>(matrix_, rhs, localToGlobal, boundaryDofs); +public: + LevelPatchPreconditioner(const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork, + const LocalAssembler& localAssembler, + const std::vector<std::shared_ptr<LocalInterfaceAssembler>>& localInterfaceAssemblers, + const Mode mode = LevelPatchPreconditioner::Mode::additive) : + levelInterfaceNetwork_(levelInterfaceNetwork), + localAssembler_(localAssembler), + localInterfaceAssemblers_(localInterfaceAssemblers), + mode_(mode), + grid_(levelInterfaceNetwork_.grid()), + level_(levelInterfaceNetwork_.level()), + basis_(levelInterfaceNetwork_) + { + setPatchDepth(); + setBoundaryMode(); - /* - if ((i+1) % 10 == 0) { - std::cout << '\r' << std::floor((i+1.0)/patchLevelBasis_.size()*100) << " % done. Elapsed time: " << timer.elapsed() << " seconds. Predicted total setup time: " << timer.elapsed()/(i+1.0)*patchLevelBasis_.size() << " seconds." << std::flush; - }*/ - } + assert(localInterfaceAssemblers_.size() == levelInterfaceNetwork_.size()); - std::cout << std::endl; - std::cout << "Total setup time: " << timer.elapsed() << " seconds." << std::endl; - std::cout << "---------------------------------------------" << std::endl; - timer.stop(); + setup(); } void setPatchDepth(const size_t patchDepth = 0) { @@ -183,13 +120,30 @@ public: } } - virtual void iterate() { - if (mode_ == additive) + virtual void iterate(Direction dir = SYMMETRIC) { + if (mode_ == ADDITIVE) iterateAdd(); else - iterateMult(); + iterateMult(dir); + } + + 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 iterateAdd() { *(this->x_) = 0; @@ -206,54 +160,38 @@ public: } } - void iterateMult() { + void iterateMult(Direction dir) { + if (dir != BACKWARD) { + for (size_t i=0; i<localProblems_.size(); i++) + iterateStep(i); + } + + if (dir != 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; - VectorType it, x; - for (size_t i=0; i<localProblems_.size(); i++) { - VectorType updatedRhs(*(this->rhs_)); - matrix_.mmv(*(this->x_), updatedRhs); + auto rhs = *(this->rhs_); - //step(i); - //print(updatedRhs, "localRhs: "); - //writeToVTK(basis_, updatedRhs, "/storage/mi/podlesny/data/faultnetworks/rhs/local", "exactvertexdata_step_"+std::to_string(i)); + VectorType it, x; if (boundaryMode_ == BoundaryMode::homogeneous) - localProblems_[i]->updateRhs(updatedRhs); + localProblems_[i]->updateRhs(rhs); else - localProblems_[i]->updateRhsAndBoundary(updatedRhs, *(this->x_)); + localProblems_[i]->updateRhsAndBoundary(rhs, *(this->x_)); localProblems_[i]->solve(it); localProblems_[i]->prolong(it, x); + VectorType residual; + localProblems_[i]->localResidual(it, residual); + localProblems_[i]->updateVector(residual, rhs); - //print(it, "it: "); - //print(x, "x: "); - - //writeToVTK(basis_, x, "/storage/mi/podlesny/data/faultnetworks/sol/local", "exactvertexdata_step_"+std::to_string(i)); - - /*if (i==5) { - writeToVTK(basis_, x, "/storage/mi/podlesny/data/faultnetworks/iterates/", "exactvertexdata_patchDepth_"+std::to_string(patchDepth_)); - }*/ *(this->x_) += x; - } - } - - 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(); } }; diff --git a/dune/faultnetworks/preconditioners/supportpatchpreconditioner.hh b/dune/faultnetworks/preconditioners/supportpatchpreconditioner.hh new file mode 100644 index 0000000..baad90f --- /dev/null +++ b/dune/faultnetworks/preconditioners/supportpatchpreconditioner.hh @@ -0,0 +1,70 @@ +#ifndef SUPPORT_PATCH_PRECONDITIONER_HH +#define SUPPORT_PATCH_PRECONDITIONER_HH + +#include <string> + +#include <dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh> +#include <dune/faultnetworks/patchfactories/supportpatchfactory.hh> + +template <class BasisType, class LocalAssembler, class LocalInterfaceAssembler, class MatrixType, class VectorType> +class SupportPatchPreconditioner : public LevelPatchPreconditioner<BasisType, LocalAssembler, LocalInterfaceAssembler, MatrixType, VectorType> { +private: + using Base = LevelPatchPreconditioner<BasisType, LocalAssembler, LocalInterfaceAssembler, MatrixType, VectorType>; + using GridView = typename Base::GridView; + using GridType = typename Base::GridType; + using Mode = typename Base::Mode; + + const BasisType& patchLevelBasis_; + +public: + // for each coarse patch given by patchLevelBasis: set up local problem, compute local correction + SupportPatchPreconditioner(const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork, + const BasisType& patchLevelBasis, + const LocalAssembler& localAssembler, + const std::vector<std::shared_ptr<LocalInterfaceAssembler>>& localInterfaceAssemblers, + const Mode mode = Mode::additive) : + Base(levelInterfaceNetwork, localAssembler, localInterfaceAssemblers, mode), + patchLevelBasis_(patchLevelBasis) {} + + void build() { + // init vertexInElements + const int dim = GridType::dimension; + using Element = typename GridType::template Codim<0>::Entity; + std::vector<std::vector<Element>> vertexInElements; + + const GridView& patchLevelGridView = patchLevelBasis_.getGridView(); + vertexInElements.resize(patchLevelGridView.size(dim)); + for (size_t i=0; i<vertexInElements.size(); i++) { + vertexInElements[i].resize(0); + } + + for (const auto& elem : elements(patchLevelGridView)) { + // compute coarseGrid vertexInElements + const auto& coarseFE = patchLevelBasis_.getLocalFiniteElement(elem); + + for (size_t i=0; i<coarseFE.localBasis().size(); ++i) { + int dofIndex = patchLevelBasis_.indexInGridView(elem, i); + vertexInElements[dofIndex].push_back(elem); + } + } + + std::cout << "SupportPatchPreconditioner::build() level: " << this->level_ << std::endl; + + this->localProblems_.resize(vertexInElements.size()); + const int patchLevel = patchLevelBasis_.faultNetwork().level(); + for (size_t i=0; i<vertexInElements.size(); i++) { + SupportPatchFactory<BasisType> patchFactory(patchLevelBasis_, this->basis_, patchLevel, this->level_, vertexInElements, i, this->patchDepth_); + const auto& localToGlobal = patchFactory.getLocalToGlobal(); + const auto& boundaryDofs = patchFactory.getBoundaryDofs(); + + VectorType rhs; + rhs.resize(this->matrix_.N()); + rhs = 0; + + this->localProblems_[i] = std::make_shared<decltype(*(this->localProblems_[i]))>(this->matrix_, rhs, localToGlobal, boundaryDofs); + } + } +}; + +#endif + diff --git a/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc b/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc index 3441ee8..2dbe0de 100644 --- a/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc +++ b/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc @@ -302,7 +302,7 @@ int main(int argc, char** argv) { try typedef MultilevelPatchPreconditioner<DGBasis, LocalOscAssembler, LocalInterfaceAssembler, MatrixType, VectorType> MultilevelPatchPreconditioner; typedef typename MultilevelPatchPreconditioner::LevelPatchPreconditionerType LevelPatchPreconditioner; - MultilevelPatchPreconditioner::Mode preconditionerMode = MultilevelPatchPreconditioner::Mode::multiplicative; + MultilevelPatchPreconditioner::Mode preconditionerMode = MultilevelPatchPreconditioner::Mode::additive; MultilevelPatchPreconditioner preconditioner(interfaceNetwork, activeLevels, localAssemblers, localIntersectionAssemblers, preconditionerMode); for (size_t i=0; i<preconditioner.size()-1; i++) { -- GitLab