diff --git a/dune/solvers/iterationsteps/mmgstep.cc b/dune/solvers/iterationsteps/mmgstep.cc index b3faa68148950ad97fcd3db0bd5fd444449b1161..bf7bf050a77bc15935a0e8e47a4f650004813782 100644 --- a/dune/solvers/iterationsteps/mmgstep.cc +++ b/dune/solvers/iterationsteps/mmgstep.cc @@ -31,8 +31,19 @@ preprocess() (*hasObstacleHierarchy_[i])[j][0]=false; } + recompute_.resize(this->mgTransfer_.size()); for (size_t i=0; i<this->mgTransfer_.size(); i++) - dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[i])->setRecomputeBitField(hasObstacleHierarchy_[i]); + { + recompute_[i].resize(hasObstacleHierarchy_[i]->size(), false); + dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[i])->setRecomputeBitField(&recompute_[i]); + } + + oldCritical_.resize(this->numLevels()); + for (size_t i=0; i<this->numLevels(); i++) + { + oldCritical_[i].resize(hasObstacleHierarchy_[i]->size()); + oldCritical_[i].unsetAll(); + } // ///////////////////////////////////////////// // Set up base solver @@ -183,6 +194,27 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() } } + /////////////////////////////////////////////////////////////////////////////// + // Compute the part of the coarse grid matrix that needs to be recomputed. + // There are two reasons why a matrix entry may need to be recomputed: + // 1) A corresponding fine grid vertex switched from critical to non-critical or vice versa + // 2) A corresponding fine grid matrix entry got recomputed + /////////////////////////////////////////////////////////////////////////////// + + Dune::BitSetVector<dim> changed(critical.size()); + for (size_t i=0; i<changed.size(); i++) + for (int j=0; j<dim; j++) + changed[i][j] = (critical[i][j] != oldCritical_[level][i][j]); + + if (level < this->numLevels()-1 ) + for (size_t i=0; i<changed.size(); i++) + for (int j=0; j<dim; j++) + changed[i][j] = (changed[i][j] || recompute_[level][i][j]); + + dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[level-1])->restrict(changed, recompute_[level-1]); + + oldCritical_[level] = critical; + // Set bitfield of nodes that will be truncated dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[level-1])->setCriticalBitField(&critical); diff --git a/dune/solvers/iterationsteps/mmgstep.hh b/dune/solvers/iterationsteps/mmgstep.hh index cd373fa08a069cc3953054022e31920d0e34b52d..4c0244e990ee269332e557abb39475e70c50edba 100644 --- a/dune/solvers/iterationsteps/mmgstep.hh +++ b/dune/solvers/iterationsteps/mmgstep.hh @@ -64,6 +64,12 @@ protected: //! Bitfield hierarchy containing the coarse obstacle nodes std::vector<Dune::BitSetVector<dim>* > hasObstacleHierarchy_; + //! For each level specify the matrix lines that need reassembly + std::vector<Dune::BitSetVector<dim> > recompute_; + + //! For each level specify dofs that changed status + std::vector<Dune::BitSetVector<dim> > oldCritical_; + //! Hierarchy containing the obstacle values of the coarse obstacles std::vector<ObstacleVectorType*> obstacleHierarchy_; };