Esempio n. 1
0
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);
  }
}
Esempio n. 2
0
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';
        }
    }
}