Exemple #1
0
void setBorkedFlux(EBFluxFAB&          a_flux,
                   const EBISBox&      a_ebisBox,
                   const Box&          a_box,
                   const RealVect&     a_fluxVal,
                   const BaseFab<int>& a_map)
{
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      Real bogval = 0;
      //the bogus value will be zero so it will not
      //do to have the correct value be zero
      if (Abs(a_fluxVal[idir]) < 1.0e-3) bogval = 1.0;

      a_flux[idir].setVal(a_fluxVal[idir]);
      //if i am in a 1d box and the box next to me
      //is 2d, set the border flux to
      for (SideIterator sit; sit.ok(); ++sit)
        {
          Box borderBox;
          if (sit() == Side::Lo)
            {
              borderBox = adjCellLo(a_box, idir,  -1);
            }
          else
            {
              borderBox = adjCellHi(a_box, idir,  -1);
            }
          for (BoxIterator bit(borderBox); bit.ok(); ++bit)
            {
              const IntVect& thisIV = bit();
              IntVect thatIV = thisIV + sign(sit())*BASISV(idir);
              if ((a_map(thisIV, 0) == 1) && (a_map(thatIV, 0) == 2))
                {
                  Vector<FaceIndex> faces = a_ebisBox.getAllFaces(thisIV, idir, sit());
                  for (int iface = 0; iface < faces.size(); iface++)
                    {
                      a_flux[idir](faces[iface],0) = bogval;
                    }
                }
            }
        }
    }

}
Exemple #2
0
void
CFStencil::define(
                  const ProblemDomain& a_fineDomain,
                  const Box& a_grid,
                  const Vector<Box>& a_periodicVector,
                  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()) return;


  int w1 = edgebox.smallEnd()[0];
  int w2 = edgebox.bigEnd()[0];
  m_fineIVS.define(edgebox);
  // moving window loop in i-direction (bvs)
  for (int i=0; i<a_periodicVector.size(); ++i)
    {
      const Box& b = a_periodicVector[i];
      if (b.bigEnd()[0] >= w1)
        {
          m_fineIVS -= b;
          if (b.smallEnd()[0] > w2)
          {
            i=a_periodicVector.size();
          }
        }

    }


  //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();
    }
}
Exemple #3
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();
    }
}
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]);
                        }
                    }

                }
        }
    }

}
void
MappedLevelFluxRegister::incrementFine(const FArrayBox& a_fineFlux,
                                 Real a_scale,
                                 const DataIndex& a_fineDataIndex,
                                 const Interval& a_srcInterval,
                                 const Interval& a_dstInterval,
                                 int a_dir,
                                 Side::LoHiSide a_sd)
{
    CH_assert(isDefined());
    if (!(m_isDefined & FluxRegFineDefined)) return;
    CH_assert(a_srcInterval.size() == a_dstInterval.size());

    CH_TIME("MappedLevelFluxRegister::incrementFine");

    // We cast away the constness in a_coarseFlux for the scope of this function. This
    // should be acceptable, since at the end of the day there is no change to it. -JNJ
    FArrayBox& fineFlux = const_cast<FArrayBox&>(a_fineFlux); // Muhahaha.
    fineFlux.shiftHalf(a_dir, sign(a_sd));
    Real denom = 1.0;

    if (m_scaleFineFluxes) {
        denom = m_nRefine.product() / m_nRefine[a_dir];
    }

    Real scale = sign(a_sd) * a_scale / denom;

    FArrayBox& cFine = m_fineFlux[a_fineDataIndex];
    //  FArrayBox  cFineFortran(cFine.box(), cFine.nComp());
    //  cFineFortran.copy(cFine);

    Box clipBox = m_fineFlux.box(a_fineDataIndex);
    clipBox.refine(m_nRefine);
    Box fineBox;
    if (a_sd == Side::Lo) {
        fineBox = adjCellLo(clipBox, a_dir, 1);
        fineBox &= fineFlux.box();
    } else {
        fineBox = adjCellHi(clipBox, a_dir, 1);
        fineBox &= fineFlux.box();
    }
#if 0
    for (BoxIterator b(fineBox); b.ok(); ++b) {
        int s = a_srcInterval.begin();
        int d = a_dstInterval.begin();
        for (; s <= a_srcInterval.end(); ++s, ++d) {
            cFine(coarsen(b(), m_nRefine), d) += scale * fineFlux(b(), s);
        }
    }
#else
    // shifting to ensure fineBox is in the positive quadrant, so IntVect coarening
    // is just integer division.

    const Box& box = coarsen(fineBox, m_nRefine);
    Vector<Real> regbefore(cFine.nComp());
    Vector<Real>  regafter(cFine.nComp());
    if (s_verbose && (a_dir == debugdir) && box.contains(ivdebnoeb)) {
        for (int ivar = 0; ivar < cFine.nComp(); ivar++) {
            regbefore[ivar] = cFine(ivdebnoeb, ivar);
        }
    }


    const IntVect& iv = fineBox.smallEnd();
    IntVect civ = coarsen(iv, m_nRefine);
    int srcComp = a_srcInterval.begin();
    int destComp = a_dstInterval.begin();
    int ncomp = a_srcInterval.size();
    FORT_MAPPEDINCREMENTFINE(CHF_CONST_FRA_SHIFT(fineFlux, iv),
                             CHF_FRA_SHIFT(cFine, civ),
                             CHF_BOX_SHIFT(fineBox, iv),
                             CHF_CONST_INTVECT(m_nRefine),
                             CHF_CONST_REAL(scale),
                             CHF_CONST_INT(srcComp),
                             CHF_CONST_INT(destComp),
                             CHF_CONST_INT(ncomp));


    if (s_verbose && (a_dir == debugdir) && box.contains(ivdebnoeb)) {
        for (int ivar = 0; ivar < cFine.nComp(); ivar++) {
            regafter[ivar] = cFine(ivdebnoeb, ivar);
        }
    }

    if (s_verbose && (a_dir == debugdir) && box.contains(ivdebnoeb)) {

        pout() << "levelfluxreg::incrementFine: scale = " << scale << endl;
        Box refbox(ivdebnoeb, ivdebnoeb);
        refbox.refine(m_nRefine);
        refbox &= fineBox;
        if (!refbox.isEmpty()) {
            pout() << "fine fluxes = " << endl;
            for (BoxIterator  bit(refbox); bit.ok(); ++bit) {
                for (int ivar = 0; ivar < cFine.nComp(); ivar++) {
                    pout() << "iv = " << bit() << "(";
                    for (int ivar = 0; ivar < cFine.nComp(); ivar++) {
                        pout() << fineFlux(bit(), ivar);
                    }
                    pout() << ")" << endl;
                }
            }
        }

        for (int ivar = 0; ivar < cFine.nComp(); ivar++) {
            pout() << " reg before = " <<               regbefore[ivar] << ", ";
            pout() << " reg after  = " <<                regafter[ivar] << ", ";
        }
        pout() << endl;

    }


    //fineBox.shift(-shift);
    // now, check that cFineFortran and cFine are the same
    //fineBox.coarsen(m_nRefine);
    //    for (BoxIterator b(fineBox); b.ok(); ++b)
    //      {
    //        if (cFineFortran(b(),0) != cFine(b(),0))
    //          {
    //            MayDay::Error("Fortran doesn't match C++");
    //          }
    //      }
    // need to shift boxes back to where they were on entry.

    //  cFine.shift(-shift/m_nRefine);
#endif
    fineFlux.shiftHalf(a_dir, - sign(a_sd));
}
// 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);
    }
  }
}
void VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>&        a_phiFine,
                            const LevelData<FArrayBox>&        a_phi,
                            LevelData<FArrayBox>&              a_residual,
                            AMRLevelOp<LevelData<FArrayBox> >* a_finerOp)
{
  CH_TIME("VCAMRPoissonOp2::reflux");

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

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

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

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

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

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

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

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

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

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

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

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

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

  Real scale =  1.0/m_dx;
  levfluxreg.reflux(a_residual, scale);
}
Exemple #8
0
void oldLoHiCenter(Box&                 a_loBox,
                   int&                 a_hasLo,
                   Box&                 a_hiBox,
                   int&                 a_hasHi,
                   Box&                 a_centerBox,
                   Box&                 a_entireBox,
                   const Box&           a_inBox,
                   const ProblemDomain& a_domain,
                   const int&           a_dir)
{
    // Make a copy of the input box which can be modified
    Box inBox = a_inBox;
    inBox &= a_domain;

    // The centered difference box is always one smaller in a_dir
    a_centerBox = inBox;
    a_centerBox.grow(a_dir,-1);

    // The union of all the output boxes start off equal to the center
    // difference portion on the input box (intersected with the domain)
    a_entireBox = a_centerBox;

    // See if this chops off the high side of the input box
    Box tmp = a_inBox;
    tmp.shift(a_dir,-1);
    tmp &= a_domain;
    tmp.shift(a_dir,1);

    // If so, set up the high, one-sided difference box, a_hiBox, and expand
    // the entire box to include it
    if (!a_domain.contains(tmp))
    {
        a_hasHi = 1;
        tmp.shift(a_dir,-2);
        a_hiBox = adjCellHi(tmp,a_dir);
        a_entireBox.growHi(a_dir,1);
    }
    else
    {
        a_hasHi = 0;
        a_hiBox = Box();
    }

    // See if this chops off the low side of the input box
    tmp = a_inBox;
    tmp.shift(a_dir,1);
    tmp &= a_domain;
    tmp.shift(a_dir,-1);

    // If so, set up the low, one-sided difference box, a_loBox, and expand
    // the entire box to include it
    if (!a_domain.contains(tmp))
    {
        a_hasLo = 1;
        tmp.shift(a_dir,2);
        a_loBox = adjCellLo(tmp,a_dir);
        a_entireBox.growLo(a_dir,1);
    }
    else
    {
        a_hasLo = 0;
        a_loBox = Box();
    }

    // Make some simple sanity checks
    CH_assert(a_entireBox.contains(a_centerBox));

    if (a_hasLo == 1)
    {
        CH_assert(a_entireBox.contains(a_loBox));
    }

    if (a_hasHi == 1)
    {
        CH_assert(a_entireBox.contains(a_hiBox));
    }
}
Exemple #9
0
void
EBPoissonOp::
defineStencils()
{
  CH_TIMERS("EBPoissonOp::defineStencils");
  CH_TIMER("opStencil_define", t1);
  CH_TIMER("colorStencil_define", t2);

  // define ebstencil for irregular applyOp
  m_opEBStencil.define(m_eblg.getDBL());
  // create vofstencils for applyOp
  LayoutData<BaseIVFAB<VoFStencil> > opStencil;
  opStencil.define(m_eblg.getDBL());
  //define bc stencils and create flux stencil
  m_ebBC->define((*m_eblg.getCFIVS()), m_dxScale*m_beta);
  LayoutData<BaseIVFAB<VoFStencil> >* fluxStencil = m_ebBC->getFluxStencil(0);
  //create and define colored stencils (2 parts)
  LayoutData<BaseIVFAB<VoFStencil> > colorStencil;
  colorStencil.define(m_eblg.getDBL());
  LayoutData<BaseIVFAB<VoFStencil> > rhsColorStencil;
  rhsColorStencil.define(m_eblg.getDBL());

  m_alphaDiagWeight.define(   m_eblg.getDBL());
  m_betaDiagWeight.define(   m_eblg.getDBL());
  m_vofItIrreg.define( m_eblg.getDBL()); // vofiterator cache

  Box domainBox = m_eblg.getDomain().domainBox();
  Box sideBoxLo[SpaceDim];
  Box sideBoxHi[SpaceDim];
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      sideBoxLo[idir] = adjCellLo(domainBox, idir, 1);
      sideBoxLo[idir].shift(idir,  1);
      sideBoxHi[idir] = adjCellHi(domainBox, idir, 1);
      sideBoxHi[idir].shift(idir, -1);
      m_vofItIrregDomLo[idir].define( m_eblg.getDBL()); // vofiterator cache for domain lo
      m_vofItIrregDomHi[idir].define( m_eblg.getDBL()); // vofiterator cache for domain hi
    }

  CH_START(t1);
  for (DataIterator dit = m_eblg.getDBL().dataIterator(); dit.ok(); ++dit)
    {
      const Box& curBox = m_eblg.getDBL().get(dit());
      const EBISBox& curEBISBox = m_eblg.getEBISL()[dit()];
      const EBGraph& curEBGraph = curEBISBox.getEBGraph();

      IntVectSet notRegular = curEBISBox.getIrregIVS  (curBox);

      BaseIVFAB<VoFStencil>& curStencilBaseIVFAB = opStencil[dit()];
      BaseIVFAB<Real>&       alphaWeight  = m_alphaDiagWeight[dit()];
      BaseIVFAB<Real>&        betaWeight  = m_betaDiagWeight[dit()];
      curStencilBaseIVFAB.define(notRegular,curEBGraph, 1);
      alphaWeight.define(        notRegular,curEBGraph, 1);
      betaWeight.define(         notRegular,curEBGraph, 1);

      //cache the vofIterators
      m_vofItIrreg[dit()].define(notRegular,curEBISBox.getEBGraph());
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          IntVectSet loIrreg = notRegular;
          IntVectSet hiIrreg = notRegular;
          loIrreg &= sideBoxLo[idir];
          hiIrreg &= sideBoxHi[idir];
          m_vofItIrregDomLo[idir][dit()].define(loIrreg,curEBISBox.getEBGraph());
          m_vofItIrregDomHi[idir][dit()].define(hiIrreg,curEBISBox.getEBGraph());
        }

      //Operator vofstencil
      VoFIterator& vofit = m_vofItIrreg[dit()];
      for (vofit.reset(); vofit.ok(); ++vofit)
        {
          const VolIndex& VoF = vofit();

          VoFStencil& curStencil = curStencilBaseIVFAB(VoF,0);
          getOpVoFStencil(curStencil,curEBISBox,VoF);

          Real& curAlphaWeight  = alphaWeight(VoF,0);
          Real& curBetaWeight  =   betaWeight(VoF,0);

          const Real kappa = curEBISBox.volFrac(VoF);

          curAlphaWeight = kappa;
          curBetaWeight = 0.0;
          for (int i = 0; i < curStencil.size(); i++)
            {
              if (curStencil.vof(i) == VoF)
                {
                  curBetaWeight += curStencil.weight(i);
                  break;
                }
            }

          curStencil *= m_beta;
          if (m_alpha != 0)
            {
              curStencil.add(VoF, kappa*m_alpha);
            }

          const IntVect& iv = VoF.gridIndex();

          for (int idir = 0; idir < SpaceDim; idir++)
            {
              Box loSide = bdryLo(m_eblg.getDomain(),idir);
              loSide.shiftHalf(idir,1);
              if (loSide.contains(iv))
                {
                  Real faceAreaFrac = 0.0;
                  Vector<FaceIndex> faces = curEBISBox.getFaces(VoF,idir,Side::Lo);
                  for (int i = 0; i < faces.size(); i++)
                    {
                      faceAreaFrac += curEBISBox.areaFrac(faces[i]);
                    }
                  curBetaWeight += -faceAreaFrac * m_invDx2[idir];
                }

              Box hiSide = bdryHi(m_eblg.getDomain(),idir);
              hiSide.shiftHalf(idir,-1);
              if (hiSide.contains(iv))
                {
                  Real faceAreaFrac = 0.0;
                  Vector<FaceIndex> faces = curEBISBox.getFaces(VoF,idir,Side::Hi);
                  for (int i = 0; i < faces.size(); i++)
                    {
                      faceAreaFrac += curEBISBox.areaFrac(faces[i]);
                    }
                  curBetaWeight += -faceAreaFrac * m_invDx2[idir];
                }
            }

          if (curBetaWeight == 0.0)
            {
              curBetaWeight = -1.0;
            }
          if (fluxStencil != NULL)
            {
              BaseIVFAB<VoFStencil>& fluxStencilBaseIVFAB = (*fluxStencil)[dit()];
              VoFStencil& fluxStencilPt = fluxStencilBaseIVFAB(VoF,0);
              curStencil += fluxStencilPt;
            }
        }//vofit

      //Operator ebstencil
      m_opEBStencil[dit()] = RefCountedPtr<EBStencil>(new EBStencil(m_vofItIrreg[dit()].getVector(), opStencil[dit()], m_eblg.getDBL().get(dit()), m_eblg.getEBISL()[dit()], m_ghostCellsPhi, m_ghostCellsRHS));

    }//dit
  CH_STOP(t1);

  //color vofstencils and ebstencils
  IntVect color = IntVect::Zero;
  IntVect limit = IntVect::Unit;
  color[0]=-1;
  // Loop over all possibilities (in all dimensions)
  CH_START(t2);
  for (int icolor = 0; icolor < m_colors.size(); icolor++)
    {
      m_colorEBStencil[icolor].define(m_eblg.getDBL());
      m_rhsColorEBStencil[icolor].define(m_eblg.getDBL());
      m_vofItIrregColor[icolor].define( m_eblg.getDBL());
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          m_vofItIrregColorDomLo[icolor][idir].define( m_eblg.getDBL());
          m_vofItIrregColorDomHi[icolor][idir].define( m_eblg.getDBL());
        }
      for (DataIterator dit = m_eblg.getDBL().dataIterator(); dit.ok(); ++dit)
        {
          IntVectSet ivsColor;
          const EBISBox& curEBISBox = m_eblg.getEBISL()[dit()];
          const EBGraph& curEBGraph = curEBISBox.getEBGraph();
          Box dblBox( m_eblg.getDBL().get(dit()) );

          BaseIVFAB<VoFStencil>& curStencilBaseIVFAB = opStencil[dit()];
          BaseIVFAB<VoFStencil>& colorStencilBaseIVFAB = colorStencil[dit()];
          BaseIVFAB<VoFStencil>& rhsColorStencilBaseIVFAB = rhsColorStencil[dit()];

          const BaseIVFAB<Real>& curAlphaWeight = m_alphaDiagWeight[dit()];
          const BaseIVFAB<Real>& curBetaWeight  = m_betaDiagWeight[dit()];

          VoFIterator& vofit = m_vofItIrreg[dit()];

          int vofOrdinal = 0;
          for (vofit.reset(); vofit.ok(); ++vofit, ++vofOrdinal)
            {
              const VolIndex& vof = vofit();
              const IntVect& iv = vof.gridIndex();

              bool doThisVoF = true;
              for (int idir = 0; idir < SpaceDim; idir++)
                {
                  if (iv[idir] % 2 != color[idir])
                    {
                      doThisVoF = false;
                      break;
                    }
                }

              if (doThisVoF)
                {
                  ivsColor |= iv;
                }
            }

          m_vofItIrregColor[icolor][dit()].define(ivsColor, curEBGraph);
          colorStencilBaseIVFAB.define(ivsColor, curEBGraph, 1);
          rhsColorStencilBaseIVFAB.define(ivsColor, curEBGraph, 1);

          for (int idir = 0; idir < SpaceDim; idir++)
            {
              IntVectSet loIrregColor = ivsColor;
              IntVectSet hiIrregColor = ivsColor;
              loIrregColor &= sideBoxLo[idir];
              hiIrregColor &= sideBoxHi[idir];
              m_vofItIrregColorDomLo[icolor][idir][dit()].define(loIrregColor,curEBISBox.getEBGraph());
              m_vofItIrregColorDomHi[icolor][idir][dit()].define(hiIrregColor,curEBISBox.getEBGraph());
            }

          VoFIterator& vofitcolor = m_vofItIrregColor[icolor][dit()];
          for (vofitcolor.reset(); vofitcolor.ok(); ++vofitcolor)
            {
              const VolIndex& vof = vofitcolor();

              VoFStencil& curStencil = curStencilBaseIVFAB(vof,0);
              VoFStencil& colorStencil = colorStencilBaseIVFAB(vof,0);
              VoFStencil& rhsColorStencil = rhsColorStencilBaseIVFAB(vof,0);
              Real weightIrreg = m_alpha*curAlphaWeight(vof,0) + m_beta*curBetaWeight(vof,0);
              colorStencil = curStencil;
              colorStencil *= (-1.0/weightIrreg);
              colorStencil.add(vof, 1.0);
              rhsColorStencil.add(vof, 1.0/weightIrreg);
            }

          Vector<VolIndex> srcVofs = m_vofItIrregColor[icolor][dit()].getVector();

          //color ebstencils
          m_colorEBStencil[icolor][dit()]    = RefCountedPtr<EBStencil>(new EBStencil(srcVofs, colorStencil[dit()]   ,  m_eblg.getDBL().get(dit()), m_eblg.getEBISL()[dit()], m_ghostCellsPhi, m_ghostCellsPhi));
          m_rhsColorEBStencil[icolor][dit()] = RefCountedPtr<EBStencil>(new EBStencil(srcVofs, rhsColorStencil[dit()]     , m_eblg.getDBL().get(dit()) , m_eblg.getEBISL()[dit()], m_ghostCellsRHS, m_ghostCellsPhi));

        }//dit
    }//color
  CH_STOP(t2);
}