From 40ffdda763c266277d0354b0e7cc8329f0c0c4df Mon Sep 17 00:00:00 2001 From: Jonathan Youett <youett@math.fu-berlin.de> Date: Mon, 18 Sep 2017 11:43:18 +0200 Subject: [PATCH] Make obstacle data protected and add setters taking l-,r-values or shared_ptr Internally this data is now stored within shared pointer --- dune/solvers/iterationsteps/mmgstep.cc | 26 ++++++++------------- dune/solvers/iterationsteps/mmgstep.hh | 32 ++++++++++++++++++++------ dune/solvers/test/mmgtest.cc | 5 ++-- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/dune/solvers/iterationsteps/mmgstep.cc b/dune/solvers/iterationsteps/mmgstep.cc index 87f4f0b6..a9395e9f 100644 --- a/dune/solvers/iterationsteps/mmgstep.cc +++ b/dune/solvers/iterationsteps/mmgstep.cc @@ -24,15 +24,11 @@ preprocess() MultigridStep<MatrixType,VectorType>::preprocess(); // Then setup the obstacle flags which specify the subset of entries to be reassembled at each iteration - for (int i=0; i<(int) hasObstacleHierarchy_.size()-1; i++) - if (hasObstacleHierarchy_[i] != nullptr) - delete(hasObstacleHierarchy_[i]); - hasObstacleHierarchy_.resize(this->numLevels()); hasObstacleHierarchy_.back() = hasObstacle_; for (int i=this->mgTransfer_.size()-1; i>=0; i--) { - hasObstacleHierarchy_[i] = new Dune::BitSetVector<dim>(); + hasObstacleHierarchy_[i] = std::make_shared<Dune::BitSetVector<dim> >(); this->mgTransfer_[i]->restrict(*hasObstacleHierarchy_[i+1], *hasObstacleHierarchy_[i]); for (size_t j=0; j<hasObstacleHierarchy_[i]->size(); j++) if ((*this->ignoreNodesHierarchy_[i])[j].any()) @@ -58,15 +54,11 @@ preprocess() // Set up base solver // ///////////////////////////////////////////// - for (int i=0; i<(int) obstacleHierarchy_.size()-1; i++) - if (obstacleHierarchy_[i] != nullptr) - delete(obstacleHierarchy_[i]); - obstacleHierarchy_.resize(this->numLevels()); obstacleHierarchy_.back() = obstacles_; for (size_t i=0; i<obstacleHierarchy_.size()-1; i++) - obstacleHierarchy_[i] = new ObstacleVectorType(); + obstacleHierarchy_[i] = std::make_shared<ObstacleVectorType>(); if (typeid(*this->basesolver_) == typeid(::LoopSolver<VectorType>)) { @@ -74,8 +66,8 @@ preprocess() typedef ProjectedBlockGSStep<MatrixType, VectorType> SmootherType; - dynamic_cast<SmootherType*>(&loopBaseSolver->getIterationStep())->hasObstacle_ = hasObstacleHierarchy_[0]; - dynamic_cast<SmootherType*>(&loopBaseSolver->getIterationStep())->obstacles_ = obstacleHierarchy_[0]; + dynamic_cast<SmootherType*>(&loopBaseSolver->getIterationStep())->hasObstacle_ = hasObstacleHierarchy_[0].get(); + dynamic_cast<SmootherType*>(&loopBaseSolver->getIterationStep())->obstacles_ = obstacleHierarchy_[0].get(); #if HAVE_IPOPT } else if (typeid(*this->basesolver_) == typeid(QuadraticIPOptSolver<MatrixType,VectorType>)) { @@ -142,7 +134,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<ObstacleVectorType* >& obstacles = obstacleHierarchy_; + auto& obstacles = obstacleHierarchy_; Dune::BitSetVector<dim> critical(x[level]->size(), false); @@ -171,8 +163,8 @@ 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->hasObstacle_ = hasObstacleHierarchy_[level]; + presmoother->obstacles_ = obstacles[level].get(); + presmoother->hasObstacle_ = hasObstacleHierarchy_[level].get(); presmoother->ignoreNodes_ = this->ignoreNodesHierarchy_[level]; for (int i=0; i<this->nu1_; i++) @@ -291,8 +283,8 @@ 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->hasObstacle_ = hasObstacleHierarchy_[level]; + postsmoother->obstacles_ = obstacles[level].get(); + postsmoother->hasObstacle_ = hasObstacleHierarchy_[level].get(); postsmoother->ignoreNodes_ = this->ignoreNodesHierarchy_[level]; for (int i=0; i<this->nu2_; i++) diff --git a/dune/solvers/iterationsteps/mmgstep.hh b/dune/solvers/iterationsteps/mmgstep.hh index 95a71526..d8c7ddfc 100644 --- a/dune/solvers/iterationsteps/mmgstep.hh +++ b/dune/solvers/iterationsteps/mmgstep.hh @@ -54,10 +54,28 @@ public: virtual void nestedIteration(); //! Set the hasObstacle bitfield - void setHasObstacles(Dune::BitSetVector<dim>* hasObstacle) {hasObstacle_ = hasObstacle;} + DUNE_DEPRECATED_MSG("Setting by raw pointer is deprecated. Use l-value or r-value or a shared_ptr") + void setHasObstacles(Dune::BitSetVector<dim>* hasObstacle) { + hasObstacle_ = Dune::stackobject_to_shared_ptr(hasObstacle); + } + + //! Set the hasObstacle bitfield + template <class BitVector, class Enable = std::enable_if_t<not std::is_pointer<BitVector>::value> > + void setHasObstacles(BitVector&& hasObstacles) { + hasObstacle_ = Dune::Solvers::wrap_own_share<Dune::BitSetVector<dim> >(std::forward<BitVector>(hasObstacles)); + } + + //! Set the obstacle field + DUNE_DEPRECATED_MSG("Setting by raw pointer is deprecated. Use l-value or r-value or a shared_ptr") + void setObstacles(ObstacleVectorType* obstacles) { + obstacles_ = Dune::stackobject_to_shared_ptr(obstacles); + } //! Set the obstacle field - void setObstacles(ObstacleVectorType* obstacles) {obstacles_ = obstacles;} + template <class ObstacleVector, class Enable = std::enable_if_t<not std::is_pointer<ObstacleVector>::value> > + void setObstacles(ObstacleVector&& obstacles) { + obstacles_ = Dune::Solvers::wrap_own_share<ObstacleVectorType>(std::forward<ObstacleVector>(obstacles)); + } //! Set the obstacle restrictor template <class Restrictor> @@ -65,22 +83,22 @@ public: obstacleRestrictor_ = Dune::Solvers::wrap_own_share<ObstacleRestrictor<VectorType> >(std::forward<Restrictor>(restrictor)); } +protected: //! Bitfield determining which fine grid nodes have an obstacle - Dune::BitSetVector<dim>* hasObstacle_; + std::shared_ptr<Dune::BitSetVector<dim> > hasObstacle_; //! Vector containing the obstacle values of the fine grid nodes - ObstacleVectorType * obstacles_; + std::shared_ptr<ObstacleVectorType> obstacles_; // Needed to track changes in the set of critical bits, and allows // to check which dofs where critical after the last iteration Dune::BitSetVector<dim> oldCritical; -protected: //! The restrictor used to construct the coarse obstacles std::shared_ptr<ObstacleRestrictor<VectorType> > obstacleRestrictor_; //! Bitfield hierarchy containing the coarse obstacle nodes - std::vector<Dune::BitSetVector<dim>* > hasObstacleHierarchy_; + std::vector<std::shared_ptr<Dune::BitSetVector<dim>> > hasObstacleHierarchy_; //! For each level specify the matrix lines that need reassembly std::vector<Dune::BitSetVector<dim> > recompute_; @@ -89,7 +107,7 @@ protected: std::vector<Dune::BitSetVector<dim> > oldCritical_; //! Hierarchy containing the obstacle values of the coarse obstacles - std::vector<ObstacleVectorType*> obstacleHierarchy_; + std::vector<std::shared_ptr<ObstacleVectorType> > obstacleHierarchy_; private: using Base::setProblem; diff --git a/dune/solvers/test/mmgtest.cc b/dune/solvers/test/mmgtest.cc index 43d6098e..cc005693 100644 --- a/dune/solvers/test/mmgtest.cc +++ b/dune/solvers/test/mmgtest.cc @@ -60,14 +60,13 @@ void solveObstacleProblemByMMGSolver(const GridType& grid, const MatrixType& mat mmgStep.setSmoother(&smoother); mmgStep.setObstacleRestrictor(MandelObstacleRestrictor<VectorType>()); - Dune::BitSetVector<blockSize> hasObstacle(x.size(),true); - mmgStep.hasObstacle_ = &hasObstacle; + mmgStep.setHasObstacles(Dune::BitSetVector<blockSize>(x.size(),true)); std::vector<BoxConstraint<typename VectorType::field_type,blockSize> > boxConstraints(rhs.size()); for (size_t i = 0; i < boxConstraints.size(); ++i) for (int j = 0; j < blockSize; ++j) boxConstraints[i][j] = { -1, +1 }; - mmgStep.obstacles_ = &boxConstraints; + mmgStep.setObstacles(boxConstraints); // we need a vector of pointers to the transfer operator base class using Transfer = TruncatedCompressedMGTransfer<VectorType>; -- GitLab