diff --git a/dune/solvers/iterationsteps/mmgstep.cc b/dune/solvers/iterationsteps/mmgstep.cc index 165284af084359eb0b9465ae57c1b7e88d370ab6..e649092f4d8be930d5dc9cf63e0740619286d39d 100644 --- a/dune/solvers/iterationsteps/mmgstep.cc +++ b/dune/solvers/iterationsteps/mmgstep.cc @@ -32,7 +32,7 @@ preprocess() } for (size_t i=0; i<this->mgTransfer_.size(); i++) - dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[i])->recompute_ = hasObstacleHierarchy_[i]; + dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[i])->setRecomputeBitField(hasObstacleHierarchy_[i]); // ///////////////////////////////////////////// // Set up base solver @@ -66,7 +66,7 @@ preprocess() #endif } else { DUNE_THROW(SolverError, "You can't use " << typeid(*this->basesolver_).name() - << " as a base solver for contact problems!"); + << " as a base solver for obstacle problems!"); } } @@ -157,7 +157,7 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() for (int i=0; i<this->nu1_; i++) presmoother->iterate(); - + // First, a backup of the obstacles for postsmoothing std::vector<BoxConstraint<field_type,dim> > obstacleBackup = *obstacles[level]; @@ -182,11 +182,12 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() } } - + + // Set bitfield of nodes that will be truncated + dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[level-1])->setCriticalBitField(&critical); // Restrict stiffness matrix - dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[level-1]) - ->galerkinRestrict(*(mat[level]), *(const_cast<MatrixType*>(mat[level-1].get())), critical); + this->mgTransfer_[level-1]->galerkinRestrict(*(mat[level]), *(const_cast<MatrixType*>(mat[level-1].get()))); // Restrict obstacles obstacleRestrictor_->restrict(*obstacles[level], *obstacles[level-1], @@ -201,7 +202,7 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() mat[level]->mmv(*x[level], fineResidual); // restrict residual - dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[level-1])->restrict(fineResidual, rhs[level-1], critical); + this->mgTransfer_[level-1]->restrict(fineResidual, rhs[level-1]); // Choose all zeros as the initial correction *x[level-1] = 0; @@ -220,9 +221,13 @@ void MonotoneMGStep<MatrixType, VectorType>::iterate() // add correction to the presmoothed solution VectorType tmp; - dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[level-1])->prolong(*x[level-1], tmp, critical); + this->mgTransfer_[level-1]->prolong(*x[level-1], tmp); *x[level] += tmp; - + + // Remove pointer to the temporary critical bitfield + // this avoids a memory problem when the same mmg step is reused + dynamic_cast<TruncatedMGTransfer<VectorType>*>(this->mgTransfer_[level-1])->setCriticalBitField(nullptr); + // restore the true (non-defect) obstacles *obstacles[level] = obstacleBackup;