diff --git a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh index 1b75e51e3f30ef7546010ef630f23eea543850a0..9d6d64e6eaf8391c6fe6e88290c3a76140130ee1 100644 --- a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh +++ b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh @@ -24,14 +24,12 @@ template <class ContactNetwork, class MatrixType, class VectorType> class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorType> { -public: - //struct Mode { enum ModeType {additive, multiplicative}; }; - private: using Base = LinearIterationStep<MatrixType, VectorType>; - using PatchSolver = typename Dune::Solvers::LoopSolver<Vector, BitVector>; - //using PatchSolver = Dune::Solvers::UMFPackSolver<MatrixType, VectorType>; + using PatchSolver = LoopSolver<Vector, BitVector>; + using PatchSolverStep = TruncatedBlockGSStep<MatrixType, VectorType>; + using CoarseSolver = Dune::Solvers::UMFPackSolver<MatrixType, VectorType>; using LevelContactNetwork = typename ContactNetwork::LevelContactNetwork; using LevelPatchPreconditioner = LevelPatchPreconditioner<LevelContactNetwork, PatchSolver, MatrixType, VectorType>; @@ -57,10 +55,10 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec std::vector<std::shared_ptr<EnergyNorm<MatrixType, VectorType>>> levelErrorNorms_; std::vector<std::shared_ptr<LinearIterationStep<MatrixType, VectorType>>> levelItSteps_; std::vector<std::shared_ptr<PatchSolver>> levelSolvers_; + CoarseSolver coarseSolver_; - std::vector<BitVector> recompute_; - //std::vector<BitVector> truncation_; - std::vector<std::shared_ptr<MGTransfer>> mgTransfer_; //TODO + //std::vector<BitVector> recompute_; + std::vector<std::shared_ptr<MGTransfer>> mgTransfer_; public: MultilevelPatchPreconditioner(const Dune::ParameterTree& parset, @@ -84,8 +82,6 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec } } - const int coarsestLevel = maxLevel; - for (size_t i=maxLevel+1; i<activeLevels_.size(); i++) { if (activeLevels_[i][0]) { // init local patch preconditioners on each level @@ -104,16 +100,6 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec levelSolvers_.resize(size()); levelItSteps_.resize(size()); levelErrorNorms_.resize(size()); - //auto coarseStep = - levelItSteps_[0] = std::make_shared<TruncatedBlockGSStep<MatrixType, VectorType>>();//Dune::Solvers::BlockGSStepFactory<MatrixType, VectorType>::createPtr(Dune::Solvers::BlockGS::LocalSolvers::direct(0.0)); - levelErrorNorms_[0] = std::make_shared<EnergyNorm<MatrixType, VectorType>>(*levelItSteps_[0].get()); - levelSolvers_[0] = std::make_shared<PatchSolver>(*levelItSteps_[0].get(), - parset.get<size_t>("maximumIterations"), - parset.get<double>("tolerance"), - *levelErrorNorms_[0].get(), - parset.get<Solver::VerbosityMode>("verbosity"), - false); // absolute error - //std::make_shared<PatchSolver>(); for (size_t i=1; i<levelSolvers_.size(); i++) { //auto gsStep = Dune::Solvers::BlockGSStepFactory<MatrixType, VectorType>::create(Dune::Solvers::BlockGS::LocalSolvers::direct(0.0)); @@ -123,13 +109,10 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec parset.get<size_t>("maximumIterations"), parset.get<double>("tolerance"), *levelErrorNorms_[i].get(), - parset.get<Solver::VerbosityMode>("verbosity"), - false); // absolute error - //std::make_shared<PatchSolver>(); + parset.get<Solver::VerbosityMode>("verbosity")); levelPatchPreconditioners_[i]->setPatchSolver(levelSolvers_[i]); } - // init multigrid transfer mgTransfer_.resize(levelPatchPreconditioners_.size()-1); for (size_t i=0; i<mgTransfer_.size(); i++) { @@ -137,19 +120,23 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec mgTransfer_[i]->setup(contactNetwork_, levelPatchPreconditioners_[i+1]->level(), levelPatchPreconditioners_[i+1]->fineLevel()); } - // Remove any recompute filed so that initially the full transferoperator is assembled + // from dune/contact/solvers/nsnewtonmgstep.cc + /*// Remove any recompute filed so that initially the full transferoperator is assembled for (size_t i=0; i<mgTransfer_.size(); i++) std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->setRecomputeBitField(nullptr); // specify the subset of entries to be reassembled at each iteration - /* recompute_.resize(size()); + recompute_.resize(size()); recompute_[recompute_.size()-1] = contactNetwork_.nBodyAssembler().totalHasObstacle_; - for (int i=mgTransfer_.size()-1; i>=0; i--) { - std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->restrict(recompute_[i+1], recompute_[i]); + for (int i=mgTransfer_.size(); i>=1; i--) { + std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i-1])->restrict(recompute_[i], recompute_[i-1]); // std::dynamic_pointer_cast<DenseMultigridTransfer<VectorType, BitVector, MatrixType> >(mgTransfer_[i])->restrict(recompute_[i+1], recompute_[i]); - std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->setRecomputeBitField(&recompute_[i]); - print(recompute_[i], "recompute: "); - }*/ + + //print(recompute_[i], "recompute: "); + } + + for (size_t i=0; i<this->mgTransfer_.size(); i++) + std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->setRecomputeBitField(&recompute_[i]); */ } void setMatrix(const MatrixType& mat) override { @@ -161,32 +148,16 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->restrictToFathers(ignoreHierarchy_[i+1], ignoreHierarchy_[i]); } - /* truncation_.resize(size()); - truncation_[size()-1] = Base::ignore(); - print(truncation_.back(), "truncation: "); - for (int i=mgTransfer_.size()-1; i>=0; i--) { - std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->restrict(truncation_[i+1], truncation_[i]); - std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->setCriticalBitField(&truncation_[i+1]); - print(truncation_[i], "truncation: "); - }*/ - size_t maxLevel = levelPatchPreconditioners_.size()-1; levelPatchPreconditioners_[maxLevel]->setMatrix(mat); - //print(mat, "levelMat_" + std::to_string(maxLevel) + ":"); - for (int i=levelPatchPreconditioners_.size()-2; i>0; i--) { const auto& transfer = *mgTransfer_[i]; - //print(*levelPatchPreconditioners_[i+1]->getMatrix(), "levelMat:"); - //print(levelMat_[i], "coarseMat:"); - transfer.galerkinRestrictSetOccupation(*levelPatchPreconditioners_[i+1]->getMatrix(), levelMat_[i]); transfer.galerkinRestrict(*levelPatchPreconditioners_[i+1]->getMatrix(), levelMat_[i]); levelPatchPreconditioners_[i]->setMatrix(levelMat_[i]); - //print(levelMat_[i], "levelMat_" + std::to_string(i) + ":"); - // Set solution vector sizes for the lower levels Dune::MatrixVector::resize(levelX_[i], levelMat_[i]); //Dune::MatrixVector::resize(levelRhs_[i], levelMat_[i]); @@ -198,58 +169,9 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec coarseTransfer.galerkinRestrictSetOccupation(fineMat, levelMat_[0]); coarseTransfer.galerkinRestrict(fineMat, levelMat_[0]); - //print(levelMat_[0], "levelMat_0:"); - - /*dynamic_cast<Base&>(levelSolvers_[0]->getIterationStep()).setMatrix(levelMat_[0]); */ - Dune::MatrixVector::resize(levelX_[0], levelMat_[0]); - //Dune::MatrixVector::resize(levelRhs_[0], levelMat_[0]); } - void setTruncation(const BitVector& truncation) { - std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_.back())->setCriticalBitField(&truncation); - } - - /*void setProblem(const MatrixType& mat, VectorType& x, const VectorType& rhs) override { - LinearIterationStep<MatrixType, VectorType>::setProblem(mat, x, rhs); - - truncation_.resize(size()); - truncation_[size()-1] = this->ignore(); - print(truncation_.back(), "truncation: "); - for (int i=mgTransfer_.size()-1; i>=0; i--) { - std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->restrict(truncation_[i+1], truncation_[i]); - std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->setCriticalBitField(&truncation_[i]); - print(truncation_[i], "truncation: "); - } - - size_t maxLevel = levelPatchPreconditioners_.size()-1; - levelX_[maxLevel] = x; - levelRhs_[maxLevel] = rhs; - levelPatchPreconditioners_[maxLevel]->setProblem(mat, levelX_[maxLevel], levelRhs_[maxLevel]); - - for (int i=levelPatchPreconditioners_.size()-2; i>0; i--) { - const auto& transfer = *mgTransfer_[i]; - - transfer.restrict(levelX_[i+1], levelX_[i]); - transfer.restrict(levelRhs_[i+1], levelRhs_[i]); - transfer.galerkinRestrict(*levelPatchPreconditioners_[i+1]->getMatrix(), levelMat_[i]); - - levelPatchPreconditioners_[i]->setProblem(levelMat_[i], levelX_[i], levelRhs_[i]); - } - - // set coarse global problem - const auto& coarseTransfer = *mgTransfer_[0]; - - coarseTransfer.restrict(levelX_[1], levelX_[0]); - coarseTransfer.restrict(levelRhs_[1], levelRhs_[0]); - coarseTransfer.galerkinRestrict(levelMat_[1], levelMat_[0]); - - dynamic_cast<LinearIterationStep<MatrixType, VectorType>&>(levelSolvers_[0]->getIterationStep()).setProblem(levelMat_[0], levelX_[0], levelRhs_[0]); - - // EnergyNorm<MatrixType, VectorType> coarseErrorNorm(levelSolvers_[0]->getIterationStep()); - // levelSolvers_[0]->setErrorNorm(coarseErrorNorm); - } */ - void iterate() { size_t maxLevel = levelPatchPreconditioners_.size()-1; levelX_[maxLevel] = *this->getIterate(); @@ -280,33 +202,15 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec VectorType x; // solve coarse global problem - auto& coarseSolver = levelSolvers_[0]; - coarseSolver->getIterationStep().setIgnore(ignoreHierarchy_[0]); - - dynamic_cast<LinearIterationStep<MatrixType, VectorType>&>(levelSolvers_[0]->getIterationStep()).setProblem(levelMat_[0], levelX_[0], levelRhs_[0]); - - coarseSolver->check(); - coarseSolver->preprocess(); - coarseSolver->solve(); - - mgTransfer_[0]->prolong(levelX_[0], x); - - - /* BitVector emptyIgnore0(levelX_[0].size(), false); LocalProblem<MatrixType, VectorType> localProblem(levelMat_[0], levelRhs_[0], ignoreHierarchy_[0]); Vector newR; localProblem.getLocalRhs(levelX_[0], newR); - auto& coarseSolver = levelSolvers_[0]; - coarseSolver->setProblem(localProblem.getMat(), levelX_[0], newR); - coarseSolver->preprocess(); - coarseSolver->solve(); - - mgTransfer_[0]->prolong(levelX_[0], x);*/ - - //print(levelX_[0], "MultilevelPatchPreconditioner: levelX_[0]"); - //print(x, "MultilevelPatchPreconditioner: x0"); + coarseSolver_.setProblem(localProblem.getMat(), levelX_[0], newR); + coarseSolver_.preprocess(); + coarseSolver_.solve(); + mgTransfer_[0]->prolong(levelX_[0], x); for (size_t i=1; i<levelPatchPreconditioners_.size()-1; i++) { const auto& transfer = *mgTransfer_[i]; @@ -315,18 +219,12 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec preconditioner.setIgnore(ignoreHierarchy_[i]); preconditioner.apply(levelX_[i], levelRhs_[i]); - //print(levelX_[i], "MultilevelPatchPreconditioner: levelX_[i] " + std::to_string(i)); - x += preconditioner.getSol(); VectorType newX; transfer.prolong(x, newX); - //print(newX, "MultilevelPatchPreconditioner: newX " + std::to_string(i)); - x = newX; - - //print(x, "MultilevelPatchPreconditioner: x " + std::to_string(i)); } auto& preconditioner = *levelPatchPreconditioners_.back(); @@ -336,29 +234,15 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec x += preconditioner.getSol(); - //print(x, "MultilevelPatchPreconditioner: xmax"); - - - /* BitVector emptyIgnore(this->x_->size(), false); - LocalProblem<MatrixType, VectorType> globalProblem(*this->mat_.get(), *this->rhs_, emptyIgnore); - globalProblem.getLocalRhs(*this->x_, newR); - VectorType totalX = *(this->x_); - auto& globalSolver = levelSolvers_.back(); - globalSolver->setProblem(globalProblem.getMat(), totalX, newR); - globalSolver->preprocess(); - globalSolver->solve(); - - print(totalX, "MultilevelPatchPreconditioner: totalX"); */ - *(this->x_) = x; - - //print(*(this->x_), "MultilevelPatchPreconditioner: sol"); } void iterateMult() { *(this->x_) = 0; + DUNE_THROW(Dune::Exception, "Not implemented!"); + /* VectorType x;