Esempio n. 1
0
void
EBLevelAdvect::
advectToFacesBCG(EBFluxFAB&                         a_extrapState,
                 BaseIVFAB<Real>&                   a_boundaryPrim,
                 const EBCellFAB &                  a_consState,
                 const EBCellFAB &                  a_normalVel,
                 const EBFluxFAB &                  a_advectionVel,
                 const Box&                         a_cellBox,
                 const EBISBox&                     a_ebisBox,
                 const Real&                        a_dt,
                 const Real&                        a_time,
                 const EBCellFAB &                  a_source,
                 const DataIndex&                   a_dit,
                 bool   a_doBoundaryPrim)
{
  CH_TIME("EBLevelAdvect::advectToFacesBCG (fluxfab)");
  IntVectSet cfivs; //not used here.  only used in flux interpolation
  m_ebPatchAdvect[a_dit]->setTimeAndDt(a_time, a_dt);
  // EBCellFAB& primState = m_ebPatchAdvect[a_dit]->getPrimState();
  m_ebPatchAdvect[a_dit]->setVelocities(a_normalVel, a_advectionVel);

  //placeholder (no flattening used here)
  EBCellFAB flattening;
  //not reused
  EBCellFAB  slopesPrim[SpaceDim];
  EBCellFAB  slopesSeco[SpaceDim];
  bool verbose = false;

  m_ebPatchAdvect[a_dit]->extrapolateBCG(a_extrapState,
                                         // primState,
                                         slopesPrim,
                                         slopesSeco,
                                         flattening,
                                         a_consState,
                                         a_source,
                                         a_cellBox,
                                         a_dit,
                                         verbose);

  if (a_doBoundaryPrim)
    {
      IntVectSet irregIVS = a_ebisBox.getIrregIVS(a_cellBox);
      m_ebPatchAdvect[a_dit]->computeEBIrregFlux(a_boundaryPrim,
                                                 // primState,
                                                 a_consState,
                                                 slopesPrim,
                                                 irregIVS,
                                                 a_source);
    }
}
Esempio n. 2
0
int
testIFFAB(const EBISBox& a_ebisBox, const Box& a_box)
{
  IntVectSet ivs = a_ebisBox.getIrregIVS(a_box);
  if (ivs.isEmpty()) return 0;

  Interval comps(0,0);
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      BaseIFFAB<Real> srcFab(ivs, a_ebisBox.getEBGraph(), idir, 1);
      BaseIFFAB<Real> dstFab(ivs, a_ebisBox.getEBGraph(), idir, 1);
      //set source fab to right ans
      for (FaceIterator faceit(ivs, a_ebisBox.getEBGraph(), idir, FaceStop::SurroundingWithBoundary);
          faceit.ok(); ++faceit)
        {
          srcFab(faceit(), 0) = rightAns(faceit());
        }

      //linearize the data to dst
      int sizeFab = srcFab.size(a_box, comps);
      unsigned char* buf = new unsigned char[sizeFab];
      srcFab.linearOut(buf, a_box, comps);
      dstFab.linearIn( buf, a_box, comps);
      delete[] buf;

      //check the answer
      int eekflag = 0;
      Real tolerance = 0.001;
      for (FaceIterator faceit(ivs, a_ebisBox.getEBGraph(), idir, FaceStop::SurroundingWithBoundary);
          faceit.ok(); ++faceit)
        {
          Real correct  = rightAns(faceit());
          if (Abs(dstFab(faceit(), 0) - correct) > tolerance)
            {
              pout() << "ivfab test failed at face "
                     << faceit().gridIndex(Side::Lo)
                     << faceit().gridIndex(Side::Hi) << endl;

              eekflag = -3;
              return eekflag;
            }
        }
    }
  return 0;
}
Esempio n. 3
0
void EBCFData::
getEBCFIVSGrid(IntVectSet&                a_ebcfivs,
               const Box&                 a_grid,
               const int&                 a_idir,
               const Side::LoHiSide&      a_side,
               const IntVect&             a_diagGrow,
               const ProblemDomain&       a_domain,
               const IntVectSet&          a_cfivs,
               const EBISBox&             a_ebisBox)
{

  Box gridSide = adjCellBox(a_grid, a_idir, a_side, 1);
  Box grownBoxSide = gridSide;
  grownBoxSide &= a_domain;

  for (int jdir = 0; jdir < SpaceDim; jdir++)
    {
      if (jdir != a_idir)
        {
          grownBoxSide.grow(jdir, a_diagGrow[jdir]);
        }
    }
  grownBoxSide &= a_domain;

  a_ebcfivs = a_cfivs;
  for (int jdir = 0; jdir < SpaceDim; jdir++)
    {
      if (jdir != a_idir)
        {
          a_ebcfivs.grow(jdir, a_diagGrow[jdir]);
        }
    }

  IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(grownBoxSide);
  ivsIrreg.grow(3);
  ivsIrreg  &= a_domain;
  a_ebcfivs &= ivsIrreg;
  a_ebcfivs &= gridSide;

}
Esempio n. 4
0
int
testIVFAB(const EBISBox& a_ebisBox, const Box& a_box)
{
  IntVectSet ivs = a_ebisBox.getIrregIVS(a_box);
  if (ivs.isEmpty()) return 0;

  Interval comps(0,0);
  BaseIVFAB<Real> srcFab(ivs, a_ebisBox.getEBGraph(), 1);
  BaseIVFAB<Real> dstFab(ivs, a_ebisBox.getEBGraph(), 1);
  //set source fab to right ans
  for (VoFIterator vofit(ivs, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit)
    {
      srcFab(vofit(), 0) = rightAns(vofit());
    }

  //linearize the data to dst
  int sizeFab = srcFab.size(a_box, comps);
  unsigned char* buf = new unsigned char[sizeFab];
  srcFab.linearOut(buf, a_box, comps);
  dstFab.linearIn( buf, a_box, comps);
  delete[] buf;

  //check the answer
  int eekflag = 0;
  Real tolerance = 0.001;
  for (VoFIterator vofit(ivs, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit)
    {
      Real correct  = rightAns(vofit());
      if (Abs(dstFab(vofit(), 0) - correct) > tolerance)
        {
          pout() << "ivfab test failed at vof " << vofit().gridIndex() << endl;
          eekflag = -1;
          return eekflag;
        }
    }

  return 0;
}
Esempio n. 5
0
int checkEBISBox(const Box& a_gridCoar, const EBISBox& a_ebisBoxCoar, const EBISBox& a_ebisBoxFine)
{
  IntVectSet ivs = a_ebisBoxCoar.getIrregIVS(a_gridCoar);
  Real dxCoar = 2;  Real dxFine = 1;

#if CH_SPACEDIM==2
  Real areaFineCell = dxFine;
  Real areaCoarCell = dxCoar;
  Real voluFineCell = dxFine*dxFine;
  Real voluCoarCell = dxCoar*dxCoar;
#elif CH_SPACEDIM==3
  Real areaFineCell = dxFine*dxFine;
  Real areaCoarCell = dxCoar*dxCoar;
  Real voluFineCell = dxFine*dxFine*dxFine;
  Real voluCoarCell = dxCoar*dxCoar*dxCoar;
#else
  MayDay::Error();
#endif
  int retval = 0;
  for (VoFIterator vofit(ivs, a_ebisBoxCoar.getEBGraph()); vofit.ok(); ++vofit)
    {
      const VolIndex&  vofCoar = vofit();
      Vector<VolIndex> vofsFine = a_ebisBoxCoar.refine(vofCoar);

      //check the easy bits
      Real volumCoar = a_ebisBoxCoar.volFrac(  vofCoar);
      RealVect areaCritCoar = a_ebisBoxCoar.bndryArea(vofCoar)*
                              a_ebisBoxCoar.normal(vofCoar);
      Real volumFine = 0;
      RealVect areaCritFine = RealVect::Zero;
      for (int ivof = 0; ivof < vofsFine.size(); ivof++)
        {
          volumFine += a_ebisBoxFine.volFrac(  vofsFine[ivof]);
          areaCritFine += a_ebisBoxFine.bndryArea(vofsFine[ivof])*
                          a_ebisBoxFine.normal(vofsFine[ivof]);
        }
      volumFine *= voluFineCell;
      areaCritFine *= areaFineCell;
      volumCoar *= voluCoarCell;
      areaCritCoar *= areaCoarCell;
      Real tolerance = 1.0e-10;
      if (Abs(volumFine -volumCoar) > tolerance*volumCoar)
        {
          pout() << "volume problem in coar cell " << vofCoar.gridIndex() << endl;
          retval = -1;
        }

      // Real maxCc  = 0.0;
      // Real maxDev = 0.0;
      for (int idir=0; idir<SpaceDim; idir++)
        {
          if (Abs(areaCritFine[idir]-areaCritCoar[idir]) >
             tolerance*Abs(areaCritCoar[idir]))
            {
              pout() << "bndry area problem in coar cell " << vofCoar.gridIndex() << endl;
              retval = -2;
            }
        }
      //centroids are a bit uglier to test
//      RealVect bndryCentroidCoar = a_ebisBoxCoar.bndryCentroid(  vofCoar);
//      RealVect bndryCentroidFine = RealVect::Zero;

      //the areas are somewhat more painful to test
//      for (int idir = 0; idir < SpaceDim; idir++)
//        {
//
//        }
    }

  return retval;
}
void
EBCompositeMACProjector::
correctTangentialVelocity(EBFaceFAB&        a_velocity,
                          const EBFaceFAB&  a_gradient,
                          const Box&        a_grid,
                          const EBISBox&    a_ebisBox,
                          const IntVectSet& a_cfivs)
{
  CH_TIME("EBCompositeMACProjector::correctTangentialVelocity");
  int velDir = a_velocity.direction();
  int gradDir = a_gradient.direction();
  //veldir is the face on which the velocity lives
  //graddir is the direction of the component
  //and the face on which the mac gradient lives
  CH_assert(velDir != gradDir);
  CH_assert(a_velocity.nComp() == 1);
  CH_assert(a_gradient.nComp() == 1);

  //updating in place in fortran so we have to save a acopy
  EBFaceFAB velSave(a_ebisBox, a_velocity.getCellRegion(),  velDir, 1);
  velSave.copy(a_velocity);

  //interior box is the box where all of the stencil can be reached
  //without going out of the domain
  ProblemDomain domainBox = a_ebisBox.getDomain();
  Box interiorBox = a_grid;
  interiorBox.grow(1);
  interiorBox &= domainBox;
  interiorBox.grow(-1);
  Box interiorFaceBox = surroundingNodes(interiorBox, velDir);

  if (!interiorBox.isEmpty())
    {
      BaseFab<Real>&       regVel  = a_velocity.getSingleValuedFAB();
      const BaseFab<Real>& regGrad = a_gradient.getSingleValuedFAB();
      FORT_REGCORRECTTANVEL(CHF_FRA1(regVel,0),
                            CHF_CONST_FRA1(regGrad,0),
                            CHF_BOX(interiorFaceBox),
                            CHF_INT(velDir),
                            CHF_INT(gradDir));
    }

  //do only irregular and boundary cells pointwise
  IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(a_grid);
  IntVectSet ivsGrid(a_grid);
  ivsGrid -= interiorBox;
  ivsGrid |= ivsIrreg;
  FaceIterator faceit(ivsGrid, a_ebisBox.getEBGraph(), velDir, FaceStop::SurroundingWithBoundary);
  for (faceit.reset(); faceit.ok(); ++faceit)
    {
      //average neighboring grads in grad dir direction
      int numGrads = 0;
      Real gradAve = 0.0;
      const FaceIndex& velFace = faceit();
      for (SideIterator sitVel; sitVel.ok(); ++sitVel)
        {
          const VolIndex& vofSide = velFace.getVoF(sitVel());
          const IntVect&   ivSide = vofSide.gridIndex();
          //do not include stuff over coarse-fine interface and inside the domain
          //cfivs includes cells just outside domain
          if (!a_cfivs.contains(ivSide) && domainBox.contains(ivSide))
            {
              for (SideIterator sitGrad; sitGrad.ok(); ++sitGrad)
                {
                  Vector<FaceIndex> gradFaces = a_ebisBox.getFaces(vofSide, gradDir, sitGrad());
                  for (int iface = 0; iface < gradFaces.size(); iface++)
                    {
                      if (!gradFaces[iface].isBoundary())
                        {
                          numGrads++;
                          gradAve += a_gradient(gradFaces[iface], 0);
                        }
                    }
                }//end loop over gradient sides
            }//end cfivs check
          else
            {
              // inside coarse/fine interface or at domain boundary. extrapolate from neighboring vofs to get the gradient
              const Side::LoHiSide inSide    = flip(sitVel());
              const VolIndex&      inSideVof = velFace.getVoF(inSide);
              const IntVect&       inSideIV  = inSideVof.gridIndex();

              IntVect inSideFarIV = inSideIV;
              inSideFarIV[velDir] += sign(inSide);
              if (domainBox.contains(inSideIV) && domainBox.contains(inSideFarIV))
                {
                  Vector<VolIndex> farVofs = a_ebisBox.getVoFs(inSideFarIV);
                  if (farVofs.size()  == 1)
                    {
                      const VolIndex& inSideFarVof = farVofs[0];
                      for (SideIterator sitGrad; sitGrad.ok(); ++sitGrad)
                        {
                          //get the grad for the face adjoining inSideVof on the sitGrad side, in the gradDir direction
                          Vector<FaceIndex> gradFaces    = a_ebisBox.getFaces(inSideVof   , gradDir, sitGrad());
                          Vector<FaceIndex> gradFarFaces = a_ebisBox.getFaces(inSideFarVof, gradDir, sitGrad());
                          if ( (gradFaces.size() == 1) && (gradFarFaces.size() == 1) )
                            {
                              // if ( (!gradFaces[0].isBoundary()) && (!gradFarFaces[0].isBoundary()) )
                              //   {
                                  const Real& inSideGrad    = a_gradient(gradFaces[0], 0);
                                  const Real& inSideFarGrad = a_gradient(gradFarFaces[0], 0);
                                  Real extrapGrad = 2.0*inSideGrad - inSideFarGrad;
                                  gradAve += extrapGrad;
                                  numGrads++;
                                // }
                            }
                        }
                    }
                }
            }//end cfivs check
        }//end loop over sides of velocity face
      if (numGrads > 1)
        {
          gradAve /= Real(numGrads);
        }

      //remember that the fortran updated the velocity  in place so
      //we have to use the saved velocity
      a_velocity(velFace, 0) = velSave(velFace, 0) - gradAve;
    }
}
Esempio n. 7
0
void
EBPlanarShockIBC::
setBndrySlopes(EBCellFAB&       a_deltaPrim,
               const EBCellFAB& a_primState,
               const EBISBox&   a_ebisBox,
               const Box&       a_box,
               const int&       a_dir)
{
  // don't want to deal with the periodic case
 CH_assert(!m_domain.isPeriodic(a_dir));
 CH_assert(m_isDefined);
 CH_assert(m_isFortranCommonSet);

  Box loBox,hiBox,centerBox,domain;
  int hasLo,hasHi;
  Box slopeBox = a_deltaPrim.getRegion()&m_domain;
  int numSlop = a_deltaPrim.nComp();
  // Generate the domain boundary boxes, loBox and hiBox, if there are
  // domain boundarys there
  eblohicenter(loBox,hasLo,hiBox,hasHi,centerBox,domain,
             slopeBox,m_domain,a_dir);

  // Set the boundary slopes if necessary
  if ((hasLo != 0) || (hasHi != 0))
    {
      BaseFab<Real>& regDeltaPrim = a_deltaPrim.getSingleValuedFAB();
      const BaseFab<Real>& regPrimState = a_primState.getSingleValuedFAB();
      /**/
      FORT_SLOPEBCS(CHF_FRA(regDeltaPrim),
                    CHF_CONST_FRA(regPrimState),
                    CHF_CONST_REAL(m_dx),
                    CHF_CONST_INT(a_dir),
                    CHF_BOX(loBox),
                    CHF_CONST_INT(hasLo),
                    CHF_BOX(hiBox),
                    CHF_CONST_INT(hasHi));
      /**/
    }
  for(SideIterator sit; sit.ok(); ++sit)
    {
      bool doThisSide;
      Box thisBox;
      if(sit() == Side::Lo)
        {
          doThisSide = (hasLo != 0);
          thisBox = loBox;
        }
      else
        {
          doThisSide = (hasHi != 0);
          thisBox = hiBox;
        }
      if(doThisSide)
        {

          // the cells for which the regular calculation
          //are incorrect are the grown set of the multivalued
          //cells intersected with the appropriate bndry box
          //and added to the irregular cells on the boundary.
          Box boxGrown = thisBox;
          boxGrown.grow(a_dir, 1);
          boxGrown &= m_domain;
          IntVectSet ivs = a_ebisBox.getMultiCells(boxGrown);
          ivs &= loBox;
          IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(thisBox);
          ivs |= ivsIrreg;
          for(VoFIterator vofit(ivs, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit)
            {
              const VolIndex& vof = vofit();
              //all slopes at boundary get set to zero
              //except normal velocity.  just following the
              //fortran here
              int inormVelVar = a_dir + QVELX;
              for(int ivar = 0; ivar < numSlop; ivar++)
                {
                  if(ivar != inormVelVar)
                    {
                      a_deltaPrim(vof, ivar) = 0.0;
                    }
                }

              //for normal velocity
              //do strangely limited slope
              //just lifted from the fortran.
              Side::LoHiSide otherSide = flip(sit());
              Vector<FaceIndex> faces =
                a_ebisBox.getFaces(vof, a_dir, otherSide);

              Real thisVel = a_primState(vof, inormVelVar);
              Real otherVel = 0.;
              for(int iface = 0; iface < faces.size(); iface++)
                {
                  VolIndex otherVoF = faces[iface].getVoF(otherSide);
                  otherVel += a_primState(otherVoF,inormVelVar);
                }
              if(faces.size() > 0)
                {
                  otherVel /= Real(faces.size());
                  Real slope;
                  if(sit() == Side::Lo)
                    {
                      slope = otherVel - thisVel;
                    }
                  else
                    {
                      slope = thisVel  - otherVel;
                    }
                  //trick to make sure state will not change sign
                  if(slope*thisVel < 0)
                    {
                      a_deltaPrim(vof, inormVelVar) = 0.0;
                    }
                  else
                    { //slope and vel same sign
                      Real rsign = 1.0;
                      if(thisVel < 0.0)
                        rsign = -1.0;
                      //told you this was odd.
                      Real dvmin = Min(Abs(slope), Abs((Real)2.*thisVel));
                      a_deltaPrim(vof, inormVelVar) = rsign*dvmin;
                    }
                }
              else //no faces on high side of low boundary vof
                {
                  a_deltaPrim(vof, inormVelVar) = 0.0;
                }
            } //end loop over irregular vofs at boundary
        }
    } //end loop over boundary sides
}
Esempio n. 8
0
void
kappaDivergence(EBCellFAB&             a_divF,
                const EBFluxFAB&       a_flux,
                const EBISBox&         a_ebisBox,
                const Box&             a_box,
                const Real&            a_dx)
{
    //set the divergence initially to zero
    //then loop through directions and increment the divergence
    //with each directions flux difference.
    a_divF.setVal(0.0);
    BaseFab<Real>&       regDivF = a_divF.getSingleValuedFAB();
    regDivF.setVal(0.);
    for (int idir = 0; idir < SpaceDim; idir++)
    {
        //update for the regular vofs in the nonconservative
        //case  works for all single valued vofs.
        /* do the regular vofs */
        /**/
        const EBFaceFAB& fluxDir = a_flux[idir];
        const BaseFab<Real>& regFluxDir = fluxDir.getSingleValuedFAB();
        int ncons = 1;
        FORT_DIVERGEF( CHF_BOX(a_box),
                       CHF_FRA(regDivF),
                       CHF_CONST_FRA(regFluxDir),
                       CHF_CONST_INT(idir),
                       CHF_CONST_INT(ncons),
                       CHF_CONST_REAL(a_dx));
        /**/
    }
    //update the irregular vofs using conservative diff
    IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(a_box);
    for (VoFIterator vofit(ivsIrreg, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit)
    {
        const VolIndex& vof = vofit();
        //divergence was set in regular update.  we reset it
        // to zero and recalc.
        Real update = 0.;
        for ( int idir = 0; idir < SpaceDim; idir++)
        {
            const EBFaceFAB& fluxDir = a_flux[idir];
            for (SideIterator sit; sit.ok(); ++sit)
            {
                int isign = sign(sit());
                Vector<FaceIndex> faces =
                    a_ebisBox.getFaces(vof, idir, sit());
                for (int iface = 0; iface < faces.size(); iface++)
                {
                    const FaceIndex& face = faces[iface];
                    Real areaFrac = a_ebisBox.areaFrac(face);
                    Real faceFlux =fluxDir(face, 0);
                    update += isign*areaFrac*faceFlux;

                }
            }
        }
        //add EB boundary condtions in divergence
        const IntVect& iv = vof.gridIndex();
        Real bndryArea = a_ebisBox.bndryArea(vof);
        RealVect bndryCent = a_ebisBox.bndryCentroid(vof);
        RealVect normal = a_ebisBox.normal(vof);
        RealVect bndryLoc;
        RealVect exactF;
        for (int idir = 0; idir < SpaceDim; idir++)
        {
            bndryLoc[idir] = a_dx*(iv[idir] + 0.5 + bndryCent[idir]);
        }
        for (int idir = 0; idir < SpaceDim; idir++)
        {
            exactF[idir] = exactFlux(bndryLoc, idir);
        }
        Real bndryFlux = PolyGeom::dot(exactF, normal);

        update -= bndryFlux*bndryArea;
        update /= a_dx; //note NOT divided by volfrac

        a_divF(vof, 0) = update;
    }
}
void
EBGradDivFilter::
cellGradient(EBCellFAB&             a_gradDiv,
             const EBCellFAB&       a_gradVel,
             const  EBCellFAB&      a_vel,
             const EBFluxFAB&       a_fluxVel,
             const EBFluxFAB&       a_div,
             const Box&             a_grid,
             const EBISBox&         a_ebisBox,
             const DataIndex&       a_dataIndex,
             bool a_multiplyByLambda,
             bool a_noExtrapToCovered)
{
  CH_TIME("EBGradDivFilter::cellGradient");
  int icomp = 0;
  EBCellFAB& lambdaFAB = m_lambda[a_dataIndex];
  IntVectSet irregIVS = a_ebisBox.getIrregIVS(a_grid);

  for (int faceDir = 0; faceDir < SpaceDim; faceDir++)
    {
      const EBFaceFAB&  faceDiv       =  a_div[faceDir];
      const BaseFab<Real>& regFaceDiv =   faceDiv.getSingleValuedFAB();
      const BaseFab<Real>& regLambda =   lambdaFAB.getSingleValuedFAB();
      BaseFab<Real>& regGradDiv       = a_gradDiv.getSingleValuedFAB();

      int imultByLambda = 0;
      if (a_multiplyByLambda)
        {
          imultByLambda = 1;
        }
      FORT_EBGDFCELLGRAD(CHF_FRA1(regGradDiv, faceDir),
                         CHF_CONST_FRA1(regFaceDiv, icomp),
                         CHF_CONST_FRA1(regLambda, icomp),
                         CHF_BOX(a_grid),
                         CHF_CONST_REAL(m_dxFine[faceDir]),
                         CHF_CONST_INT(faceDir),
                         CHF_CONST_INT(imultByLambda));

      //nonconservative gradient
      for (VoFIterator vofit(irregIVS, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit)
        {
          const VolIndex& vof = vofit();
          Real gradVal = 0.0;

          Vector<FaceIndex> facesHi = a_ebisBox.getFaces(vof, faceDir, Side::Hi);
          Vector<FaceIndex> facesLo = a_ebisBox.getFaces(vof, faceDir, Side::Lo);

          bool zeroGrad = a_noExtrapToCovered && ((facesHi.size() == 0) || (facesLo.size() == 0));
          if (zeroGrad)
            {
              gradVal = 0;
            }
          else
            {
              Real valHi= 0;
              if (facesHi.size() > 0)
                {
                  for (int iface = 0; iface < facesHi.size(); iface++)
                    {
                      valHi += faceDiv(facesHi[iface], icomp);
                    }
                  valHi /= facesHi.size();
                }
              else
                {
                  valHi = ccpGetCoveredExtrapValue(vof, faceDir, Side::Hi,
                                                   faceDiv, a_ebisBox, a_grid,
                                                   m_domainFine, m_dxFine, icomp);
                }

              Real valLo= 0;
              if (facesLo.size() > 0)
                {
                  for (int iface = 0; iface < facesLo.size(); iface++)
                    {
                      valLo += faceDiv(facesLo[iface], 0);
                    }
                  valLo /= facesLo.size();
                }
              else
                {
                  valLo = ccpGetCoveredExtrapValue(vof, faceDir, Side::Lo ,
                                                   faceDiv, a_ebisBox, a_grid,
                                                   m_domainFine, m_dxFine, icomp);

                }
              gradVal = (valHi-valLo)/(m_dxFine[faceDir]);

              //multiply the lambda in since we have the area fractions lying about
              if (a_multiplyByLambda)
                {
                  Real lambda = lambdaFAB(vof, 0);
                  gradVal *= lambda;
                }
            }

          a_gradDiv(vof, faceDir) = gradVal;
        }
    }
}
void
EBGradDivFilter::
gradVel(EBCellFAB&             a_gradVel,
        const  EBCellFAB&      a_vel,
        const Box&             a_grid,
        const EBISBox&         a_ebisBox,
        bool a_lowOrderOneSide)
{
  CH_TIME("EBGradDivFilter::gradVel");
  CH_assert(a_gradVel.nComp() == SpaceDim*SpaceDim);
  CH_assert(a_vel.nComp() == SpaceDim);

  int iLowOrderOneSide = 0;
  if (a_lowOrderOneSide)
    {
      iLowOrderOneSide = 1;
    }

  for (int derivDir = 0; derivDir < SpaceDim; derivDir++)
    {
      Box loBox, hiBox, centerBox;
      int hasLo, hasHi;
      EBArith::loHiCenter(loBox, hasLo, hiBox, hasHi, centerBox, m_domainFine, a_grid, derivDir);
      for (int velDir = 0; velDir < SpaceDim; velDir++)
        {
          BaseFab<Real>&   regGradVel  = a_gradVel.getSingleValuedFAB();
          const BaseFab<Real>& regVel  =     a_vel.getSingleValuedFAB();
          int gradcomp = getGradComp(velDir, derivDir);

          FORT_EBGDFGRADVEL(CHF_FRA1(regGradVel, gradcomp),
                            CHF_CONST_FRA1(regVel, velDir),
                            CHF_BOX(loBox),
                            CHF_INT(hasLo),
                            CHF_BOX(hiBox),
                            CHF_INT(hasHi),
                            CHF_BOX(centerBox),
                            CHF_CONST_REAL(m_dxFine[derivDir]),
                            CHF_CONST_INT(derivDir),
                            CHF_CONST_INT(iLowOrderOneSide));

          IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(a_grid);
          if (!a_lowOrderOneSide)
            {
              ivsIrreg.grow(1);
              ivsIrreg &= a_grid;
            }
          for (VoFIterator vofit(ivsIrreg, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit)
            {
              const VolIndex& vof = vofit();
              bool hasHi, hasLo;
              VolIndex vofHi, vofLo;
              Vector<FaceIndex> facesHi = a_ebisBox.getFaces(vof, derivDir, Side::Hi);
              Vector<FaceIndex> facesLo = a_ebisBox.getFaces(vof, derivDir, Side::Lo);

              hasHi = (facesHi.size() == 1) && (!facesHi[0].isBoundary());
              hasLo = (facesLo.size() == 1) && (!facesLo[0].isBoundary());
              if (hasLo)
                {
                  vofLo = facesLo[0].getVoF(Side::Lo);
                }
              if (hasHi)
                {
                  vofHi = facesHi[0].getVoF(Side::Hi);
                }

              Real gradVal;
              if (hasHi && hasLo)
                {
                  gradVal = (a_vel(vofHi, velDir) - a_vel(vofLo, velDir))/(2.*m_dxFine[derivDir]);
                }
              else if (hasHi || hasLo)
                {
                  //do one-sided diff
                  CH_assert(!(hasHi && hasLo));
                  Side::LoHiSide side;
                  VolIndex vofNear;
                  if (hasLo)
                    {
                      side = Side::Lo;
                      vofNear = vofLo;
                    }
                  else
                    {
                      side = Side::Hi;
                      vofNear = vofHi;
                    }
                  int isign = sign(side);

                  Vector<FaceIndex> facesFar = a_ebisBox.getFaces(vofNear, derivDir, side);
                  bool hasVoFFar = (facesFar.size()==1) && (!facesFar[0].isBoundary());
                  Real valStart = a_vel(vof,     velDir);
                  Real valNear  = a_vel(vofNear, velDir);
                  if (hasVoFFar && !a_lowOrderOneSide)
                    {
                      VolIndex vofFar = facesFar[0].getVoF(side);
                      Real valFar = a_vel(vofFar, velDir);
                      gradVal = (4*(valNear - valStart)- (valFar-valStart))/(2.*isign*m_dxFine[derivDir]);
                    }
                  else
                    {
                      //do not have another point for stencil or specified low order one-sided.
                      //drop order of derivative
                      gradVal = (valNear - valStart)/(isign*m_dxFine[derivDir]);
                    }
                }
              else
                {
                  //only have one point, can only set gradient to zero
                  gradVal = 0.0;
                }

              a_gradVel(vof, gradcomp) = gradVal;
            }
        }
    }
}
void
EBGradDivFilter::
faceDivergence(EBFaceFAB&             a_divVel,
               const EBCellFAB&       a_gradVel,
               const EBCellFAB&       a_vel,
               const EBFluxFAB&       a_fluxVel,
               const Box&             a_grid,
               const EBISBox&         a_ebisBox,
               const int&             a_faceDir)
{
  CH_TIME("EBGradDivFilter::faceDivergence");
  CH_assert(a_divVel.nComp() == 1);
  CH_assert(a_vel.nComp() == SpaceDim);

  a_divVel.setVal(0.0);
  BaseFab<Real>& regDivVel       =  a_divVel.getSingleValuedFAB();
  const BaseFab<Real>& regVel    =     a_vel.getSingleValuedFAB();
  const BaseFab<Real>& regGradVel= a_gradVel.getSingleValuedFAB();

  Box interiorFaceBox = a_grid;
  interiorFaceBox.grow(a_faceDir, 1);
  interiorFaceBox &= m_domainFine;
  interiorFaceBox.grow(a_faceDir, -1);
  interiorFaceBox.surroundingNodes(a_faceDir);

  for (int divDir = 0; divDir < SpaceDim; divDir++)
    {
      FORT_EBGDFFACEDIVINCR(CHF_FRA1(regDivVel, 0),
                            CHF_FRA(regVel),
                            CHF_FRA(regGradVel),
                            CHF_BOX(interiorFaceBox),
                            CHF_REAL(m_dxFine[divDir]),
                            CHF_INT(a_faceDir),
                            CHF_INT(divDir));
    }

  IntVectSet irregIVS = a_ebisBox.getIrregIVS(a_grid);
  FaceStop::WhichFaces stopCrit;
  if (m_domainFine.isPeriodic(a_faceDir))
    {
      stopCrit = FaceStop::SurroundingWithBoundary;
    }
  else
    {
      stopCrit = FaceStop::SurroundingNoBoundary;
    }
  for (FaceIterator faceit(irregIVS, a_ebisBox.getEBGraph(), a_faceDir,
                          stopCrit);
      faceit.ok(); ++faceit)
    {
      Real divVal = 0.0;
      for (int divDir=0; divDir<SpaceDim; divDir++)
        {
          if (divDir == a_faceDir)
            {
              divVal += (a_vel(faceit().getVoF(Side::Hi), a_faceDir) -
                         a_vel(faceit().getVoF(Side::Lo), a_faceDir))/m_dxFine[divDir];
            }
          else
            {
              // take average of cell-centered tangential derivatives
              // and increment div
              //so this is partial (vel_divdir)/partial (x_divdir)
              int velcomp = divDir;
              int gradcomp = getGradComp(velcomp, divDir);

              divVal += 0.5*(a_gradVel(faceit().getVoF(Side::Hi), gradcomp) +
                             a_gradVel(faceit().getVoF(Side::Lo), gradcomp));
            }
        }

      a_divVel(faceit(), 0) = divVal;
    } // end loop over interior irregular faces

  if (!m_domainFine.isPeriodic(a_faceDir))
    {
      //set the boundary face divergence to an extrapolation of the neighboring face divergences
      for (SideIterator sit; sit.ok(); ++sit)
        {
          Box bndryBox = adjCellBox(a_grid, a_faceDir, sit(), 1);
          int ishift = -sign(sit());
          bndryBox.shift(a_faceDir, ishift);
          IntVectSet bndryIVS(bndryBox);
          for (FaceIterator faceit(bndryIVS, a_ebisBox.getEBGraph(), a_faceDir,
                                  FaceStop::AllBoundaryOnly);
              faceit.ok(); ++faceit)
            {
              Real faceDiv = getDomainDivergence(a_gradVel,
                                                 a_vel,
                                                 a_fluxVel,
                                                 a_grid,
                                                 a_ebisBox,
                                                 a_faceDir,
                                                 faceit(),
                                                 sit());
              a_divVel(faceit(), 0) = faceDiv;
            }
        }
    }
}