コード例 #1
0
void
PoisselleTube::
initializeVelocity(LevelData<EBCellFAB>&    a_velocity,
                   const DisjointBoxLayout& a_grids,
                   const EBISLayout&        a_ebisl,
                   const ProblemDomain&     a_domain,
                   const RealVect&          a_origin,
                   const Real&              a_time,
                   const RealVect&          a_dx) const
{
  for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
    {
      IntVectSet ivsBox(a_grids.get(dit()));
      for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit)
        {
          RealVect xval = EBArith::getVofLocation(vofit() , a_dx, RealVect::Zero);
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              //bogus values for normal and time because they do not matter
              Real velComp = m_bcval[idir].value(xval, RealVect::Zero, a_time, idir);
              a_velocity[dit()](vofit(), idir) = velComp;
            }
        }
    }
}
コード例 #2
0
void
NoFlowVortex::
initializeVelocity(LevelData<EBCellFAB>&    a_velocity,
                   const DisjointBoxLayout& a_grids,
                   const EBISLayout&        a_ebisl,
                   const ProblemDomain&     a_domain,
                   const RealVect&          a_origin,
                   const Real&              a_time,
                   const RealVect&          a_dx) const
{
  Real pi = 4.0*atan(1.0);
  for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
    {
      IntVectSet ivsBox(a_grids.get(dit()));
      for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit)
        {
          RealVect xval, velpt;
          getXVal(xval, a_origin,vofit(), a_dx);
          getVelPt(velpt, xval, pi);
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              a_velocity[dit()](vofit(), idir) = velpt[idir];
            }
        }
    }
}
コード例 #3
0
ファイル: levelDivTest.cpp プロジェクト: rsnemmen/Chombo
void
setToExactFluxLD(LevelData<EBFluxFAB>&       a_flux,
                 const EBISLayout&           a_ebisl,
                 const DisjointBoxLayout&    a_dbl,
                 const Real&                 a_dx)
{
    for (DataIterator dit= a_dbl.dataIterator(); dit.ok(); ++dit)
    {
        setToExactFlux(a_flux[dit()],
                       a_ebisl[dit()],
                       a_dbl.get(dit()),
                       a_dx);
    }
}
コード例 #4
0
ファイル: levelDivTest.cpp プロジェクト: rsnemmen/Chombo
void
setToExactDivFLD(LevelData<EBCellFAB>&       a_soln,
                 const EBISLayout&           a_ebisl,
                 const DisjointBoxLayout&    a_dbl,
                 const Real&                 a_dx)
{
    for (DataIterator dit= a_dbl.dataIterator(); dit.ok(); ++dit)
    {
        setToExactDivF(a_soln[dit()],
                       a_ebisl[dit()],
                       a_dbl.get(dit()),
                       a_dx);
    }
}
コード例 #5
0
ファイル: AdvectTestIBC.cpp プロジェクト: rsnemmen/Chombo
// Set up initial conditions
void AdvectTestIBC::initialize(LevelData<FArrayBox>& a_U)
{
  DisjointBoxLayout grids = a_U.disjointBoxLayout();
  for (DataIterator dit = grids.dataIterator(); dit.ok(); ++dit)
    {
      const Box& grid = grids.get(dit());
      FORT_ADVECTINITF(CHF_FRA1(a_U[dit()],0),
                       CHF_CONST_REALVECT(m_center),
                       CHF_CONST_REAL(m_size),
                       CHF_CONST_REAL(m_dx),
                       CHF_BOX(grid));

    }

}
コード例 #6
0
ファイル: rampTest.cpp プロジェクト: rsnemmen/Chombo
int
makeLayout(DisjointBoxLayout& a_dbl,
           const Box& a_domain)
{
    ParmParse pp;
    int eekflag= 0;
    int ipieces;
    ipieces = Max(ipieces, 1);
    int maxsize;
    pp.get("maxboxsize",maxsize);
    Vector<Box> vbox(1, a_domain);
    domainSplit(a_domain, vbox,  maxsize);
    if (eekflag != 0)
    {
        pout() << "problem in domainsplit" << endl;
        return eekflag;
    }
    Vector<int>  procAssign;
    eekflag = LoadBalance(procAssign,vbox);
    if (eekflag != 0)
    {
        pout() << "problem in loadbalance" << endl;
        return eekflag;
    }
    a_dbl.define(vbox, procAssign);
    return eekflag;
}
コード例 #7
0
ファイル: levelDivTest.cpp プロジェクト: rsnemmen/Chombo
void
kappaDivergenceLD(LevelData<EBCellFAB>&       a_divF,
                  const LevelData<EBFluxFAB>& a_flux,
                  const EBISLayout&           a_ebisl,
                  const DisjointBoxLayout&    a_dbl,
                  const Real&                 a_dx)
{
    for (DataIterator dit= a_dbl.dataIterator(); dit.ok(); ++dit)
    {
        kappaDivergence(a_divF[dit()],
                        a_flux[dit()],
                        a_ebisl[dit()],
                        a_dbl.get(dit()),
                        a_dx);
    }

}
コード例 #8
0
ファイル: aggpwlfpTest.cpp プロジェクト: rsnemmen/Chombo
int
makeLayout(DisjointBoxLayout& a_dbl,
           const Box& a_domainFine)
{
  //set up mesh refine object
  ParmParse pp;
  int eekflag= 0;
  int maxsize;
  pp.get("maxboxsize",maxsize);
  int bufferSize = 1;
  int blockFactor = 2;
  Real fillrat = 0.75;
  Box domainCoar = coarsen(a_domainFine, 2);
  Vector<int> refRat(2,2);
  BRMeshRefine meshRefObj(domainCoar, refRat, fillrat,
                          blockFactor, bufferSize, maxsize);

  Vector<Vector<Box> > oldMeshes(2);
  oldMeshes[0] = Vector<Box>(1,   domainCoar);
  oldMeshes[1] = Vector<Box>(1, a_domainFine);

  //set up coarse tags
  int nc = domainCoar.size(0);
  int nmi = nc/2;//16
  int nqu = nc/4;//8
  int ntf = (nc*3)/4;  //24
  int nte = (nc*3)/8; //12
  int nfe = (nc*5)/8; //20
#if (CH_SPACEDIM ==2)
  Box boxf1(IntVect(0, nqu), IntVect(nmi-1,ntf-1));
  Box boxf2(IntVect(nmi,nte), IntVect(ntf-1,nfe-1));
  Box boxf3(IntVect(nqu,0  ), IntVect(nfe-1,nqu-1));
  Box boxf4(IntVect(nfe,nqu), IntVect(nc -1,nte-1));
#else
  Box boxf1(IntVect(0, nqu,nqu), IntVect(nmi-1,ntf-1,ntf-1));
  Box boxf2(IntVect(nmi,nte,nte), IntVect(ntf-1,nfe-1,nfe-1));
  Box boxf3(IntVect(nqu,0,0  ), IntVect(nfe-1,nqu-1,nqu-1));
  Box boxf4(IntVect(nfe,nqu,nqu), IntVect(nc -1,nte-1,nte-1));
#endif
  IntVectSet tags;
  tags |= boxf1;
  tags |= boxf2;
  tags |= boxf3;
  tags |= boxf4;

  int baseLevel = 0;
  int topLevel = 0;
  Vector<Vector<Box> > newMeshes;
  meshRefObj.regrid(newMeshes, tags, baseLevel,
                    topLevel, oldMeshes);

  const Vector<Box>& vbox = newMeshes[1];
  Vector<int>  procAssign;
  eekflag = LoadBalance(procAssign,vbox);
  if (eekflag != 0) return eekflag;
  a_dbl.define(vbox, procAssign);
  return eekflag;
}
コード例 #9
0
ファイル: EBAMRTestCommon.cpp プロジェクト: dtgraves/EBAMRCNS
int 
EBAMRTestCommon::
checkForZero(const LevelData<EBCellFAB>& a_errorVelo,
             const DisjointBoxLayout&    a_gridsFine,
             const EBISLayout&           a_ebislFine,
             const Box&                  a_domainFine,
             string a_funcname)
{
  int eekflag = 0;
  Real eps = 1.0e-8;
#ifdef CH_USE_FLOAT
  eps = 1.0e-3;
#endif

  for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit)
    {
      Box grownBox = a_gridsFine.get(dit());
      grownBox.grow(1);
      grownBox &= a_domainFine;
      IntVectSet ivsBox(grownBox);
      for (VoFIterator vofit(ivsBox, a_ebislFine[dit()].getEBGraph()); vofit.ok(); ++vofit)
        {
          const VolIndex& vof = vofit();
          int ihere = 0;
          if (vof.gridIndex() == EBDebugPoint::s_ivd)
            {
              ihere = 1;
            }
          for (int ivar = 0; ivar < a_errorVelo.nComp(); ivar++)
            {
              Real errorIn = a_errorVelo[dit()](vof, ivar);
              if (Abs(errorIn) > eps)
                {
                  pout() << "check for zero error too big for test " << a_funcname << endl;
                  pout() << "ivar = " << ivar <<  endl;
                  pout() << "vof = " << vof.gridIndex() << " error = " << errorIn << endl;
                  return -1;
                }
            }
        }

    }
  return eekflag;
}
コード例 #10
0
ファイル: CFStencil.cpp プロジェクト: dtgraves/EBAMRCNS
void CFStencil::buildPeriodicVector(Vector<Box>& a_periodicVector,
                                    const ProblemDomain& a_fineDomain,
                                    const DisjointBoxLayout& a_fineBoxes)
{
  Box periodicTestBox(a_fineDomain.domainBox());
  if (a_fineDomain.isPeriodic())
    {
      for (int idir=0; idir<SpaceDim; idir++)
        {
          if (a_fineDomain.isPeriodic(idir))
            {
              periodicTestBox.grow(idir,-1);
            }
        }
    }
  a_periodicVector.clear();
  a_periodicVector.reserve(a_fineBoxes.size());

  LayoutIterator lit = a_fineBoxes.layoutIterator();
  for (lit.reset(); lit.ok(); ++lit)
    {
      const Box& box = a_fineBoxes[lit()];
      a_periodicVector.push_back(box);
      // if periodic, also need to add periodic images
      // only do this IF we're periodic and box
      // adjacent to  the domain box boundary somewhere
      if (a_fineDomain.isPeriodic()
          && !periodicTestBox.contains(box))
        {
          ShiftIterator shiftIt = a_fineDomain.shiftIterator();
          IntVect shiftMult(a_fineDomain.domainBox().size());
          Box shiftedBox(box);
          for (shiftIt.begin(); shiftIt.ok(); ++shiftIt)
            {
              IntVect shiftVect = shiftMult*shiftIt();
              shiftedBox.shift(shiftVect);
              a_periodicVector.push_back(shiftedBox);
              shiftedBox.shift(-shiftVect);
            } // end loop over periodic shift directions
        } // end if periodic
    }
  a_periodicVector.sort();
}
コード例 #11
0
ファイル: pwlinterpTest.cpp プロジェクト: rsnemmen/Chombo
int
makeLayoutPart(DisjointBoxLayout& a_dbl,
               const Box& a_domainCoarsest)
{
  //  Vector<int> vecRefRat(2, 2);
  ParmParse pp;
  int eekflag= 0;
  int blockFactor, bufferSize, maxSize;
  Real fillRat;
  pp.get("block_factor", blockFactor);
  pp.get("buffer_size", bufferSize);
  pp.get("maxboxsize", maxSize);
  pp.get("fill_ratio", fillRat);
  int nlevels =  2;
  Vector<int> vecRefRat(nlevels);
  pp.getarr("ref_ratio", vecRefRat,0,nlevels);
  BRMeshRefine mesher(a_domainCoarsest, vecRefRat,
                      fillRat, blockFactor, bufferSize, maxSize);

  int topLevel  =  0;
  int baseLevel =  0;
  //tags at base level
  IntVectSet tags;
  eekflag = makeTags(tags, a_domainCoarsest);
  if (eekflag < 0) return eekflag;

  Vector<Vector<Box> > oldMeshes(nlevels);
  oldMeshes[0] = Vector<Box>(1, a_domainCoarsest);
  Box finerDomain = a_domainCoarsest;
  for (int ilev = 1; ilev < nlevels; ilev++)
    {
      finerDomain.refine(vecRefRat[ilev]);
      oldMeshes[ilev] = Vector<Box>(1, finerDomain);
    }
  Vector<Vector<Box> > newMeshes;
  mesher.regrid(newMeshes, tags, baseLevel, topLevel, oldMeshes);

  Vector<int> procAssign;
  eekflag = LoadBalance(procAssign, newMeshes[1]);
  if (eekflag != 0) return eekflag;
  a_dbl.define(newMeshes[1], procAssign);
  int iverbose;
  pp.get("verbose", iverbose);
  if (iverbose == 1)
    {
      pout() << "the grids coarser domain= " << a_domainCoarsest
             << " = " << a_dbl << endl;
    }

  return eekflag;
}
コード例 #12
0
ファイル: levelDivTest.cpp プロジェクト: rsnemmen/Chombo
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;
    }
}
コード例 #13
0
void
NoFlowVortex::
initializeScalar ( LevelData<EBCellFAB>&    a_scalar,
                   const DisjointBoxLayout& a_grids,
                   const EBISLayout&        a_ebisl,
                   const ProblemDomain&     a_domain,
                   const RealVect&          a_origin,
                   const Real&              a_time,
                   const RealVect&          a_dx) const
{
  for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
    {
      IntVectSet ivsBox(a_grids.get(dit()));
      for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit)
        {
          RealVect xval;
          Real scal;
          getXVal(xval, a_origin,vofit(), a_dx);
          getScalarPt(scal, xval);
          a_scalar[dit()](vofit(), 0) = scal;
        }
    }
}
コード例 #14
0
void
NoFlowVortex::
initializePressure(LevelData<EBCellFAB>&    a_pressure,
                   const DisjointBoxLayout& a_grids,
                   const EBISLayout&        a_ebisl,
                   const ProblemDomain&     a_domain,
                   const RealVect&          a_origin,
                   const Real&              a_time,
                   const RealVect&          a_dx) const
{
  for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
    {
      IntVectSet ivsBox(a_grids.get(dit()));
      for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit)
        {
          RealVect xval, pt;
          getXVal(xval, a_origin,vofit(), a_dx);
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              a_pressure[dit()](vofit(), idir) = 1.e99;
            }
        }
    }
}
コード例 #15
0
int checkCoarseAssortment(const Box& a_domain)
{
  int retval = 0;
  const EBIndexSpace* const ebisPtr = Chombo_EBIS::instance();
  CH_assert(ebisPtr->isDefined());
  Box fineDomain = a_domain;

  int numLevels = ebisPtr->numLevels();
  for (int ilev = 1; ilev < numLevels; ilev++)
    {
      CH_assert(!fineDomain.isEmpty());
      Vector<Box> vbox(1, fineDomain);
      Vector<int> proc(1, 0);
      DisjointBoxLayout fineDBL(vbox, proc);
      EBISLayout fineEBISL;
      int nghost = 4;
      ebisPtr->fillEBISLayout(fineEBISL, fineDBL, fineDomain, nghost);
      Box coarDomain = coarsen(fineDomain, 2);
      DisjointBoxLayout coarDBL;
      coarsen(coarDBL, fineDBL, 2);
      EBISLayout coarEBISL;
      ebisPtr->fillEBISLayout(coarEBISL, coarDBL, coarDomain, nghost);

      for (DataIterator dit = fineDBL.dataIterator(); dit.ok(); ++dit)
        {
          retval = checkEBISBox(coarDBL.get(dit()), coarEBISL[dit()], fineEBISL[dit()]);
          if (retval != 0)
            {
              pout() << "problem in coarsening  " << fineDomain << " to " << coarDomain << endl;
              return retval;
            }
        }
      fineDomain.coarsen(2);
   }
return retval;
}
コード例 #16
0
// ---------------------------------------------------------
void
NodeCoarseAverage::define(const DisjointBoxLayout& a_gridsFine,
                          const DisjointBoxLayout& a_gridsCoarse,
                          int a_numcomps,
                          int a_refRatio,
                          const ProblemDomain& a_domainFine)
{
  m_refRatio = a_refRatio;
  m_numcomps = a_numcomps;
  m_domainCoarse = coarsen(a_domainFine, m_refRatio);

  // DisjointBoxLayout::coarsen()
  coarsen(m_coarsenedGrids, a_gridsFine, m_refRatio);
  m_coarsenedFine.define(m_coarsenedGrids, m_numcomps);

  IntVect extent = (a_refRatio/2) * IntVect::Unit;
  m_refbox = Box(-extent, extent);
  m_weights.define(m_refbox, 1);
  FORT_NODEAVERAGE_GETWEIGHTS(CHF_FRA(m_weights),
                              CHF_CONST_INT(m_refRatio));

  if (m_verbose)
    cout << "IBN NodeCoarseAverage on "
         << m_domainCoarse.domainBox().size()
         << ", from "
         << m_coarsenedGrids.size() << " coarsened grids to "
         << a_gridsCoarse.size() << " coarser-level grids on "
         << m_domainCoarse.domainBox().size()
         << endl;

  interiorBoundaryNodes(m_IVSV, a_gridsCoarse, m_coarsenedGrids, m_domainCoarse);

  if (m_verbose)
    cout << "IBN NodeCoarseAverage on "
         << m_domainCoarse.domainBox().size()
         << ", from "
         << m_coarsenedGrids.size() << " coarsened grids to selves on "
         << m_domainCoarse.domainBox().size()
         << endl;

  interiorBoundaryNodes(m_IVSVsame, m_coarsenedGrids, m_domainCoarse);

  // m_IVSVfull added by petermc, 21 Jul 2003
  fullIntVectSets(m_IVSVfull, m_IVSVsame);

  m_sameGrids = false;
  is_defined = true;
}
コード例 #17
0
ファイル: NodeNorms.cpp プロジェクト: dtgraves/EBAMRCNS
// ------------------------------------------------------------
// version of 27 March 2003
Real
norm(const LevelData<NodeFArrayBox>& a_phi,
     const ProblemDomain& a_domain,
     const DisjointBoxLayout& a_finerGridsCoarsened,
     const LayoutData< Vector<Box> >& a_IVSVext,
     const LayoutData< Vector<Box> >& a_IVSVintFinerCoarsened,
     const int a_nRefFine,
     const Real a_dx,
     const Interval& a_comps,
     const int a_p,
     bool a_verbose)
{
  // Idea:  copy a_phi to temp, then zero out temp on:
  // - exterior nodes of grids at this level;
  // - projections of interior nodes of the finer grids.
  int ncomps = a_comps.size();
  const DisjointBoxLayout& grids = a_phi.getBoxes();
  LevelData<NodeFArrayBox> temp(grids, ncomps);

  // Copy a_phi to temp.
  Interval newcomps(0, ncomps-1);
  for (DataIterator dit(grids.dataIterator()); dit.ok(); ++dit)
    {
      const NodeFArrayBox& nfab = a_phi[dit()];
      const Box& bx = grids.get(dit());
      temp[dit()].copy(bx, newcomps, bx, nfab, a_comps);
    }

  // Zero out temp on exterior nodes.
  zeroBoundaryNodes(temp, a_IVSVext);

  // Define zeroCoarsened to be all zero on the coarsened finer grids.
  LevelData<NodeFArrayBox>
    zeroCoarsened(a_finerGridsCoarsened, ncomps, IntVect::Zero);
  for (DataIterator dit(a_finerGridsCoarsened.dataIterator()); dit.ok(); ++dit)
    zeroCoarsened[dit()].getFab().setVal(0.);

  // Set temp to zero on interior nodes of coarsened finer grids.
  copyInteriorNodes(temp, zeroCoarsened, a_IVSVintFinerCoarsened);

  Real normLevel = norm(temp, a_dx, a_p, newcomps, a_verbose);

  return normLevel;
}
コード例 #18
0
ファイル: halfQuadTest.cpp プロジェクト: rsnemmen/Chombo
int
makeLayout(DisjointBoxLayout& a_dbl,
           const Box& a_domainFine)
{
  //set up mesh refine object
  ParmParse pp;
  int eekflag= 0;
  int maxsize;
  pp.get("maxboxsize",maxsize);
  int bufferSize = 2;
  int blockFactor = 8;
  Real fillrat = 0.7;
  Box domainCoar = coarsen(a_domainFine, 2);
  Vector<int> refRat(2,2);
  BRMeshRefine meshRefObj(domainCoar, refRat, fillrat,
                          blockFactor, bufferSize, maxsize);

  Vector<Vector<Box> > oldMeshes(2);
  oldMeshes[0] = Vector<Box>(1,   domainCoar);
  oldMeshes[1] = Vector<Box>(1, a_domainFine);

  //set up coarse tags
  int nc = domainCoar.size(0);
  Box halfBox = domainCoar;
  halfBox.growHi(0, -nc/2);
  IntVectSet tags(halfBox);


  int baseLevel = 0;
  int topLevel = 0;
  Vector<Vector<Box> > newMeshes;
  meshRefObj.regrid(newMeshes, tags, baseLevel,
                    topLevel, oldMeshes);

  const Vector<Box>& vbox = newMeshes[1];
  Vector<int>  procAssign;
  eekflag = LoadBalance(procAssign,vbox);
  if (eekflag != 0) return eekflag;
  a_dbl.define(vbox, procAssign);
  return eekflag;
}
コード例 #19
0
ファイル: testPeriodic.cpp プロジェクト: rsnemmen/Chombo
int
main(int argc ,char *argv[] )
{
#ifdef CH_MPI
  MPI_Init(&argc, &argv);
#endif

  int status = 0;
  // Make this test pass automatically if DIM > 3, to avoid FAIL message.
  if (SpaceDim <= 3)
  {
    parseTestOptions(argc, argv);

    // establish periodic domain -- first multiply periodic in all directions
    int baseDomainSize = 8;
    int numGhost = 2;
    IntVect ghostVect(numGhost*IntVect::Unit);

    Box baseDomBox(IntVect::Zero, (baseDomainSize-1)*IntVect::Unit);
    ProblemDomain baseDomain(baseDomBox);

    // set periodic in all directions
    for (int dir=0; dir<SpaceDim; dir++)
    {
      baseDomain.setPeriodic(dir, true);
    }

    {
      // QuadCFInterp test
      int nRef = 2;
      ProblemDomain fineDomain(baseDomain);
      fineDomain.refine(nRef);

      const Box domainBox = baseDomain.domainBox();
      Vector<Box> crseBoxes(1, domainBox);
      Vector<int> crseProcAssign(1,0);
      DisjointBoxLayout crseGrids(crseBoxes, crseProcAssign, baseDomain);

      // note the lack of ghost cells on the base level
      LevelData<FArrayBox> crseData(crseGrids, 1, IntVect::Zero);

      Real dxCrse = 1.0/(baseDomainSize);
      Real dxFine = dxCrse/nRef;
      initData(crseData, dxCrse);

#if (CH_SPACEDIM == 1)
      Vector<Box> fineBoxes(2);
      Vector<int> fineProcAssign(2);

      fineBoxes[0] = Box(IntVect::Zero, 5*IntVect::Unit);
      fineBoxes[1] = Box(IntVect(D_DECL6(6,10,10,6,10,0)), IntVect(D_DECL6(11,15,15,11,15,15)));
#else
      // try multiple boxes for fine level
      Vector<Box> fineBoxes(4);
      Vector<int> fineProcAssign(4);

      fineBoxes[0] = Box(IntVect::Zero, 9*IntVect::Unit);
      fineBoxes[1] = Box(IntVect(D_DECL6(6,10,10,6,10,0)), IntVect(D_DECL6(11,15,15,11,15,15)));
      // this box should fail the disjointness test
      //fineBoxes[1] = Box(IntVect(D_DECL(7,10,10)), 17*IntVect::Unit);
      fineBoxes[2] = Box(IntVect(D_DECL6(12,2,0,12,2,0)), IntVect(D_DECL6(15,7,7,15,7,7)));
      fineBoxes[3] = Box(IntVect(D_DECL6(12,12,0,12,12,0)), 15*IntVect::Unit);
#endif

      int loadbalancestatus = LoadBalance(fineProcAssign, fineBoxes);
      CH_assert (loadbalancestatus == 0);

      DisjointBoxLayout fineGrids;
      fineGrids.define(fineBoxes, fineProcAssign, fineDomain);
      LevelData<FArrayBox> fineData(fineGrids, 1, ghostVect);

      // set these to a bogus value to start with
      DataIterator fineDit = fineData.dataIterator();
      for (fineDit.begin(); fineDit.ok(); ++fineDit)
        {
          fineData[fineDit()].setVal(1.0e9);
        }

      FineInterp interpolator(fineGrids, 1, nRef, fineDomain);

      // turn on fine-data averaging even though it's unnecessary
      // since this is a test (so we'd like to know if it's broken)
      bool averageFineData = true;
      interpolator.interpToFine(fineData, crseData, averageFineData);

      // now fill in ghost cells
      QuadCFInterp filler(fineGrids, &crseGrids, dxFine, nRef, 1,
              fineDomain);

      filler.coarseFineInterp(fineData, crseData);
    }

    {
      // fineInterp near boundary test
      int numLev = 3;
      Vector<int> nRefVect(numLev);
      nRefVect[0] = 4;
      nRefVect[1] = 2;
      nRefVect[2] = -1;
      Vector<Real> dxVect(numLev);
      Vector<ProblemDomain> levelDomains(numLev);
      levelDomains[0] = Box(IntVect::Zero, 15*IntVect::Unit);
      dxVect[0] = 1.0/(levelDomains[0].domainBox().size(0));
      for (int lev=1; lev<numLev; lev++)
        {
          levelDomains[lev] = levelDomains[lev-1];
          levelDomains[lev].refine(nRefVect[lev-1]);
          dxVect[lev] = dxVect[lev-1]/nRefVect[lev-1];
        }

      Vector<DisjointBoxLayout> levelGrids(numLev);
      Vector<LevelData<FArrayBox>* > levelData(numLev, NULL);

      const Box domainBox = levelDomains[0].domainBox();
      Vector<Box> crseBoxes(1, domainBox);
      Vector<int> crseProcAssign(1,0);
      DisjointBoxLayout level0Grids(crseBoxes, crseProcAssign,
                                    levelDomains[0]);
      levelGrids[0] = level0Grids;

      // note the lack of ghost cells on the base level
      levelData[0] = new LevelData<FArrayBox>(level0Grids,
                                              1, IntVect::Zero);

      initData(*levelData[0], dxVect[0]);

      Vector<Box> level1Boxes(1, levelDomains[1].domainBox());
      int loadbalancestatus = LoadBalance(crseProcAssign, level1Boxes);
      CH_assert (loadbalancestatus == 0);

      IntVect newGhostVect(4*IntVect::Unit);
      DisjointBoxLayout fineGrids;
      fineGrids.define(level1Boxes, crseProcAssign, levelDomains[1]);
      levelGrids[1] = fineGrids;
      levelData[1] = new LevelData<FArrayBox>(fineGrids, 1,
                                              newGhostVect);

      Vector<Box> level2Boxes(1);
      //level2Boxes[0] = Box(20*IntVect::Unit, 119*IntVect::Unit);
      level2Boxes[0] = Box(100*IntVect::Unit, 127*IntVect::Unit);
      DisjointBoxLayout finestGrids(level2Boxes, crseProcAssign,
                                    levelDomains[2]);
      levelGrids[2] = finestGrids;
      levelData[2] = new LevelData<FArrayBox>(finestGrids, 1,
                                              newGhostVect);

      for (int lev=1; lev<numLev; lev++)
        {
          LevelData<FArrayBox>& fineData = *levelData[lev];
          LevelData<FArrayBox>& crseData = *levelData[lev-1];

          // set these to a bogus value to start with
          DataIterator fineDit = fineData.dataIterator();
          for (fineDit.begin(); fineDit.ok(); ++fineDit)
            {
              fineData[fineDit()].setVal(1.0e9);
            }

          FineInterp interpolator(levelGrids[lev], 1, nRefVect[lev-1],
                                  levelDomains[lev]);

          // turn on fine-data averaging even though it's unnecessary
          // since this is a test (so we'd like to know if it's broken)
          bool averageFineData = true;
          interpolator.interpToFine(fineData, crseData, averageFineData);

          pout() << "grids at level = " << lev << endl;
          dumpDBL(&levelGrids[lev]);
          pout() << "grids at level = " << lev-1 << endl;
          dumpDBL(&levelGrids[lev-1]);

          // now fill in ghost cells
          QuadCFInterp filler(levelGrids[lev], &levelGrids[lev-1],
                              dxVect[lev],
                              nRefVect[lev-1], 1,
                              levelDomains[lev]);

          filler.coarseFineInterp(fineData, crseData);
        }

#ifdef CH_USE_HDF5
      // dump data
      if (writePlots)
        {
          string fname = "interp.hdf5";
          Vector<string> varNames(1,"phi");
          Real dt = 0.0;
          Real time= 0.0;
          WriteAMRHierarchyHDF5(fname, levelGrids,
                                levelData, varNames,
                                levelDomains[0].domainBox(),
                                dxVect[0], dt, time,
                                nRefVect, numLev);
        }
#endif

      // clean up memory
      for (int lev=0; lev<levelData.size(); lev++)
        {
          if (levelData[lev] != NULL)
            {
              delete levelData[lev];
              levelData[lev] = NULL;
            }
        }
    }

    // now test partially periodic case (also coarsen back to original domain
    // no such thing as "partially periodic" for 1D; for 1D, test moving
    // fine-grid boxes from low-end of domain to high-end of domain

    {

      baseDomain.setPeriodic(0,false);
      // try similar tests to the previous case
      int nRef = 2;
      ProblemDomain fineDomain(baseDomain);
      fineDomain.refine(nRef);

      const Box domainBox = baseDomain.domainBox();
      Vector<Box> crseBoxes(1, domainBox);
      Vector<int> crseProcAssign(1,0);
      DisjointBoxLayout crseGrids(crseBoxes, crseProcAssign, baseDomain);

      // note the lack of ghost cells on the base level
      LevelData<FArrayBox> crseData(crseGrids, 1, IntVect::Zero);

      Real dxCrse = 1.0/(baseDomainSize);
      Real dxFine = dxCrse/nRef;
      initData(crseData, dxCrse);

#if (CH_SPACEDIM == 1)
      Vector<Box> fineBoxes(2);
      Vector<int> fineProcAssign(2);

      fineBoxes[0] = Box(12*IntVect::Unit, 15*IntVect::Unit);
      fineBoxes[1] = Box(IntVect(D_DECL6(6,10,10,6,10,10)), IntVect(D_DECL6(11,15,15,11,15,15)));
#else
      // try multiple boxes for fine level
      // note grids are different in this case to allow for all periodic checking
      Vector<Box> fineBoxes(3);
      Vector<int> fineProcAssign(3);

      fineBoxes[0] = Box(IntVect::Zero, 9*IntVect::Unit);
      fineBoxes[1] = Box(IntVect(D_DECL6(6,10,10,6,10,10)), IntVect(D_DECL6(11,15,15,11,15,15)));
      // this box should fail the disjointness test
      //fineBoxes[1] = Box(IntVect(D_DECL(7,10,10)), 17*IntVect::Unit);
      fineBoxes[2] = Box(IntVect(D_DECL6(12,2,0,12,2,0)), IntVect(D_DECL6(15,7,7,15,7,7)));
      //fineBoxes[3] = Box(IntVect(D_DECL(12,12,0)), 15*IntVect::Unit);
#endif

      int loadbalancestatus = LoadBalance(fineProcAssign, fineBoxes);
      CH_assert (loadbalancestatus == 0);

      DisjointBoxLayout fineGrids;
      fineGrids.define(fineBoxes, fineProcAssign, fineDomain);
      LevelData<FArrayBox> fineData(fineGrids, 1, ghostVect);

      // set these to a bogus value to start with
      DataIterator fineDit = fineData.dataIterator();
      for (fineDit.begin(); fineDit.ok(); ++fineDit)
        {
          fineData[fineDit()].setVal(1.0e9);
        }

      FineInterp interpolator(fineGrids, 1, nRef, fineDomain);

      // turn on fine-data averaging even though it's unnecessary
      // since this is a test (so we'd like to know if it's broken)
      bool averageFineData = true;
      interpolator.interpToFine(fineData, crseData, averageFineData);

      // now fill in first layer of ghost cells
      QuadCFInterp filler(fineGrids, &crseGrids, dxFine, nRef, 1,
                          fineDomain);

      filler.coarseFineInterp(fineData, crseData);

      // now fill in remaining ghost cell with extrapolation
      Interval extrapInterval(1,1);
      ExtrapFillPatch extrapFiller(fineGrids, fineDomain,
                                   extrapInterval);

      for (int dir=0; dir<SpaceDim; dir++)
        {
          extrapFiller.fillExtrap(fineData,dir,0,1);
        }

      fineData.exchange(fineData.interval());

    }

  } // if (SpaceDim <= 3)
  pout() << indent << pgmname << ": "
         << ( (status == 0) ? "passed all tests" : "failed at least one test,")
         << endl;

#ifdef CH_MPI
  MPI_Finalize();
#endif
  return status ;
}
コード例 #20
0
ファイル: CFStencil.cpp プロジェクト: dtgraves/EBAMRCNS
void
CFStencil::define(
                  const ProblemDomain& a_fineDomain,
                  const Box& a_grid,
                  const DisjointBoxLayout& a_fineBoxes,
                  const DisjointBoxLayout& a_coarBoxes,
                  int a_refRatio,
                  int a_direction,
                  Side::LoHiSide a_hiorlo)
{
  m_isDefined = true;
  CH_assert(a_refRatio >= 1);
  CH_assert(a_direction >= 0);
  CH_assert(a_direction < SpaceDim);
  CH_assert((a_hiorlo == Side::Lo) ||
         (a_hiorlo == Side::Hi));
  CH_assert(!a_fineDomain.isEmpty());

  //set internal vars.  most of these are kept around
  //just to keep the class from having an identity crisis.
  m_direction = a_direction;
  m_hiorlo =  a_hiorlo;

  Box finebox = a_grid;


  //compute intvectset of all points on fine grid that
  //need to be interpolated

  //shift direction
  int hilo = sign(a_hiorlo);

  //create fine stencil
  Box edgebox;
  CH_assert((hilo ==1) || (hilo == -1));
  if (hilo == -1)
    {
      edgebox = adjCellLo(finebox,m_direction,1);
    }
  else
    {
      edgebox = adjCellHi(finebox,m_direction,1);
    }
  edgebox = a_fineDomain & edgebox;
  if (!edgebox.isEmpty())
    {
      Box periodicTestBox(a_fineDomain.domainBox());
      if (a_fineDomain.isPeriodic())
        {
          for (int idir=0; idir<SpaceDim; idir++)
            {
              if (a_fineDomain.isPeriodic(idir))
                {
                  periodicTestBox.grow(idir,-1);
                }
            }
        }

      m_fineIVS.define(edgebox);
      LayoutIterator lit = a_fineBoxes.layoutIterator();
      for (lit.reset(); lit.ok(); ++lit)
        {
          m_fineIVS -= a_fineBoxes[lit()];
          // if periodic, also need to subtract periodic images
          // only do this IF we're periodic _and_ both boxes
          // adjoin the domain box boundary somewhere
          if (a_fineDomain.isPeriodic() && !periodicTestBox.contains(edgebox)
              && !periodicTestBox.contains(a_fineBoxes[lit()]))
            {
              ShiftIterator shiftIt = a_fineDomain.shiftIterator();
              IntVect shiftMult(a_fineDomain.domainBox().size());
              Box shiftedBox(a_fineBoxes[lit()]);
              for (shiftIt.begin(); shiftIt.ok(); ++shiftIt)
                {
                  IntVect shiftVect = shiftMult*shiftIt();
                  shiftedBox.shift(shiftVect);
                  m_fineIVS -= shiftedBox;
                  shiftedBox.shift(-shiftVect);
                } // end loop over periodic shift directions
            } // end if periodic
        }
    }

  //ivs where all coarse slopes are defined
  //== coarsened fine ivs
  m_coarIVS.define(m_fineIVS);
  m_coarIVS.coarsen(a_refRatio);
  // this is a trick to get around the lack of a IntVectSet intersection
  // operator which works with a ProblemDomain
  ProblemDomain coardom= coarsen(a_fineDomain, a_refRatio);
  Box domainIntersectBox = m_coarIVS.minBox();
  domainIntersectBox = coardom & domainIntersectBox;
  m_coarIVS &= domainIntersectBox;

  m_packedBox = m_fineIVS.minBox();
  if (m_fineIVS.numPts() == m_packedBox.numPts())
    {
      m_isPacked = true;
    }
  else
    {
      m_isPacked = false;
      m_packedBox = Box();
    }
}
コード例 #21
0
ファイル: rampTest.cpp プロジェクト: rsnemmen/Chombo
int checkEBISL(const EBISLayout& a_ebisl,
               const DisjointBoxLayout& a_grids,
               const Box& a_domain,
               const Real& a_dx,
               const RealVect& a_origin,
               const int& a_upDir,
               const int& a_indepVar,
               const Real& a_startPt,
               const Real& a_slope)
{
    //check to see that the sum of the volume fractions
    //comes to close to exactly the total volume
    int eekflag =  0;
#ifdef CH_USE_FLOAT
    Real tolerance  = 60 * PolyGeom::getTolerance();
#else
    Real tolerance  = PolyGeom::getTolerance();
#endif
    const IntVect& ivSize= a_domain.size();
    RealVect hiCorn;
    RealVect domLen;
    Real cellVolume = 1.0;
    Real totalVolume = 1.0;
    for (int idir = 0; idir < SpaceDim; idir++)
    {
        hiCorn[idir] = a_origin[idir] + a_dx*Real(ivSize[idir]);
        cellVolume *= a_dx;
        domLen[idir] = hiCorn[idir] - a_origin[idir];
        totalVolume *= domLen[idir];
    }
    //find normal and alpha in the space where the length of
    //the domain in all directions is unity
    int iy = a_upDir;
    int ix = a_indepVar;
    RealVect normal = RealVect::Zero;
    normal[iy] =          domLen[iy];
    normal[ix] = -a_slope*domLen[ix];
    Real alpha = a_slope*(a_origin[ix]-a_startPt)-a_origin[iy];
    Real volExact = totalVolume*PolyGeom::computeVolume(alpha, normal);

    RealVect correctNorm = RealVect::Zero;
    Real sumSquare;
    correctNorm[a_upDir] = 1.0;
    correctNorm[a_indepVar] = -a_slope;
    PolyGeom::unifyVector(correctNorm, sumSquare);
    //
    //voltot = sum(cellVolume*volFrac) = numerical domain volume.
    Real voltot = 0;
    for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
    {
        const EBISBox& ebisBox = a_ebisl[dit()];
        for (BoxIterator bit(a_grids.get(dit())); bit.ok(); ++bit)
        {
            const IntVect& iv = bit();
            Vector<VolIndex> vofs = ebisBox.getVoFs(iv);
            if (vofs.size() > 1)
            {
                eekflag = 2;
                return eekflag;
            }
            for (int ivof = 0; ivof < vofs.size(); ivof++)
            {
                Real volFrac = ebisBox.volFrac(vofs[ivof]);
                voltot += volFrac*cellVolume;
                if (volFrac > tolerance && volFrac < 1.0-tolerance)
                {
                    if (!ebisBox.isIrregular(iv))
                    {
                        eekflag = 4;
                        return eekflag;
                    }
                    RealVect normal= ebisBox.normal(vofs[ivof]);
                    for (int idir = 0; idir < SpaceDim; idir++)
                    {
                        if (Abs(normal[idir] - correctNorm[idir]) > tolerance)
                        {
                            eekflag = 5;
                            return eekflag;
                        }
                    }
                    RealVect centroid= ebisBox.centroid(vofs[ivof]);
                    for (int idir = 0; idir < SpaceDim; idir++)
                    {
                        if (Abs(centroid[idir]) > 0.5)
                        {
                            eekflag = 6;
                            return eekflag;
                        }
                    }
                }
            }
        }
    }
#ifdef CH_MPI
    Real t=voltot;
    MPI_Allreduce ( &t, &voltot, 1,
                    MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm);
#endif

    if (Abs(voltot -volExact) > tolerance)
    {
        pout() << Abs(voltot - volExact)
               << " > " << tolerance << endl;
        eekflag = 3;
        return eekflag;
    }
    return eekflag;
}
コード例 #22
0
ファイル: ldBaseIFFABTest.cpp プロジェクト: rsnemmen/Chombo
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;
}
コード例 #23
0
ファイル: impFuncTest.cpp プロジェクト: rsnemmen/Chombo
int checkEBISL(const EBISLayout&        a_ebisl,
               const DisjointBoxLayout& a_grids,
               const Box&               a_domain,
               const Real&              a_dx,
               const RealVect&          a_origin,
               const Real&              a_radius,
               const RealVect&          a_center,
               const bool&              a_insideRegular)
{
  //check to see that the sum of the volume fractions
  //comes to close to exactly the total volume
  int eekflag =  0;
  //First: calculate volume of domain

  const IntVect& ivSize = a_domain.size();
  RealVect hiCorn;
  RealVect domLen;
  Real cellVolume = 1.0;
  Real totalVolume = 1.0;

  for (int idir = 0; idir < SpaceDim; idir++)
  {
    hiCorn[idir] = a_origin[idir] + a_dx*Real(ivSize[idir]);
    cellVolume *= a_dx;
    domLen[idir] = hiCorn[idir] - a_origin[idir];
    totalVolume *= domLen[idir];
  }

  // Calculate the exact volume of the regular region
  Real volExact;
  Real volError;
  Real bndryExact;
  Real bndryError;

  if (SpaceDim == 2)
  {
    volExact = acos(-1.0) * a_radius*a_radius;
    volError = 0.0001851;

    bndryExact = 2*acos(-1.0) * a_radius;
    bndryError = 0.000047;
  }

  if (SpaceDim == 3)
  {
    volExact = 4.0/3.0 * acos(-1.0) * a_radius*a_radius*a_radius;
    volError = 0.000585;

    bndryExact = 4.0 * acos(-1.0) * a_radius*a_radius;
    bndryError = 0.000287;
  }

  if (a_insideRegular == false)
  {
    volExact = totalVolume - volExact;
  }

  // Now calculate the volume of approximate sphere
  Real tolerance = 0.001;
  Real volTotal = 0.0;
  Real bndryTotal = 0.0;


  for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
  {
    const EBISBox& ebisBox = a_ebisl[dit()];
    for (BoxIterator bit(a_grids.get(dit())); bit.ok(); ++bit)
    {
      const IntVect& iv = bit();
      Vector<VolIndex> vofs = ebisBox.getVoFs(iv);

      if (vofs.size() > 1)
      {
        eekflag = 2;
        return eekflag;
      }

      for (int ivof = 0; ivof < vofs.size(); ivof++)
      {
        Real volFrac = ebisBox.volFrac(vofs[ivof]);
        if (ebisBox.isIrregular(iv))
          {
            pout() << "iv = " << iv << ", volFrac = " << volFrac << endl;
          }
        volTotal += volFrac * cellVolume;

        Real bndryArea = ebisBox.bndryArea(vofs[ivof]);
        bndryTotal += bndryArea * cellVolume / a_dx;

        if (volFrac > tolerance && volFrac < 1.0 - tolerance)
        {
          if (!ebisBox.isIrregular(iv))
          {
            eekflag = 4;
            return eekflag;
          }
        }
      }
    }
  }
#ifdef CH_MPI
  Real t=volTotal;
  MPI_Allreduce ( &t, &volTotal, 1,
                  MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm);
  t=bndryTotal;
  MPI_Allreduce ( &t, &bndryTotal, 1,
                   MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm);
#endif

  //check how close is the answer
  pout() << endl;

  Real error;
  error = volTotal - volExact;

  if (Abs(error/volExact) > volError)
  {
    eekflag = 5;
  }

  pout() << "volTotal  = " << volTotal             << endl;
  pout() << "volExact  = " << volExact             << endl;
  pout() << "error     = " << error                << endl;
  pout() << "relError  = " << Abs(error/volExact) << endl;
  pout() << "tolerance = " << volError             << endl;
  pout() << endl;

  error = bndryTotal - bndryExact;

  if (Abs(error/bndryExact) > bndryError)
  {
    eekflag = 6;
  }

  pout() << "bndryTotal = " << bndryTotal             << endl;
  pout() << "bndryExact = " << bndryExact             << endl;
  pout() << "error      = " << error                  << endl;
  pout() << "relError   = " << Abs(error/bndryExact) << endl;
  pout() << "tolerance  = " << bndryError             << endl;
  pout() << endl;

  return eekflag;
}
コード例 #24
0
ファイル: NodeQCFI.cpp プロジェクト: dtgraves/EBAMRCNS
// ---------------------------------------------------------
void
NodeQCFI::define(const DisjointBoxLayout& a_grids,
                 Real a_dx,
                 const ProblemDomain& a_domain,
                 const LayoutData<NodeCFIVS>* const a_loCFIVS,
                 const LayoutData<NodeCFIVS>* const a_hiCFIVS,
                 int a_refToCoarse,
                 NodeBCFunc               a_bc,
                 int a_interpolationDegree,
                 int a_ncomp,
                 bool a_verbose)
{
  CH_assert(a_refToCoarse >= 2);
  m_bc = a_bc;
  m_grids = a_grids;
  m_dx = a_dx;
  m_verbose = a_verbose;

  // m_coarsenings == log2(a_refToCoarse);
  m_coarsenings = 0;
  for (int interRatio = a_refToCoarse; interRatio >= 2; interRatio /= 2)
    m_coarsenings++;

  m_qcfi2.resize(m_coarsenings);
  m_inter.resize(m_coarsenings-1);
  m_loCFIVScoarser.resize(m_coarsenings-1);
  m_hiCFIVScoarser.resize(m_coarsenings-1);
  // for i=1:m_c-2, m_qcfi2[i] interpolates m_inter[i] from m_inter[i-1].

  if (m_coarsenings == 1)
    {
      m_qcfi2[0] = new NodeQuadCFInterp2(a_grids, a_domain,
                                         a_loCFIVS, a_hiCFIVS,
                                         false, a_interpolationDegree, a_ncomp);
    }
  else
    {
      // if m_coarsenings == 2:
      // m_qcfi2[1] = new NodeQuadCFInterp2(a_grids, true);
      // m_qcfi2[0] = new NodeQuadCFInterp2(a_grids.coarsen(2), false);
      // m_inter[0] = new LevelData(a_grids.coarsen(2));

      ProblemDomain domainLevel(a_domain);
      Real dxLevel = m_dx;
      DisjointBoxLayout gridsInterFine(a_grids);
      DisjointBoxLayout gridsInterCoarse;
      // m_qcfi2[m_coarsenings-1] interpolates from a 2-coarsening of
      // the fine grids onto the fine grids (a_grids).
      // Interpolation is from the interface only.
      m_qcfi2[m_coarsenings-1] =
        new NodeQuadCFInterp2(a_grids, domainLevel,
                              a_loCFIVS, a_hiCFIVS,
                              true, a_interpolationDegree, a_ncomp);
      for (int interlev = m_coarsenings - 2; interlev >= 0; interlev--)
        {
          // m_coarsenings >= 2, so this will be executed at least once.
          coarsen(gridsInterCoarse, gridsInterFine, 2);
          domainLevel.coarsen(2);
          dxLevel *= 2.;
          bool interfaceOnly = (interlev > 0);
          // m_qcfi2[interlev] interpolates from some coarsening of
          // the fine grids onto gridsInterCoarse.
          // Except for the first time (interlev == 0),
          // interpolation is from the interface only.

          // Define objects containing the nodes of the coarse/fine interfaces.
          m_loCFIVScoarser[interlev] = new LayoutData<NodeCFIVS>[SpaceDim];
          m_hiCFIVScoarser[interlev] = new LayoutData<NodeCFIVS>[SpaceDim];
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              LayoutData<NodeCFIVS>& loCFIVS =
                m_loCFIVScoarser[interlev][idir];
              LayoutData<NodeCFIVS>& hiCFIVS =
                m_hiCFIVScoarser[interlev][idir];

              loCFIVS.define(gridsInterCoarse);
              hiCFIVS.define(gridsInterCoarse);
              for (DataIterator dit = gridsInterCoarse.dataIterator(); dit.ok(); ++dit)
                {
                  const Box& bx = gridsInterCoarse.get(dit());
                  loCFIVS[dit()].define(domainLevel, bx, gridsInterCoarse,
                                        idir, Side::Lo);
                  hiCFIVS[dit()].define(domainLevel, bx, gridsInterCoarse,
                                        idir, Side::Hi);
                }
            }

          m_qcfi2[interlev] =
            new NodeQuadCFInterp2(gridsInterCoarse, domainLevel,
                                  m_loCFIVScoarser[interlev],
                                  m_hiCFIVScoarser[interlev],
                                  interfaceOnly, a_interpolationDegree, a_ncomp);

          m_inter[interlev] =
            new LevelData<NodeFArrayBox>(gridsInterCoarse, a_ncomp, IntVect::Zero);
          gridsInterFine = gridsInterCoarse;
        }
      m_domainPenultimate = domainLevel;
      m_dxPenultimate = dxLevel;
    }

  m_ncomp = a_ncomp;

  m_isDefined = true;
}
コード例 #25
0
ファイル: fluxRegTest.cpp プロジェクト: rsnemmen/Chombo
int
makeLayouts(DisjointBoxLayout& a_dblCoar,
            DisjointBoxLayout& a_dblFine,
            const Box& a_domainCoar,
            const Box& a_domainFine)
{
  //set up mesh refine object
  int eekflag= 0;
  Vector<Box> vboxCoar;
  Vector<Box> vboxFine;
#if 1
  ParmParse pp;
  int maxsize;
  pp.get("maxboxsize",maxsize);
  int bufferSize = 1;
  int blockFactor = 2;
  Real fillrat = 0.75;
  Vector<int> refRat(2,2);
  BRMeshRefine meshRefObj(a_domainCoar, refRat, fillrat,
                          blockFactor, bufferSize, maxsize);

  Vector<Vector<Box> > oldMeshes(2);
  oldMeshes[0] = Vector<Box>(1, a_domainCoar);
  oldMeshes[1] = Vector<Box>(1, a_domainFine);

  //set up coarse tags
  int nc = a_domainCoar.size(0);
  int nmi = nc/2;//16
  int nqu = nc/4;//8
  int ntf = (nc*3)/4;  //24
  int nte = (nc*3)/8; //12
  int nfe = (nc*5)/8; //20
#if (CH_SPACEDIM ==2)
  Box boxf1(IntVect(0, nqu), IntVect(nmi-1,ntf-1));
  Box boxf2(IntVect(nmi,nte), IntVect(ntf-1,nfe-1));
  Box boxf3(IntVect(nqu,0  ), IntVect(nfe-1,nqu-1));
  Box boxf4(IntVect(nfe,nqu), IntVect(nc -1,nte-1));
  //  Box boxf5(IntVect(nqu,nqu), IntVect(ntf-1,ntf-1));
#else
  Box boxf1(IntVect(0, nqu,nqu), IntVect(nmi-1,ntf-1,ntf-1));
  Box boxf2(IntVect(nmi,nte,nte), IntVect(ntf-1,nfe-1,nfe-1));
  Box boxf3(IntVect(nqu,0,0  ), IntVect(nfe-1,nqu-1,nqu-1));
  Box boxf4(IntVect(nfe,nqu,nqu), IntVect(nc -1,nte-1,nte-1));
  //  Box boxf5(IntVect(nqu,nqu), IntVect(ntf-1,ntf-1))
#endif
  IntVectSet tags;
  tags |= boxf1;
  tags |= boxf2;
  tags |= boxf3;
  tags |= boxf4;

  //  tags |= boxf5;
  int baseLevel = 0;
  int topLevel = 0;
  Vector<Vector<Box> > newMeshes;
  meshRefObj.regrid(newMeshes, tags, baseLevel,
                    topLevel, oldMeshes);

  vboxCoar = newMeshes[0];
  vboxFine = newMeshes[1];
#else
  vboxCoar = Vector<Box>(1, a_domainCoar);
  Box shrunkFine = a_domainFine;
  int nc = Max(a_domainCoar.size(0)/4, 2);
  shrunkFine.grow(-nc);
  vboxFine = Vector<Box>(1, shrunkFine);
#endif

  Vector<int>  procAssignFine, procAssignCoar;
  eekflag = LoadBalance(procAssignFine,vboxFine);
  if (eekflag != 0) return eekflag;
  eekflag = LoadBalance(procAssignCoar,vboxCoar);
  if (eekflag != 0) return eekflag;

  a_dblFine.define(vboxFine, procAssignFine);
  a_dblCoar.define(vboxCoar, procAssignCoar);
  return eekflag;
}
コード例 #26
0
void
MappedLevelFluxRegister::define(const DisjointBoxLayout& a_dbl,
                          const DisjointBoxLayout& a_dblCoarse,
                          const ProblemDomain&     a_dProblem,
                          const IntVect&           a_nRefine,
                          int                      a_nComp,
                          bool                     a_scaleFineFluxes)
{
    CH_TIME("MappedLevelFluxRegister::define");
    m_isDefined = FluxRegDefined;  // Basically, define was called
    m_nRefine   = a_nRefine;

    m_scaleFineFluxes = a_scaleFineFluxes;

    DisjointBoxLayout coarsenedFine;
    coarsen(coarsenedFine, a_dbl, a_nRefine);

#ifndef DISABLE_TEMPORARY_FLUX_REGISTER_OPTIMIZATION
    // This doesn't work for multi-block calculations, which are
    // not properly nested. -JNJ

    //begin temporary optimization.  bvs
    int numPts = 0;
    for (LayoutIterator lit = a_dblCoarse.layoutIterator(); lit.ok(); ++lit) {
        numPts += a_dblCoarse[lit].numPts();
    }
    for (LayoutIterator lit = coarsenedFine.layoutIterator(); lit.ok(); ++lit) {
        numPts -= coarsenedFine[lit].numPts();
    }

    if (numPts == 0) {
        m_coarFlux.clear();
        // OK, fine region completely covers coarse region.  no registers.
        return;
    }
#endif

    //end temporary optimization.   bvs
    m_coarFlux.define( a_dblCoarse, a_nComp);
    m_isDefined |= FluxRegCoarseDefined;
    m_domain = a_dProblem;
    ProblemDomain coarsenedDomain;
    coarsen(coarsenedDomain, a_dProblem, a_nRefine);

    m_fineFlux.define( coarsenedFine, a_nComp, IntVect::Unit);
    m_isDefined |= FluxRegFineDefined;

    m_reverseCopier.ghostDefine(coarsenedFine, a_dblCoarse,
                                coarsenedDomain, IntVect::Unit);

    for (int i = 0; i < CH_SPACEDIM; i++) {
        m_coarseLocations[i].define(a_dblCoarse);
        m_coarseLocations[i + CH_SPACEDIM].define(a_dblCoarse);
    }


    DataIterator dC   = a_dblCoarse.dataIterator();
    LayoutIterator dF = coarsenedFine.layoutIterator();

    for (dC.begin(); dC.ok(); ++dC) {
        const Box& cBox = a_dblCoarse.get(dC);

        for (dF.begin(); dF.ok(); ++dF) {
            const Box& fBox  = coarsenedFine.get(dF);

            if (fBox.bigEnd(0) + 1 < cBox.smallEnd(0)) {
                //can skip this box since they cannot intersect, due to sorting
            } else if (fBox.smallEnd(0) - 1 > cBox.bigEnd(0)) {
                //skip to end, since all the rest of boxes will not intersect either
                dF.end();
            } else {

                for (int i = 0; i < CH_SPACEDIM; i++) {
                    Vector<Box>& lo = m_coarseLocations[i][dC];
                    Vector<Box>& hi = m_coarseLocations[i + CH_SPACEDIM][dC];

                    Box loBox = adjCellLo(fBox, i, 1);
                    Box hiBox = adjCellHi(fBox, i, 1);
                    if (cBox.intersectsNotEmpty(loBox)) lo.push_back(loBox & cBox);
                    if (cBox.intersectsNotEmpty(hiBox)) hi.push_back(hiBox & cBox);
                }
            }
        }
    }

    Box domainBox = coarsenedDomain.domainBox();

    if (a_dProblem.isPeriodic()) {
        Vector<Box> periodicBoxes[2 * CH_SPACEDIM];
        for (dF.begin(); dF.ok(); ++dF) {
            const Box& fBox  = coarsenedFine.get(dF);
            for (int i = 0; i < CH_SPACEDIM; i++) {
                if (a_dProblem.isPeriodic(i)) {
                    if (fBox.smallEnd(i) == domainBox.smallEnd(i))
                        periodicBoxes[i].push_back(adjCellLo(fBox, i, 1));
                    if (fBox.bigEnd(i) == domainBox.bigEnd(i))
                        periodicBoxes[i + CH_SPACEDIM].push_back(adjCellHi(fBox, i, 1));
                }
            }
        }
        for (int i = 0; i < CH_SPACEDIM; i++) {
            Vector<Box>& loV = periodicBoxes[i];
            Vector<Box>& hiV = periodicBoxes[i + CH_SPACEDIM];
            int size = domainBox.size(i);
            for (int j = 0; j < loV.size(); j++) loV[j].shift(i, size);
            for (int j = 0; j < hiV.size(); j++) hiV[j].shift(i, -size);
        }
        for (dC.begin(); dC.ok(); ++dC) {
            const Box& cBox = a_dblCoarse.get(dC);
            for (int i = 0; i < CH_SPACEDIM; i++)
                if (a_dProblem.isPeriodic(i)) {
                    Vector<Box>& loV = periodicBoxes[i];
                    Vector<Box>& hiV = periodicBoxes[i + CH_SPACEDIM];

                    if (cBox.smallEnd(i) == domainBox.smallEnd(i) ) {
                        Vector<Box>& hi = m_coarseLocations[i + CH_SPACEDIM][dC];
                        for (int j = 0; j < hiV.size(); j++) {
                            if (cBox.intersectsNotEmpty(hiV[j])) hi.push_back(cBox & hiV[j]);
                        }
                    }
                    if (cBox.bigEnd(i) == domainBox.bigEnd(i) ) {
                        Vector<Box>& lo = m_coarseLocations[i][dC];
                        for (int j = 0; j < loV.size(); j++) {
                            if (cBox.intersectsNotEmpty(loV[j])) lo.push_back(cBox & loV[j]);
                        }
                    }

                }
        }
    }

}
コード例 #27
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
}
コード例 #28
0
// new define
void
LevelFluxRegisterEdge::define(
                              const DisjointBoxLayout& a_dbl,
                              const DisjointBoxLayout& a_dblCoarse,
                              const ProblemDomain& a_dProblem,
                              int a_nRefine,
                              int a_nComp)
{
  m_isDefined = true;
  CH_assert(a_nRefine > 0);
  CH_assert(a_nComp > 0);
  CH_assert(!a_dProblem.isEmpty());
  m_nComp = a_nComp;
  m_nRefine = a_nRefine;
  m_domainCoarse = coarsen(a_dProblem, a_nRefine);
  CH_assert (a_dblCoarse.checkPeriodic(m_domainCoarse));

  // allocate copiers
  m_crseCopiers.resize(SpaceDim*2);

  SideIterator side;

  // create a Vector<Box> of the fine boxes which also includes periodic images,
  // since we don't really care about the processor layouts, etc
  Vector<Box> periodicFineBoxes;
  CFStencil::buildPeriodicVector(periodicFineBoxes, a_dProblem, a_dbl);
  // now coarsen these boxes...
  for (int i=0; i<periodicFineBoxes.size(); i++)
    {
      periodicFineBoxes[i].coarsen(m_nRefine);
    }

  for (int idir=0 ; idir<SpaceDim; ++idir)
  {
    for (side.begin(); side.ok(); ++side)
    {
      // step one, build fineBoxes, flux register boxes
      // indexed by the fine level but in the coarse index
      // space
      DisjointBoxLayout fineBoxes,tmp;
      // first create coarsened dbl, then compute flux register boxes
      // adjacent to coarsened fine boxes
      coarsen(tmp, a_dbl, m_nRefine);
      if (side() == Side::Lo)
        {
          adjCellLo(fineBoxes, tmp, idir,1);
        }
      else
        {
          adjCellHi(fineBoxes, tmp, idir,1);
        }

      // now define the FluxBoxes of fabFine on this DisjointBoxLayout
      m_fabFine[index(idir, side())].define(fineBoxes, a_nComp);



      LayoutData<Vector<Vector<IntVectSet> > >& ivsetsVect
        = m_refluxLocations[index(idir, side())];
      ivsetsVect.define(a_dblCoarse);

      LayoutData<Vector<DataIndex> >& mapsV =
        m_coarToCoarMap[index(idir, side())];
      mapsV.define(a_dblCoarse);

      DisjointBoxLayout coarseBoxes = a_dblCoarse;
      DataIterator dit = a_dblCoarse.dataIterator();
      for (dit.begin(); dit.ok(); ++dit)
        {
          unsigned int thisproc = a_dblCoarse.procID(dit());
          if (thisproc == procID())
          {
            ivsetsVect[DataIndex(dit())].resize(SpaceDim);
          }
          const Box& coarseBox = a_dblCoarse[dit()];
          int count = 0;
          for (int i=0; i<periodicFineBoxes.size(); i++)
            {
              Box regBox;
              if (side() == Side::Lo)
                {
                  regBox = adjCellLo(periodicFineBoxes[i], idir, 1);
                }
              else
                {
                  regBox = adjCellHi(periodicFineBoxes[i], idir, 1);
                }

              // do this little dance in order to ensure that
              // we catch corner cells which might be in different
              // boxes.
              Box testBox(regBox);
              testBox.grow(1);
              testBox.grow(idir,-1);
              if (testBox.intersectsNotEmpty(coarseBox))
                {
                  testBox &= coarseBox;
                  ++count;
                  unsigned int proc = a_dblCoarse.procID(dit());
                  const DataIndex index = DataIndex(dit());
                  if (proc == procID())
                  {
                    mapsV[DataIndex(dit())].push_back(index);
                    // loop over face directions here
                    for (int faceDir=0; faceDir<SpaceDim; faceDir++)
                    {
                      // do nothing in normal direction
                      if (faceDir != idir)
                      {
                        // this should give us the face indices for the
                        // faceDir-centered faces adjacent to the coarse-fine
                        // interface which are contained in the current
                        // coarse box
                        Box intersectBox(regBox);
                        Box coarseEdgeBox(coarseBox);
                        coarseEdgeBox.surroundingNodes(faceDir);
                        intersectBox.surroundingNodes(faceDir);
                        intersectBox &= coarseEdgeBox;
                        intersectBox.shiftHalf(faceDir,1);
                        IntVectSet localIV(intersectBox);
                        ivsetsVect[DataIndex(dit())][faceDir].push_back(localIV);
                      }
                    }
                  }
                }
            } // end loop over boxes on coarse level
        }
      m_regCoarse.define(coarseBoxes, a_nComp, IntVect::Unit);

      // last thing to do is to define copiers
      m_crseCopiers[index(idir, side())].define(fineBoxes, coarseBoxes,
                                                IntVect::Unit);
    }
  }
}
コード例 #29
0
ファイル: compare.cpp プロジェクト: rsnemmen/Chombo
// this function averages down the fine solution to the valid
// regions of the computed solution, then subtracts ir from
// the computed solution.  (error is exact-computed)
void computeAMRError(Vector<LevelData<FArrayBox>* >&       a_error,
                     const Vector<string>&                 a_errorVars,
                     const Vector<LevelData<FArrayBox>* >& a_computedSoln,
                     const Vector<string>&                 a_computedVars,
                     const Vector<DisjointBoxLayout>&      a_computedGrids,
                     const Real                            a_computedDx,
                     const Vector<int>&                    a_computedRefRatio,
                     const Vector<LevelData<FArrayBox>* >& a_exactSoln,
                     const Vector<string>&                 a_exactVars,
                     const Real                            a_exactDx,
                     Real                                  a_bogus_value,
                     bool                                  a_HOaverage,
                     bool                                  a_computeRelativeError)
{
  int numLevels = a_computedSoln.size();

  CH_assert(a_exactSoln.size() == 1);
  CH_assert(a_error.size() == numLevels);
  CH_assert(a_exactDx <= a_computedDx);
  CH_assert(a_computedRefRatio.size() >= numLevels - 1);

  if (a_exactDx == a_computedDx)
  {
    cerr << "Exact dx and computed dx are equal." << endl;
  }

  // check whether input file selects "sum all variables"
  bool sumAll = false;
  ParmParse pp;
  pp.query("sumAll",sumAll);
  
  // const DisjointBoxLayout& exactGrids = a_exactSoln[0]->getBoxes();

  Real dxLevel = a_computedDx;

  // do a bit of sleight-of-hand in the case where there are no
  // ghost cells in the exact solution -- allocate a temporary which
  // _has_ ghost cells, and do a copyTo
  LevelData<FArrayBox>* exactSolnPtr = NULL;
  bool allocatedMemory = false;
  if (a_exactSoln[0]->ghostVect() == IntVect::Zero)
    {
      exactSolnPtr = new LevelData<FArrayBox>(a_exactSoln[0]->getBoxes(),
                                              a_exactSoln[0]->nComp(),
                                              IntVect::Unit);
      a_exactSoln[0]->copyTo(*exactSolnPtr);

      allocatedMemory = true;
     }
   else
     {
       // if there are ghost cells, we can use the exactSoln as-is
       exactSolnPtr = a_exactSoln[0];
     }
   LevelData<FArrayBox>& exactSolnRef = *exactSolnPtr;

   // first need to set boundary conditions on exactsoln
   // this is for the Laplacian which is needed in AverageHO
   DataIterator ditFine = exactSolnRef.dataIterator();
   DomainGhostBC exactBC;
   Interval exactComps(0, a_exactVars.size() - 1);
   for (int dir = 0; dir < SpaceDim; dir++)
   {
     SideIterator sit;
     for (sit.reset(); sit.ok(); ++sit)
     {
       // use HO extrapolation at physical boundaries
       HOExtrapBC thisBC(dir, sit(), exactComps);
       exactBC.setBoxGhostBC(thisBC);
     }
   }

   for (ditFine.begin(); ditFine.ok(); ++ditFine)
   {
     FArrayBox& thisFineSoln = exactSolnRef[ditFine()];
     const Box& fineBox = exactSolnRef.getBoxes()[ditFine()];
     exactBC.applyInhomogeneousBCs(thisFineSoln, fineBox, a_exactDx);
   }
   exactSolnRef.exchange(exactComps);

   // outer loop is over levels
   for (int level = 0; level < numLevels; level++)
   {
     LevelData<FArrayBox>& thisLevelError = *a_error[level];
     LevelData<FArrayBox>& thisLevelComputed = *a_computedSoln[level];

     // compute refinement ratio between solution at this level
     // and exact solution
     Real nRefTemp = (dxLevel / a_exactDx);
     int nRefExact = (int) nRefTemp;

     // this is to do rounding properly if necessary
     if (nRefTemp - nRefExact > 0.5) nRefExact += 1;

     // make sure it's not zero
     if (nRefExact == 0) nRefExact =1;

     const DisjointBoxLayout levelGrids = a_error[level]->getBoxes();
     const DisjointBoxLayout fineGrids = a_exactSoln[0]->getBoxes();
     DisjointBoxLayout coarsenedFineGrids;

     // petermc, 14 Jan 2014: Replace this because fineGrids might
     // not be coarsenable by nRefExact.
     // coarsen(coarsenedFineGrids, fineGrids, nRefExact);
     int nCoarsenExact = nRefExact;
     while ( !fineGrids.coarsenable(nCoarsenExact) && (nCoarsenExact > 0) )
       {
         // Divide nCoarsenExact by 2 until fineGrids is coarsenable by it.
         nCoarsenExact /= 2;
       }
     if (nCoarsenExact == 0)
       {
         nCoarsenExact = 1;
       }
     coarsen(coarsenedFineGrids, fineGrids, nCoarsenExact);

     int numExact = a_exactVars.size();
     LevelData<FArrayBox> averagedExact(coarsenedFineGrids, numExact);

     Box fineRefBox(IntVect::Zero, (nCoarsenExact-1)*IntVect::Unit);

     // average fine solution down to coarsened-fine level
     // loop over grids and do HO averaging down
     //DataIterator crseExactDit = coarsenedFineGrids.dataIterator();
     for (ditFine.reset(); ditFine.ok(); ++ditFine)
       {
         const Box fineBox = exactSolnRef.getBoxes()[ditFine()];
         FArrayBox fineTemp(fineBox, 1);
         Box coarsenedFineBox(fineBox);
         coarsenedFineBox.coarsen(nCoarsenExact);
         if (a_exactDx < a_computedDx)
           {
             // loop over components
             for (int comp = 0; comp < numExact; comp++)
               {
                 Box coarseBox(coarsenedFineGrids.get(ditFine()));
                 coarseBox &= coarsenedFineBox;
                 
                 if (!coarseBox.isEmpty())
                   {
                     // for now, this is a quick and dirty way to avoid
                     // stepping out of bounds if there are no ghost cells.
                     // LapBox will be the box over which we are
                     // able to compute the Laplacian.
                     Box LapBox = exactSolnRef[ditFine()].box();
                     LapBox.grow(-1);
                     LapBox &= fineBox;
                     fineTemp.setVal(0.0);
                     int doHO = 0;
                     if (a_HOaverage)
                       { 
                         doHO = 1;
                       }
                     
                     // average by default
                     int doAverage = 1;
                     
                     if (sumAll || sumVar(a_exactVars[comp]))
                       {
                         doAverage = 0;
                       }
                     
                     // average or sum, based on booleans
                     FORT_AVERAGEHO(CHF_FRA1(averagedExact[ditFine], comp),
                                    CHF_CONST_FRA1(exactSolnRef[ditFine], comp),
                                    CHF_FRA1(fineTemp, 0),
                                    CHF_BOX(coarseBox),
                                    CHF_BOX(LapBox),
                                    CHF_CONST_INT(nCoarsenExact),
                                    CHF_BOX(fineRefBox),
                                    CHF_INT(doHO),
                                    CHF_INT(doAverage));
                   } // end if crseBox not empty
               } // end loop over comps
           }
         else
           {
             // if cell sizes are the same, then copy
             averagedExact[ditFine].copy(exactSolnRef[ditFine]);
           }
         
       } // end loop over exact solution boxes
     
     int nRefineComputed = nRefExact / nCoarsenExact;
     LevelData<FArrayBox>* thisLevelComputedRefinedPtr = &thisLevelComputed;
     LevelData<FArrayBox>* thisLevelErrorRefinedPtr = &thisLevelError;
     if (nRefineComputed > 1)
       {
         // Do piecewise constant interpolation (replication) by nRefineComputed
         // on thisLevelComputed.
         DisjointBoxLayout levelRefinedGrids;
         refine(levelRefinedGrids, levelGrids, nRefineComputed);
         int nCompComputed = thisLevelComputed.nComp();
         IntVect ghostVectComputed = nRefineComputed * thisLevelComputed.ghostVect();
         thisLevelComputedRefinedPtr =
           new LevelData<FArrayBox>(levelRefinedGrids, nCompComputed, ghostVectComputed);
         ProblemDomain levelDomain = levelRefinedGrids.physDomain();
         FineInterp interpolator(levelRefinedGrids, nCompComputed, nRefineComputed,
                                 levelDomain);
         interpolator.pwcinterpToFine(*thisLevelComputedRefinedPtr, thisLevelComputed);

         int nCompErr = thisLevelError.nComp();
         IntVect ghostVectErr = nRefineComputed * thisLevelError.ghostVect();
         thisLevelErrorRefinedPtr =
           new LevelData<FArrayBox>(levelRefinedGrids, nCompErr, ghostVectErr);
       }

     // initialize error to 0
     // also initialize error to a bogus value
     DataIterator levelDit = thisLevelError.dataIterator();
     for (levelDit.begin(); levelDit.ok(); ++levelDit)
       {
         (*thisLevelErrorRefinedPtr)[levelDit].setVal(a_bogus_value);
       }

     Box refComputedBox(IntVect::Zero, (nRefineComputed-1)*IntVect::Unit);
     // loop over variables
     for (int nErr = 0; nErr < a_errorVars.size(); nErr++)
       {
         string thisErrVar = a_errorVars[nErr];
         bool done = false;

         // first loop over exact variables
         for (int exactComp = 0; exactComp < a_exactVars.size(); exactComp++)
           {
             string thisExactVar = a_exactVars[exactComp];
             // check if this exact variable is "the one"
             if ((thisExactVar == thisErrVar) || nonAverageVar(thisErrVar))
               {
                 int computedComp = 0;
                 // now loop over computed variables
                 while (!done && (computedComp < a_computedVars.size()))
                   {
                     if (a_computedVars[computedComp] == thisErrVar)
                       {
                         if (!nonAverageVar(thisErrVar))
                           {
                             // copy averaged exact solution -> error
                             // and then subtract computed solution
                             Interval exactInterval(exactComp, exactComp);
                             Interval errorInterval(nErr, nErr);
                             averagedExact.copyTo(exactInterval, *thisLevelErrorRefinedPtr,
                                                  errorInterval);
                           }
                         
                         DataIterator levelDit = thisLevelError.dataIterator();
                         for (levelDit.reset(); levelDit.ok(); ++levelDit)
                           {
                             FArrayBox& thisComputedRefined = (*thisLevelComputedRefinedPtr)[levelDit];
                             FArrayBox& thisErrorRefined = (*thisLevelErrorRefinedPtr)[levelDit];
                             if (a_computeRelativeError)
                               {
                                 // do this a little strangely -- relative
                                 // error is one - computed/exact.
                                 thisErrorRefined.divide(thisComputedRefined, computedComp, nErr, 1);
                                 thisErrorRefined.invert(-1.0, nErr, 1);
                                 thisErrorRefined.plus(1.0, nErr, 1);
                               }
                             else
                               {
                                 thisErrorRefined.minus(thisComputedRefined, computedComp, nErr, 1);
                               }
                             if (nRefineComputed > 1)
                               {
                                 FArrayBox& thisError = thisLevelError[levelDit];
                                 Box coarseBox = thisError.box();
                                 // Average thisErrorRefined to thisError.
                                 int doHO = 0;
                                 if (a_HOaverage)
                                   { 
                                     doHO = 1;
                                   }
                                 CH_assert(doHO == 0);

                                 // for now, this is a quick and dirty way to avoid
                                 // stepping out of bounds if there are no ghost cells.
                                 // LapBox will be the box over which we are
                                 // able to compute the Laplacian.
                                 Box LapBox = thisErrorRefined.box();
                                 LapBox.grow(-1);
                                 // LapBox &= fineBox;
                                 FArrayBox fineTemp(thisErrorRefined.box(), 1);
                                 fineTemp.setVal(0.0);
                                 
                                 // average by default
                                 int doAverage = 1;
                                 // average or sum, based on booleans
                                 FORT_AVERAGEHO(CHF_FRA1(thisError, nErr),
                                                CHF_CONST_FRA1(thisErrorRefined, nErr),
                                                CHF_FRA1(fineTemp, 0),
                                                CHF_BOX(coarseBox),
                                                CHF_BOX(LapBox),
                                                CHF_CONST_INT(nRefineComputed),
                                                CHF_BOX(refComputedBox),
                                                CHF_INT(doHO),
                                                CHF_INT(doAverage));
                                 
                               }
                           } // end loop over coarse grids
                         
                         done = true;
                       } // if computedVar is a_errorVar
                     
                     computedComp += 1;
                   } // end loop over a_computedVars
                 
                 if (!done)
                   {
                     pout() << "Variable " << thisErrVar  << " not found!!!" << endl;
                     MayDay::Error();
                   }
               } // end if this exactVar is correct
           } // end loop over exact variables
       } // end loop over errors
     
     if (nRefineComputed > 1)
       {
         delete thisLevelComputedRefinedPtr;
         delete thisLevelErrorRefinedPtr;
       }
     
     // now need to set covered regions to 0
     if (level < numLevels - 1)
       {
         // will need to loop over all boxes in finer level, not just
         // those on this processor...
         const BoxLayout& finerGrids = a_computedSoln[level + 1]->boxLayout();
         LayoutIterator fineLit = finerGrids.layoutIterator();
         
         // outer loop over this level's grids, since there are fewer of them
         DataIterator levelDit = thisLevelError.dataIterator();
         for (levelDit.reset(); levelDit.ok(); ++levelDit)
           {
             const Box& coarseBox = levelGrids[levelDit()];
             FArrayBox& thisError = thisLevelError[levelDit()];
             int numError = thisError.nComp();
             
             for (fineLit.reset(); fineLit.ok(); ++fineLit)
               {
                 Box fineBox(finerGrids[fineLit()]);
                 // now coarsen box down to this level
                 fineBox.coarsen(a_computedRefRatio[level]);
                 // if coarsened fine box intersects error's box, set
                 // overlap to 0
                 fineBox &= coarseBox;
                 if (!fineBox.isEmpty())
                   {
                     thisError.setVal(0.0, fineBox, 0, numError);
                   }
               } // end loop over finer-level grids
           } // end loop over this-level grids
         
         // this is a good place to update dx as well
         dxLevel = dxLevel / a_computedRefRatio[level];
       } // end if there is a finer level
     
     thisLevelError.exchange();
   } // end loop over levels
   
   // clean up if we need to
   if (allocatedMemory)
     {
       delete exactSolnPtr;
       exactSolnPtr = NULL;
     }
}
コード例 #30
0
ファイル: compare.cpp プロジェクト: rsnemmen/Chombo
// this function works on two solutions on equivalent grids.
// It subtracts the computed solution from the exact solution
// if a_doGhostCells == true, then does box-by-box comparison,
// including ghost cells (boxes must be the same for each).
// Otherwise, only does this for valid cells, but boxes don't
// need to be the same.
void computeSameSizeError(Vector<LevelData<FArrayBox>* >&       a_error,
                          const Vector<string>&                 a_errorVars,
                          const Vector<LevelData<FArrayBox>* >& a_computedSoln,
                          const Vector<string>&                 a_computedVars,
                          const Vector<DisjointBoxLayout>&      a_computedGrids,
                          const Real                            a_dx,
                          const Vector<int>&                    a_refRatio,
                          const Vector<LevelData<FArrayBox>* >& a_exactSoln,
                          const Vector<string>&                 a_exactVars,
                          Real                                  a_bogus_value,
                          bool                                  a_computeRelativeError,
                          bool                                  a_doGhostCells)

{
  int numLevels = a_computedSoln.size();

  CH_assert(a_exactSoln.size() == numLevels);
  CH_assert(a_error.size() == numLevels);
  CH_assert(a_refRatio.size() >= numLevels - 1);

  Real dxLevel = a_dx;

  // outer loop is over levels
  for (int level = 0; level < numLevels; level++)
  {
    LevelData<FArrayBox>& thisLevelError = *a_error[level];
    LevelData<FArrayBox>& thisLevelComputed = *a_computedSoln[level];
    LevelData<FArrayBox>& thisLevelExact = *a_exactSoln[level];

    const DisjointBoxLayout levelGrids = thisLevelComputed.getBoxes();
    const DisjointBoxLayout exactGrids = thisLevelExact.getBoxes();

    DataIterator levelDit = levelGrids.dataIterator();
    for (levelDit.begin(); levelDit.ok(); ++levelDit)
    {
      // initialize error to a bogus value
      thisLevelError[levelDit()].setVal(a_bogus_value);
    }

    // loop over variables
    for (int nErr = 0; nErr < a_errorVars.size(); nErr++)
    {
      string thisErrVar = a_errorVars[nErr];
      bool done = false;

      // this is where things differ between the ghost-cell
      // and non-ghost-cell approach.
      if (a_doGhostCells)
      {
        // this is the older approach to things --
        // do everything grid-by-grid

        // first loop over exact variables
        for (int exactComp = 0; exactComp < a_exactVars.size(); exactComp++)
        {
          string thisExactVar = a_exactVars[exactComp];
          // check if this exact variable is "the one"
          if (thisExactVar == thisErrVar)
          {
            int computedComp = 0;

            // now loop over computed variables
            while (!done && (computedComp < a_computedVars.size()))
            {
              if (a_computedVars[computedComp] == thisErrVar)
              {
                // copy exact solution -> error
                // and then subtract computed solution
                DataIterator exactDit = thisLevelExact.dataIterator();
                for (levelDit.reset(); levelDit.ok(); ++levelDit)
                {
                  FArrayBox& thisComputed = thisLevelComputed[levelDit()];
                  FArrayBox& thisError = thisLevelError[levelDit()];
                  const Box& thisBox = levelGrids[levelDit()];

                  for (exactDit.begin(); exactDit.ok(); ++exactDit)
                  {
                    if (thisBox.contains(exactGrids[exactDit()]))
                    {
                      thisError.copy(thisLevelExact[exactDit()],
                                     exactComp, nErr, 1);
                    } // end if exact and computed boxes match
                  } // end loop over exact grids

                  if (a_computeRelativeError)
                  {
                    // do this a little strangely -- relative
                    // error is one - computed/exact.
                    thisError.divide(thisComputed, computedComp, nErr, 1);
                    thisError.invert(-1.0, nErr, 1);
                    thisError.plus(1.0, nErr, 1);
                  }
                  else
                  {
                    thisError.minus(thisComputed, computedComp, nErr, 1);
                  }
                } // end loop over grids

                done = true;
              } // if a_computedVar is a_errorVar

              computedComp += 1;
            } // end loop over a_computedVars

            if (!done)
            {
              pout() << "Variable " << thisErrVar  << " not found!!!" << endl;
              MayDay::Error();
            }
          } // end if this exactVar is correct
        }  // end loop over exact variables
      }
      else
        // non-ghost cell case; this is simpler:
      {
        // first loop over exact variables and copy into error
        for (int exactComp=0; exactComp<a_exactVars.size(); ++exactComp)
        {
          string thisExactVar = a_exactVars[exactComp];

          // check if this exact variable is "the one"
          if (thisExactVar == thisErrVar)
          {
            // copy exact solution -> error
            Interval exactInterval(exactComp, exactComp);
            Interval errInterval(nErr, nErr);
            thisLevelExact.copyTo(exactInterval,
                                  thisLevelError,
                                  errInterval);
            done = true;
          } // end if this exact var is the error var
        } // end loop over exact comps

        if (!done)
        {
          pout() << "Variable " << thisErrVar
                 << " not found in exact solution!!!" << endl;
          MayDay::Error();
        }

        done = false;
        int computedComp = 0;
        // now loop over computed variables and subtract computed solution
        while (!done && (computedComp < a_computedVars.size()))
        {
          if (a_computedVars[computedComp] == thisErrVar)
          {
            for (levelDit.reset(); levelDit.ok(); ++levelDit)
            {
              FArrayBox& thisComputed = thisLevelComputed[levelDit()];
              FArrayBox& thisError = thisLevelError[levelDit()];

              thisError.minus(thisComputed, computedComp, nErr, 1);
            } // end loop over computed/error grids

            done = true;
          } // if a_computedVar is a_errorVar

          computedComp += 1;
        } // end loop over a_computedVars

        if (!done)
        {
          pout() << "Variable " << thisErrVar  << " not found!!!" << endl;
          MayDay::Error();
        }
      } // end non-ghost-cell case
    } // end loop over errors

    // now need to set covered regions to 0
    if (level < numLevels - 1)
    {
      // will need to loop over all boxes in finer level, not just
      // those on this processor...
      const BoxLayout& finerGrids = a_computedSoln[level + 1]->boxLayout();
      LayoutIterator fineLit = finerGrids.layoutIterator();

      // outer loop over this level's grids, since there are fewer of them
      DataIterator levelDit = thisLevelError.dataIterator();
      for (levelDit.reset(); levelDit.ok(); ++levelDit)
      {
        const Box& coarseBox = levelGrids[levelDit()];
        FArrayBox& thisError = thisLevelError[levelDit()];
        int numError = thisError.nComp();

        for (fineLit.reset(); fineLit.ok(); ++fineLit)
        {
          Box fineBox(finerGrids[fineLit()]);
          // now coarsen box down to this level
          fineBox.coarsen(a_refRatio[level]);
          // if coarsened fine box intersects error's box, set
          // overlap to 0
          fineBox &= coarseBox;
          if (!fineBox.isEmpty())
          {
            thisError.setVal(0.0, fineBox, 0, numError);
          }
        } // end loop over finer-level grids
      } // end loop over this-level grids

      // this is a good place to update dx as well
      dxLevel = dxLevel / a_refRatio[level];
    } // end if there is a finer level

    // finally, if we're not doing ghost cells, do an exchange just
    // to "prettify" the output
    if (!a_doGhostCells)
    {
      thisLevelError.exchange(thisLevelError.interval());
    }
  } // end loop over levels
}