void MCMultiGrid::relax (MultiFab& solL, MultiFab& rhsL, int level, Real eps_rel, Real eps_abs, MCBC_Mode bc_mode) { // // Recursively relax system. Equivalent to multigrid V-cycle. // At coarsest grid, call coarsestSmooth. // if (level < numlevels - 1 ) { for (int i = preSmooth() ; i > 0 ; i--) { Lp.smooth(solL, rhsL, level, bc_mode); } Lp.residual(*res[level], rhsL, solL, level, bc_mode); prepareForLevel(level+1); average(*rhs[level+1], *res[level]); cor[level+1]->setVal(0.0); for (int i = cntRelax(); i > 0 ; i--) { relax(*cor[level+1],*rhs[level+1],level+1,eps_rel,eps_abs,bc_mode); } interpolate(solL, *cor[level+1]); for (int i = postSmooth(); i > 0 ; i--) { Lp.smooth(solL, rhsL, level, bc_mode); } } else { coarsestSmooth(solL, rhsL, level, eps_rel, eps_abs, bc_mode); } }
void MultiGrid::relax (MultiFab& solL, MultiFab& rhsL, int level, Real eps_rel, Real eps_abs, LinOp::BC_Mode bc_mode, Real& cg_time) { BL_PROFILE("MultiGrid::relax()"); // // Recursively relax system. Equivalent to multigrid V-cycle. // At coarsest grid, call coarsestSmooth. // if ( level < numlevels - 1 ) { if ( verbose > 2 ) { Real rnorm = errorEstimate(level, bc_mode); if (ParallelDescriptor::IOProcessor()) { std::cout << " AT LEVEL " << level << '\n'; std::cout << " DN:Norm before smooth " << rnorm << '\n';; } } for (int i = preSmooth() ; i > 0 ; i--) { Lp.smooth(solL, rhsL, level, bc_mode); } Lp.residual(*res[level], rhsL, solL, level, bc_mode); if ( verbose > 2 ) { Real rnorm = norm_inf(*res[level]); if (ParallelDescriptor::IOProcessor()) std::cout << " DN:Norm after smooth " << rnorm << '\n'; } prepareForLevel(level+1); average(*rhs[level+1], *res[level]); cor[level+1]->setVal(0.0); for (int i = cntRelax(); i > 0 ; i--) { relax(*cor[level+1],*rhs[level+1],level+1,eps_rel,eps_abs,bc_mode,cg_time); } interpolate(solL, *cor[level+1]); if ( verbose > 2 ) { Lp.residual(*res[level], rhsL, solL, level, bc_mode); Real rnorm = norm_inf(*res[level]); if ( ParallelDescriptor::IOProcessor() ) { std::cout << " AT LEVEL " << level << '\n'; std::cout << " UP:Norm before smooth " << rnorm << '\n'; } } for (int i = postSmooth(); i > 0 ; i--) { Lp.smooth(solL, rhsL, level, bc_mode); } if ( verbose > 2 ) { Lp.residual(*res[level], rhsL, solL, level, bc_mode); Real rnorm = norm_inf(*res[level]); if ( ParallelDescriptor::IOProcessor() ) std::cout << " UP:Norm after smooth " << rnorm << '\n'; } } else { if ( verbose > 2 ) { Real rnorm = norm_inf(rhsL); if ( ParallelDescriptor::IOProcessor() ) { std::cout << " AT LEVEL " << level << '\n'; std::cout << " DN:Norm before bottom " << rnorm << '\n'; } } coarsestSmooth(solL, rhsL, level, eps_rel, eps_abs, bc_mode, usecg, cg_time); if ( verbose > 2 ) { Lp.residual(*res[level], rhsL, solL, level, bc_mode); Real rnorm = norm_inf(*res[level]); if ( ParallelDescriptor::IOProcessor() ) std::cout << " UP:Norm after bottom " << rnorm << '\n'; } } }