Beispiel #1
0
/// Set up initial conditions
void SWIBC::initializeBdry(LevelData<FArrayBox>& a_B)
{
    const Real tmpVal  =  0.0;
    const Real tmpVal2 = 100;
    for (DataIterator dit = a_B.dataIterator(); dit.ok(); ++dit)
    {
        // Storage for current grid
        FArrayBox& B = a_B[dit()];

        // Box of current grid
        Box bBox = B.box();
        bBox &= m_domain;

        // Set up initial condition in this grid
        FORT_LINELASTSETFAB(CHF_FRA1(B,4),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,5),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,6),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal2));
    }
}
Beispiel #2
0
void
EBPoissonOp::
applyOpRegularAllDirs(Box * a_loBox,
                      Box * a_hiBox,
                      int * a_hasLo,
                      int * a_hasHi,
                      Box & a_curDblBox,
                      Box & a_curPhiBox,
                      int a_nComps,
                      BaseFab<Real> & a_curOpPhiFAB,
                      const BaseFab<Real> & a_curPhiFAB,
                      bool a_homogeneousPhysBC,
                      const DataIndex& a_dit,
                      const Real& a_beta)
{
  CH_TIME("EBPoissonOp::applyOpRegularAllDirs");
  CH_assert(m_domainBC != NULL);

  //need to monkey with the ghost cells to account for boundary conditions
  BaseFab<Real>& phiFAB = (BaseFab<Real>&) a_curPhiFAB;
  applyDomainFlux(a_loBox, a_hiBox, a_hasLo, a_hasHi,
                  a_curDblBox, a_nComps, phiFAB,
                  a_homogeneousPhysBC, a_dit,m_beta);

  for (int comp = 0; comp<a_nComps; comp++)
    {

      FORT_REGGET1DLAPLACIAN_INPLACE(CHF_FRA1(a_curOpPhiFAB,comp),
                                     CHF_CONST_FRA1(a_curPhiFAB,comp),
                                     CHF_CONST_REAL(a_beta),
                                     CHF_CONST_REALVECT(m_dx),
                                     CHF_BOX(a_curDblBox));
    }
}
Beispiel #3
0
void CellToEdge(const FArrayBox& a_cellData,
                FluxBox& a_edgeData)
{

  // loop over components -- assumption is that in cell-centered
  // data, direction changes faster than component
  int cellcomp;
  for (int comp = 0; comp < a_edgeData.nComp(); comp++)
    {
      // loop over directions
      for (int dir = 0; dir < SpaceDim; dir++)
        {
          // define faces over which we can do averaging
          Box edgeBox = surroundingNodes(a_cellData.box(), dir);
          edgeBox.grow(dir,-1);
          edgeBox &= a_edgeData[dir].box();

          if (a_cellData.nComp() == a_edgeData.nComp())
            {
              // straightforward cell->edge averaging
              cellcomp = comp;
            }
          else
            {
              // each cell comp represents a different spatial direction
              cellcomp = SpaceDim*comp + dir;
            }
          FORT_CELLTOEDGE(CHF_CONST_FRA1(a_cellData, cellcomp),
                          CHF_FRA1(a_edgeData[dir], comp),
                          CHF_BOX(edgeBox),
                          CHF_CONST_INT(dir));
        }
    }
}
Beispiel #4
0
// ------------------------------------------------------------
void CellToEdge(const FArrayBox& a_cellData, FArrayBox& a_edgeData,
                const int a_dir)

{

  Box edgeBox = surroundingNodes(a_cellData.box(), a_dir);
  edgeBox.grow(a_dir,-1);
  edgeBox &= a_edgeData.box();

  int cellComp;
  for (int comp = 0; comp < a_edgeData.nComp(); comp++)
    {
      if (a_cellData.nComp() == a_edgeData.nComp())
        {
          // straightforward cell->edge averaging
          cellComp = comp;
        }
      else
        {
          // each cell comp represents a different spatial direction
          cellComp = SpaceDim*comp + a_dir;
        }

      FORT_CELLTOEDGE(CHF_CONST_FRA1(a_cellData, cellComp),
                      CHF_FRA1(a_edgeData, comp),
                      CHF_BOX(edgeBox),
                      CHF_CONST_INT(a_dir));
    }

}
Beispiel #5
0
void
EBMGAverage::averageFAB(EBCellFAB&       a_coar,
                        const Box&       a_boxCoar,
                        const EBCellFAB& a_refCoar,
                        const DataIndex& a_datInd,
                        const Interval&  a_variables) const
{
  CH_TIMERS("EBMGAverage::average");
  CH_TIMER("regular_average", t1);
  CH_TIMER("irregular_average", t2);
  CH_assert(isDefined());

  const Box& coarBox = a_boxCoar;

  //do all cells as if they were regular
  Box refBox(IntVect::Zero, IntVect::Zero);
  refBox.refine(m_refRat);
  int numFinePerCoar = refBox.numPts();

  BaseFab<Real>& coarRegFAB =             a_coar.getSingleValuedFAB();
  const BaseFab<Real>& refCoarRegFAB = a_refCoar.getSingleValuedFAB();

  //set to zero because the fortran is a bit simpleminded
  //and does stuff additively
  a_coar.setVal(0.);
  CH_START(t1);
  for (int comp = a_variables.begin();  comp <= a_variables.end(); comp++)
    {
      FORT_REGAVERAGE(CHF_FRA1(coarRegFAB,comp),
                      CHF_CONST_FRA1(refCoarRegFAB,comp),
                      CHF_BOX(coarBox),
                      CHF_BOX(refBox),
                      CHF_CONST_INT(numFinePerCoar),
                      CHF_CONST_INT(m_refRat));
    }
  CH_STOP(t1);

  //this is really volume-weighted averaging even though it does
  //not look that way.

  //so (in the traditional sense) we want to preserve
  //rhoc * volc = sum(rhof * volf)
  //this translates to
  //volfrac_C * rhoC = (1/numFinePerCoar)(sum(volFrac_F * rhoF))
  //but the data input to this routine is all kappa weigthed so
  //the volumefractions have already been multiplied
  //which means
  // rhoC = (1/numFinePerCoar)(sum(rhoF))
  //which is what this does

  CH_START(t2);
  for (int comp = a_variables.begin();  comp <= a_variables.end(); comp++)
    {
      m_averageEBStencil[a_datInd]->apply(a_coar, a_refCoar, false, comp);
    }
  CH_STOP(t2);

}
Beispiel #6
0
void EdgeToCell(const FluxBox& a_edgeData, const int a_edgeComp,
                FArrayBox& a_cellData, const int a_cellComp,
                const Box& a_cellBox, const int a_dir)
{

  FORT_EDGETOCELL(CHF_CONST_FRA1(a_edgeData[a_dir],a_edgeComp),
                  CHF_FRA1(a_cellData, a_cellComp),
                  CHF_BOX(a_cellBox),
                  CHF_CONST_INT(a_dir));
}
Beispiel #7
0
void EdgeToCellMax(const FluxBox& a_edgeData, const int a_edgeComp,
                   FArrayBox& a_cellData, const int a_cellComp,
                   const int a_dir)
{

  const Box& cellBox = a_cellData.box();
  FORT_EDGETOCELLMAX(CHF_CONST_FRA1(a_edgeData[a_dir],a_edgeComp),
                     CHF_FRA1(a_cellData, a_cellComp),
                     CHF_BOX(cellBox),
                     CHF_CONST_INT(a_dir));
}
Beispiel #8
0
void EBPoissonOp::
GSColorAllRegular(LevelData<EBCellFAB>&        a_phi,
                  const LevelData<EBCellFAB>&  a_rhs,
                  const IntVect&               a_color,
                  const Real&                  a_weight,
                  const bool&                  a_homogeneousPhysBC)
{
  CH_TIME("EBPoissonOp::GSColorAllRegular");
  CH_assert(a_rhs.ghostVect() == m_ghostCellsRHS);
  CH_assert(a_phi.ghostVect() == m_ghostCellsPhi);

  int nComps = a_phi.nComp();
  for (DataIterator dit = a_phi.dataIterator(); dit.ok(); ++dit)
    {
      Box dblBox(m_eblg.getDBL().get(dit()));
      BaseFab<Real>& phiFAB       = (a_phi[dit()] ).getSingleValuedFAB();
      const BaseFab<Real>& rhsFAB = (a_rhs[dit()] ).getSingleValuedFAB();

      Box loBox[SpaceDim],hiBox[SpaceDim];
      int hasLo[SpaceDim],hasHi[SpaceDim];

      applyDomainFlux(loBox, hiBox, hasLo, hasHi,
                      dblBox, nComps, phiFAB,
                      a_homogeneousPhysBC, dit(),m_beta);

      IntVect loIV = dblBox.smallEnd();
      IntVect hiIV = dblBox.bigEnd();

      for (int idir = 0; idir < SpaceDim; idir++)
        {
          if (loIV[idir] % 2 != a_color[idir])
            {
              loIV[idir]++;
            }
        }

      if (loIV <= hiIV)
        {
          Box coloredBox(loIV, hiIV);

          for (int comp=0; comp<a_phi.nComp(); comp++)
            {
              FORT_DOALLREGULARMULTICOLOR(CHF_FRA1(phiFAB,comp),
                                          CHF_CONST_FRA1(rhsFAB,comp),
                                          CHF_CONST_REAL(a_weight),
                                          CHF_CONST_REAL(m_alpha),
                                          CHF_CONST_REAL(m_beta),
                                          CHF_CONST_REALVECT(m_dx),
                                          CHF_BOX(coloredBox));
            }
        }
    }
}
Beispiel #9
0
// 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));

    }

}
// ---------------------------------------------------------
void
AMRNavierStokes::computeKineticEnergy(LevelData<FArrayBox>& a_energy) const
{
  // this is simple since no BC's need to be set.
  const LevelData<FArrayBox>& levelVel = *m_vel_new_ptr;
  const DisjointBoxLayout& levelGrids = levelVel.getBoxes();

  DataIterator dit = a_energy.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      FORT_KINETICENERGY(CHF_FRA1(a_energy[dit],0),
                         CHF_CONST_FRA(levelVel[dit]),
                         CHF_BOX(levelGrids[dit]));
    }
}
Beispiel #11
0
// ------------------------------------------------------------
void CellToEdge(const FArrayBox& a_cellData, const int a_cellComp,
                FArrayBox& a_edgeData, const int a_edgeComp,
                const int a_dir)

{

  Box edgeBox = surroundingNodes(a_cellData.box(),a_dir);
  edgeBox.grow(a_dir, -1);
  edgeBox &= a_edgeData.box();

  FORT_CELLTOEDGE(CHF_CONST_FRA1(a_cellData,a_cellComp),
                  CHF_FRA1(a_edgeData,a_edgeComp),
                  CHF_BOX(edgeBox),
                  CHF_CONST_INT(a_dir));
}
Beispiel #12
0
void
EBMGInterp::pwcInterpFAB(EBCellFAB&       a_refCoar,
                         const Box&       a_coarBox,
                         const EBCellFAB& a_coar,
                         const DataIndex& a_datInd,
                         const Interval&  a_variables) const
{
  CH_TIMERS("EBMGInterp::interp");
  CH_TIMER("regular_interp", t1);
  CH_TIMER("irregular_interp", t2);
  CH_assert(isDefined());

  const Box& coarBox = a_coarBox;

  for (int ivar = a_variables.begin();  ivar <= a_variables.end(); ivar++)
    {
      m_interpEBStencil[a_datInd]->cache(a_refCoar, ivar);

      //do all cells as if they were regular
      Box refBox(IntVect::Zero, IntVect::Zero);
      refBox.refine(m_refRat);

      const BaseFab<Real>& coarRegFAB =    a_coar.getSingleValuedFAB();
      BaseFab<Real>& refCoarRegFAB    = a_refCoar.getSingleValuedFAB();

      CH_START(t1);

      FORT_REGPROLONG(CHF_FRA1(refCoarRegFAB,ivar),
                      CHF_CONST_FRA1(coarRegFAB,ivar),
                      CHF_BOX(coarBox),
                      CHF_BOX(refBox),
                      CHF_CONST_INT(m_refRat));

      CH_STOP(t1);

      m_interpEBStencil[a_datInd]->uncache(a_refCoar, ivar);

      CH_START(t2);
      m_interpEBStencil[a_datInd]->apply(a_refCoar, a_coar, true, ivar);
      CH_STOP(t2);
    }
}
Beispiel #13
0
// ----------------------------------------------------------------
void EdgeToCell(const FluxBox& a_edgeData,
                FArrayBox& a_cellData)
{
  // loop over components -- assumption is that in cell-centered
  // data, direction changes faster than component.
  for (int comp = 0; comp<a_edgeData.nComp(); comp++)
    {
      // loop over directions
      for (int dir = 0; dir < SpaceDim; dir++)
        {
          Box cellBox = a_cellData.box();
          cellBox &= a_edgeData.box();
          int cellcomp = SpaceDim*comp + dir;
          FORT_EDGETOCELL(CHF_CONST_FRA1(a_edgeData[dir],comp),
                          CHF_FRA1(a_cellData, cellcomp),
                          CHF_BOX(cellBox),
                          CHF_CONST_INT(dir));
        } // end loop over directions
    } // end loop over components
}
Beispiel #14
0
void NewPoissonOp::
levelRelaxColor(FArrayBox&       a_phi,
                const FArrayBox& a_rhs,
                const IntVect&   a_color,
                const Real&      a_weight,
                const bool&      a_homogeneousPhysBC)
{
  CH_assert(a_phi.nComp() == 1);

  Box dblBox = a_rhs.box();

  //apply domain boundary condtions
  m_bc(a_phi, m_domain.domainBox(), m_domain, m_dx[0], a_homogeneousPhysBC);

  //find box over which we are iterating
  IntVect loIV = dblBox.smallEnd();
  IntVect hiIV = dblBox.bigEnd();

  for (int idir = 0; idir < SpaceDim; idir++)
    {
      if (loIV[idir] % 2 != a_color[idir])
        {
          loIV[idir]++;
        }
    }

  if (loIV <= hiIV)
    {
      Box coloredBox(loIV, hiIV);
      int comp = 0;
      Real alpha = 0;
      Real beta = 1.;
      FORT_AMRPMULTICOLOR(CHF_FRA1(a_phi,comp),
                          CHF_CONST_FRA1(a_rhs,comp),
                          CHF_CONST_REAL(a_weight),
                          CHF_CONST_REAL(alpha),
                          CHF_CONST_REAL(beta),
                          CHF_CONST_REALVECT(m_dx),
                          CHF_BOX(coloredBox));
    }
}
Beispiel #15
0
void TraceState(/// state at time t+dt/2 on edges in direction dir
                FArrayBox& a_stateHalf,
                /// cell-centered state at time t
                const FArrayBox& a_state,
                /// cell-centered velocity at time t
                const FArrayBox& a_cellVel,
                /// edge-centered advection velocity at time t+dt/2
                const FluxBox& a_advectionVel,
                /// cell-centered source
                const FArrayBox& a_source,
                /// Physical domain
                const ProblemDomain& a_dProblem,
                /// interior of grid patch
                const Box& a_gridBox,
                /// timeStep
                const Real a_dt,
                /// cell-spacing
                const Real a_dx,
                /// direction in which to perform tracing
                const int a_dir,
                /// which components to trace
                const Interval& a_srcComps,
                ///  where to put traced components in a_stateHalf,
                const Interval& a_destComps)

{

  int ncomp = a_srcComps.size();
  CH_assert (ncomp == a_destComps.size());
  int offset = a_destComps.begin() - a_srcComps.begin();
  Box edgeBox = a_gridBox;
  edgeBox.surroundingNodes(a_dir);

#ifdef SIMPLEUPWIND
  // simple cell-to-edge averaging may be causing us problems --
  // instead do simple upwinding

  for (int comp=a_srcComps.begin(); comp <= a_srcComps.end(); comp++)
  {
    int destcomp = comp+offset;
    FORT_UPWINDCELLTOEDGE(CHF_FRA1(a_stateHalf, destComp),
                          CHF_CONST_FRA1(a_state,comp),
                          CHF_CONST_FRA(a_advectionVel[a_dir]),
                          CHF_BOX(edgeBox),
                          CHF_CONST_INT(a_dir));
  }

#else


  // first compute slopes
  Box slopesBox = grow(a_gridBox,1);

  // these are debugging changes to sync with old code
#ifdef MATCH_OLDCODE
  FluxBox tempEdgeVel(slopesBox,1);
  tempEdgeVel.setVal(0.0);

  FArrayBox tempCellVel(slopesBox,SpaceDim);
  tempCellVel.setVal(0.0);


  CellToEdge(a_cellVel, tempEdgeVel);
  EdgeToCell(tempEdgeVel, tempCellVel);
  tempEdgeVel.clear(); // done with this, so reclaim memory
  EdgeToCell(a_advectionVel, tempCellVel);
#endif

  FArrayBox delS(slopesBox,1);
  FArrayBox sHat(slopesBox,1);
  FArrayBox sTilde(a_state.box(),1);

  for (int comp=a_srcComps.begin(); comp<=a_srcComps.end(); comp++)
  {
    int destComp = comp+offset;

#ifdef SET_BOGUS_VALUES
    delS.setVal(BOGUS_VALUE);
    sHat.setVal(BOGUS_VALUE);
    sTilde.setVal(BOGUS_VALUE);
#endif

    // compute van leer limited slopes in the normal direction
    // for now, always limit slopes, although might want to make
    // this a parameter
    int limitSlopes = 1;
    FORT_SLOPES(CHF_FRA1(delS,0),
                CHF_CONST_FRA1(a_state,comp),
                CHF_BOX(slopesBox),
                CHF_CONST_INT(a_dir),
                CHF_CONST_INT(limitSlopes));

    // this is a way to incorporate the minion correction --
    // stateTilde = state + (dt/2)*source
    sTilde.copy(a_source,comp,0,1);
    Real sourceFactor = a_dt/2.0;
    sTilde *= sourceFactor;
    sTilde.plus(a_state, comp,0,1);
    sHat.copy(sTilde,slopesBox);

    // now loop over directions, adding transverse components
    for (int localDir=0; localDir < SpaceDim; localDir++)
    {
      if (localDir != a_dir)
      {
        // add simple transverse components
        FORT_TRANSVERSE(CHF_FRA1(sHat,0),
                        CHF_CONST_FRA1(sTilde,0),
#ifdef MATCH_OLDCODE
                        CHF_CONST_FRA1(tempCellVel, localDir),
#else
                        CHF_CONST_FRA1(a_cellVel,localDir),
#endif
                        CHF_BOX(slopesBox),
                        CHF_CONST_REAL(a_dt),
                        CHF_CONST_REAL(a_dx),
                        CHF_CONST_INT(localDir));
                        //CHF_FRA1(temp,0));  // not used in function

      }
      else if (SpaceDim == 3)
      {
        // only add cross derivative transverse piece if we're in 3D
        // note that we need both components of velocity for this one
        FORT_TRANSVERSECROSS(CHF_FRA1(sHat,0),
                             CHF_CONST_FRA1(sTilde,0),
                             CHF_CONST_FRA(a_cellVel),
                             CHF_BOX(slopesBox),
                             CHF_CONST_REAL(a_dt),
                             CHF_CONST_REAL(a_dx),
                             CHF_CONST_INT(localDir));
      }
    } // end loop over directions

    // now compute left and right states and resolve the Reimann
    // problem to get single set of edge-centered values
    FORT_PREDICT(CHF_FRA1(a_stateHalf,destComp),
                 CHF_CONST_FRA1(sHat,0),
                 CHF_CONST_FRA1(delS,0),
                 CHF_CONST_FRA1(a_cellVel,a_dir),
                 CHF_CONST_FRA1(a_advectionVel[a_dir],0),
                 CHF_BOX(edgeBox),
                 CHF_CONST_REAL(a_dt),
                 CHF_CONST_REAL(a_dx),
                 CHF_CONST_INT(a_dir));
  } // end loop over components

#endif


}
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;
    }
}
Beispiel #17
0
void
EBCoarseAverage::averageFAB(EBCellFAB&       a_coar,
                            const EBCellFAB& a_fine,
                            const DataIndex& a_datInd,
                            const Interval&  a_variables) const
{
  CH_TIME("EBCoarseAverage::averageFAB(EBCellFAB)");
  CH_assert(isDefined());
  //do all cells as if they were regular
  BaseFab<Real>& coarRegFAB =  a_coar.getSingleValuedFAB();
  const BaseFab<Real>& fineRegFAB = a_fine.getSingleValuedFAB();
  Box refbox(IntVect::Zero, (m_refRat-1)*IntVect::Unit);

  const Box& coarBox = m_eblgCoFi.getDBL().get(a_datInd);

#ifndef NDEBUG
  Box fineBox = refine(coarBox, m_refRat);
  CH_assert(coarRegFAB.box().contains(coarBox));
  CH_assert(fineRegFAB.box().contains(fineBox));
#endif

  for (int ivar = a_variables.begin();
      ivar <= a_variables.end(); ivar++)
    {
      FORT_EBAVERAGE(CHF_FRA1(coarRegFAB,ivar),
                     CHF_CONST_FRA1(fineRegFAB,ivar),
                     CHF_BOX(coarBox),
                     CHF_CONST_INT(m_refRat),
                     CHF_BOX(refbox));
    }

  //overwrite irregular cells

  //recall that datInd is from the fine layout.
  const EBISBox& ebisBoxCoar = m_eblgCoFi.getEBISL()[a_datInd];
  const EBISBox& ebisBoxFine = m_eblgFine.getEBISL()[a_datInd];
  IntVectSet coarIrregIVS = ebisBoxCoar.getIrregIVS(coarBox);

  //fine cell volume is normalized to one.
  //compute coarse volume
  Real dxCoar = Real(m_refRat);
  Real cellVolCoar = 1.0;
  for (int idir = 0; idir < SpaceDim; idir++)
    cellVolCoar *= dxCoar;

  for (VoFIterator vofitCoar(coarIrregIVS, ebisBoxCoar.getEBGraph());
      vofitCoar.ok(); ++vofitCoar)
    {
      const VolIndex& coarVoF = vofitCoar();
      Vector<VolIndex> fineVoFs =
        m_eblgCoFi.getEBISL().refine(coarVoF, m_refRat, a_datInd);

      Real volCoar = cellVolCoar*ebisBoxCoar.volFrac(coarVoF);
      for (int ivar = a_variables.begin();
          ivar <= a_variables.end(); ivar++)
        {
          Real dataVal = 0.0;
          if (volCoar > 0.)
            {
              for (int ifine = 0; ifine < fineVoFs.size(); ifine++)
                {
                  const VolIndex& fineVoF = fineVoFs[ifine];
                  //fine cell volume is normalized to one...
                  Real volFine  = ebisBoxFine.volFrac(fineVoF);
                  Real fineVal =  a_fine(fineVoF, ivar);
                  if (volFine > 0.)
                    {
                      dataVal += fineVal*volFine;
                    }
                }
              dataVal /= volCoar;
            }
          else
            {
              //if there is no real volume, just take the ave
              //of fine values
              for (int ifine = 0; ifine < fineVoFs.size(); ifine++)
                {
                  const VolIndex& fineVoF = fineVoFs[ifine];
                  Real fineVal =  a_fine(fineVoF, ivar);
                  dataVal += fineVal;
                }
              if (fineVoFs.size() > 0)
                {
                  dataVal /= Real(fineVoFs.size());
                }
            }
          a_coar(coarVoF, ivar) = dataVal;
        }
    }
}
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;
        }
    }
}
// ---------------------------------------------------------------
// tag cells for regridding
void
AMRNavierStokes::tagCells(IntVectSet & a_tags)
{
  if (s_verbosity >= 3)
    {
      pout () << "AMRNavierStokes::tagCells " << m_level << endl;
    }

  IntVectSet local_tags;

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

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

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

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

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

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

  a_tags = local_tags;
}
Beispiel #20
0
void
EBCoarseAverage::averageFAB(EBFaceFAB&       a_coar,
                            const EBFaceFAB& a_fine,
                            const DataIndex& a_datInd,
                            const Interval&  a_variables,
                            const int&       a_dir) const
{
  CH_TIME("EBCoarseAverage::averageFAB(EBFaceFAB)");
  CH_assert(isDefined());

  //do all cells as if they were regular
  BaseFab<Real>& coarRegFAB =  a_coar.getSingleValuedFAB();
  const BaseFab<Real>& fineRegFAB = a_fine.getSingleValuedFAB();
  Box refbox(IntVect::Zero,
             (m_refRat-1)*IntVect::Unit);
  refbox.surroundingNodes(a_dir);
  const Box& coarDBLBox = m_eblgCoFi.getDBL().get(a_datInd);
  Box coarFaceBox = coarDBLBox;
  coarFaceBox.surroundingNodes(a_dir);

#ifndef NDEBUG
  Box fineBox = refine(coarFaceBox, m_refRat);
  CH_assert(coarRegFAB.box().contains(coarFaceBox));
  CH_assert(fineRegFAB.box().contains(fineBox));
#endif

  for (int ivar = a_variables.begin();
      ivar <= a_variables.end(); ivar++)
    {
      FORT_EBAVERAGEFACE(CHF_FRA1(coarRegFAB,ivar),
                         CHF_CONST_FRA1(fineRegFAB,ivar),
                         CHF_BOX(coarFaceBox),
                         CHF_CONST_INT(m_refRat),
                         CHF_BOX(refbox),
                         CHF_CONST_INT(a_dir));
    }

  //overwrite irregular cells

  //recall that datInd is from the fine layout.
  const EBISBox& ebisBoxCoar = m_eblgCoFi.getEBISL()[a_datInd];
  const EBISBox& ebisBoxFine = m_eblgFine.getEBISL()[a_datInd];
  IntVectSet coarIrregIVS = ebisBoxCoar.getIrregIVS(coarDBLBox);

  //fine face area is normalized to one.
  //compute coarse volume
  Real dxCoar = Real(m_refRat);
  Real faceAreaCoar = 1.0;
  for (int idir = 0; idir < (SpaceDim - 1); idir++)
    faceAreaCoar *= dxCoar;

  for (FaceIterator faceitCoar(coarIrregIVS, ebisBoxCoar.getEBGraph(),a_dir,
                              FaceStop::SurroundingWithBoundary);
      faceitCoar.ok(); ++faceitCoar)
    {
      const FaceIndex& coarFace = faceitCoar();
      Vector<FaceIndex> fineFaces = m_eblgCoFi.getEBISL().refine(coarFace,m_refRat,a_datInd);

      Real areaCoar = faceAreaCoar*ebisBoxCoar.areaFrac(coarFace);
      for (int ivar = a_variables.begin();
          ivar <= a_variables.end(); ivar++)
        {
          Real dataVal = 0.0;
          if (areaCoar > 0.)
            {
              for (int ifine = 0; ifine < fineFaces.size(); ifine++)
                {
                  const FaceIndex& fineFace = fineFaces[ifine];
                  //fine face area is normalized to one...
                  Real areaFine  = ebisBoxFine.areaFrac(fineFace);
                  Real fineVal =  a_fine(fineFace, ivar);
                  if (areaFine > 0.)
                    {
                      dataVal += fineVal*areaFine;
                    }
                }
              dataVal /= areaCoar;
            }
          else
            {
              //if there is no real area, just take the ave
              //of fine values
              for (int ifine = 0; ifine < fineFaces.size(); ifine++)
                {
                  const FaceIndex& fineFace = fineFaces[ifine];
                  Real fineVal =  a_fine(fineFace, ivar);
                  dataVal += fineVal;
                }
              if (fineFaces.size() > 0)
                {
                  dataVal /= Real(fineFaces.size());
                }
            }

          a_coar(coarFace, ivar) = dataVal;
        }
    }
}
Beispiel #21
0
void
EBCoarsen::coarsenFAB(EBCellFAB&       a_coar,
                      const EBCellFAB& a_fine,
                      const DataIndex& a_datInd,
                      const Interval&  a_variables)
{
  CH_assert(isDefined());
  //do all cells as if they were regular
  BaseFab<Real>& coarRegFAB =  a_coar.getSingleValuedFAB();
  const BaseFab<Real>& fineRegFAB = a_fine.getSingleValuedFAB();

  //this is how much we need to grow a coarse box to get a fine box that
  // only has the fine iv's that are neighbors of the coarse iv
  const int fac = 1 - m_refRat/2;//NOTE: fac = 0 for refRat==2...
  Box refbox(IntVect::Zero,
             (m_refRat-1)*IntVect::Unit);
  refbox.grow(fac);

  Box coarBox = m_coarsenedFineGrids.get(a_datInd);

  Box fineBox = refine(coarBox, m_refRat);
  CH_assert(coarRegFAB.box().contains(coarBox));
  CH_assert(fineRegFAB.box().contains(fineBox));

  for (int ivar = a_variables.begin();
      ivar <= a_variables.end(); ivar++)
    {
      BaseFab<Real> laplFine(fineBox, 1);
      laplFine.setVal(0.);
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          Box loBox, hiBox, centerBox;
          int hasLo, hasHi;
          EBArith::loHiCenter(loBox, hasLo,
                              hiBox, hasHi,
                              centerBox, m_domainFine,
                              fineBox, idir, &((*m_cfivsPtr)[a_datInd]));

          FORT_H2LAPL1DADDITIVE(CHF_FRA1(laplFine, 0),
                                CHF_FRA1(fineRegFAB, ivar),
                                CHF_CONST_INT(idir),
                                CHF_BOX(loBox),
                                CHF_CONST_INT(hasLo),
                                CHF_BOX(hiBox),
                                CHF_CONST_INT(hasHi),
                                CHF_BOX(centerBox));
        }

      FORT_EBCOARSEN(CHF_FRA1(coarRegFAB,ivar),
                     CHF_CONST_FRA1(fineRegFAB,ivar),
                     CHF_CONST_FRA1(laplFine, 0),
                     CHF_BOX(coarBox),
                     CHF_CONST_INT(m_refRat),
                     CHF_BOX(refbox));
    }

  //overwrite irregular vofs and coarse vofs next to the cfivs if refRat<4,
  //  for these vofs we coarsen based on
  //  taylor expansions from fine vofs to the coarse cell center
  coarsenIrreg(a_coar,a_fine,a_datInd,a_variables);
}
Beispiel #22
0
void
EBMGInterp::pwlInterpFAB(EBCellFAB&       a_refCoar,
                         const Box&       a_coarBox,
                         const EBCellFAB& a_coar,
                         const DataIndex& a_datInd,
                         const Interval&  a_variables) const
{
  CH_TIMERS("EBMGInterp::pwlinterpfab");
  CH_TIMER("regular_interp", t1);
  CH_TIMER("irregular_interp", t2);
  CH_assert(isDefined());


  //first interpolate piecewise constant.
  pwcInterpFAB(a_refCoar,
               a_coarBox,
               a_coar,
               a_datInd,
               a_variables);

  //then add in slope*distance.
  const Box& coarBox = a_coarBox;

  for (int ivar = a_variables.begin();  ivar <= a_variables.end(); ivar++)
    {
      //save stuff at irreg cells because fortran result will be garbage
      //and this is an incremental process
      m_linearEBStencil[a_datInd]->cache(a_refCoar, ivar);

      //do all cells as if they were regular
      Box refBox(IntVect::Zero, IntVect::Zero);
      refBox.refine(m_refRat);

      const BaseFab<Real>& coarRegFAB =    a_coar.getSingleValuedFAB();
      BaseFab<Real>& refCoarRegFAB    = a_refCoar.getSingleValuedFAB();

      CH_START(t1);

      Real dxf = 1.0/m_coarDomain.size(0);
      Real dxc = 2.0*dxf;

      //do every cell as regular
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          FORT_PROLONGADDSLOPE(CHF_FRA1(refCoarRegFAB,ivar),
                               CHF_CONST_FRA1(coarRegFAB,ivar),
                               CHF_BOX(coarBox),
                               CHF_BOX(refBox),
                               CHF_INT(idir),
                               CHF_REAL(dxf),
                               CHF_REAL(dxc),
                               CHF_CONST_INT(m_refRat));
        }
      CH_STOP(t1);

      //replace garbage fortran put in with original values (at irregular cells)
      m_linearEBStencil[a_datInd]->uncache(a_refCoar, ivar);

      CH_START(t2);
      //do what fortran should have done at irregular cells.
      m_linearEBStencil[a_datInd]->apply(a_refCoar, a_coar, true, ivar);
      CH_STOP(t2);
    }
}
// ---------------------------------------------------------
void
AMRNavierStokes::computeVorticity(LevelData<FArrayBox>& a_vorticity) const
{
  // this breaks the "const"-ness of the function,
  // but is necessary to ensure that boundary
  // conditions are properly set.
  LevelData<FArrayBox>& vel =
    *(const_cast<LevelData<FArrayBox>*>(m_vel_new_ptr));

  const DisjointBoxLayout& grids = vel.getBoxes();

  if (m_level > 0)
    {
      // do quadratic C/F BC's
      // for now, assume that BC's are with new velocity
      // (may need to be changed for fine-level regridding)
      LevelData<FArrayBox>& crseVel = crseNSPtr()->newVel();
      const DisjointBoxLayout& crseGrids = crseVel.getBoxes();
      int nRefCrse = crseNSPtr()->refRatio();

      QuadCFInterp interpolator(grids, &crseGrids, m_dx, nRefCrse,
                                SpaceDim, m_problem_domain);

      interpolator.coarseFineInterp(vel, crseVel);
    }

  Interval velComps(0,SpaceDim-1);
  vel.exchange(velComps);

  DataIterator dit = vel.dataIterator();

  // at the moment, do extrap at physical boundaries
  // (same effect as one-sided differencing)
  BCHolder vortVelBC = m_physBCPtr->extrapFuncBC(1);

  for (dit.reset(); dit.ok(); ++dit)
    {
      // apply physical BC's
      vortVelBC(vel[dit], grids[dit],
                m_problem_domain, m_dx,
                true); // homogeneous
      if (SpaceDim == 3)
        {
          for (int dir=0; dir<SpaceDim; dir++)
            {
              // and then compute vorticity
              FORT_COMPUTEVORT(CHF_FRA1(a_vorticity[dit],dir),
                               CHF_CONST_FRA(vel[dit]),
                               CHF_BOX(grids[dit]),
                               CHF_CONST_REAL(m_dx),
                               CHF_CONST_INT(dir));
            }
        }
      else if (SpaceDim == 2)
        {
          int dir = 2;
          FORT_COMPUTEVORT(CHF_FRA1(a_vorticity[dit],0),
                           CHF_CONST_FRA(vel[dit]),
                           CHF_BOX(grids[dit]),
                           CHF_CONST_REAL(m_dx),
                           CHF_CONST_INT(dir));
        } // end dimensionality choice
    } // end loop over grids
}
Beispiel #24
0
void
EBPoissonOp::
applyDomainFlux(Box * a_loBox,
                Box * a_hiBox,
                int * a_hasLo,
                int * a_hasHi,
                Box & a_dblBox,
                int a_nComps,
                BaseFab<Real> & a_phiFAB,
                bool a_homogeneousPhysBC,
                const DataIndex& a_dit,
                const Real& a_beta)
{
  CH_TIME("EBPoissonOp::applyDomainFlux");
  CH_assert(m_domainBC != NULL);

  for (int idir=0; idir<SpaceDim; idir++)
    {

      EBArith::loHi(a_loBox[idir], a_hasLo[idir],
                             a_hiBox[idir], a_hasHi[idir],
                             m_eblg.getDomain(), a_dblBox, idir);

      for (int comp = 0; comp<a_nComps; comp++)
        {

          if (a_hasLo[idir] == 1)
            {
              Box lbox=a_loBox[idir];
              lbox.shift(idir,-1);
              BaseFab<Real> loFaceFlux(a_loBox[idir],a_nComps);
              int side = -1;

              m_domainBC->getFaceFlux(loFaceFlux,a_phiFAB,m_origin,m_dx,idir,Side::Lo,a_dit,m_time,a_homogeneousPhysBC);

              FORT_REGAPPLYDOMAINFLUX_INPLACE(CHF_FRA1(a_phiFAB,comp),
                                              CHF_CONST_FRA1(loFaceFlux,comp),
                                              CHF_CONST_REAL(m_dx[idir]),
                                              CHF_CONST_INT(side),
                                              CHF_CONST_INT(idir),
                                              CHF_BOX(lbox));
            }

          if (a_hasHi[idir] == 1)
            {
              Box hbox=a_hiBox[idir];
              hbox.shift(idir,1);
              BaseFab<Real> hiFaceFlux(a_hiBox[idir],a_nComps);
              int side = 1;

              m_domainBC->getFaceFlux(hiFaceFlux,a_phiFAB,m_origin,m_dx,idir,Side::Hi,a_dit,m_time,a_homogeneousPhysBC);

              FORT_REGAPPLYDOMAINFLUX_INPLACE(CHF_FRA1(a_phiFAB,comp),
                                              CHF_CONST_FRA1(hiFaceFlux,comp),
                                              CHF_CONST_REAL(m_dx[idir]),
                                              CHF_CONST_INT(side),
                                              CHF_CONST_INT(idir),
                                              CHF_BOX(hbox));
            }

        }
    }
}
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;
            }
        }
    }
}
Beispiel #26
0
/// Set up initial conditions
void RSIBC::initializeBdry(LevelData<FArrayBox>& a_B)
{
    const Real tmpVal  =  0.0;
    const Real tmpVal2 = 1e10;
    for (DataIterator dit = a_B.dataIterator(); dit.ok(); ++dit)
    {
        // Storage for current grid
        FArrayBox& B = a_B[dit()];

        // Box of current grid
        Box bBox = B.box();
        bBox &= m_domain;

        // Set up initial condition in this grid
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_VX),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_VZ),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_SXY),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_SYZ),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_V),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_DX),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_DZ),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_DT),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_RT),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal2));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_SYY),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,RX_PSI),
            CHF_BOX(bBox),
            CHF_CONST_REAL(m_psi));
    }
}
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;
            }
        }
    }
}