Ejemplo n.º 1
0
void
getError(LevelData<EBCellFAB>&       a_error,
         const EBISLayout&           a_ebisl,
         const DisjointBoxLayout&    a_dbl,
         const Real&                 a_dx)
{
    EBCellFactory ebcellfact(a_ebisl);
    EBFluxFactory ebfluxfact(a_ebisl);
    a_error.define(a_dbl, 1, IntVect::Zero,   ebcellfact);
    LevelData<EBCellFAB> divFCalc(a_dbl, 1, IntVect::Zero,   ebcellfact);
    LevelData<EBCellFAB> divFExac(a_dbl, 1, IntVect::Zero,   ebcellfact);
    LevelData<EBFluxFAB> faceFlux(a_dbl, 1, IntVect::Zero,   ebfluxfact);

    for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
    {
        a_error[dit()].setVal(0.);
        divFCalc[dit()].setVal(0.);
        divFExac[dit()].setVal(0.);
    }

    setToExactDivFLD(divFExac,  a_ebisl, a_dbl, a_dx);
    setToExactFluxLD(faceFlux,  a_ebisl, a_dbl, a_dx);

    Interval interv(0, 0);
    faceFlux.exchange(interv);

    kappaDivergenceLD(divFCalc, faceFlux, a_ebisl, a_dbl, a_dx);

    for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
    {
        EBCellFAB& errorFAB = a_error[dit()];
        EBCellFAB& exactFAB = divFExac[dit()];
        EBCellFAB& calcuFAB = divFCalc[dit()];

        errorFAB += calcuFAB;
        errorFAB -= exactFAB;
    }
}
Ejemplo n.º 2
0
 void
   Multigrid::avgDown(
                      LevelData<double >& a_resc,
                      const LevelData<double >& a_res
                      )
{
  CH_TIMERS("Multigrid::avgDown");
  // Conservative, finite-volume averaging from coarse to fine.
  BLIterator blit(m_bl);

  for (blit.begin();blit !=blit.end();++blit)
    {
      RectMDArray<double >& resc = a_resc[*blit];
      resc.setVal(0.0);
      Box bxc = a_resc.getBoxLayout()[*blit];
      const RectMDArray<double >& res = a_res[*blit];

      for (int i = 0; i < (1 << DIM); i++)
      {
        resc += g_AvgDown[i](res,bxc);
      }
    }
};
Ejemplo n.º 3
0
/// Set up initial conditions
void SWIBC::initialize(LevelData<FArrayBox>& a_U)
{
    // pout() << "SWIBC::initialize" << endl;
    CH_assert(m_isFortranCommonSet == true);
    CH_assert(m_isDefined == true);

    // Iterator of all grids in this level
    for (DataIterator dit = a_U.dataIterator();
        dit.ok(); ++dit)
    {
        // Storage for current grid
        FArrayBox& U = a_U[dit()];

        // Box of current grid
        Box uBox = U.box();
        uBox &= m_domain;

        // Set up initial condition in this grid
        FORT_LEINITF(CHF_FRA(U),
            CHF_CONST_REAL(m_dx),
            CHF_BOX(uBox));
    }
}
Ejemplo n.º 4
0
// ------------------------------------------------------------
// version of 27 March 2003
Real
integral(const LevelData<NodeFArrayBox>& a_phi,
         const ProblemDomain& a_domain,
         const DisjointBoxLayout* a_finerGridsPtr,
         const int a_nRefFine,
         const Real a_dx,
         const Interval a_comps,
         bool a_verbose)
{
  const DisjointBoxLayout& grids = a_phi.getBoxes();

  LayoutData< Vector<IntVectSet> > IVSVint, IVSVext;
  interiorBoundaryNodes(IVSVint, grids, a_domain);
  exteriorBoundaryNodes(IVSVext, IVSVint, grids);

  Real integralLevel = 0.;
  if (a_finerGridsPtr == NULL)
    {
      integralLevel = integral(a_phi, a_domain,
                       IVSVext,
                       a_dx, a_comps, a_verbose);
    }
  else
    {
      DisjointBoxLayout coarsenedFinerGrids;
      coarsen(coarsenedFinerGrids, *a_finerGridsPtr, a_nRefFine);
      LayoutData< Vector<IntVectSet> > IVSVintFinerCoarsened;
      interiorBoundaryNodes(IVSVintFinerCoarsened, grids,
                            coarsenedFinerGrids, a_domain);

      integralLevel = integral(a_phi, a_domain, coarsenedFinerGrids,
                               IVSVext, IVSVintFinerCoarsened,
                               a_nRefFine, a_dx, a_comps, a_verbose);
    }

  return integralLevel;
}
Ejemplo n.º 5
0
void
EBLevelTGA::
setSourceGhostCells(LevelData<EBCellFAB>&    a_src,
                    const DisjointBoxLayout& a_grids,
                    int a_lev)
{
  int ncomp = a_src.nComp();
  for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
    {
      const Box& grid   = a_grids.get(dit());
      const Box& srcBox = a_src[dit()].box();
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          for (SideIterator sit; sit.ok(); ++sit)
            {
              int iside = sign(sit());
              Box bc_box = adjCellBox(grid, idir, sit(), 1);

              for (int jdir = 0; jdir < SpaceDim; jdir++)
                {
                  //want corners too
                  if (jdir != idir)
                    {
                      bc_box.grow(jdir, 1);
                    }
                }

              //if fails might not have a ghost cell.
              bc_box &= m_eblg[a_lev].getDomain().domainBox();

              CH_assert(srcBox.contains(bc_box));
              if (grid.size(idir) >= 4)
                {
                  FORT_HORESGHOSTBC(CHF_FRA(a_src[dit()].getSingleValuedFAB()),
                                    CHF_BOX(bc_box),
                                    CHF_CONST_INT(idir),
                                    CHF_CONST_INT(iside),
                                    CHF_CONST_INT(ncomp));
                }
              else
                {
                  // valid region not wide enough to apply HOExtrap -- drop
                  // to linear extrap
                  FORT_RESGHOSTBC(CHF_FRA(a_src[dit()].getSingleValuedFAB()),
                                  CHF_BOX(bc_box),
                                  CHF_CONST_INT(idir),
                                  CHF_CONST_INT(iside),
                                  CHF_CONST_INT(ncomp));
                }
              IntVectSet ivs = m_eblg[a_lev].getEBISL()[dit()].getIrregIVS(bc_box);
              for (VoFIterator vofit(ivs, m_eblg[a_lev].getEBISL()[dit()].getEBGraph()); vofit.ok(); ++vofit)
                {
                  for (int icomp = 0; icomp < ncomp; icomp++)
                    {
                      Real valNeigh = 0;
                      Vector<FaceIndex> faces = m_eblg[a_lev].getEBISL()[dit()].getFaces(vofit(), idir, flip(sit()));
                      for (int iface = 0; iface < faces.size(); iface++)
                        {
                          VolIndex vofNeigh = faces[iface].getVoF(flip(sit()));
                          valNeigh += a_src[dit()](vofNeigh, icomp);
                        }
                      if (faces.size() > 1) valNeigh /= faces.size();
                      a_src[dit()](vofit(), icomp) = valNeigh;
                    }
                }
            }
        }
    }
}
Ejemplo n.º 6
0
void VCAMRPoissonOp2::looseGSRB(LevelData<FArrayBox>&       a_phi,
                               const LevelData<FArrayBox>& a_rhs)
{
  CH_TIME("VCAMRPoissonOp2::looseGSRB");
#if 1
  MayDay::Abort("VCAMRPoissonOp2::looseGSRB - Not implemented");
#else
  // This implementation converges at half the rate of "levelGSRB" in
  // multigrid solves
  CH_assert(a_phi.isDefined());
  CH_assert(a_rhs.isDefined());
  CH_assert(a_phi.ghostVect() >= IntVect::Unit);
  CH_assert(a_phi.nComp() == a_rhs.nComp());

  // Recompute the relaxation coefficient if needed.
  resetLambda();

  const DisjointBoxLayout& dbl = a_phi.disjointBoxLayout();

  DataIterator dit = a_phi.dataIterator();

  // fill in intersection of ghostcells and a_phi's boxes
  {
    CH_TIME("VCAMRPoissonOp2::looseGSRB::homogeneousCFInterp");
    homogeneousCFInterp(a_phi);
  }

  {
    CH_TIME("VCAMRPoissonOp2::looseGSRB::exchange");
    a_phi.exchange(a_phi.interval(), m_exchangeCopier);
  }

  // now step through grids...
  for (dit.begin(); dit.ok(); ++dit)
  {
    // invoke physical BC's where necessary
    {
      CH_TIME("VCAMRPoissonOp2::looseGSRB::BCs");
      m_bc(a_phi[dit], dbl[dit()], m_domain, m_dx, true);
    }

    const Box& region = dbl.get(dit());
    const FluxBox& thisBCoef  = (*m_bCoef)[dit];

    int whichPass = 0;

#if CH_SPACEDIM == 1
    FORT_GSRBHELMHOLTZVC1D
#elif CH_SPACEDIM == 2
    FORT_GSRBHELMHOLTZVC2D
#elif CH_SPACEDIM == 3
    FORT_GSRBHELMHOLTZVC3D
#else
    This_will_not_compile!
#endif
                          (CHF_FRA(a_phi[dit]),
                           CHF_CONST_FRA(a_rhs[dit]),
                           CHF_BOX(region),
                           CHF_CONST_REAL(m_dx),
                           CHF_CONST_REAL(m_alpha),
                           CHF_CONST_FRA((*m_aCoef)[dit]),
                           CHF_CONST_REAL(m_beta),
#if CH_SPACEDIM >= 1
                           CHF_CONST_FRA(thisBCoef[0]),
#endif
#if CH_SPACEDIM >= 2
                           CHF_CONST_FRA(thisBCoef[1]),
#endif
#if CH_SPACEDIM >= 3
                           CHF_CONST_FRA(thisBCoef[2]),
#endif
#if CH_SPACEDIM >= 4
                           This_will_not_compile!
#endif
                           CHF_CONST_FRA(m_lambda[dit]),
                           CHF_CONST_INT(whichPass));

    whichPass = 1;

#if CH_SPACEDIM == 1
    FORT_GSRBHELMHOLTZVC1D
#elif CH_SPACEDIM == 2
    FORT_GSRBHELMHOLTZVC2D
#elif CH_SPACEDIM == 3
    FORT_GSRBHELMHOLTZVC3D
#else
    This_will_not_compile!
#endif
                          (CHF_FRA(a_phi[dit]),
                           CHF_CONST_FRA(a_rhs[dit]),
                           CHF_BOX(region),
                           CHF_CONST_REAL(m_dx),
                           CHF_CONST_REAL(m_alpha),
                           CHF_CONST_FRA((*m_aCoef)[dit]),
                           CHF_CONST_REAL(m_beta),
#if CH_SPACEDIM >= 1
                           CHF_CONST_FRA(thisBCoef[0]),
#endif
#if CH_SPACEDIM >= 2
                           CHF_CONST_FRA(thisBCoef[1]),
#endif
#if CH_SPACEDIM >= 3
                           CHF_CONST_FRA(thisBCoef[2]),
#endif
#if CH_SPACEDIM >= 4
                           This_will_not_compile!
#endif
                           CHF_CONST_FRA(m_lambda[dit]),
                           CHF_CONST_INT(whichPass));
  } // end loop through grids
#endif
}
Ejemplo n.º 7
0
void
EBMGInterp::fillGhostCellsPWC(LevelData<EBCellFAB>& a_data,
                              const EBISLayout&     a_ebisl,
                              const ProblemDomain&  a_dom)
{
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      if (m_ghost[idir] < 1)
        {
          MayDay::Error("EBMGInterp:I need a ghost cell for linear interpolation");
        }
    }
  //extrapolate to every ghost cell
  const DisjointBoxLayout& dbl = a_data.disjointBoxLayout();
  for (DataIterator dit = dbl.dataIterator(); dit.ok(); ++dit)
    {
      const Box& grid = dbl.get(dit());
      const EBGraph& ebgraph = a_ebisl[dit()].getEBGraph();
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          for (SideIterator sit; sit.ok(); ++sit)
            {
              Side::LoHiSide flipSide = flip(sit());
              Box ghostBox = adjCellBox(grid, idir, sit(), 1);

              for (BoxIterator boxit(ghostBox); boxit.ok(); ++boxit)
                {
                  if (a_dom.contains(boxit()))
                    {
                      Vector<VolIndex> vofs = ebgraph.getVoFs(boxit());
                      for (int ivof = 0; ivof < vofs.size(); ivof++)
                        {
                          Real extrapVal = 0;
                          Vector<FaceIndex> faces = ebgraph.getFaces(vofs[ivof], idir, flipSide);
                          for (int ivar = 0; ivar < a_data.nComp(); ivar++)
                            {
                              for (int iface = 0; iface < faces.size(); iface++)
                                {
                                  const VolIndex& flipVoF = faces[iface].getVoF(flipSide);
                                  extrapVal += a_data[dit()](flipVoF, ivar);
                                }
                              if (faces.size() > 1) extrapVal /= faces.size();
                              a_data[dit()](vofs[ivof], ivar) = extrapVal;
                            }
                        }

                    }
                  else
                    {
                      //just put in the single valued part of the data holder something sensible
                      //if not inside domain
                      int isign = sign(flipSide);
                      BaseFab<Real>& bfdata = a_data[dit()].getSingleValuedFAB();
                      IntVect otherIV = boxit() + isign*BASISV(idir);
                      for (int ivar = 0; ivar < a_data.nComp(); ivar++)
                        {
                          bfdata(boxit(), ivar) = bfdata(otherIV, ivar);
                        }
                    }
                }
            }
        }
    }
  //do exchange to overwrite ghost cells where there exists real data
  a_data.exchange();
}
Ejemplo n.º 8
0
void EBPoissonOp::
restrictResidual(LevelData<EBCellFAB>&       a_resCoar,
                 LevelData<EBCellFAB>&       a_phiThisLevel,
                 const LevelData<EBCellFAB>& a_rhsThisLevel)
{
  CH_TIME("EBPoissonOp::restrictResidual");

  CH_assert(a_resCoar.nComp() == 1);
  CH_assert(a_phiThisLevel.nComp() == 1);
  CH_assert(a_rhsThisLevel.nComp() == 1);

  LevelData<EBCellFAB> resThisLevel;
  bool homogeneous = true;

  EBCellFactory ebcellfactTL(m_eblg.getEBISL());
  IntVect ghostVec = a_rhsThisLevel.ghostVect();

  resThisLevel.define(m_eblg.getDBL(), 1, ghostVec, ebcellfactTL);

  // Get the residual on the fine grid
  residual(resThisLevel,a_phiThisLevel,a_rhsThisLevel,homogeneous);

  // now use our nifty averaging operator
  Interval variables(0, 0);
  CH_assert(m_hasMGObjects);
  m_ebAverageMG.average(a_resCoar, resThisLevel, variables);

#ifdef DO_EB_RHS_CORRECTION
  // Apply error-correction modification to restricted RHS
  // Right now this only works with Dirichlet BC's, and only makes sense for the EB

  int correctionType = 0;    // Change this to activate RHS correction

  if (correctionType != 0)
    {
      for (DataIterator dit = a_resCoar.disjointBoxLayout().dataIterator(); dit.ok(); ++dit)
        {
          EBCellFAB&       resFAB = a_resCoar[dit()];                      // Extract the FAB for this box
          const EBISBox&   ebis   = resFAB.getEBISBox();                   // Get the set of all IntVect indices

          // Iterate over the parts of the RHS corresponding to the irregular cells,
          // correcting the RHS in each cell
          VoFIterator ebvofit(ebis.getIrregIVS(ebis.getRegion()), ebis.getEBGraph());
          for (ebvofit.reset(); ebvofit.ok(); ++ebvofit)
            {
              for (int icomp = 0; icomp < resFAB.nComp(); ++icomp)    // For each component of the residual on this VoF
                {
                  if (correctionType == 1)
                    {
                      // Setting the residual to zero on the irregular cells gives convergence,
                      // though the rate isn't as good as the full correction
                      resFAB(ebvofit(), icomp) = 0.0;
                    }
                  else if (correctionType == 2)
                    {
                      // Kludge valid only for pseudo-1D test case.  May not work for you.
                      Real kappa = ebis.volFrac(ebvofit());
                      kappa = (kappa > 0.5 ? kappa : 0.5);    // Floor on kappa to prevent dividing by a tiny number
                      Real rhoCoeff = (kappa + 0.5)/(2.0*kappa);
                      resFAB(ebvofit(), icomp) *= (1.0 - rhoCoeff);
                    }
                  // else silently do nothing
                }
            }
        }
    }
#endif
}
Ejemplo n.º 9
0
void VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>&        a_phiFine,
                            const LevelData<FArrayBox>&        a_phi,
                            LevelData<FArrayBox>&              a_residual,
                            AMRLevelOp<LevelData<FArrayBox> >* a_finerOp)
{
  CH_TIME("VCAMRPoissonOp2::reflux");

  int ncomp = 1;
  ProblemDomain fineDomain = refine(m_domain, m_refToFiner);
  LevelFluxRegister levfluxreg(a_phiFine.disjointBoxLayout(),
                               a_phi.disjointBoxLayout(),
                               fineDomain,
                               m_refToFiner,
                               ncomp);

  levfluxreg.setToZero();
  Interval interv(0,a_phi.nComp()-1);

  DataIterator dit = a_phi.dataIterator();
  for (dit.reset(); dit.ok(); ++dit)
    {
      const FArrayBox& coarfab = a_phi[dit];
      const FluxBox& coarBCoef  = (*m_bCoef)[dit];
      const Box& gridBox = a_phi.getBoxes()[dit];

      for (int idir = 0; idir < SpaceDim; idir++)
        {
          FArrayBox coarflux;
          Box faceBox = surroundingNodes(gridBox, idir);
          getFlux(coarflux, coarfab, coarBCoef , faceBox, idir);

          Real scale = 1.0;
          levfluxreg.incrementCoarse(coarflux, scale,dit(),
                                     interv,interv,idir);
        }
    }
  LevelData<FArrayBox>& p = ( LevelData<FArrayBox>&)a_phiFine;

  // has to be its own object because the finer operator
  // owns an interpolator and we have no way of getting to it
  VCAMRPoissonOp2* finerAMRPOp = (VCAMRPoissonOp2*) a_finerOp;
  QuadCFInterp& quadCFI = finerAMRPOp->m_interpWithCoarser;

  quadCFI.coarseFineInterp(p, a_phi);
  // p.exchange(a_phiFine.interval()); // BVS is pretty sure this is not necesary.
  IntVect phiGhost = p.ghostVect();

  DataIterator ditf = a_phiFine.dataIterator();
  const  DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout();
  for (ditf.reset(); ditf.ok(); ++ditf)
    {
      const FArrayBox& phifFab = a_phiFine[ditf];
      const FluxBox& fineBCoef  = (*(finerAMRPOp->m_bCoef))[ditf];
      const Box& gridbox = dblFine.get(ditf());
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          int normalGhost = phiGhost[idir];
          SideIterator sit;
          for (sit.begin(); sit.ok(); sit.next())
            {
              Side::LoHiSide hiorlo = sit();
              Box fabbox;
              Box facebox;

              // assumption here that the stencil required
              // to compute the flux in the normal direction
              // is 2* the number of ghost cells for phi
              // (which is a reasonable assumption, and probably
              // better than just assuming you need one cell on
              // either side of the interface
              // (dfm 8-4-06)
              if (sit() == Side::Lo)
                {
                  fabbox = adjCellLo(gridbox,idir, 2*normalGhost);
                  fabbox.shift(idir, 1);
                  facebox = bdryLo(gridbox, idir,1);
                }
              else
                {
                  fabbox = adjCellHi(gridbox,idir, 2*normalGhost);
                  fabbox.shift(idir, -1);
                  facebox = bdryHi(gridbox, idir, 1);
                }

              // just in case we need ghost cells in the transverse direction
              // (dfm 8-4-06)
              for (int otherDir=0; otherDir<SpaceDim; ++otherDir)
                {
                  if (otherDir != idir)
                    {
                      fabbox.grow(otherDir, phiGhost[otherDir]);
                    }
                }
              CH_assert(!fabbox.isEmpty());

              FArrayBox phifab(fabbox, a_phi.nComp());
              phifab.copy(phifFab);

              FArrayBox fineflux;
              getFlux(fineflux, phifab, fineBCoef, facebox, idir,
                      m_refToFiner);

              Real scale = 1.0;
              levfluxreg.incrementFine(fineflux, scale, ditf(),
                                       interv, interv, idir, hiorlo);
            }
        }
    }

  Real scale =  1.0/m_dx;
  levfluxreg.reflux(a_residual, scale);
}
Ejemplo n.º 10
0
// ---------------------------------------------------------------
// tag cells for regridding
void
AMRNavierStokes::tagCells(IntVectSet & a_tags)
{
  if (s_verbosity >= 3)
    {
      pout () << "AMRNavierStokes::tagCells " << m_level << endl;
    }

  IntVectSet local_tags;

  // create tags based on something or other
  // for now, don't do anything
  const DisjointBoxLayout& level_domain = newVel().getBoxes();

  if (s_tag_vorticity)
    {
      LevelData<FArrayBox> vorticity;
      LevelData<FArrayBox> mag_vorticity;
      if (SpaceDim == 2)
        {
          vorticity.define(level_domain,1);
        }
      else if (SpaceDim == 3)
        {
          vorticity.define(level_domain,SpaceDim);
          mag_vorticity.define(level_domain,1);
        }
      computeVorticity(vorticity);

      Interval vortInterval(0,0);
      if (SpaceDim == 3)
        {
          vortInterval = Interval(0,SpaceDim-1);
        }
      Real tagLevel = norm(vorticity, vortInterval, 0);
      // Real tagLevel = 1.0;
      //tagLevel *= s_vort_factor/m_dx;
      // actually tag where vort*dx > s_vort_factor*max(vort)
      tagLevel = s_vort_factor/m_dx;

      if (tagLevel > 0)
        {
          // now tag where vorticity magnitude is greater than or equal
          // to tagLevel
          DataIterator dit = vorticity.dataIterator();
          for (dit.reset(); dit.ok(); ++dit)
            {
              FArrayBox& vortFab = vorticity[dit];

              // this only needs to be done in 3d...
              if (SpaceDim==3)
                {
                  FArrayBox& magVortFab = mag_vorticity[dit];
                  FORT_MAGVECT(CHF_FRA1(magVortFab,0),
                               CHF_CONST_FRA(vortFab),
                               CHF_BOX(level_domain[dit]));
                }

              BoxIterator bit(vortFab.box());
              for (bit.begin(); bit.ok(); ++bit)
                {
                  const IntVect& iv = bit();
                  if (SpaceDim == 2)
                    {
                      if (abs(vortFab(iv)) >= tagLevel)
                        {
                          local_tags |= iv;
                        }
                    }
                  else if (SpaceDim == 3)
                    {
                      FArrayBox& magVortFab = mag_vorticity[dit];
                      if (abs(magVortFab(iv)) >= tagLevel)
                        {
                          local_tags |= iv;
                        }
                    } // end if DIM=3
                } // end loop over interior of box
            } // loop over grids
        } // if taglevel > 0
    } // if tagging on vorticity

  a_tags = local_tags;
}
Ejemplo n.º 11
0
int
testIFFAB(const DisjointBoxLayout&              a_dbl,
          const EBISLayout       &              a_ebisl,
          const Box              &              a_domain,
          const Real             &              a_dx )
{
  int faceDir = 0;
  int nFlux = 1;
  LayoutData<IntVectSet>        irregSetsGrown;
  LevelData< BaseIFFAB<Real> > fluxInterpolant;

  EBArith::defineFluxInterpolant(fluxInterpolant,
                                 irregSetsGrown,
                                 a_dbl, a_ebisl, a_domain, nFlux, faceDir);

  //set source fab to right ans over set only on grids interior cells
  int ibox = 0;
  for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
    {
      BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()];
      srcFab.setVal(-1.0);
      IntVectSet ivsSmall = irregSetsGrown[dit()];
      const Box& grid = a_dbl.get(dit());
      ivsSmall &=  grid;
      for (FaceIterator faceit(ivsSmall, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary);
          faceit.ok(); ++faceit)
        {
          srcFab(faceit(), 0) = rightAns(faceit());
        }
      ibox++;
    }

  //diagnostics
  if (g_diagnosticMode)
    {
      pout() << " diagnostics for processor " << procID() << endl;
      for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
        {
          const IntVectSet& ivsGrown = irregSetsGrown[dit()];
          const Box& grid = a_dbl.get(dit());
          pout() << "============" << endl;
          pout() << " box = " << grid;
          pout() << ", full ivs = "  ;
          dumpIVS(&ivsGrown);
          pout() << "============" << endl;
          for (LayoutIterator lit = a_dbl.layoutIterator(); lit.ok(); ++lit)
            {
              const Box& grid2 = a_dbl.get(lit());
              IntVectSet ivsIntersect = ivsGrown;
              ivsIntersect &= grid2;
              pout() << "intersection with box " << grid2 << " = ";
              dumpIVS(&ivsIntersect);
              pout() << "============" << endl;
            }
        }

    }

  BaseIFFAB<Real>::setVerbose(true);
  //do the evil exchange
  Interval interv(0, nFlux-1);
  fluxInterpolant.exchange(interv);
  ibox = 0;
  //check the answer over grown set
  Real tolerance = 0.001;
  for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
    {
      const BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()];
      const IntVectSet& ivsGrown = irregSetsGrown[dit()];
      for (FaceIterator faceit(ivsGrown, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary);
          faceit.ok(); ++faceit)
        {
          Real correct = rightAns(faceit());
          Real fabAns  =   srcFab(faceit(), 0);
          if (Abs(correct - fabAns)  > tolerance)
            {
              pout() << "iffab test failed at face "
                     << faceit().gridIndex(Side::Lo)
                     << faceit().gridIndex(Side::Hi) << endl;
              pout() << " right ans = " << correct  << endl;
              pout() << " data holds= " << fabAns << endl;

              int eekflag = -3;
              return eekflag;
            }

        }
      ibox++;
    }
  return 0;
}
Ejemplo n.º 12
0
// migrate only object LDStat in group
// leaf nodes actually migrate objects
void HybridBaseLB::ReceiveMigration(LBMigrateMsg *msg)
{
#if CMK_LBDB_ON
#if CMK_MEM_CHECKPOINT
  CkResetInLdb();
#endif
  FindNeighbors();

  int atlevel = msg->level - 1;

  DEBUGF(("[%d] ReceiveMigration\n", CkMyPe()));

  LevelData *lData = levelData[atlevel];

  // only non NULL when level > 0
  LDStats *statsData = lData->statsData;

  // do LDStats migration
  const int me = CkMyPe();
  lData->migrates_expected = 0;
  for(int i=0; i < msg->n_moves; i++) {
    MigrateInfo& move = msg->moves[i];
    // incoming
    if (move.from_pe != me && move.to_pe == me) {
      // I can not be the parent node
      DEBUGF(("[%d] expecting LDStats object from %d\n",me,move.from_pe));
      // will receive a ObjData message
      lData->migrates_expected ++;
    }
    else if (move.from_pe == me) {   // outgoing
      if (statsData) {		// this is inner node
        // send objdata
        int obj;
        int found = 0;
        for (obj = 0; obj<statsData->n_objs; obj++) {
          if (move.obj.omID() == statsData->objData[obj].handle.omID() && 
            move.obj.objID() == statsData->objData[obj].handle.objID())
          {
            DEBUGF(("[%d] level: %d sending objData %d to %d. \n", CkMyPe(), atlevel, obj, move.to_pe));
	    found = 1;
            // TODO send comm data
            CkVec<LDCommData> comms;
            collectCommData(obj, comms, atlevel);
	    if (move.to_pe != -1) {
              // this object migrates to another PE of the parent domain
              thisProxy[move.to_pe].ObjMigrated(statsData->objData[obj], comms.getVec(), comms.size(), atlevel);
            }
            lData->outObjs.push_back(MigrationRecord(move.obj, lData->children[statsData->from_proc[obj]], -1));
            statsData->removeObject(obj);
            break;
          }
        }
        CmiAssert(found == 1);
      }
      else {		// this is leave node
        if (move.to_pe == -1) {
          lData->outObjs.push_back(MigrationRecord(move.obj, CkMyPe(), -1));
        }
        else {
          // migrate the object
          theLbdb->Migrate(move.obj,move.to_pe);
        }
      }
    }   // end if
  }

  if (lData->migrationDone())
    StatsDone(atlevel);
#endif
}
Ejemplo n.º 13
0
 LevelData &levelData(void)
 {
     levelData_.wrap(buffer_, offset_ + 36, actingVersion_, bufferLength_);
     return levelData_;
 }
//----------------------------------------------------------------------------
void
EBNormalizeByVolumeFraction::
operator()(LevelData<EBCellFAB>& a_Q,
           const Interval& a_compInterval) const
{
  CH_TIME("EBNormalizer::operator()");
   // Endpoints of the given interval.
   int begin = a_compInterval.begin(), end = a_compInterval.end(),
       length = a_compInterval.size();

   // Loop over the EBISBoxes within our grid. The EB data structures are
   // indexed in the same manner as the non-EB data structures, so we piggy-
   // back the former on the latter.
   a_Q.exchange();
   EBISLayout ebisLayout = m_levelGrid.getEBISL();
   DisjointBoxLayout layout = m_levelGrid.getDBL();
   for (DataIterator dit = layout.dataIterator(); dit.ok(); ++dit)
   {
      const EBISBox& box = ebisLayout[dit()];
      EBCellFAB& QFAB = a_Q[dit()];

      // Go over the irregular cells in this box.
      const IntVectSet& irregCells = box.getIrregIVS(layout[dit()]);

      // The average has to be computed from the uncorrected data from all
      // the neighbors, so we can't apply the corrections in place. For now,
      // we stash them in a map.
      map<VolIndex, vector<Real> > correctedValues;
      for (VoFIterator vit(irregCells, box.getEBGraph()); vit.ok(); ++vit)
        {
          Real kappajSum = 0.0;
          vector<Real> kappajQjSum(length, 0.0);

          // Get all of the indices of the VoFs within a monotone path
          // radius of 1.
          VolIndex vofi = vit();
          Vector<VolIndex> vofjs;
          EBArith::getAllVoFsInMonotonePath(vofjs, vofi, box, 1);

          // Accumulate the contributions from the neighboring cells.
          for (unsigned int j = 0; j < vofjs.size(); ++j)
            {
              VolIndex vofj = vofjs[j];

              Real kappaj = box.volFrac(vofj);
              for (int icomp = begin; icomp <= end; ++icomp)
                {
                  kappajQjSum[icomp] += QFAB(vofj, icomp);
                }

              // Add this volume fraction to the sum.
              kappajSum += kappaj;
            }

          if (kappajSum > 0.)
            {
              // Normalize the quantity and stow it.
              vector<Real> correctedValue(length);
              //         Real kappai = box.volFrac(vofi);  //unused dtg
              for (int icomp = begin; icomp <= end; ++icomp)
                {
                  // correctedValue[icomp - begin] =
                  //    QFAB(vofi, icomp) + (1.0 - kappai) * kappajQjSum[icomp] / kappajSum;
                  correctedValue[icomp - begin] = kappajQjSum[icomp] / kappajSum;
                }
              correctedValues[vofi] = correctedValue;
            }
        }

      // Apply the corrections.
      for (map<VolIndex, vector<Real> >::const_iterator
           cit = correctedValues.begin(); cit != correctedValues.end(); ++cit)
      {
         for (int icomp = begin; icomp <= end; ++icomp)
         {
            QFAB(cit->first, icomp) = cit->second[icomp-begin];
         }
      }
   }
}
Ejemplo n.º 15
0
void HybridBaseLB::PropagateInfo(Location *loc, int n, int fromlevel)
{
#if CMK_LBDB_ON
  int i, obj;
  int atlevel = fromlevel - 1;
  LevelData *lData = levelData[atlevel];
  CkVec<Location> &matchedObjs = lData->matchedObjs;
  //CkVec<Location> &unmatchedObjs = lData->unmatchedObjs;
  std::map<LDObjKey, int> &unmatchedObjs = lData->unmatchedObjs;

  if (atlevel > 0) {
    if (_lb_args.debug() > 1)
      CkPrintf("[%d] PropagateInfo at level %d started at %f\n",
	        CkMyPe(), atlevel, CkWallTimer());
    // search in unmatched
#if 0
    for (i=0; i<n; i++) {
       // search and see if we have answer, put to matched
       // store in unknown
       for (obj=0; obj<unmatchedObjs.size(); obj++) {
         if (loc[i].key == unmatchedObjs[obj].key) {
           // answer must exist now
           CmiAssert(unmatchedObjs[obj].loc != -1 || loc[i].loc != -1);
           if (unmatchedObjs[obj].loc == -1) unmatchedObjs[obj].loc = loc[i].loc;
           matchedObjs.push_back(unmatchedObjs[obj]);
           unmatchedObjs.remove(obj);
           break;
         }
       }
    }
#else
   for (int i=0; i<n; i++) {
       // search and see if we have answer, put to matched
     const LDObjKey key = loc[i].key;
     std::map<LDObjKey, int>::iterator iter = unmatchedObjs.find(key);
     if (iter != unmatchedObjs.end()) {
       // answer must exist now
       CmiAssert(iter->second != -1 || loc[i].loc != -1);
       if (loc[i].loc == -1) loc[i].loc = iter->second;
       matchedObjs.push_back(loc[i]);
       unmatchedObjs.erase(iter);
     }
   }
#endif
    CmiAssert(unmatchedObjs.size() == 0);
    DEBUGF(("[%d] level %d PropagateInfo had %d matchedObjs. \n", CkMyPe(), atlevel, matchedObjs.size()));

      // send down
    thisProxy.PropagateInfo(matchedObjs.getVec(), matchedObjs.size(), atlevel, lData->nChildren, lData->children);

    lData->statsData->clear();
    matchedObjs.free();
  }
  else {  // leaf node
      // now start to migrate
    CkVec<MigrationRecord> & outObjs = lData->outObjs;
    int migs = outObjs.size() + newObjs.size();
    for (i=0; i<outObjs.size(); i++) {
      if (outObjs[i].toPe == -1) {
        for (obj=0; obj<n; obj++) {
          if (loc[obj].key.omID() == outObjs[i].handle.omID() &&
              loc[obj].key.objID() == outObjs[i].handle.objID()) {
            outObjs[i].toPe = loc[obj].loc;
            break;
          }
        }
        CmiAssert(obj < n);
      }
      CmiAssert(outObjs[i].toPe != -1);
        // migrate now!
      theLbdb->Migrate(outObjs[i].handle,outObjs[i].toPe);
    }   // end for out
    // incoming
    lData->migrates_expected = 0;
    future_migrates_expected = 0;
    for (i=0; i<newObjs.size(); i++) {
      if (newObjs[i].loc == -1) {
        for (obj=0; obj<n; obj++) {
          if (loc[obj].key == newObjs[i].key) {
            newObjs[i].loc = loc[obj].loc;
            break;
          }
        }
        CmiAssert(obj < n);
      }
      CmiAssert(newObjs[i].loc != -1);
      lData->migrates_expected++;
    }   // end of for
    DEBUGF(("[%d] expecting %d\n", CkMyPe(), lData->migrates_expected));
    if (lData->migrationDone()) {
      MigrationDone(1);
    }
  }
#endif
}
//----------------------------------------------------------------------------
void
EBNormalizeByVolumeFraction::
operator()(LevelData<EBCellFAB>& a_Q) const
{
   return (*this)(a_Q, Interval(0, a_Q.nComp()-1));
}
Ejemplo n.º 17
0
// -----------------------------------------------------------------------------
// Interpolate ghosts at CF interface using zeros on coarser grids.
// Only do one face.
// -----------------------------------------------------------------------------
void homogeneousCFInterp (LevelData<FArrayBox>& a_phif,
                          const DataIndex&      a_index,
                          const int             a_dir,
                          const Side::LoHiSide  a_side,
                          const Real            a_fineDxDir,
                          const Real            a_crseDxDir,
                          const CFRegion&       a_cfRegion)
{
    CH_TIME("homogeneousCFInterp (single grid)");

    // Sanity checks
    CH_assert((a_dir >= 0) && (a_dir < SpaceDim));
    CH_assert(a_phif.ghostVect()[a_dir] >= 1);

    // Get the C/F region
    const CFIVS* cfivs_ptr = NULL;
    if (a_side == Side::Lo) {
        CFRegion& castCFRegion = (CFRegion&)a_cfRegion;
        cfivs_ptr = &(castCFRegion.loCFIVS(a_index, a_dir));
    } else {
        CFRegion& castCFRegion = (CFRegion&)a_cfRegion;
        cfivs_ptr = &(castCFRegion.hiCFIVS(a_index, a_dir));
    }

    if (cfivs_ptr->isPacked()) {
        // The C/F region is a box.
        // Iterate over the box and interpolate.
        int ihiorlo = sign(a_side);
        FArrayBox& phiFab = a_phif[a_index];
        const Box region = cfivs_ptr->packedBox();

        CH_assert(a_crseDxDir > 0.0 || region.isEmpty());

        if (phiFab.box().size(a_dir) == 3) {
            // Linear interpolation of fine ghosts assuming
            // all zeros on coarser level.
            FORTNT_INTERPHOMOLINEAR(
                CHF_FRA(phiFab),
                CHF_BOX(region),
                CHF_CONST_REAL(a_fineDxDir),
                CHF_CONST_REAL(a_crseDxDir),
                CHF_CONST_INT(a_dir),
                CHF_CONST_INT(ihiorlo));
        } else {
            // Quadratic interpolation of fine ghosts assuming
            // all zeros on coarser level.
            FORTNT_INTERPHOMO(
                CHF_FRA(phiFab),
                CHF_BOX(region),
                CHF_CONST_REAL(a_fineDxDir),
                CHF_CONST_REAL(a_crseDxDir),
                CHF_CONST_INT(a_dir),
                CHF_CONST_INT(ihiorlo));
        }
    } else {
        // The C/F region is sparse.
        // Iterate over the IVS and interpolate.
        const IntVectSet& interp_ivs = cfivs_ptr->getFineIVS();

        if (!interp_ivs.isEmpty()) {
            CH_assert(a_crseDxDir > 0.0);
            interpOnIVSHomo(a_phif,
                            a_index,
                            a_dir,
                            a_side,
                            interp_ivs,
                            a_fineDxDir,
                            a_crseDxDir);
        }
    }
}
Ejemplo n.º 18
0
// ---------------------------------------------------------
int main(int argc, char* argv[])
{
  int status = 0; // number of errors detected.
  // Do nothing if DIM > 3.
#if (CH_SPACEDIM <= 3)
#ifdef CH_MPI
  MPI_Init (&argc, &argv);
#endif
  //scoping trick
  {
    // test parameters
    const int testOrder = 4; // expected order of convergence

    // A test is considered as a failure
    //  if its convergence rate is smaller than below.
    Real targetConvergeRate = testOrder*0.9;
#ifdef CH_USE_FLOAT
    targetConvergeRate = testOrder*0.89;
#endif

    // number of ghost cells being interpolated
    int numGhost = 5;

    // refinement ratio between coarse and fine levels
    int refRatio = 4;

    Vector<Interval> fixedDimsAll;
    if (SpaceDim == 3)
      {
        fixedDimsAll.push_back(Interval(SpaceDim-1, SpaceDim-1));
      }
    // Always include empty interval, meaning NO fixed dimensions.
    fixedDimsAll.push_back(Interval());

    // real domain has length 1. in every dimension
    RealVect physLength = RealVect::Unit;

    for (int ifixed = 0; ifixed < fixedDimsAll.size(); ifixed++)
      {
        const Interval& fixedDims = fixedDimsAll[ifixed];
        int nfixed = fixedDims.size();

        IntVect interpUnit = IntVect::Unit;
        IntVect refineVect = refRatio * IntVect::Unit;
        for (int dirf = fixedDims.begin(); dirf <= fixedDims.end(); dirf++)
          {
            interpUnit[dirf] = 0;
            refineVect[dirf] = 1;
          }

        // No ghost cells in fixed dimensions.
        IntVect ghostVect = numGhost * interpUnit;

#ifdef CH_USE_FLOAT
        // Single precision doesn't get us very far.
#if (CH_SPACEDIM == 1)
        int domainLengthMin = 16;
        int domainLengthMax = 32;
#else
        int domainLengthMin = 32;
        int domainLengthMax = 64;
#endif
#endif

#ifdef CH_USE_DOUBLE
        int domainLengthMin = 32;
#if CH_SPACEDIM >= 3
        int domainLengthMax = 64;
        if (nfixed > 0) domainLengthMax = 128;
#else
        int domainLengthMax = 512;
#endif
#endif

        Vector<int> domainLengths;
        int len = domainLengthMin;
        while (len <= domainLengthMax)
          {
            domainLengths.push_back(len);
            len *= 2;
          }
        int nGrids = domainLengths.size();

        if (nGrids > 0)
          {
            pout() << endl
                   << "Testing FourthOrderFillPatch DIM=" << SpaceDim;
            if (nfixed > 0)
              {
                pout() << " fixing " << fixedDims.begin()
                       << ":" << fixedDims.end();
              }
            pout() << endl;
            pout() << "size  "
                   << "max diff   rate";
            pout() << endl;
          }

        Real diffMaxCoarser;
        for (int iGrid = 0; iGrid < nGrids; iGrid++)
          {
            int domainLength = domainLengths[iGrid];
            IntVect lenCoarse = domainLength * IntVect::Unit;

            RealVect dxCoarseVect = physLength / RealVect(lenCoarse);
            RealVect dxFineVect = dxCoarseVect / RealVect(refineVect);

            Box coarDomain, fineDomain;
            Vector<Box> coarBoxes, fineBoxes;
            setHierarchy(lenCoarse,
                         refineVect,
                         coarBoxes,
                         fineBoxes,
                         coarDomain,
                         fineDomain);

            mortonOrdering(coarBoxes);
            mortonOrdering(fineBoxes);

            Vector<int> procCoar(coarBoxes.size());
            Vector<int> procFine(fineBoxes.size());
            LoadBalance(procCoar, coarBoxes);
            LoadBalance(procFine, fineBoxes);

            DisjointBoxLayout dblCoar(coarBoxes, procCoar);
            DisjointBoxLayout dblFine(fineBoxes, procFine);

            ProblemDomain probCoar(coarDomain);
            ProblemDomain probFine(fineDomain);

            FourthOrderFillPatch interpolator;
            int ncomp = 1;
            // Set coarseGhostsFill = ceil(numGhosts / refRatio).
            // int coarseGhostsFill = numGhost / refRatio;
            // if (coarseGhostsFill * refRatio < numGhost) coarseGhostsFill++;
            bool fixedTime = true;
            interpolator.define(dblFine, dblCoar, ncomp,
                                probCoar, refRatio, numGhost, fixedTime,
                                fixedDims);
                                
            LevelData<FArrayBox> exactCoarse(dblCoar, ncomp);

            // Set exact value of function on coarse level.
            for (DataIterator dit = exactCoarse.dataIterator(); dit.ok(); ++dit)
              {
                CH_TIME("computing exactCoarse on FAB");
                FArrayBox& exactCoarseFab = exactCoarse[dit];
                const Box& bx = exactCoarseFab.box();
                // Get average of function on each cell.
                for (BoxIterator bit(bx); bit.ok(); ++bit)
                  {
                    const IntVect& iv = bit();
                    RealVect cellLo = RealVect(iv) * dxCoarseVect;
                    RealVect cellHi = cellLo + dxCoarseVect;
                    exactCoarseFab(iv, 0) = avgFunVal(cellLo, cellHi, physLength);
                  }
              }
            
            /*
              Define data holders on fine level.
            */
            Interval intvlExact(0, ncomp-1);
            Interval intvlCalc(ncomp, 2*ncomp-1);
            Interval intvlDiff(2*ncomp, 3*ncomp-1);
            LevelData<FArrayBox> allFine;
            LevelData<FArrayBox> exactFine, calcFine, diffFine;
            { CH_TIME("allocate allFine");
              allFine.define(dblFine, 3*ncomp, ghostVect);
              
              aliasLevelData(exactFine, &allFine, intvlExact);
              aliasLevelData(calcFine, &allFine, intvlCalc);
              aliasLevelData(diffFine, &allFine, intvlDiff);
            }
            
            /*
              Fill in data holders on fine level.
            */

            // Set exact value of function on fine level.
            Real exactMax = 0.;
            for (DataIterator dit = exactFine.dataIterator(); dit.ok(); ++dit)
              {
                CH_TIME("computing exactFine on FAB");
                FArrayBox& exactFineFab = exactFine[dit];
                const Box& bx = exactFineFab.box();
                // Get average of function on each cell.
                for (BoxIterator bit(bx); bit.ok(); ++bit)
                  {
                    const IntVect& iv = bit();
                    RealVect cellLo = RealVect(iv) * dxFineVect;
                    RealVect cellHi = cellLo + dxFineVect;
                    exactFineFab(iv, 0) = avgFunVal(cellLo, cellHi, physLength);
                  }
                Real exactFabMax = exactFineFab.norm(0);
                if (exactFabMax > exactMax) exactMax = exactFabMax;
              }
#ifdef CH_MPI
            reduceReal(exactMax, MPI_MAX);
#endif

            // Fill in valid cells of calcFine by copying from exact.
            for (DataIterator dit = dblFine.dataIterator(); dit.ok(); ++dit)
              {
                const FArrayBox& exactFineFab = exactFine[dit];
                FArrayBox& calcFineFab = calcFine[dit];
                const Box& bx = dblFine[dit];
                calcFineFab.copy(exactFineFab, bx);
              }

            // Fill in ghost cells of calcFine by copying where possible.
            calcFine.exchange();

            // Fill in ghost cells of calcFine by interpolation where necessary.
            interpolator.fillInterp(calcFine, exactCoarse, 0, 0, ncomp);

            /*
              Got results.  Now take differences,
              diffFine = calcFine - exactFine.
            */
            Real diffMax = 0.;
            for (DataIterator dit = diffFine.dataIterator(); dit.ok(); ++dit)
              { CH_TIME("calculating diffFine");
                FArrayBox& diffFineFab = diffFine[dit];
                const FArrayBox& exactFineFab = exactFine[dit];
                const FArrayBox& calcFineFab = calcFine[dit];

                Box bxWithin(diffFineFab.box());
                bxWithin &= probFine;
                diffFineFab.setVal(0.);
                diffFineFab.copy(exactFineFab, bxWithin);
                diffFineFab.minus(calcFineFab, bxWithin, 0, 0, ncomp);

                Real diffFabMax = diffFineFab.norm(0);
                if (diffFabMax > diffMax) diffMax = diffFabMax;
                // dummy statement in order to get around gdb bug
                int dummy_unused = 0; dummy_unused = 0;
              }
#ifdef CH_MPI
            reduceReal(diffMax, MPI_MAX);
#endif

            pout() << setw(4) << domainLength;
            pout() << "  " << scientific << setprecision(4)
                   << diffMax;
            if (iGrid > 0)
              {
                Real ratio = diffMaxCoarser / diffMax;
                Real rate = log(ratio) / log(2.0);
                pout () << " " << fixed << setprecision(2) << rate;
                if (rate < targetConvergeRate)
                  {
                    status += 1;
                  }
              }
            pout() << endl;
            
            diffMaxCoarser = diffMax;
          } // end loop over grid sizes
      } // end loop over which dimensions are fixed
    if (status==0)
      {
        pout() <<  "All tests passed!\n";
      }
    else
      {
        pout() <<  status << " tests failed!\n";
      }
  } // end scoping trick
#ifdef CH_MPI
  CH_TIMER_REPORT();
  MPI_Finalize();
#endif
#endif

  return status;
}
Ejemplo n.º 19
0
// Advance the solution by "a_dt" by using an unsplit method.
// "a_finerFluxRegister" is the flux register with the next finer level.
// "a_coarseFluxRegister" is flux register with the next coarser level.
// If source terms do not exist, "a_S" should be null constructed and not
// defined (i.e. its define() should not be called).
Real OldLevelGodunov::step(LevelData<FArrayBox>&       a_U,
                           LevelData<FArrayBox>        a_flux[CH_SPACEDIM],
                           LevelFluxRegister&          a_finerFluxRegister,
                           LevelFluxRegister&          a_coarserFluxRegister,
                           const LevelData<FArrayBox>& a_S,
                           const LevelData<FArrayBox>& a_UCoarseOld,
                           const Real&                 a_TCoarseOld,
                           const LevelData<FArrayBox>& a_UCoarseNew,
                           const Real&                 a_TCoarseNew,
                           const Real&                 a_time,
                           const Real&                 a_dt)
{
  // Make sure everything is defined
  CH_assert(m_defined);

  // Clear flux registers with next finer level
  if (m_hasFiner)
    {
      a_finerFluxRegister.setToZero();
    }

  // Setup an interval corresponding to the conserved variables
  Interval UInterval(0,m_numCons-1);

  // Create temporary storage with a layer of "m_numGhost" ghost cells
  IntVect ivGhost = m_numGhost*IntVect::Unit;
  LevelData<FArrayBox> U(m_grids,m_numCons,ivGhost);

  for (DataIterator dit = U.dataIterator(); dit.ok(); ++dit)
    {
      U[dit()].setVal(0.);
    }

  // Copy the current conserved variables into the temporary storage
  a_U.copyTo(UInterval,U,UInterval);

  // Fill U's ghost cells using fillInterp
  if (m_hasCoarser)
    {
      // Truncate the fraction to the range [0,1] to remove floating-point
      // subtraction roundoff effects
      Real eps = 0.04 * a_dt / m_refineCoarse;

      // check for current time too far outside the coarse time range
      if ( a_time+eps < a_TCoarseOld || a_time-eps > a_TCoarseNew )
      {
        pout() << "error: OldLevelGodunov::step: a_time [" << a_time
               << "] is outside the old,new range of coarse level times ["
               << a_TCoarseOld << "," << a_TCoarseNew << "]" << endl ;
        MayDay::Error( "OldLevelGodunov::step: new time is outside acceptable range" );
      }
      // if just a little outside the range (e.g. roundoff errors), just fix it
      Real curtime = a_time ;
      if ( a_time < a_TCoarseOld ) curtime = a_TCoarseOld ;
      if ( a_time > a_TCoarseNew ) curtime = a_TCoarseNew ;

      // "time" falls in the range of the old and the new coarse times
      Real alpha = (curtime - a_TCoarseOld) / (a_TCoarseNew - a_TCoarseOld);

      // Interpolate ghost cells from next coarser level using both space
      // and time interpolation
      m_patcher.fillInterp(U,
                           a_UCoarseOld,
                           a_UCoarseNew,
                           alpha,
                           0,0,m_numCons);
    }

  // Exchange all the data between grids at this level
  // I don't think this is necessary
  //U.exchange(UInterval);

  // Potentially used in boundary conditions
  m_patchGodunov->setCurrentTime(a_time);

  // Dummy source used if source term passed in is empty
  FArrayBox zeroSource;

  // Use to restrict maximum wave speed away from zero
  Real maxWaveSpeed = 1.0e-12;

  // Beginning of loop through patches/grids.
  for (DataIterator dit = m_grids.dataIterator(); dit.ok(); ++dit)
    {
      // The current box
      Box curBox = m_grids.get(dit());

    // The current grid of conserved variables
      FArrayBox& curU = U[dit()];

      // The current source terms if they exist
      const FArrayBox* source = &zeroSource;
      if (a_S.isDefined())
        {
          source = &a_S[dit()];
        }

      // The fluxes computed for this grid - used for refluxing and returning
      // other face centered quantities
      FArrayBox flux[SpaceDim];

    // Set the current box for the patch integrator
      m_patchGodunov->setCurrentBox(curBox);

      Real maxWaveSpeedGrid;

    // Update the current grid's conserved variables, return the final
    // fluxes used for this, and the maximum wave speed for this grid
      m_patchGodunov->updateState(curU,
                                  flux,
                                  maxWaveSpeedGrid,
                                  *source,
                                  a_dt,
                                  curBox);

      // Clamp away from zero
      maxWaveSpeed = Max(maxWaveSpeed,maxWaveSpeedGrid);

      // Do flux register updates
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          // Increment coarse flux register between this level and the next
          // finer level - this level is the next coarser level with respect
          // to the next finer level
          if (m_hasFiner)
            {
              a_finerFluxRegister.incrementCoarse(flux[idir],a_dt,dit(),
                                                  UInterval,
                                                  UInterval,idir);
            }

          // Increment fine flux registers between this level and the next
          // coarser level - this level is the next finer level with respect
          // to the next coarser level
          if (m_hasCoarser)
            {
              a_coarserFluxRegister.incrementFine(flux[idir],a_dt,dit(),
                                                  UInterval,
                                                  UInterval,idir,Side::Lo);
              a_coarserFluxRegister.incrementFine(flux[idir],a_dt,dit(),
                                                  UInterval,
                                                  UInterval,idir,Side::Hi);
            }
        }
    }

  // Now that we have completed the updates of all the patches, we copy the
  // contents of temporary storage, U, into the permanent storage, a_U.
  // U.copyTo(UInterval,a_U,UInterval);

  for (DataIterator dit = U.dataIterator(); dit.ok(); ++dit)
    {
      a_U[dit()].copy(U[dit()]);
    }

  // Find the minimum of dt's over this level
  Real local_dtNew = m_dx / maxWaveSpeed;
  Real dtNew;

#ifdef CH_MPI
  int result = MPI_Allreduce(&local_dtNew, &dtNew, 1, MPI_CH_REAL,
                                 MPI_MIN, Chombo_MPI::comm);
  if (result != MPI_SUCCESS)
  {
    MayDay::Error("sorry, but I had a communcation error on new dt");
  }
#else
  dtNew = local_dtNew;
#endif

  // Return the maximum stable time step
  return dtNew;
}
Ejemplo n.º 20
0
	void parseAndAddEvent(LevelData& mLevelData, Json::Value &mEventRoot)
	{
		mLevelData.addEvent(mEventRoot);
	}
Ejemplo n.º 21
0
void
LevelFluxRegisterEdge::refluxCurl(LevelData<FluxBox>& a_uCoarse,
                                  Real a_scale)
{
  CH_assert(isDefined());
  CH_assert(a_uCoarse.nComp() == m_nComp);

  SideIterator side;
  // idir is the normal direction to the coarse-fine interface
  for (int idir=0 ; idir<SpaceDim; ++idir)
  {
    for (side.begin(); side.ok(); ++side)
    {
      LevelData<FluxBox>& fineReg = m_fabFine[index(idir, side())];

      // first, create temp LevelData<FluxBox> to hold "coarse flux"
      const DisjointBoxLayout coarseBoxes = m_regCoarse.getBoxes();

      // this fills the place of what used to be m_fabCoarse in the old
      // implementation
      LevelData<FluxBox> coarReg(coarseBoxes, m_nComp, IntVect::Unit);


      // now fill the coarReg with the curl of the stored coarse-level
      // edge-centered flux
      DataIterator crseDit = coarseBoxes.dataIterator();
      for (crseDit.begin(); crseDit.ok(); ++crseDit)
        {
          FluxBox& thisCoarReg = coarReg[crseDit];
          thisCoarReg.setVal(0.0);

          EdgeDataBox& thisEdgeData = m_regCoarse[crseDit];

          for (int edgeDir=0; edgeDir<SpaceDim; edgeDir++)
            {
              if (idir != edgeDir)
                {
                  FArrayBox& crseEdgeDataDir = thisEdgeData[edgeDir];
                  for (int faceDir = 0; faceDir<SpaceDim; faceDir++)
                    {
                      if (faceDir != edgeDir)
                        {
                          FArrayBox& faceData = thisCoarReg[faceDir];
                          int shiftDir = -1;
                          for (int i=0; i<SpaceDim; i++)
                            {
                              if ((i != faceDir) && (i != edgeDir) )
                                {
                                  shiftDir = i;
                                }
                            }
                          CH_assert(shiftDir >= 0);
                          crseEdgeDataDir.shiftHalf(shiftDir, sign(side()));
                          // scaling already taken care of in incrementCrse
                          Real scale = 1.0;
                          faceData.plus(crseEdgeDataDir, scale, 0, 0, faceData.nComp());
                          crseEdgeDataDir.shiftHalf(shiftDir, -sign(side()));
                        } // end if not normal direction
                    } // end loop over face directions
                } // end if edgeDir != idir
            } // end loop over edge directions
        } // end loop over crse boxes


      // first, we need to create a temp LevelData<FluxBox>
      // to make a local copy in the coarse layout space of
      // the fine register increments

      LevelData<FluxBox> fineRegLocal(coarReg.getBoxes(), m_nComp, IntVect::Unit);

      fineReg.copyTo(fineReg.interval(), fineRegLocal,
                     fineRegLocal.interval(),
                     m_crseCopiers[index(idir,side())]);

      for (DataIterator it = a_uCoarse.dataIterator(); it.ok(); ++it)
        {
          // loop over flux components here
          for (int fluxComp=0; fluxComp < SpaceDim; fluxComp++)
            {
              // we don't do anything in the normal direction
              if (fluxComp != idir)
                {
                  // fluxDir is the direction of the face-centered flux
                  FArrayBox& U = a_uCoarse[it()][fluxComp];
                  // set up IntVectSet to avoid double counting of updates
                  Box coarseGridBox = U.box();
                  // transfer to Cell-centered, then create IVS
                  coarseGridBox.shiftHalf(fluxComp,1);
                  IntVectSet nonUpdatedEdges(coarseGridBox);

                  // remember, we want to take the curl here
                  // also recall that fluxComp is the component
                  // of the face-centered curl (not the edge-centered
                  // vector field that we're refluxing, which is why
                  // the sign may seem like it's the opposite of what
                  // you might expect!
                  Real local_scale = -sign(side())*a_scale;
                  //int testDir = (fluxComp+1)%(SpaceDim);
                  if (((fluxComp+1)%(SpaceDim)) == idir)  local_scale *= -1;
                  Vector<IntVectSet>& ivsV =
                    m_refluxLocations[index(idir, side())][it()][fluxComp];
                  Vector<DataIndex>&  indexV =
                    m_coarToCoarMap[index(idir, side())][it()];
                  IVSIterator iv;

                  for (int i=0; i<ivsV.size(); ++i)
                    {
                      iv.define(ivsV[i]);
                      const FArrayBox& coar = coarReg[indexV[i]][fluxComp];
                      const FArrayBox& fine = fineRegLocal[indexV[i]][fluxComp];
                      for (iv.begin(); iv.ok(); ++iv)
                        {
                          IntVect thisIV = iv();
                          if (nonUpdatedEdges.contains(thisIV))
                          {
                            for (int comp=0; comp <m_nComp; ++comp)
                              {
                                //Real coarVal = coar(thisIV, comp);
                                //Real fineVal = fine(thisIV, comp);
                                U(thisIV, comp) -=
                                local_scale*(coar(thisIV, comp)
                                             +fine(thisIV, comp));
                              }
                            nonUpdatedEdges -= thisIV;
                          }
                        }

                    }
                } // end if not normal face
            } // end loop over fluxbox directions
        } // end loop over coarse boxes
    } // end loop over sides
  } // end loop over directions
}
Ejemplo n.º 22
0
void getError(LevelData<double, 1> & a_error,
              double               & a_maxError,
              const double         & a_dx)
{

  BoxLayout layout = a_error.getBoxLayout();

  LevelData<double, 1> phi(layout, s_nghost);
  LevelData<double, 1> lphcalc(layout, 0);
  LevelData<double, 1> lphexac(layout, 0);

  //  cout << "initializing phi to sum_dir(sin 2*pi*xdir)" << endl;
  initialize(phi,lphexac, a_dx);

  //set ghost cells of phi
  phi.exchange();
  //  dumpLevelRDA(&phi);
  Stencil<double> laplace;
  setStencil(laplace, a_dx);

  //apply stencil operator independently on each box
  a_maxError = 0;
  
  for(BLIterator blit(layout); blit != blit.end(); ++blit)
    {
      RectMDArray<double>& phiex =     phi[*blit];
      RectMDArray<double>& lphca = lphcalc[*blit];
      RectMDArray<double>& lphex = lphexac[*blit];
      RectMDArray<double>& error = a_error[*blit];

      //apply is set as an increment so need to set this to zero initially
      lphca.setVal(0.);

      Box bxdst=layout[*blit];
//      Stencil<double>::apply(laplace, phiex, lphca, bxdst);
  const class Box sourceBoxRef = phiex . getBox();
  const class Box destinationBoxRef = lphca . getBox();
  int iter_lb2 = bxdst .  getLowCorner ()[2];
  int src_lb2 = sourceBoxRef .  getLowCorner ()[2];
  int dest_lb2 = destinationBoxRef .  getLowCorner ()[2];
  int k = 0;
  int iter_ub2 = bxdst .  getHighCorner ()[2];
  int src_ub2 = sourceBoxRef .  getHighCorner ()[2];
  int dest_ub2 = destinationBoxRef .  getHighCorner ()[2];
  int arraySize_X = bxdst .  size (0);
  int arraySize_X_src = sourceBoxRef .  size (0);
  int iter_lb1 = bxdst .  getLowCorner ()[1];
  int src_lb1 = sourceBoxRef .  getLowCorner ()[1];
  int dest_lb1 = destinationBoxRef .  getLowCorner ()[1];
  int j = 0;
  int iter_ub1 = bxdst .  getHighCorner ()[1];
  int src_ub1 = sourceBoxRef .  getHighCorner ()[1];
  int dest_ub1 = destinationBoxRef .  getHighCorner ()[1];
  int arraySize_Y = bxdst .  size (1);
  int arraySize_Y_src = sourceBoxRef .  size (1);
  int iter_lb0 = bxdst .  getLowCorner ()[0];
  int src_lb0 = sourceBoxRef .  getLowCorner ()[0];
  int dest_lb0 = destinationBoxRef .  getLowCorner ()[0];
  int i = 0;
  int iter_ub0 = bxdst .  getHighCorner ()[0];
  int src_ub0 = sourceBoxRef .  getHighCorner ()[0];
  int dest_ub0 = destinationBoxRef .  getHighCorner ()[0];
  int arraySize_Z = bxdst .  size (2);
  int arraySize_Z_src = sourceBoxRef .  size (2);
  double *sourceDataPointer = phiex . getPointer();
  double *destinationDataPointer = lphca . getPointer();
  for (k = iter_lb2; k < iter_ub2; ++k) {
    for (j = iter_lb1; j < iter_ub1; ++j) {
      for (i = iter_lb0; i < iter_ub0; ++i) {
        destinationDataPointer[arraySize_X * (arraySize_Y * (k - dest_lb2) + (j - dest_lb1)) + (i - dest_lb0)] = 
          (1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2 + -1) + (j - src_lb1)) + (i - src_lb0)] + 
           1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2 + 1) + (j - src_lb1)) + (i - src_lb0)] + 
           1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1 + -1)) + (i - src_lb0)] + 
           1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1 + 1)) + (i - src_lb0)] + 
           1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1)) + (i - src_lb0 + -1)] + 
           1.0*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1)) + (i - src_lb0 + 1)] + 
          (-2.0*DIM)*sourceDataPointer[arraySize_X_src * (arraySize_Y_src * (k - src_lb2) + (j - src_lb1)) + (i - src_lb0)]) * (1.0/a_dx/a_dx);
//cout << destinationDataPointer[arraySize_X * (arraySize_Y * (k - dest_lb2) + (j - dest_lb1)) + (i - dest_lb0)] << " " << lphex.getPointer()[arraySize_X * (arraySize_Y * (k - dest_lb2) + (j - dest_lb1)) + (i - dest_lb0)] << endl;
      }
    }
  }        
      //error = lphicalc -lphiexac
      lphca.copyTo(error);
      //here err holds lphi calc
      double maxbox = forall_max(error, lphex, &errorF, bxdst);
cout << "maxbox= " << maxbox << endl;

      a_maxError = max(maxbox, a_maxError);
    }
}
Ejemplo n.º 23
0
// -----------------------------------------------------------------------------
// Adds coarse cell values directly to all overlying fine cells,
// then removes the average from the fine result.
// -----------------------------------------------------------------------------
void ZeroAvgConstInterpPS::prolongIncrement (LevelData<FArrayBox>&       a_phiThisLevel,
                                             const LevelData<FArrayBox>& a_correctCoarse)
{
    CH_TIME("ZeroAvgConstInterpPS::prolongIncrement");

    // Gather grids, domains, refinement ratios...
    const DisjointBoxLayout& fineGrids = a_phiThisLevel.getBoxes();
    const DisjointBoxLayout& crseGrids = a_correctCoarse.getBoxes();
    CH_assert(fineGrids.compatible(crseGrids));

    const ProblemDomain& fineDomain = fineGrids.physDomain();
    const ProblemDomain& crseDomain = crseGrids.physDomain();

    const IntVect mgRefRatio = fineDomain.size() / crseDomain.size();
    CH_assert(mgRefRatio.product() > 1);

    // These will accumulate averaging data.
    Real localSum = 0.0;
    Real localVol = 0.0;
    CH_assert(!m_CCJinvPtr.isNull());
    CH_assert(m_dxProduct > 0.0);

    DataIterator dit = fineGrids.dataIterator();
    for (dit.reset(); dit.ok(); ++dit) {
        // Create references for convenience
        FArrayBox& fineFAB = a_phiThisLevel[dit];
        const FArrayBox& crseFAB = a_correctCoarse[dit];
        const Box& fineValid = fineGrids[dit];
        const FArrayBox& JinvFAB = (*m_CCJinvPtr)[dit];

        // To make things easier, we will offset the
        // coarse and fine data boxes to zero.
        const IntVect& fiv = fineValid.smallEnd();
        const IntVect civ = coarsen(fiv, mgRefRatio);

        // Correct the fine data
        FORT_CONSTINTERPWITHAVGPS (
            CHF_FRA_SHIFT(fineFAB, fiv),
            CHF_CONST_FRA_SHIFT(crseFAB, civ),
            CHF_BOX_SHIFT(fineValid, fiv),
            CHF_CONST_INTVECT(mgRefRatio),
            CHF_CONST_FRA1_SHIFT(JinvFAB,0,fiv),
            CHF_CONST_REAL(m_dxProduct),
            CHF_REAL(localVol),
            CHF_REAL(localSum));
    }

    // Compute global sum (this is where the MPI communication happens)
#ifdef CH_MPI
    Real globalSum = 0.0;
    int result = MPI_Allreduce(&localSum, &globalSum, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm);

    if (result != MPI_SUCCESS) {
        MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement");
    }

    Real globalVol = 0.0;
    result = MPI_Allreduce(&localVol, &globalVol, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm);

    if (result != MPI_SUCCESS) {
        MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement");
    }

#else
    Real globalSum = localSum;
    Real globalVol = localVol;
#endif

    // Remove the average from phi.
    Real avgPhi = globalSum / globalVol;
    for (dit.reset(); dit.ok(); ++dit) {
        a_phiThisLevel[dit] -= avgPhi;
    }
}
Ejemplo n.º 24
0
void
EBMGAverage::average(LevelData<EBCellFAB>&       a_coarData,
                     const LevelData<EBCellFAB>& a_fineData,
                     const Interval&             a_variables)
{
  CH_TIMERS("EBMGAverage::average");
  CH_TIMER("layout_changed_coarsenable", t1);
  CH_TIMER("layout_changed_not_coarsenable", t2);
  CH_TIMER("not_layout_changed", t3);
  CH_assert(a_fineData.ghostVect() == m_ghost);
  //CH_assert(a_coarData.ghostVect() == m_ghost);

  CH_assert(isDefined());

  if (m_layoutChanged)
    {
      if (m_coarsenable)
        {
          CH_START(t1);
          EBCellFactory ebcellfact(m_buffEBISL);
          LevelData<EBCellFAB> coarsenedFineData(m_buffGrids, m_nComp, m_ghost, ebcellfact);
          EBLevelDataOps::setVal(coarsenedFineData, 0.0);

          for (DataIterator dit = m_fineGrids.dataIterator(); dit.ok(); ++dit)
            {
              averageFAB(coarsenedFineData[dit()],
                         m_buffGrids[dit()],
                         a_fineData[dit()],
                         dit(),
                         a_variables);
            }
          coarsenedFineData.copyTo(a_variables, a_coarData, a_variables, m_copier);
          CH_STOP(t1);
        }
      else
        {
          CH_START(t2);
          EBCellFactory ebcellfact(m_buffEBISL);
          LevelData<EBCellFAB> refinedCoarseData(m_buffGrids, m_nComp, m_ghost, ebcellfact);
          EBLevelDataOps::setVal(refinedCoarseData, 0.0);

          a_fineData.copyTo(a_variables, refinedCoarseData, a_variables, m_copier);

          for (DataIterator dit = m_coarGrids.dataIterator(); dit.ok(); ++dit)
            {
              averageFAB(a_coarData[dit()],
                         m_coarGrids[dit()],
                         refinedCoarseData[dit()],
                         dit(),
                         a_variables);
            }
          CH_STOP(t2);
        }
    }
  else
    {
      CH_START(t3);
      averageMG(a_coarData, a_fineData, a_variables);
      CH_STOP(t3);
    }
}
Ejemplo n.º 25
0
void TimeInterpolatorRK4::intermediate(/// intermediate RK4 solution on this level coarsened
                                       LevelData<FArrayBox>&   a_U,
                                       /// time interpolation coefficient in range [0:1]
                                       const Real&             a_timeInterpCoeff,
                                       /// which RK4 stage:  0, 1, 2, 3
                                       const int&              a_stage,
                                       /// interval of a_U to fill in
                                       const Interval&         a_intvl) const
{
  CH_assert(m_defined);
  CH_assert(m_gotFullTaylorPoly);
  CH_assert(a_U.nComp() == m_numStates);
  CH_assert(a_stage >= 0);
  CH_assert(a_stage < 4);

  Real rinv = 1. / Real(m_refineCoarse);
  Vector<Real> intermCoeffs(4);
  // 0 is coefficient of m_taylorCoeffs[0] = Ucoarse(0)
  // 1 is coefficient of m_taylorCoeffs[1] =           K1
  // 2 is coefficient of m_taylorCoeffs[2] = 1/2 * (-3*K1 + 2*K2 + 2*K3 - K4)
  // 3 is coefficient of m_taylorCoeffs[3] = 2/3 * (   K1 -   K2 -   K3 + K4)
  Real diff12Coeffs;
  // coefficient of m_diff12               =              -   K2 +   K3
  switch (a_stage)
    {
    case 0:
      intermCoeffs[0] = 1.;
      intermCoeffs[1] = a_timeInterpCoeff;
      intermCoeffs[2] = a_timeInterpCoeff * a_timeInterpCoeff;
      intermCoeffs[3] = a_timeInterpCoeff * a_timeInterpCoeff  * a_timeInterpCoeff;
      diff12Coeffs = 0.;
      break;
    case 1:
      intermCoeffs[0] = 1.;
      intermCoeffs[1] = 0.5*rinv + a_timeInterpCoeff;
      intermCoeffs[2] = a_timeInterpCoeff * (rinv + a_timeInterpCoeff);
      intermCoeffs[3] = a_timeInterpCoeff * a_timeInterpCoeff * (1.5*rinv + a_timeInterpCoeff);
      diff12Coeffs = 0.;
      break;
    case 2:
      intermCoeffs[0] = 1.;
      intermCoeffs[1] = 0.5*rinv + a_timeInterpCoeff;
      intermCoeffs[2] = 0.5*rinv*rinv + a_timeInterpCoeff * (rinv + a_timeInterpCoeff);
      intermCoeffs[3] = 0.375*rinv*rinv*rinv + a_timeInterpCoeff * (1.5*rinv*rinv + a_timeInterpCoeff * (1.5*rinv + a_timeInterpCoeff));
      diff12Coeffs = -0.25 * rinv * rinv;
      break;
    case 3:
      intermCoeffs[0] = 1.;
      intermCoeffs[1] = rinv + a_timeInterpCoeff;
      intermCoeffs[2] = rinv*rinv + a_timeInterpCoeff * (2.*rinv + a_timeInterpCoeff);
      intermCoeffs[3] = 0.75*rinv*rinv*rinv + a_timeInterpCoeff * (3.*rinv*rinv + a_timeInterpCoeff * (3.*rinv + a_timeInterpCoeff));
      diff12Coeffs = 0.5 * rinv * rinv;
      break;
    default:
      MayDay::Error("TimeInterpolatorRK4::intermediate must have a_stage in range 0:3");
    }
  LevelData<FArrayBox> UComp;
  aliasLevelData(UComp, &a_U, a_intvl);

  // For i in 0:m_numCoeffs-1,
  // coeffFirst[i] is index of first component of m_taylorCoeffs
  // that corresponds to a coefficient of t^i.
  Vector<int> coeffFirst(m_numCoeffs);
  int intervalLength = a_intvl.size();
  for (int i = 0; i < m_numCoeffs; i++)
    {
      coeffFirst[i] = a_intvl.begin() + i * m_numStates;
    }

  DataIterator dit = UComp.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      FArrayBox& UFab = UComp[dit];
      const FArrayBox& taylorFab = m_taylorCoeffs[dit];

      // WAS:  Evaluate a0 + a1*t + a2*t^2 + a3*t^3
      // as a0 + t * (a1 + t * (a2 + t * a3)):
      // that is, set UFab to
      // a3, t*a3 + a2, t*(t*a3 + a2) + a1, t*(t*(t*a3 + a2) + a1) * a0.

      // NEW:  Evaluate a0*c0 + a1*c1 + a2*c2 + a3*c3,
      // where c0, c1, c2, c3 are scalars,
      // and c0 = intermCoeffs[0] = 1.
      UFab.copy(taylorFab, coeffFirst[0], 0, intervalLength);
      for (int ind = 1; ind < 4; ind++)
        {
          UFab.plus(taylorFab, intermCoeffs[ind],
                    coeffFirst[ind], 0, intervalLength);
        }
      const FArrayBox& diff12Fab = m_diff12[dit];
      UFab.plus(diff12Fab, diff12Coeffs, 0, 0, intervalLength);
    }
  // dummy statement in order to get around gdb bug
  int dummy_unused = 0; dummy_unused = 0;
}
Ejemplo n.º 26
0
void EBPoissonOp::
applyOp(LevelData<EBCellFAB>&             a_opPhi,
        const LevelData<EBCellFAB>&       a_phi,
        bool                              a_homogeneousPhysBC,
        DataIterator& dit,
        bool a_do_exchange)
{
  CH_TIMERS("EBPoissonOp::applyOp");
  CH_TIMER("regular_apply", t1);
  CH_TIMER("irregular_apply", t2);
  CH_TIMER("eb_bcs_apply", t3);
  CH_TIMER("dom_bcs_apply", t4);
  CH_TIMER("alpha_apply", t5);
  CH_assert(a_opPhi.ghostVect() == m_ghostCellsRHS);
  CH_assert(a_phi.ghostVect() == m_ghostCellsPhi);


  CH_assert(a_phi.nComp() == a_opPhi.nComp());

  LevelData<EBCellFAB>& phi = const_cast<LevelData<EBCellFAB>&>(a_phi);
  if (a_do_exchange)
    {
      phi.exchange(phi.interval());
    }

  int nComps = a_phi.nComp();

  for (dit.reset(); dit.ok(); ++dit)
    {

      Box dblBox( m_eblg.getDBL().get(dit()) );
      const EBCellFAB& phifab = phi[dit()];
      Box curPhiBox = phifab.box();
      const BaseFab<Real>& curPhiFAB = phifab.getSingleValuedFAB();

      EBCellFAB& opphifab = a_opPhi[dit()];
      BaseFab<Real>& curOpPhiFAB = opphifab.getSingleValuedFAB();

      //       Interval interv(0, nComps-1);
      CH_START(t5);
      if (m_alpha == 0)
        {
          opphifab.setVal(0.0);
        }
      else
        {
          opphifab.copy(phifab);
          opphifab.mult(m_alpha);
        }
      CH_STOP(t5);

      Box loBox[SpaceDim],hiBox[SpaceDim];
      int hasLo[SpaceDim],hasHi[SpaceDim];
      CH_START(t1);
      applyOpRegularAllDirs( loBox, hiBox, hasLo, hasHi,
                             dblBox, curPhiBox, nComps,
                             curOpPhiFAB,
                             curPhiFAB,
                             a_homogeneousPhysBC,
                             dit(),
                             m_beta);

      CH_STOP(t1);

      CH_START(t2);
      //apply stencil
      m_opEBStencil[dit()]->apply(opphifab, phifab, false);
      CH_STOP(t2);
      //apply inhom boundary conditions
      CH_START(t3);
      if (!a_homogeneousPhysBC)
        {
          const Real factor = m_dxScale*m_beta;
          m_ebBC->applyEBFlux(opphifab, phifab, m_vofItIrreg[dit()], (*m_eblg.getCFIVS()),
                              dit(), m_origin, m_dx, factor,
                              a_homogeneousPhysBC, m_time);
        }
      CH_STOP(t3);

      CH_START(t4);
      int comp = 0;
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          for (m_vofItIrregDomLo[idir][dit()].reset(); m_vofItIrregDomLo[idir][dit()].ok();  ++m_vofItIrregDomLo[idir][dit()])
            {
              Real flux;
              const VolIndex& vof = m_vofItIrregDomLo[idir][dit()]();
              m_domainBC->getFaceFlux(flux,vof,comp,a_phi[dit()],
                                      m_origin,m_dx,idir,Side::Lo, dit(), m_time,
                                      a_homogeneousPhysBC);

              opphifab(vof,comp) -= flux * m_beta*m_invDx[idir];
            }
          for (m_vofItIrregDomHi[idir][dit()].reset(); m_vofItIrregDomHi[idir][dit()].ok();  ++m_vofItIrregDomHi[idir][dit()])
            {
              Real flux;
              const VolIndex& vof = m_vofItIrregDomHi[idir][dit()]();
              m_domainBC->getFaceFlux(flux,vof,comp,a_phi[dit()],
                                      m_origin,m_dx,idir,Side::Hi,dit(), m_time,
                                      a_homogeneousPhysBC);

              opphifab(vof,comp) += flux * m_beta*m_invDx[idir];
            }

        }
      CH_STOP(t4);
    }
}
Ejemplo n.º 27
0
void VCAMRPoissonOp2::restrictResidual(LevelData<FArrayBox>&       a_resCoarse,
                                      LevelData<FArrayBox>&       a_phiFine,
                                      const LevelData<FArrayBox>& a_rhsFine)
{
  CH_TIME("VCAMRPoissonOp2::restrictResidual");

  homogeneousCFInterp(a_phiFine);
  const DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout();
  for (DataIterator dit = a_phiFine.dataIterator(); dit.ok(); ++dit)
    {
      FArrayBox& phi = a_phiFine[dit];
      m_bc(phi, dblFine[dit()], m_domain, m_dx, true);
    }

  a_phiFine.exchange(a_phiFine.interval(), m_exchangeCopier);

  for (DataIterator dit = a_phiFine.dataIterator(); dit.ok(); ++dit)
    {
      FArrayBox&       phi = a_phiFine[dit];
      const FArrayBox& rhs = a_rhsFine[dit];
      FArrayBox&       res = a_resCoarse[dit];

      const FArrayBox& thisACoef = (*m_aCoef)[dit];
      const FluxBox&   thisBCoef = (*m_bCoef)[dit];

      Box region = dblFine.get(dit());
      const IntVect& iv = region.smallEnd();
      IntVect civ = coarsen(iv, 2);

      res.setVal(0.0);

#if CH_SPACEDIM == 1
      FORT_RESTRICTRESVC1D
#elif CH_SPACEDIM == 2
      FORT_RESTRICTRESVC2D
#elif CH_SPACEDIM == 3
      FORT_RESTRICTRESVC3D
#else
      This_will_not_compile!
#endif
                          (CHF_FRA_SHIFT(res, civ),
                           CHF_CONST_FRA_SHIFT(phi, iv),
                           CHF_CONST_FRA_SHIFT(rhs, iv),
                           CHF_CONST_REAL(m_alpha),
                           CHF_CONST_FRA_SHIFT(thisACoef, iv),
                           CHF_CONST_REAL(m_beta),
#if CH_SPACEDIM >= 1
                           CHF_CONST_FRA_SHIFT(thisBCoef[0], iv),
#endif
#if CH_SPACEDIM >= 2
                           CHF_CONST_FRA_SHIFT(thisBCoef[1], iv),
#endif
#if CH_SPACEDIM >= 3
                           CHF_CONST_FRA_SHIFT(thisBCoef[2], iv),
#endif
#if CH_SPACEDIM >= 4
                           This_will_not_compile!
#endif
                           CHF_BOX_SHIFT(region, iv),
                           CHF_CONST_REAL(m_dx));
    }
}
Ejemplo n.º 28
0
//
// VCAMRPoissonOp2::reflux()
//   There are currently the new version (first) and the old version (second)
//   in this file.  Brian asked to preserve the old version in this way for
//   now. - TJL (12/10/2007)
//
void VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>&        a_phiFine,
                            const LevelData<FArrayBox>&        a_phi,
                            LevelData<FArrayBox>&              a_residual,
                            AMRLevelOp<LevelData<FArrayBox> >* a_finerOp)
{
  CH_TIMERS("VCAMRPoissonOp2::reflux");

  m_levfluxreg.setToZero();
  Interval interv(0,a_phi.nComp()-1);

  CH_TIMER("VCAMRPoissonOp2::reflux::incrementCoarse", t2);
  CH_START(t2);

  DataIterator dit = a_phi.dataIterator();
  for (dit.reset(); dit.ok(); ++dit)
  {
    const FArrayBox& coarfab   = a_phi[dit];
    const FluxBox&   coarBCoef = (*m_bCoef)[dit];
    const Box&       gridBox   = a_phi.getBoxes()[dit];

    if (m_levfluxreg.hasCF(dit()))
    {
      for (int idir = 0; idir < SpaceDim; idir++)
      {
        FArrayBox coarflux;
        Box faceBox = surroundingNodes(gridBox, idir);

        getFlux(coarflux, coarfab, coarBCoef, faceBox, idir);

        Real scale = 1.0;
        m_levfluxreg.incrementCoarse(coarflux, scale,dit(),
            interv, interv, idir);
      }
    }
  }

  CH_STOP(t2);

  // const cast:  OK because we're changing ghost cells only
  LevelData<FArrayBox>& phiFineRef = ( LevelData<FArrayBox>&)a_phiFine;

  VCAMRPoissonOp2* finerAMRPOp = (VCAMRPoissonOp2*) a_finerOp;
  QuadCFInterp& quadCFI = finerAMRPOp->m_interpWithCoarser;

  quadCFI.coarseFineInterp(phiFineRef, a_phi);
  // I'm pretty sure this is not necessary. bvs -- flux calculations use
  // outer ghost cells, but not inner ones
  // phiFineRef.exchange(a_phiFine.interval());
  IntVect phiGhost = phiFineRef.ghostVect();
  int ncomps = a_phiFine.nComp();

  CH_TIMER("VCAMRPoissonOp2::reflux::incrementFine", t3);
  CH_START(t3);

  DataIterator ditf = a_phiFine.dataIterator();
  const DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout();
  for (ditf.reset(); ditf.ok(); ++ditf)
    {
      const FArrayBox& phifFab   = a_phiFine[ditf];
      const FluxBox&   fineBCoef = (*(finerAMRPOp->m_bCoef))[ditf];
      const Box&       gridbox   = dblFine.get(ditf());

      for (int idir = 0; idir < SpaceDim; idir++)
        {
          //int normalGhost = phiGhost[idir];
          SideIterator sit;
          for (sit.begin(); sit.ok(); sit.next())
            {
              if (m_levfluxreg.hasCF(ditf(), sit()))
                {
                  Side::LoHiSide hiorlo = sit();
                  Box fluxBox = bdryBox(gridbox,idir,hiorlo,1);

                  FArrayBox fineflux(fluxBox,ncomps);
                  getFlux(fineflux, phifFab, fineBCoef, fluxBox, idir,
                          m_refToFiner);

                  Real scale = 1.0;
                  m_levfluxreg.incrementFine(fineflux, scale, ditf(),
                                             interv, interv, idir, hiorlo);
                }
            }
        }
    }

  CH_STOP(t3);

  Real scale = 1.0/m_dx;
  m_levfluxreg.reflux(a_residual, scale);
}
Ejemplo n.º 29
0
void
EBLevelAdvect::
advectToFacesBCG(LevelData< EBFluxFAB >&                         a_extrapState,
                 const LevelData< EBCellFAB >&                   a_consState,
                 const LevelData< EBCellFAB >&                   a_normalVel,
                 const LevelData< EBFluxFAB >&                   a_advectionVel,
                 const LevelData< EBCellFAB >*                   a_consStateCoarseOld,
                 const LevelData< EBCellFAB >*                   a_consStateCoarseNew,
                 const LevelData< EBCellFAB >*                   a_normalVelCoarseOld,
                 const LevelData< EBCellFAB >*                   a_normalVelCoarseNew,
                 const Real&                                     a_timeCoarseOld,
                 const Real&                                     a_timeCoarseNew,
                 const Real&                                     a_timeFine,
                 const Real&                                     a_dt,
                 const LevelData<EBCellFAB>* const               a_source,
                 const LevelData<EBCellFAB>* const               a_sourceCoarOld,
                 const LevelData<EBCellFAB>* const               a_sourceCoarNew)
{
  CH_TIME("EBLevelAdvect::advectToFacesBCG (level)");
  CH_assert(isDefined());

  //create temp data with the correct number of ghost cells
  IntVect ivGhost = m_nGhost*IntVect::Unit;
  Interval consInterv(0, m_nVar-1);
  Interval intervSD(0, SpaceDim-1);

  // LevelData<EBCellFAB>& consTemp = (LevelData<EBCellFAB>&) a_consState;
  // LevelData<EBCellFAB>& veloTemp = (LevelData<EBCellFAB>&) a_normalVel;

  EBCellFactory factory(m_thisEBISL);
  LevelData<EBCellFAB> consTemp(m_thisGrids, m_nVar, ivGhost, factory);
  LevelData<EBCellFAB> veloTemp(m_thisGrids, SpaceDim, ivGhost, factory);
  for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit)
    {
      consTemp[dit()].setVal(0.);
    }

  a_consState.copyTo(consInterv, consTemp, consInterv);
  a_normalVel.copyTo(intervSD, veloTemp, intervSD);
  // Fill ghost cells using fillInterp, and copyTo.
  if (m_hasCoarser)
    {
      CH_TIME("fillPatch");
      m_fillPatch.interpolate(consTemp,
                              *a_consStateCoarseOld,
                              *a_consStateCoarseNew,
                              a_timeCoarseOld,
                              a_timeCoarseNew,
                              a_timeFine,
                              consInterv);

      m_fillPatchVel.interpolate(veloTemp,
                                 *a_normalVelCoarseOld,
                                 *a_normalVelCoarseNew,
                                 a_timeCoarseOld,
                                 a_timeCoarseNew,
                                 a_timeFine,
                                 intervSD);
    }
  // Exchange all the data between grids
  {
    CH_TIME("initial_exchange");
    consTemp.exchange(consInterv);
    veloTemp.exchange(intervSD);
  }

  LevelData<EBCellFAB>* srcTmpPtr = NULL;
  if (a_source != NULL)
    {
      // srcTmpPtr = (LevelData<EBCellFAB>*) a_source;

      srcTmpPtr = new LevelData<EBCellFAB>(m_thisGrids, m_nVar, ivGhost, factory);
      for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit)
        {
          (*srcTmpPtr)[dit()].setVal(0.);
        }
      a_source->copyTo(consInterv, *srcTmpPtr, consInterv);

      if ( (a_sourceCoarOld != NULL) &&
           (a_sourceCoarNew != NULL) &&
           (m_hasCoarser) )
        {
          CH_TIME("fillPatch");

          m_fillPatch.interpolate(*srcTmpPtr,
                                  *a_sourceCoarOld,
                                  *a_sourceCoarNew,
                                  a_timeCoarseOld,
                                  a_timeCoarseNew,
                                  a_timeFine,
                                  consInterv);
          {
            CH_TIME("initial_exchange");
            srcTmpPtr->exchange(consInterv);
          }
        }
    }

  {
    CH_TIME("advectToFaces");
    int ibox = 0;
    for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit)
      {
        const Box& cellBox = m_thisGrids.get(dit());
        const EBISBox& ebisBox = m_thisEBISL[dit()];
        if (!ebisBox.isAllCovered())
          {
            //the viscous term goes into here
            EBCellFAB dummy;
            EBCellFAB* srcPtr = &dummy;
            if (srcTmpPtr != NULL)
              {
                srcPtr = (EBCellFAB*)(&((*srcTmpPtr)[dit()]));
              }

            const EBCellFAB& source = *srcPtr;
            //unused in this case
            BaseIVFAB<Real> boundaryPrim;
            bool doBoundaryPrim = false;

            EBFluxFAB& extrapFAB  = a_extrapState[dit()];
            advectToFacesBCG(extrapFAB,
                             boundaryPrim,
                             consTemp[dit()],
                             veloTemp[dit()],
                             a_advectionVel[dit()],
                             cellBox,
                             ebisBox,
                             a_dt,
                             a_timeFine,
                             source,
                             dit(),
                             doBoundaryPrim);



            ibox++;
          }
      }
  }
  if (srcTmpPtr != NULL)
    {
      delete srcTmpPtr;
    }
}
Ejemplo n.º 30
0
void
EBFineToCoarRedist::
resetWeights(const LevelData<EBCellFAB>& a_modifierCoar,
             const int& a_ivar)
{
  CH_TIME("EBFineToCoarRedist::resetWeights");
  //set the weights to mass weighting if the modifier
  //is the coarse density.
  Interval srcInterv(a_ivar, a_ivar);
  Interval dstInterv(0,0);
  a_modifierCoar.copyTo(srcInterv, m_densityCoar, dstInterv);
  for (DataIterator dit = m_gridsCoar.dataIterator(); dit.ok(); ++dit)
    {
      const IntVectSet& fineSet = m_setsRefCoar[dit()];
      BaseIVFAB<VoFStencil>& massStenFAB = m_stenRefCoar[dit()];
      const BaseIVFAB<VoFStencil>& volStenFAB  = m_volumeStenc[dit()];
      const BaseIVFAB<VoFStencil>& stanStenFAB  = m_standardStenc[dit()];
      const EBISBox& ebisBoxFine = m_ebislRefCoar[dit()];
      const EBCellFAB& modFAB = m_densityCoar[dit()];

      for (VoFIterator vofit(fineSet, ebisBoxFine.getEBGraph()); vofit.ok(); ++vofit)
        {
          const VolIndex& vofFine = vofit();

          const VoFStencil& oldSten = volStenFAB(vofFine, 0);
          const VoFStencil& stanSten = stanStenFAB(vofFine, 0);

          VoFStencil newSten;
          for (int isten = 0; isten < oldSten.size(); isten++)
            {
              const VolIndex& thatVoFFine = oldSten.vof(isten);
              VolIndex refCoarVoF =
                m_ebislRefCoar.coarsen(thatVoFFine, m_refRat, dit());

              Real weight = modFAB(refCoarVoF, a_ivar);

              //it is weight*volfrac that is normalized
              newSten.add(thatVoFFine, weight);
            }
          //have to normalize using the whole stencil
          Real sum = 0.0;
          for (int isten = 0; isten < stanSten.size(); isten++)
            {
              const VolIndex& thatVoFFine = stanSten.vof(isten);
              VolIndex refCoarVoF =
                m_ebislRefCoar.coarsen(thatVoFFine, m_refRat, dit());

              Real weight = modFAB(refCoarVoF, a_ivar);

              Real volfrac = ebisBoxFine.volFrac(thatVoFFine);
              //it is weight*volfrac that is normalized
              sum += weight*volfrac;
            }
          if (Abs(sum) > 0.0)
            {
              Real scaling = 1.0/sum;
              newSten *= scaling;
            }
          massStenFAB(vofFine, 0) = newSten;

        }
    }
}