18#ifndef MULTIGRIDSTACKS_HH
19#define MULTIGRIDSTACKS_HH
33#include "dune/grid/common/grid.hh"
34#include "dune/grid/common/entitypointer.hh"
35#include "dune/grid/common/entity.hh"
36#include "dune/grid/io/file/dgfparser/dgfparser.hh"
37#include "dune/istl/matrix.hh"
38#include "dune/istl/bcrsmatrix.hh"
39#include "dune/common/fmatrix.hh"
40#include "dune/common/iteratorfacades.hh"
41#include "dune/istl/matrixindexset.hh"
43#include "dune/istl/preconditioners.hh"
44#include "dune/istl/solvers.hh"
93 typedef typename Grd::LevelGridView::IndexSet::IndexType IndexType;
94 typedef typename std::pair<IndexType,float> FatherIndexValue;
95 typedef typename std::vector<FatherIndexValue> FatherSimplexPairs;
98 void findParents(
const Grd& grd,
int levelNr );
105 for(
int levelNr=1; levelNr<=grd.maxLevel(); levelNr++)
106 findParents(grd,levelNr);
110template <
class Grd >
121 typedef typename Grd::template Codim<0>::LevelIterator ElementLevelIterator;
122 typedef typename Grd::LevelGridView::IndexSet::IndexType IndexType;
124 std::vector<FatherSimplexPairs> levelParents;
125 levelParents.resize( grd.size(levelNr,Grd::dimension) );
128 std::vector<bool> processed(grd.size(Grd::dimension),
false);
131 std::vector<bool> disappears( grd.size(levelNr-1,Grd::dimension) ,
true );
133 typename Grd::LevelGridView::IndexSet
const& indexSet = grd.levelGridView(levelNr).indexSet() ;
134 typename Grd::LevelGridView::IndexSet
const& fatherIndexSet = grd.levelGridView(levelNr-1).indexSet();
137 ElementLevelIterator itEnd = grd.levelGridView(levelNr).template end<0>() ;
138 for (ElementLevelIterator it = grd.levelGridView(levelNr).template begin<0>() ; it != itEnd; ++it)
141 std::vector<IndexType> fatherIndices;
144 typename Grd::template Codim<0>::Entity itFather = (*it).father();
146 for(
int i=0 ; i<=Grd::dimension ; i++ )
148 fatherIndices.push_back( fatherIndexSet.subIndex(itFather, i, Grd::dimension) );
150 disappears[ indexSet.subIndex( itFather,i,Grd::dimension ) ] =
false;
154 for(
int i=0 ; i<=Grd::dimension ; i++ )
156 IndexType idx_child = indexSet.subIndex(*it, i, Grd::dimension);
157 if (!processed[idx_child])
159 processed[idx_child] =
true;
161 std::vector<float> relativeCoord;
162 relativeCoord.push_back(1);
165 relativeCoord.push_back( it->geometryInFather().corner(i)[
component] );
166 relativeCoord.front() -= relativeCoord.back();
171 FatherIndexValue couple;
173 couple.second = relativeCoord[
component];
174 levelParents[idx_child].push_back(couple);
191 for (
int k = 0 ; k < disappears.size(); k++ )
193 levelDisappear[levelNr-1].push_back(k);
196 levelParentsVector[levelNr-1].swap(levelParents);
229template <
class Grd >
240template <
class Grd >
243 int maxiLevel = grd.maxLevel();
247 std::vector<std::vector<int> > disappear(parentalNodes.
levelDisappear);
249 int disappearSumBefore = 0;
250 int disappearSumAfter = 0;
252 for(
int levelNr = 1 ; levelNr <= maxiLevel ; levelNr++)
254 disappearSumBefore = disappearSumAfter;
255 disappearSumAfter += disappear[levelNr-1].size();
257 int prolCols = grd.size( levelNr-1 , Grd::dimension ) + disappearSumBefore ;
258 int prolRows = grd.size( levelNr , Grd::dimension ) + disappearSumAfter ;
266 int nz = disappearSumAfter + grd.size(levelNr,Grd::dimension)*(Grd::dimension+1);
267 Dune::BCRSMatrix<M> prolMatrix(prolRows,prolCols,nz,Dune::BCRSMatrix<M>::row_wise);
272 typedef Dune::BCRSMatrix<M>::CreateIterator Iter;
274 for (Iter row=prolMatrix.createbegin(); row!=prolMatrix.createend(); ++row)
276 if (row.index() < disappearSumBefore)
277 row.insert( row.index() );
278 else if (row.index() >= disappearSumBefore && row.index() < disappearSumAfter )
279 row.insert( disappearSumBefore + disappear[levelNr-1][ row.index() - disappearSumBefore ] );
281 for(
int k = 0 ; k <= Grd::dimension ; k++ )
282 if (parentalNodes.
levelParentsVector[levelNr-1][row.index()-disappearSumAfter][k].second > 0)
283 row.insert( parentalNodes.
levelParentsVector[levelNr-1][row.index()-disappearSumAfter][k].first + disappearSumBefore );
287 for(
int row = 0 ; row < disappearSumBefore ; row++)
288 prolMatrix[row][row] = 1;
289 for(
int indx = 0 ; indx < disappear[levelNr-1].size(); indx++)
290 prolMatrix[ disappearSumBefore + indx ][ disappear[levelNr-1][indx] + disappearSumBefore ] = 1;
291 for(
int row = disappearSumAfter ; row < prolRows ; row++)
293 for(
int k = 0 ; k <= Grd::dimension ; k++ )
294 if (parentalNodes.
levelParentsVector[levelNr-1][row-disappearSumAfter ][k].second > 0)
296 prolMatrix[row][ parentalNodes.
levelParentsVector[levelNr-1][row-disappearSumAfter][k].first + disappearSumBefore ]
301 prolStack.push_back( prolMatrix );
322template <
class Grd >
333template <
class Grd >
339 levelMatrixStack.push_back(bcrsA);
341 for(
int i = 0 ; i < prols ; i++)
344 std::unique_ptr<Dune::MatrixIndexSet> C = conjugationPattern<double,M>( ps.
prolStack[prols-1-i] , levelMatrixStack[ i ] , onlyLowerTriangle);
345 Dune::BCRSMatrix<M> Cnew;
354 levelMatrixStack.push_back( Cnew );
374template <
class Grd ,
class domain_type >
384 double mJacRelaxFactor, mMgIter, mMgSmoothings, mMaxTol, mTimeDirectSolve , mExactSolEnergyNorm ;
392 void mgSolve( domain_type& solution , domain_type& rightHand );
399template <
class Grd ,
class domain_type >
406 ): mProlongations( prolongations ),
407 mLevelMatrices( levelMatrices )
410 mJacRelaxFactor = relax;
412 mMgSmoothings = mgSmoothings;
417template <
class Grd ,
class domain_type >
420 int Level = mNumOfLevels - 1;
424 CoeffVector &solution = boost::fusion::at_c<0>(domain_type_solution.data);
425 CoeffVector &rightHand = boost::fusion::at_c<0>(domain_type_rightHand.data);
427 for(
int i=0;i<mMgIter;i++)
429 mgSolveRecursive( solution , rightHand , Level );
432 mLevelMatrices.levelMatrixStack.front().mmv( solution , defect );
433 relDefect = defect.two_norm()/rightHand.two_norm();
434 if( relDefect < mMaxTol)
436 cout <<
"MG converged: " << i <<
" iterations. rel.Defect = "<< relDefect<<
"\n";
439 else if( i==mMgIter-1 )
440 cout <<
"MG not converged: " << mMgIter <<
" iterations. rel. Defect = "<< relDefect<<
'\n';
445template <
class Grd,
class domain_type >
451 Dune::MatrixAdapter<Dune::BCRSMatrix<M>, CoeffVector, CoeffVector> matrixAdapter( mLevelMatrices.levelMatrixStack.back() );
452 TrivialPreconditioner<CoeffVector> trivialPrecond;
453 Dune::InverseOperatorResult resultInfo;
454 CoeffVector rhsDummy(rightHand);
455 Dune::CGSolver<CoeffVector> cg( matrixAdapter , trivialPrecond , 1.0e-14 , 1000 , 0 );
456 cg.apply( solution , rhsDummy , resultInfo );
457 mTimeDirectSolve += resultInfo.elapsed;
463 jacobiSmooth( solution , rightHand , Level );
464 CoeffVector levelRightHand( mProlongations.prolStack[Level-1].M() ), tmpRhs(rightHand);
465 mLevelMatrices.levelMatrixStack[mNumOfLevels-Level-1].mmv( solution , tmpRhs );
467 mProlongations.prolStack[Level-1].mtv( tmpRhs , levelRightHand );
469 CoeffVector levelError(levelRightHand);
471 mgSolveRecursive( levelError , levelRightHand , Level - 1 );
473 mProlongations.prolStack[Level-1].umv( levelError , solution );
475 jacobiSmooth( solution , rightHand , Level );
481template <
class Grd ,
class domain_type>
484 JacobiSmoother jacobi( mLevelMatrices.levelMatrixStack[ mNumOfLevels-Level-1 ] , mMgSmoothings , mJacRelaxFactor );
485 CoeffVector rhsDummy(rightHand);
486 jacobi.pre( solution , rhsDummy );
487 jacobi.apply( solution , rhsDummy );
488 jacobi.post( solution );
496 for(
int i=0;i<bcrsMatrix.N();i++)
498 for(
int k =0;k<bcrsMatrix.M();k++)
500 if(bcrsMatrix.exists(i,k)) cout << bcrsMatrix[i][k] <<
" ";
515 matrix_.mv(vec_,Avec_);
516 return sqrt(Avec_*vec_);
MlStack(ProlongationStack< Grd > const &ps, Dune::BCRSMatrix< M > const &bcrsA, bool onlyLowerTriangle=false)
std::vector< Dune::BCRSMatrix< M > > levelMatrixStack
void mgSolve(domain_type &solution, domain_type &rightHand)
MultigridSolver(const ProlongationStack< Grd > &prolongations, const MlStack< Grd > &levelMatrices, double relax, double mgIter, double mgSmoothings, double maxTol)
Finds the parent nodes and their interpolation weight for each node in the grid. usage eg....
std::vector< std::vector< FatherSimplexPairs > > levelParentsVector
std::vector< std::vector< int > > levelDisappear
ParentalNodes(Grd const &grd)
std::vector< Dune::BCRSMatrix< M > > prolStack
ProlongationStack(const Grd &grd)
Tools for transfer of data between grids.
This file contains various utility functions that augment the basic functionality of Dune.
auto conjugation(NumaBCRSMatrix< EntryP, IndexP > const &P, NumaBCRSMatrix< EntryA, IndexA > const &A, bool onlyLowerTriangle=false, bool createDiagonal=false)
Creates the conjugation product .
auto const & component(LinearProductSpace< Scalar, Sequence > const &x)
Provides access to the m-th component of a product space.
Class for transformations between ancestors and their children.
void bcrsPrint(const Dune::BCRSMatrix< Dune::FieldMatrix< double, 1, 1 > > &bcrsMatrix)
double energyNorm(const Dune::BCRSMatrix< Dune::FieldMatrix< double, 1, 1 > > &matrix_, const Dune::BlockVector< Dune::FieldVector< double, 1 > > &vec_)