Ejemplo n.º 1
0
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();
}
Ejemplo n.º 2
0
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();
    }
}
Ejemplo n.º 3
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]);
                        }
                    }

                }
        }
    }

}
Ejemplo n.º 4
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.º 5
0
void
EBCoarseAverage::define(const DisjointBoxLayout& a_dblFine,
                        const DisjointBoxLayout& a_dblCoar,
                        const EBISLayout& a_ebislFine,
                        const EBISLayout& a_ebislCoar,
                        const ProblemDomain& a_domainCoar,
                        const int& a_nref,
                        const int& a_nvar,
                        const EBIndexSpace* ebisPtr)
{
  CH_TIME("EBCoarseAverage::define");
  CH_assert(ebisPtr->isDefined());

  ProblemDomain domainFine = a_domainCoar;
  domainFine.refine(a_nref);
  EBLevelGrid eblgFine;
  EBLevelGrid eblgCoar = EBLevelGrid(a_dblCoar, a_ebislCoar, a_domainCoar);
  EBLevelGrid eblgCoFi;

  //check to see if the input layout is coarsenable.
  //if so, proceed with ordinary drill
  //otherwise, see if the layout covers the domain.
  //if it does, we can use domainsplit
  if (a_dblFine.coarsenable(a_nref))
    {
      eblgFine = EBLevelGrid(a_dblFine, a_ebislFine,   domainFine);
      m_useFineBuffer = false;
    }
  else
    {
      Box fineDomBox = refine(a_domainCoar.domainBox(), a_nref);
      int numPtsDom = fineDomBox.numPts();
      //no need for gathers here because the meta data is global
      int numPtsLayout = 0;
      for (LayoutIterator lit = a_dblFine.layoutIterator(); lit.ok(); ++lit)
        {
          numPtsLayout += a_dblFine.get(lit()).numPts();
        }
      bool coveringDomain = (numPtsDom == numPtsLayout);
      if (coveringDomain)
        {
          m_useFineBuffer = true;
          int maxBoxSize = 4*a_nref;
          Vector<Box> boxes;
          Vector<int> procs;
          domainSplit(fineDomBox, boxes, maxBoxSize);
          mortonOrdering(boxes);
          LoadBalance(procs, boxes);
          DisjointBoxLayout dblBufFine(boxes, procs);

          eblgFine = EBLevelGrid(dblBufFine, domainFine, 2, eblgCoar.getEBIS());
        }
      else
        {
          pout() << "EBCoarseAverage::input layout is not coarsenable and does not cover the domain--bailing out" << endl;
          MayDay::Error();
        }
    }

  coarsen(eblgCoFi, eblgFine, a_nref);
  define(eblgFine, eblgCoar, eblgCoFi, a_nref, a_nvar);
}