From 3352f104815be206fdeaec508244c9e10e13f54b Mon Sep 17 00:00:00 2001 From: Nils-Arne Dreier <n.dreier@uni-muenster.de> Date: Wed, 9 Feb 2022 17:31:44 +0100 Subject: [PATCH] [amg] fix w-cycle --- dune/istl/paamg/amg.hh | 8 +++++++- dune/istl/paamg/test/amgtest.cc | 22 ++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/dune/istl/paamg/amg.hh b/dune/istl/paamg/amg.hh index 1e05f663e..3825ce851 100644 --- a/dune/istl/paamg/amg.hh +++ b/dune/istl/paamg/amg.hh @@ -1057,8 +1057,14 @@ namespace Dune if(processNextLevel) { // next level - for(std::size_t i=0; i<gamma_; i++) + for(std::size_t i=0; i<gamma_; i++){ mgc(levelContext); + if (levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels()) + break; + if(i+1 < gamma_){ + levelContext.matrix->applyscaleadd(-1., *levelContext.lhs, *levelContext.rhs); + } + } } moveToFineLevel(levelContext, processNextLevel); diff --git a/dune/istl/paamg/test/amgtest.cc b/dune/istl/paamg/test/amgtest.cc index b8dbd0e9a..c7e1843a0 100644 --- a/dune/istl/paamg/test/amgtest.cc +++ b/dune/istl/paamg/test/amgtest.cc @@ -77,7 +77,7 @@ void randomize(const M& mat, V& b) template <class Matrix, class Vector> -void testAMG(int N, int coarsenTarget, int ml) +Dune::InverseOperatorResult testAMG(int N, int coarsenTarget, int ml, int gamma = 1) { std::cout<<"N="<<N<<" coarsenTarget="<<coarsenTarget<<" maxlevel="<<ml<<std::endl; @@ -139,6 +139,7 @@ void testAMG(int N, int coarsenTarget, int ml) criterion.setDefaultValuesIsotropic(2); criterion.setAlpha(.67); criterion.setBeta(1.0e-4); + criterion.setGamma(gamma); criterion.setMaxLevel(ml); criterion.setSkipIsolated(false); // specify pre/post smoother steps @@ -176,6 +177,7 @@ void testAMG(int N, int coarsenTarget, int ml) std::cout<<"CG solving took "<<watch.elapsed()<<" seconds"<<std::endl; */ + return r; } @@ -195,11 +197,19 @@ try if(argc>3) ml = atoi(argv[3]); - { - using Matrix = Dune::BCRSMatrix<XREAL>; - using Vector = Dune::BlockVector<XREAL>; - - testAMG<Matrix,Vector>(N, coarsenTarget, ml); + Dune::InverseOperatorResult gamma1_res; + for(int gamma = 1; gamma<=2;++gamma){ + { + using Matrix = Dune::BCRSMatrix<XREAL>; + using Vector = Dune::BlockVector<XREAL>; + + Dune::InverseOperatorResult res = testAMG<Matrix,Vector>(N, coarsenTarget, ml, gamma); + if(gamma==1){ + gamma1_res = res; + }else{ + assert(res.conv_rate < gamma1_res.conv_rate); + } + } } { -- GitLab