Exemple #1
0
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);
    }
}
Exemple #2
0
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);
        }
    }
}