From 223fb8f67cc9d7394e74785de660f1e42e6c3cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carsten=20Gr=C3=A4ser?= <graeser@mi.fu-berlin.de> Date: Tue, 10 Apr 2012 21:38:17 +0000 Subject: [PATCH] Implement (algebraic) nested iteration This purely algebraic variant of nested iteration can be used to compute initial iterates. [[Imported from SVN: r5920]] --- .../iterationsteps/obstacletnnmgstep.hh | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/dune/solvers/iterationsteps/obstacletnnmgstep.hh b/dune/solvers/iterationsteps/obstacletnnmgstep.hh index 79990283..2b36ca51 100644 --- a/dune/solvers/iterationsteps/obstacletnnmgstep.hh +++ b/dune/solvers/iterationsteps/obstacletnnmgstep.hh @@ -17,6 +17,7 @@ #include <dune/solvers/solvers/loopsolver.hh> #include <dune/solvers/norms/energynorm.hh> #include <dune/solvers/common/boxconstraint.hh> +#include <dune/solvers/transferoperators/mandelobsrestrictor.hh> @@ -335,6 +336,83 @@ class ObstacleTNNMGStep return s; } + + /** + * \brief Compute initial iterate by nested iteration + * + * This method performs a purely algebraic variant of nested iteration. + * The coarse matrix and rhs are obtained using the transfer operators. + * Coarse obstacles are constructed using a local max/min over the + * support of coarse basis functions as suggested by J. Mandel. + * The ignore-marks are restricted such that a coarse dof + * is ignored if it is associated to an ignored fine dof + * in the sense that the corresponding transfer operators entry is 1. + * + * On each level a fixed number of v-cycles is performed. + * + * This method can be called before the preprocess() method. + * It does not change the ObstacleTNNMGStep state despite + * updating the solution vector. + * + * \param coarseIterationSteps Number of v-cycle performed on the corse levels. + */ + void nestedIteration(int coarseIterationSteps=2) + { + int maxLevel = transfer_.size(); + + std::vector<Matrix> coarseMatrix(maxLevel); + std::vector<Vector> coarseSolution(maxLevel); + std::vector<Vector> coarseRhs(maxLevel); + std::vector<BitVector> coarseIgnore(maxLevel); + std::vector<BoxConstraintVector> coarseObstacle(maxLevel); + MandelObstacleRestrictor<Vector> obstacleRestrictor; + BitVector critical; + + critical.resize(x_->size()); + critical.unsetAll(); + + transfer_[maxLevel-1]->galerkinRestrictSetOccupation(mat_, coarseMatrix[maxLevel-1]); + transfer_[maxLevel-1]->galerkinRestrict(mat_, coarseMatrix[maxLevel-1]); + transfer_[maxLevel-1]->restrict(rhs_, coarseRhs[maxLevel-1]); + transfer_[maxLevel-1]->restrictToFathers(*ignoreNodes_, coarseIgnore[maxLevel-1]); + obstacleRestrictor.restrict(obstacles_, coarseObstacle[maxLevel-1], hasObstacle_, hasObstacle_, *(transfer_[maxLevel-1]), critical); + for (int i = maxLevel-2; i>=0; --i) + { + transfer_[i]->galerkinRestrictSetOccupation(coarseMatrix[i+1], coarseMatrix[i]); + transfer_[i]->galerkinRestrict(coarseMatrix[i+1], coarseMatrix[i]); + transfer_[i]->restrict(coarseRhs[i+1], coarseRhs[i]); + transfer_[i]->restrictToFathers(coarseIgnore[i+1], coarseIgnore[i]); + obstacleRestrictor.restrict(coarseObstacle[i+1], coarseObstacle[i], hasObstacle_, hasObstacle_, *(transfer_[i]), critical); + coarseSolution[i].resize(coarseMatrix[i].N()); + } + + coarseSolution[0] = 0; + for (int i = 0; i<maxLevel; ++i) + { + + TransferPointerVector coarseTransfer(i); + for (int j = 0; j < i; ++j) + coarseTransfer[j] = transfer_[j]; + + ObstacleTNNMGStep coarseTNNMGStep( + coarseMatrix[i], + coarseSolution[i], + coarseRhs[i], + coarseIgnore[i], + coarseObstacle[i], + coarseTransfer, + truncationTol_); + coarseTNNMGStep.preprocess(); + for (int j = 0; j < coarseIterationSteps; ++j) + coarseTNNMGStep.iterate(); + coarseSolution[i] = coarseTNNMGStep.getSol(); + + if (i<maxLevel-1) + transfer_[i]->prolong(coarseSolution[i], coarseSolution[i+1]); + } + transfer_[maxLevel-1]->prolong(coarseSolution[maxLevel-1], *x_); + } + protected: // problem description given by the user -- GitLab