void MCMultiGrid::coarsestSmooth (MultiFab& solL, MultiFab& rhsL, int level, Real eps_rel, Real eps_abs, MCBC_Mode bc_mode) { prepareForLevel(level); if (usecg == 0) { for (int i = finalSmooth(); i > 0; i--) Lp.smooth(solL, rhsL, level, bc_mode); } else { bool use_mg_precond = false; MCCGSolver cg(Lp, use_mg_precond, level); cg.solve(solL, rhsL, rtol_b, atol_b, bc_mode); for(int i=0; i<nu_b; i++) Lp.smooth(solL, rhsL, level, bc_mode); } }
void MultiGrid::coarsestSmooth (MultiFab& solL, MultiFab& rhsL, int level, Real eps_rel, Real eps_abs, LinOp::BC_Mode bc_mode, int local_usecg, Real& cg_time) { BL_PROFILE("MultiGrid::coarsestSmooth()"); prepareForLevel(level); if ( local_usecg == 0 ) { Real error0 = 0; if ( verbose > 0 ) { error0 = errorEstimate(level, bc_mode); if ( ParallelDescriptor::IOProcessor() ) std::cout << " Bottom Smoother: Initial error (error0) = " << error0 << '\n'; } for (int i = finalSmooth(); i > 0; i--) { Lp.smooth(solL, rhsL, level, bc_mode); if ( verbose > 1 || (i == 1 && verbose) ) { Real error = errorEstimate(level, bc_mode); const Real rel_error = (error0 != 0) ? error/error0 : 0; if ( ParallelDescriptor::IOProcessor() ) std::cout << " Bottom Smoother: Iteration " << i << " error/error0 = " << rel_error << '\n'; } } } else { bool use_mg_precond = false; CGSolver cg(Lp, use_mg_precond, level); cg.setMaxIter(maxiter_b); const Real stime = ParallelDescriptor::second(); int ret = cg.solve(solL, rhsL, rtol_b, atol_b, bc_mode); // // The whole purpose of cg_time is to accumulate time spent in CGSolver. // cg_time += (ParallelDescriptor::second() - stime); if ( ret != 0 ) { if ( smooth_on_cg_unstable ) { // // If the CG solver returns a nonzero value indicating // the problem is unstable. Assume this is not an accuracy // issue and pound on it with the smoother. // if ret == 8, then you have failure to converge // if ( ParallelDescriptor::IOProcessor() && (verbose > 0) ) std::cout << "MultiGrid::coarsestSmooth(): CGSolver returns nonzero. Smoothing ...\n"; coarsestSmooth(solL, rhsL, level, eps_rel, eps_abs, bc_mode, 0, cg_time); } else { // // cg failure probably indicates loss of precision accident. // if ret == 8, then you have failure to converge // setting solL to 0 should be ok. // solL.setVal(0); if ( ParallelDescriptor::IOProcessor() && (verbose > 0) ) { std::cout << "MultiGrid::coarsestSmooth(): setting coarse corr to zero" << '\n'; } } } for (int i = 0; i < nu_b; i++) { Lp.smooth(solL, rhsL, level, bc_mode); } } }