From 66ac772dcd0fc2755c4d0795548f7ccc46a6e04b Mon Sep 17 00:00:00 2001 From: Jonathan Youett <youett@math.fu-berlin.de> Date: Fri, 27 Jun 2014 16:00:02 +0200 Subject: [PATCH] The vector containing the coarse grid obstacles is now a member of the mmgstep. The only thing that has to be provided are the fine grid obstacles --- dune/solvers/iterationsteps/mmgstep.cc | 62 +++++++++++++++----------- dune/solvers/iterationsteps/mmgstep.hh | 10 +++-- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/dune/solvers/iterationsteps/mmgstep.cc b/dune/solvers/iterationsteps/mmgstep.cc index 11ae553e..68dfcfdc 100644 --- a/dune/solvers/iterationsteps/mmgstep.cc +++ b/dune/solvers/iterationsteps/mmgstep.cc @@ -37,6 +37,17 @@ preprocess() // ///////////////////////////////////////////// // Set up base solver // ///////////////////////////////////////////// + + for (size_t i=0; i<obstacleHierarchy_.size()-1; i++) + if (obstacleHierarchy_[i]) + delete(obstacleHierarchy_[i]); + + obstacleHierarchy_.resize(numLevels()); + obstacleHierarchy_.back() = obstacles_; + + for (size_t i=0; i<obstacleHierarchy_.size()-1; i++) + obstacleHierarchy_[i] = new ObstacleVectorType(); + if (typeid(*this->basesolver_) == typeid(LoopSolver<VectorType>)) { LoopSolver<VectorType>* loopBaseSolver = dynamic_cast<LoopSolver<VectorType>* > (this->basesolver_); @@ -44,14 +55,14 @@ preprocess() typedef ProjectedBlockGSStep<MatrixType, VectorType> SmootherType; dynamic_cast<SmootherType*>(loopBaseSolver->iterationStep_)->hasObstacle_ = hasObstacleHierarchy_[0]; - dynamic_cast<SmootherType*>(loopBaseSolver->iterationStep_)->obstacles_ = &obstacles_->at(0); + dynamic_cast<SmootherType*>(loopBaseSolver->iterationStep_)->obstacles_ = obstacleHierarchy_[0]; #if HAVE_IPOPT } else if (typeid(*this->basesolver_) == typeid(QuadraticIPOptSolver<MatrixType,VectorType>)) { QuadraticIPOptSolver<MatrixType,VectorType>* ipoptBaseSolver = dynamic_cast<QuadraticIPOptSolver<MatrixType,VectorType>*> (this->basesolver_); - ipoptBaseSolver->obstacles_ = &(*obstacles_)[0]; + ipoptBaseSolver->obstacles_ = obstacleHierarchy_[0]; #endif } else { DUNE_THROW(SolverError, "You can't use " << typeid(*this->basesolver_).name() @@ -69,12 +80,9 @@ void MonotoneMGStep<MatrixType, VectorType>::nestedIteration() // ///////////////////////////// // Restrict obstacles // ////////////////////////////// - obstacleRestrictor_->restrict((*obstacles_)[i], - (*obstacles_)[i-1], - *hasObstacleHierarchy_[i], - *hasObstacleHierarchy_[i-1], - *this->mgTransfer_[i-1], - dummy); + obstacleRestrictor_->restrict(*obstacleHierarchy_[i], *obstacleHierarchy_[i-1], + *hasObstacleHierarchy_[i], *hasObstacleHierarchy_[i-1], + *this->mgTransfer_[i-1], dummy); // Restrict right hand side this->mgTransfer_[i-1]->restrict(this->rhsHierarchy_[i], this->rhsHierarchy_[i-1]); @@ -86,7 +94,7 @@ void MonotoneMGStep<MatrixType, VectorType>::nestedIteration() // obstacles may be inconsistent. We do an ad hoc correction here. // The true obstacles on the maxlevel are not touched. for (size_t i=0; i<(*obstacles_)[this->level_].size(); i++) { - BoxConstraint<field_type,dim>& cO = (*obstacles_)[this->level_][i]; + BoxConstraint<field_type,dim>& cO = (*obstacleHierarchy_[this->level_])[i]; for (int j=0; j<dim; j++) if (cO.lower(j) > cO.upper(j)) cO.lower(j) = cO.upper(j) = (cO.lower(j) + cO.upper(j)) / 2; @@ -114,7 +122,7 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() std::vector<std::shared_ptr<const MatrixType> >& mat = this->matrixHierarchy_; std::vector<std::shared_ptr<VectorType> >& x = this->xHierarchy_; std::vector<VectorType>& rhs = this->rhsHierarchy_; - std::vector<std::vector<BoxConstraint<field_type,dim> > >& obstacles = *this->obstacles_; + std::vector<ObstacleVectorType* >& obstacles = obstaclesHierarchy_; Dune::BitSetVector<dim> critical(x[level]->size(), false); @@ -125,12 +133,12 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() // Determine critical nodes (only for debugging) const double eps = 1e-12; - for (size_t i=0; i<obstacles[level].size(); i++) { + for (size_t i=0; i<obstacles[level]->size(); i++) { for (int j=0; j<dim; j++) { - if (obstacles[level][i].lower(j) >= (*x[level])[i][j] - eps - || obstacles[level][i].upper(j) <= (*x[level])[i][j] + eps) { + if ((*obstacles[level])[i].lower(j) >= (*x[level])[i][j] - eps + || (*obstacles[level])[i].upper(j) <= (*x[level])[i][j] + eps) { critical[i][j] = true; } @@ -143,7 +151,7 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() ProjectedBlockGSStep<MatrixType,VectorType>* presmoother = dynamic_cast<ProjectedBlockGSStep<MatrixType, VectorType>*>(this->presmoother_[level].get()); assert(presmoother); presmoother->setProblem(*(mat[level]), *x[level], rhs[level]); - presmoother->obstacles_ = &(obstacles[level]); + presmoother->obstacles_ = obstacles[level]; presmoother->hasObstacle_ = hasObstacleHierarchy_[level]; presmoother->ignoreNodes_ = this->ignoreNodesHierarchy_[level]; @@ -151,11 +159,11 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() presmoother->iterate(); // First, a backup of the obstacles for postsmoothing - std::vector<BoxConstraint<field_type,dim> > obstacleBackup = obstacles[level]; + std::vector<BoxConstraint<field_type,dim> > obstacleBackup = *obstacles[level]; // Compute defect obstacles - for (size_t i=0; i<obstacles[level].size(); i++) - obstacles[level][i] -= (*x[level])[i]; + for (size_t i=0; i<obstacles[level]->size(); i++) + (*obstacles[level])[i] -= (*x[level])[i]; // /////////////////////// // Truncation @@ -163,12 +171,12 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() // Determine critical nodes const double eps = 1e-12; - for (size_t i=0; i<obstacles[level].size(); i++) { + for (size_t i=0; i<obstacles[level]->size(); i++) { for (int j=0; j<dim; j++) { - if (obstacles[level][i].lower(j) >= -eps - || obstacles[level][i].upper(j) <= eps) { + if ((*obstacles[level])[i].lower(j) >= -eps + || (*obstacles[level])[i].upper(j) <= eps) { critical[i][j] = true; } @@ -181,7 +189,7 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() ->galerkinRestrict(*(mat[level]), *(const_cast<MatrixType*>(mat[level-1].get())), critical); // Restrict obstacles - obstacleRestrictor_->restrict(obstacles[level], obstacles[level-1], + obstacleRestrictor_->restrict(*obstacles[level], *obstacles[level-1], *hasObstacleHierarchy_[level], *hasObstacleHierarchy_[level-1], *this->mgTransfer_[level-1], critical); @@ -216,18 +224,18 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() *x[level] += tmp; // restore the true (non-defect) obstacles - obstacles[level] = obstacleBackup; + *obstacles[level] = obstacleBackup; #ifndef NDEBUG // Debug: is the current iterate really admissible? - for (size_t i=0; i<obstacles[level].size(); i++) + for (size_t i=0; i<obstacles[level]->size(); i++) for (int j=0; j<VectorType::block_type::dimension; j++) - if (((*x[level])[i][j] - obstacles[level][i].lower(j)<-1e-14 - || (*x[level])[i][j] - obstacles[level][i].upper(j) >1e-14 ) + if (((*x[level])[i][j] - (*obstacles[level])[i].lower(j)<-1e-14 + || (*x[level])[i][j] - (*obstacles[level])[i].upper(j) >1e-14 ) && (!(*this->ignoreNodesHierarchy_[level])[i][j])) { std::cout << "Obstacle disregarded!\n"; - std::cout << (*x[level])[i] << std::endl << obstacles[level][i] << std::endl; + std::cout << (*x[level])[i] << std::endl << (*obstacles[level])[i] << std::endl; std::cout << "level: " << level << " index: " << i << " komponent: " << j << std::endl; std::cout << "is " << ((critical[i][j]) ? "" : "not") << "critical" << std::endl; } @@ -237,7 +245,7 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() ProjectedBlockGSStep<MatrixType,VectorType>* postsmoother = dynamic_cast<ProjectedBlockGSStep<MatrixType, VectorType>*>(this->postsmoother_[level].get()); assert(postsmoother); postsmoother->setProblem(*(mat[level]), *x[level], rhs[level]); - postsmoother->obstacles_ = &obstacles[level]; + postsmoother->obstacles_ = obstacles[level]; postsmoother->hasObstacle_ = hasObstacleHierarchy_[level]; postsmoother->ignoreNodes_ = this->ignoreNodesHierarchy_[level]; diff --git a/dune/solvers/iterationsteps/mmgstep.hh b/dune/solvers/iterationsteps/mmgstep.hh index 01031cdf..b7917a8f 100644 --- a/dune/solvers/iterationsteps/mmgstep.hh +++ b/dune/solvers/iterationsteps/mmgstep.hh @@ -17,7 +17,7 @@ class MonotoneMGStep : public MultigridStep<MatrixType, VectorType> static const int dim = VectorType::block_type::dimension; typedef typename VectorType::field_type field_type; - + typedef std::vector<BoxConstraint<field_type,dim> > ObstacleVectorType; public: MonotoneMGStep() {} @@ -50,8 +50,9 @@ public: //! Bitfield determining which fine grid nodes have an obstacle Dune::BitSetVector<1>* hasObstacle_; - - std::vector<std::vector<BoxConstraint<field_type,dim> > >* obstacles_; + + //! Vector containing the obstacle values of the fine grid nodes + ObstacleVectorType * obstacles_; // Needed to track changes in the set of critical bits, and allows // to check which dofs where critical after the last iteration @@ -60,6 +61,9 @@ public: protected: //! Bitfield hierarchy containing the coarse obstacle nodes std::vector<Dune::BitSetVector<1>* > hasObstacleHierarchy_; + + //! Hierarchy containing the obstacle values of the coarse obstacles + std::vector<ObstacleVectorType*> obstacleHierarchy_; }; #include "mmgstep.cc" -- GitLab