コード例 #1
0
ファイル: MCMultiGrid.cpp プロジェクト: dwillcox/BoxLib
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);
  }
}
コード例 #2
0
ファイル: MultiGrid.cpp プロジェクト: suhasjains/BoxLib
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);
        }
    }
}
コード例 #3
0
ファイル: MultiGrid.cpp プロジェクト: suhasjains/BoxLib
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';
        }
    }
}