Beispiel #1
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 #2
0
// Compute the primitive variables from the conserved variables
void PolytropicPhysics::consToPrim(FArrayBox&       a_W,
                                   const FArrayBox& a_U,
                                   const Box&       a_box)
{
    CH_assert(isDefined());
    CH_assert(a_U.box().contains(a_box));
    CH_assert(a_W.box().contains(a_box));

    FORT_CONSTOPRIMF(CHF_FRA(a_W),
                     CHF_CONST_FRA(a_U),
                     CHF_BOX(a_box));
}
Beispiel #3
0
void
CellBilinear::interp (const FArrayBox&  crse,
                      int               crse_comp,
                      FArrayBox&        fine,
                      int               fine_comp,
                      int               ncomp,
                      const Box&        fine_region,
                      const IntVect &   ratio,
                      const Geometry& /*crse_geom*/,
                      const Geometry& /*fine_geom*/,
                      Array<BCRec>&   /*bcr*/,
                      int               actual_comp,
                      int               actual_state)
{
    BL_PROFILE("CellBilinear::interp()");
#if (BL_SPACEDIM == 3)
    BoxLib::Error("interp: not implemented");
#endif
    //
    // Set up to call FORTRAN.
    //
    const int* clo = crse.box().loVect();
    const int* chi = crse.box().hiVect();
    const int* flo = fine.loVect();
    const int* fhi = fine.hiVect();
    const int* lo  = fine_region.loVect();
    const int* hi  = fine_region.hiVect();
    int num_slope  = D_TERM(2,*2,*2)-1;
    int len0       = crse.box().length(0);
    int slp_len    = num_slope*len0;

    Array<Real> slope(slp_len);

    int strp_len = len0*ratio[0];

    Array<Real> strip(strp_len);

    int strip_lo = ratio[0] * clo[0];
    int strip_hi = ratio[0] * chi[0];

    const Real* cdat  = crse.dataPtr(crse_comp);
    Real*       fdat  = fine.dataPtr(fine_comp);
    const int* ratioV = ratio.getVect();

    FORT_CBINTERP (cdat,ARLIM(clo),ARLIM(chi),ARLIM(clo),ARLIM(chi),
                   fdat,ARLIM(flo),ARLIM(fhi),ARLIM(lo),ARLIM(hi),
                   D_DECL(&ratioV[0],&ratioV[1],&ratioV[2]),&ncomp,
                   slope.dataPtr(),&num_slope,strip.dataPtr(),&strip_lo,&strip_hi,
                   &actual_comp,&actual_state);
}
Beispiel #4
0
void VCAMRPoissonOp2::getFlux(FArrayBox&       a_flux,
                             const FArrayBox& a_data,
                             const FluxBox&   a_bCoef,
                             const Box&       a_facebox,
                             int              a_dir,
                             int              a_ref) const
{
  CH_TIME("VCAMRPoissonOp2::getFlux");

  CH_assert(a_dir >= 0);
  CH_assert(a_dir <  SpaceDim);
  CH_assert(!a_data.box().isEmpty());
  CH_assert(!a_facebox.isEmpty());

  // probably the simplest way to test centering
  // a_box needs to be face-centered in the a_dir
  Box faceTestBox(IntVect::Zero, IntVect::Unit);
  faceTestBox.surroundingNodes(a_dir);
  CH_assert(a_facebox.type() == faceTestBox.type());

  const FArrayBox& bCoefDir = a_bCoef[a_dir];

  // reality check for bCoef
  CH_assert(bCoefDir.box().contains(a_facebox));

  a_flux.resize(a_facebox, a_data.nComp());
  BoxIterator bit(a_facebox);

  Real scale = m_beta * a_ref / m_dx;

  for ( bit.begin(); bit.ok(); bit.next())
    {
      IntVect iv = bit();
      IntVect shiftiv = BASISV(a_dir);
      IntVect ivlo = iv - shiftiv;
      IntVect ivhi = iv;

      CH_assert(a_data.box().contains(ivlo));
      CH_assert(a_data.box().contains(ivhi));

      for (int ivar = 0; ivar < a_data.nComp(); ivar++)
        {
          Real phihi = a_data(ivhi,ivar);
          Real philo = a_data(ivlo,ivar);
          Real gradphi = (phihi - philo ) * scale;

          a_flux(iv,ivar) = -bCoefDir(iv, ivar) * gradphi;
        }
    }
}
Beispiel #5
0
void LinElastPhysics::consToPrim(FArrayBox&       a_W,
    const FArrayBox& a_U,
    const Box&       a_box)
{
    //JK Our primitives are our conserved variables
    //JK pout() << "LinElastPhysics::consToPrim" << endl;
    CH_assert(isDefined());
    CH_assert(a_U.box().contains(a_box));
    CH_assert(a_W.box().contains(a_box));

    FORT_COPYF(CHF_FRA(a_W),
        CHF_CONST_FRA(a_U),
        CHF_BOX(a_box));
}
Beispiel #6
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 #7
0
void NewPoissonOp::
levelGSRB(FArrayBox&       a_phi,
          const FArrayBox& a_rhs)
{
  CH_assert(a_phi.nComp() == a_rhs.nComp());

  Real dx = m_dx[0];

  // do first red, then black passes
  for (int whichPass =0; whichPass <= 1; whichPass++)
    {

      m_bc(a_phi,  m_domain.domainBox(), m_domain,  dx, true);

      // now step through grids...
      //fill in intersection of ghostcells and a_phi's boxes
      // dfm -- for a 5 point stencil, this should not be necessary
      //a_phi.exchange(a_phi.interval(), m_exchangeCopier);

      // invoke physical BC's where necessary
      //m_bc(a_phi,  m_domain,  dx, true); //new approach to help with checker
#ifndef NDEBUG

#endif

      FORT_GSRBLAPLACIAN(CHF_FRA(a_phi),
                         CHF_CONST_FRA(a_rhs),
                         CHF_BOX(a_rhs.box()),
                         CHF_CONST_REAL(dx),
                         CHF_CONST_INT(whichPass));

    } // end loop through red-black
}
Beispiel #8
0
// Set boundary slopes:
//   The boundary slopes in a_dW are already set to one sided difference
//   approximations.  If this function doesn't change them they will be
//   used for the slopes at the boundaries.
void ExplosionIBC::setBdrySlopes(FArrayBox&       a_dW,
                                 const FArrayBox& a_W,
                                 const int&       a_dir,
                                 const Real&      a_time)
{
  CH_assert(m_isFortranCommonSet == true);
  CH_assert(m_isDefined == true);

  // In periodic case, this doesn't do anything
  if (!m_domain.isPeriodic(a_dir))
  {
    Box loBox,hiBox,centerBox,domain;
    int hasLo,hasHi;
    Box slopeBox = a_dW.box();
    slopeBox.grow(a_dir,1);

    // Generate the domain boundary boxes, loBox and hiBox, if there are
    // domain boundarys there
    loHiCenter(loBox,hasLo,hiBox,hasHi,centerBox,domain,
               slopeBox,m_domain,a_dir);

    // Set the boundary slopes if necessary
    if ((hasLo != 0) || (hasHi != 0))
    {
      FORT_SLOPEBCSF(CHF_FRA(a_dW),
                     CHF_CONST_FRA(a_W),
                     CHF_CONST_INT(a_dir),
                     CHF_BOX(loBox),
                     CHF_CONST_INT(hasLo),
                     CHF_BOX(hiBox),
                     CHF_CONST_INT(hasHi));
    }
  }
}
Beispiel #9
0
void PatchGodunov::updateState(FArrayBox&       a_U,
                               FluxBox&         a_F,
                               Real&            a_maxWaveSpeed,
                               const FArrayBox& a_S,
                               const Real&      a_dt,
                               const Box&       a_box)
{
  CH_assert(isDefined());
  CH_assert(a_box == m_currentBox);

  int numPrim = m_gdnvPhysics->numPrimitives();
  int numFlux = m_gdnvPhysics->numFluxes();

  FluxBox whalf(a_box,numPrim);
  whalf.setVal(0.0);

  a_F.resize(a_box,numFlux);
  a_F.setVal(0.0);

  computeWHalf(whalf, a_U, a_S, a_dt, a_box);

  FArrayBox dU(a_U.box(),a_U.nComp());
  computeUpdate(dU, a_F, a_U, whalf, a_dt, a_box);

  a_U += dU;

  // Get and return the maximum wave speed on this patch/grid
  a_maxWaveSpeed = m_gdnvPhysics->getMaxWaveSpeed(a_U, m_currentBox);
}
Beispiel #10
0
// Set boundary fluxes
void RampIBC::primBC(FArrayBox&            a_WGdnv,
                     const FArrayBox&      a_Wextrap,
                     const FArrayBox&      a_W,
                     const int&            a_dir,
                     const Side::LoHiSide& a_side,
                     const Real&           a_time)
{
  CH_assert(m_isFortranCommonSet == true);
  CH_assert(m_isDefined == true);

  // Neither the x or y direction can be periodic
  if ((a_dir == 0 || a_dir == 1) && m_domain.isPeriodic(a_dir))
    {
      MayDay::Error("RampIBC::primBC: Neither the x or y boundaries can be periodic");
    }

  Box boundaryBox;
  getBoundaryFaces(boundaryBox, a_WGdnv.box(), a_dir, a_side);

  if (! boundaryBox.isEmpty() )
    {
      // Set the boundary fluxes
      int lohisign = sign(a_side);
      FORT_RAMPBCF(CHF_FRA(a_WGdnv),
                   CHF_CONST_FRA(a_Wextrap),
                   CHF_CONST_FRA(a_W),
                   CHF_CONST_REAL(a_time),
                   CHF_CONST_INT(lohisign),
                   CHF_CONST_REAL(m_dx),
                   CHF_CONST_INT(a_dir),
                   CHF_BOX(boundaryBox));
    }
}
Beispiel #11
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 #12
0
/**
  Given input left and right states in a direction, a_dir, compute a
  Riemann problem and generate fluxes at the faces within a_box.
  */
void LinElastPhysics::riemann(/// face-centered solution to Riemann problem
    FArrayBox&       a_WStar,
    /// left state, on cells to left of each face
    const FArrayBox& a_WLeft,
    /// right state, on cells to right of each face
    const FArrayBox& a_WRight,
    /// state on cells, used to set boundary conditions
    const FArrayBox& a_W,
    /// current time
    const Real&      a_time,
    /// direction of faces
    const int&       a_dir,
    /// face-centered box on which to set a_WStar
    const Box&       a_box)
{
    //JK pout() << "LinElastPhysics::riemann" << endl;
    CH_assert(isDefined());

    CH_assert(a_WStar.box().contains(a_box));

    // Get the numbers of relevant variables
    int numPrim = numPrimitives();

    CH_assert(a_WStar .nComp() == numPrim);
    CH_assert(a_WLeft .nComp() == numPrim);
    CH_assert(a_WRight.nComp() == numPrim);

    // Cast away "const" inputs so their boxes can be shifted left or right
    // 1/2 cell and then back again (no net change is made!)
    FArrayBox& shiftWLeft  = (FArrayBox&)a_WLeft;
    FArrayBox& shiftWRight = (FArrayBox&)a_WRight;

    // Solution to the Riemann problem

    // Shift the left and right primitive variable boxes 1/2 cell so they are
    // face centered
    shiftWLeft .shiftHalf(a_dir, 1);
    shiftWRight.shiftHalf(a_dir,-1);

    CH_assert(shiftWLeft .box().contains(a_box));
    CH_assert(shiftWRight.box().contains(a_box));

    // Riemann solver computes Wgdnv all edges that are not on the physical
    // boundary.
    FORT_RIEMANNF(CHF_FRA(a_WStar),
        CHF_CONST_FRA(shiftWLeft),
        CHF_CONST_FRA(shiftWRight),
        CHF_CONST_INT(a_dir),
        CHF_BOX(a_box));

    // Call boundary Riemann solver (note: periodic BC's are handled there).
    m_bc->primBC(a_WStar,shiftWLeft ,a_W,a_dir,Side::Hi,a_time);
    m_bc->primBC(a_WStar,shiftWRight,a_W,a_dir,Side::Lo,a_time);

    // Shift the left and right primitive variable boxes back to their original
    // position.
    shiftWLeft .shiftHalf(a_dir,-1);
    shiftWRight.shiftHalf(a_dir, 1);
}
Beispiel #13
0
void
ABec4::bCoefficients (const FArrayBox& _b,
		      int              gridno)
{
    BL_ASSERT(_b.box().contains((bcoefs[0])->boxArray()[gridno]));
    invalidate_b_to_level(0);
    (*bcoefs[0])[gridno].copy(_b,0,0,bcoefs[0]->nComp());
}
Beispiel #14
0
void GodunovPhysics::artVisc(FArrayBox&       a_F,
                             const FArrayBox& a_U,
                             const Real&      a_artificialViscosity,
                             const Real&      a_currentTime,
                             const int&       a_dir,
                             const Box&       a_box)
{
  CH_assert(a_U.box().contains(a_box)); // a_box:  valid cells

  // Take the cell-centered box, a_box, and derive a face-centered box in
  // direction a_dir.
  // faceBox consists of all a_dir-faces of valid cells.
  Box faceBox = a_box;
  faceBox &= m_domain;
  faceBox.surroundingNodes(a_dir);

  CH_assert(a_F.box().contains(faceBox));

  // Derive a cell-centered box where the primitive variables are needed.
  // wBox consists of valid cells grown by 1, intersected with m_domain.
  Box wBox = faceBox;
  wBox.enclosedCells(a_dir);
  wBox.grow(1);
  wBox &= m_domain;

  // Get the primitive variables from the conserved variables (as needed).
  int numPrim = numPrimitives();
  FArrayBox W(wBox, numPrim);
  consToPrim(W, a_U, wBox); // W on valid cells + 1 layer of ghosts

  // Compute the divergence of the velocity
  FArrayBox divu(faceBox, 1);
  Interval velInt = velocityInterval();
  m_util.divVel(divu, W, velInt, a_dir, faceBox);
  // If using fourth-order artificial viscosity, apply the nonlinear operator to
  // divu.
  if (m_useFourthOrderArtificialViscosity)
    m_util.divVelHO(divu, W, a_dir, faceBox, this);

  // Change fluxes due to artificial viscosity on the interior faces
  m_util.artificialViscosity(a_F, a_U,
                             divu, a_artificialViscosity, a_dir, faceBox);

  // Change fluxes due to artificial viscosity on the boundary faces
  m_bc->artViscBC(a_F, a_U, divu, a_dir, a_currentTime);
}
void
LevelFluxRegisterEdge::incrementFine(
                                     FArrayBox& a_fineFlux,
                                     Real a_scale,
                                     const DataIndex& a_fineDataIndex,
                                     const Interval& a_srcInterval,
                                     const Interval& a_dstInterval)
{
  CH_assert(isDefined());
  CH_assert(!a_fineFlux.box().isEmpty());
  CH_assert(a_srcInterval.size() == a_dstInterval.size());
  CH_assert(a_srcInterval.begin() >= 0);
  CH_assert(a_srcInterval.end() < a_fineFlux.nComp());
  CH_assert(a_dstInterval.begin() >= 0);
  CH_assert(a_dstInterval.end() < m_nComp);

  int edgeDir = -1;
  for (int sideDir = 0; sideDir<SpaceDim; sideDir++)
    {
      if (a_fineFlux.box().type(sideDir) == IndexType::CELL)
        {
          edgeDir = sideDir;
        }
    }
  CH_assert(edgeDir >= 0);
  CH_assert(edgeDir < SpaceDim);

  for (int faceDir=0; faceDir<SpaceDim; faceDir++)
    {
      if (faceDir != edgeDir)
        {

          SideIterator sit;
          for (sit.begin(); sit.ok(); ++sit)
            {
              incrementFine(a_fineFlux,
                            a_scale,
                            a_fineDataIndex,
                            a_srcInterval,
                            a_dstInterval,
                            faceDir,
                            sit());
            }
        }
    }
}
Beispiel #16
0
void NewPoissonOp::
createCoarsened(FArrayBox&                  a_lhs,
                const FArrayBox&            a_rhs,
                const int &                 a_refRat)
{
  int ncomp = a_rhs.nComp();
  //fill ebislayout
  Box coarsenedBox = coarsen(a_rhs.box(), a_refRat);
  a_lhs.define(coarsenedBox, ncomp);
}
void
LevelFluxRegisterEdge::incrementCoarse(FArrayBox& a_coarseFlux,
                                       Real a_scale,
                                       const DataIndex& a_coarseDataIndex,
                                       const Interval& a_srcInterval,
                                       const Interval& a_dstInterval)
{
  CH_assert(isDefined());
  CH_assert(!a_coarseFlux.box().isEmpty());

  CH_assert(a_srcInterval.size() == a_dstInterval.size());
  CH_assert(a_srcInterval.begin() >= 0);
  CH_assert(a_srcInterval.end() < a_coarseFlux.nComp());
  CH_assert(a_dstInterval.begin() >= 0);
  CH_assert(a_dstInterval.end() < m_nComp);

  // get edge-centering of coarseFlux
  const Box& edgeBox = a_coarseFlux.box();
  int edgeDir = -1;
  for (int dir=0; dir<SpaceDim; dir++)
    {
      if (edgeBox.type(dir) == IndexType::CELL)
        {
          if (edgeDir == -1)
            {
              edgeDir = dir;
            }
          else
            {
              // already found a cell-centered direction (should only be
              // one for edge-centering)
              MayDay::Error("LevelFluxRegisterEdge::incrementCoarse -- e-field not edge-centered");
            }
        }
    } // end loop over directions
  CH_assert(edgeDir != -1);

  FArrayBox& thisCrseReg = m_regCoarse[a_coarseDataIndex][edgeDir];

  thisCrseReg.plus(a_coarseFlux, -a_scale, a_srcInterval.begin(),
                   a_dstInterval.begin(), a_srcInterval.size());

}
Beispiel #18
0
void RSIBC::updateBoundary(const FArrayBox& a_WHalf,int a_dir,const Real& a_dt,const Real& a_dx,const Real& a_time,const bool a_final)
{
    if(a_dir == 1 && bdryLo(m_domain,a_dir).contains(bdryLo(a_WHalf.box(),a_dir)))
    {
        if(a_final)
        {
            FORT_RSSETBND(
                CHF_FRA((*m_bdryData)),
                CHF_BOX(bdryLo(a_WHalf.box(),a_dir)),
                CHF_CONST_FRA((*m_bdryData)),
                CHF_CONST_FRA(a_WHalf),
                CHF_CONST_REAL(a_dt),
                CHF_CONST_REAL(a_dx),
                CHF_CONST_REAL(a_time));
        }
        // THIS MAY BE NECESSARY IN 3-D, NOT SURE!!!
        // else if(m_tmpBdryDataSet)
        // {
        //     FORT_RSSETBND(
        //         CHF_FRA((*m_tmpBdryData)),
        //         CHF_BOX(bdryLo(a_WHalf.box(),a_dir)),
        //         CHF_CONST_FRA((*m_tmpBdryData)),
        //         CHF_CONST_FRA(a_WHalf),
        //         CHF_CONST_REAL(a_dt),
        //         CHF_CONST_REAL(a_dx),
        //         CHF_CONST_REAL(a_time));
        // }
        else
        {
            // m_tmpBdryData = new FArrayBox(m_bdryData->box(), m_numBdryVars);
            FORT_RSSETBND(
                CHF_FRA((*m_tmpBdryData)),
                CHF_BOX(bdryLo(a_WHalf.box(),a_dir)),
                CHF_CONST_FRA((*m_bdryData)),
                CHF_CONST_FRA(a_WHalf),
                CHF_CONST_REAL(a_dt),
                CHF_CONST_REAL(a_dx),
                CHF_CONST_REAL(a_time));
            m_tmpBdryDataSet = true;
        }
    }
}
Beispiel #19
0
void NewPoissonOp::prolongIncrement(FArrayBox& a_phiThisLevel,
                                    const FArrayBox& a_correctCoarse)
{

  FArrayBox& phi =  a_phiThisLevel;
  const FArrayBox& coarse = a_correctCoarse;
  //FArrayBox& c = (FArrayBox&)coarse;
  Box region = a_phiThisLevel.box();
  region.grow(-1);
  Box cBox = a_correctCoarse.box();
  cBox.grow(-1);
  CH_assert(cBox == coarsen(region, 2));

  int r = 2;

  FORT_PROLONG(CHF_FRA(phi),
               CHF_CONST_FRA(coarse),
               CHF_BOX(region),
               CHF_CONST_INT(r));
}
Beispiel #20
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 #21
0
void 
CompGridVTOBC::operator()( FArrayBox&           a_state,
			   const Box&           a_valid,
			   const ProblemDomain& a_domain,
			   Real                 a_dx,
			   bool                 a_homogeneous)
{
  const Box& domainBox = a_domain.domainBox();
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      if (!a_domain.isPeriodic(idir))
        {
          for (SideIterator sit; sit.ok(); ++sit)
            {
              Side::LoHiSide side = sit();              
              if (a_valid.sideEnd(side)[idir] == domainBox.sideEnd(side)[idir])
                {
                  // Dirichlet BC
                  int isign = sign(side);
                  Box toRegion = adjCellBox(a_valid, idir, side, 1);
                  // include corner cells if possible by growing toRegion in transverse direction
                  toRegion.grow(1);
                  toRegion.grow(idir, -1);
                  toRegion &= a_state.box();
                  for (BoxIterator bit(toRegion); bit.ok(); ++bit)
                    {
                      IntVect ivTo = bit();                     
                      IntVect ivClose = ivTo - isign*BASISV(idir);
                      for (int ighost=0;ighost<m_nGhosts[0];ighost++,ivTo += isign*BASISV(idir))
                        {
                          //for (int icomp = 0; icomp < a_state.nComp(); icomp++) a_state(ivTo, icomp) = 0.0;
                          IntVect ivFrom = ivClose;
                          
                          // hardwire to linear BCs for now
                          for (int icomp = 0; icomp < a_state.nComp() ; icomp++)
                            {
                              if (m_bcDiri[idir][side][icomp]) 
                                {
                                  a_state(ivTo, icomp) = (-1.0)*a_state(ivFrom, icomp);
                                }
                              else 
                                {
                                  a_state(ivTo, icomp) = (1.0)*a_state(ivFrom, icomp);
                                }
                            }   
                        }
                    } // end loop over cells
                } // if ends match
            } // end loop over sides
        } // if not periodic in this direction
    } // end loop over directions    
}
Beispiel #22
0
void NewPoissonOp::createCoarser(FArrayBox& a_coarse,
                                 const FArrayBox& a_fine,
                                 bool ghosted)
{
  Box c = a_fine.box();
  if (ghosted)
    {
      c.grow(-1);
    }
  c.coarsen(2);
  c.refine(2);
  if (ghosted) c.grow(1);
  CH_assert(c == a_fine.box());
  if (ghosted) c.grow(-1);
  c.coarsen(2);
  if (ghosted)
    {
      c.grow(1);
    }
  a_coarse.define(c, a_fine.nComp());

}
Beispiel #23
0
void
NodeBilinear::interp (const FArrayBox&  crse,
                      int               crse_comp,
                      FArrayBox&        fine,
                      int               fine_comp,
                      int               ncomp,
                      const Box&        fine_region,
                      const IntVect&    ratio,
                      const Geometry& /*crse_geom */,
                      const Geometry& /*fine_geom */,
                      Array<BCRec>&   /*bcr*/,
                      int               actual_comp,
                      int               actual_state)
{
    BL_PROFILE("NodeBilinear::interp()");
    //
    // Set up to call FORTRAN.
    //
    const int* clo = crse.box().loVect();
    const int* chi = crse.box().hiVect();
    const int* flo = fine.loVect();
    const int* fhi = fine.hiVect();
    const int* lo  = fine_region.loVect();
    const int* hi  = fine_region.hiVect();
    int num_slope  = D_TERM(2,*2,*2)-1;
    int len0       = crse.box().length(0);
    int slp_len    = num_slope*len0;

    Array<Real> strip(slp_len);

    const Real* cdat  = crse.dataPtr(crse_comp);
    Real*       fdat  = fine.dataPtr(fine_comp);
    const int* ratioV = ratio.getVect();

    FORT_NBINTERP (cdat,ARLIM(clo),ARLIM(chi),ARLIM(clo),ARLIM(chi),
                   fdat,ARLIM(flo),ARLIM(fhi),ARLIM(lo),ARLIM(hi),
                   D_DECL(&ratioV[0],&ratioV[1],&ratioV[2]),&ncomp,
                   strip.dataPtr(),&num_slope,&actual_comp,&actual_state);
}
Beispiel #24
0
// Compute a Riemann problem and generate fluxes at the faces.
void PolytropicPhysics::riemann(FArrayBox&       a_WGdnv,
                                const FArrayBox& a_WLeft,
                                const FArrayBox& a_WRight,
                                const FArrayBox& a_W,
                                const Real&      a_time,
                                const int&       a_dir,
                                const Box&       a_box)
{
    CH_assert(isDefined());

    CH_assert(a_WGdnv.box().contains(a_box));

    // Get the numbers of relevant variables
    int numPrim = numPrimitives();

    CH_assert(a_WGdnv .nComp() == numPrim);
    CH_assert(a_WLeft .nComp() == numPrim);
    CH_assert(a_WRight.nComp() == numPrim);

    // Cast away "const" inputs so their boxes can be shifted left or right
    // 1/2 cell and then back again (no net change is made!)
    FArrayBox& shiftWLeft  = (FArrayBox&)a_WLeft;
    FArrayBox& shiftWRight = (FArrayBox&)a_WRight;

    // Solution to the Riemann problem

    // Shift the left and right primitive variable boxes 1/2 cell so they are
    // face centered
    shiftWLeft .shiftHalf(a_dir, 1);
    shiftWRight.shiftHalf(a_dir,-1);

    CH_assert(shiftWLeft .box().contains(a_box));
    CH_assert(shiftWRight.box().contains(a_box));

    // Riemann solver computes Wgdnv all edges that are not on the physical
    // boundary.
    FORT_RIEMANNF(CHF_FRA(a_WGdnv),
                  CHF_CONST_FRA(shiftWLeft),
                  CHF_CONST_FRA(shiftWRight),
                  CHF_CONST_INT(a_dir),
                  CHF_BOX(a_box));

    // Call boundary Riemann solver (note: periodic BC's are handled there).
    m_bc->primBC(a_WGdnv,shiftWLeft ,a_W,a_dir,Side::Hi,a_time);
    m_bc->primBC(a_WGdnv,shiftWRight,a_W,a_dir,Side::Lo,a_time);

    // Shift the left and right primitive variable boxes back to their original
    // position.
    shiftWLeft .shiftHalf(a_dir,-1);
    shiftWRight.shiftHalf(a_dir, 1);
}
Beispiel #25
0
void LinElastPhysics::artVisc(FArrayBox&       a_F,
                             const FArrayBox& a_U,
                             const Real&      a_artificialViscosity,
                             const Real&      a_currentTime,
                             const int&       a_dir,
                             const Box&       a_box)
{
    MayDay::Error("artVisc needs to be thought through more!");
  CH_assert(a_U.box().contains(a_box));

  // Take the cell centered box, a_box, and derive a face centered box in
  // direction a_dir
  Box faceBox = a_box;
  faceBox &= m_domain;
  faceBox.surroundingNodes(a_dir);

  CH_assert(a_F.box().contains(faceBox));

  // Note: a_box is face centered in the a_dir direction and is set up for
  // updating a_F

  // Remove any boundary faces in direction a_dir from a_box
  Box noBoundaryBox = faceBox;
  noBoundaryBox.enclosedCells(a_dir);
  noBoundaryBox.grow(a_dir,1);
  noBoundaryBox &= m_domain;
  noBoundaryBox.grow(a_dir,-1);
  noBoundaryBox.surroundingNodes(a_dir);

  FORT_ARTDISP(CHF_FRA(a_F),
                CHF_CONST_FRA(a_U),
                CHF_CONST_REAL(a_artificialViscosity),
                CHF_CONST_INT(a_dir),
                CHF_BOX(noBoundaryBox));

  // Change fluxes due to artificial viscosity on the boundary faces
  // m_bc->artViscBC(a_F,a_U,divu,a_dir,a_currentTime);
}
Beispiel #26
0
bool RSIBC::tagCellsInit(FArrayBox& markFAB,const Real& threshold)
{
    // If grid spacing > R0 refine otherwise only refine the nucleation patch
    if(m_dx > m_R0)
    {
        // pout() << m_dx << "  " << m_R0 << endl;
        markFAB.setVal(1,bdryLo(m_domain.domainBox(),1,1) & markFAB.box(),0);
    }
    else
    {
        IntVect nucSm;
        IntVect nucBg;
        if(SpaceDim > 0)
        {
            nucSm.setVal(0,floor(m_x0/m_dx));
            nucBg.setVal(0, ceil(m_x0/m_dx));
        }
        if(SpaceDim > 1)
        {
            nucSm.setVal(1,0);
            nucBg.setVal(1,0);
        }
        if(SpaceDim > 2)
        {
            nucSm.setVal(2,floor(m_x0/m_dx));
            nucBg.setVal(2, ceil(m_x0/m_dx));
        }
        markFAB.setVal(1,Box(nucSm,nucBg)& markFAB.box(),0);
    }

    // pout() << m_domain << endl;
    // FORT_ALLBOUNDREFINE(
    //     CHF_FRA1(markFAB,0),
    //     CHF_CONST_REAL(threshold),
    //     CHF_BOX(markFAB.box()));
    return true;
}
Beispiel #27
0
// this preconditioner first initializes phihat to (IA)phihat = rhshat
// (diagonization of L -- A is the matrix version of L)
// then smooths with a couple of passes of levelGSRB
void NewPoissonOp::preCond(   FArrayBox& a_phi, const FArrayBox& a_rhs)
{
    // diagonal term of this operator is 4/h/h in 2D, 6/h/h in 3D,
  // so inverse of this is our initial multiplier
  Real mult = -m_dx[0]*m_dx[0]/(2.0*SpaceDim);
  Interval comps = a_phi.interval();
  CH_assert(a_phi.nComp() == a_rhs.nComp());

  a_phi.copy(a_rhs.box(), comps,
             a_rhs.box(), a_rhs,
             comps);

  a_phi *= mult;

  relax(a_phi, a_rhs, 2);
}
Beispiel #28
0
// Set boundary fluxes
void ExplosionIBC::primBC(FArrayBox&            a_WGdnv,
                          const FArrayBox&      a_Wextrap,
                          const FArrayBox&      a_W,
                          const int&            a_dir,
                          const Side::LoHiSide& a_side,
                          const Real&           a_time)
{
  CH_assert(m_isFortranCommonSet == true);
  CH_assert(m_isDefined == true);

  // In periodic case, this doesn't do anything
  if (!m_domain.isPeriodic(a_dir))
  {
    int lohisign;
    Box tmp = a_WGdnv.box();

    // Determine which side and thus shifting directions
    lohisign = sign(a_side);
    tmp.shiftHalf(a_dir,lohisign);

    // Is there a domain boundary next to this grid
    if (!m_domain.contains(tmp))
    {
      tmp &= m_domain;

      Box boundaryBox;

      // Find the strip of cells next to the domain boundary
      if (a_side == Side::Lo)
      {
        boundaryBox = bdryLo(tmp,a_dir);
      }
      else
      {
        boundaryBox = bdryHi(tmp,a_dir);
      }

      // Set the boundary fluxes
      FORT_SOLIDBCF(CHF_FRA(a_WGdnv),
                    CHF_CONST_FRA(a_Wextrap),
                    CHF_CONST_FRA(a_W),
                    CHF_CONST_INT(lohisign),
                    CHF_CONST_INT(a_dir),
                    CHF_BOX(boundaryBox));
    }
  }
}
Beispiel #29
0
// Compute increment of primitive variables.
void PolytropicPhysics::quasilinearUpdate(FArrayBox&       a_dWdx,
        const FArrayBox& a_WHalf,
        const FArrayBox& a_W,
        const Real&      a_scale,
        const int&       a_dir,
        const Box&       a_box)
{
    CH_assert(isDefined());
    CH_assert(a_dWdx.box().contains(a_box));

    FORT_GETADWDXF(CHF_FRA(a_dWdx),
                   CHF_CONST_FRA(a_WHalf),
                   CHF_CONST_FRA(a_W),
                   CHF_CONST_REAL(a_scale),
                   CHF_CONST_INT(a_dir),
                   CHF_BOX(a_box));
}
Beispiel #30
0
/**
  Compute dU = dt*dUdt, the change in the conserved variables over
  the time step. The fluxes are returned are suitable for use in refluxing.
  This has a default implementation but can be redefined as needed.
  */
void LinElastPhysics::computeUpdate(FArrayBox&       a_dU,
    FluxBox&         a_F,
    const FArrayBox& a_U,
    const FluxBox&   a_WHalf,
    const bool&      a_useArtificialViscosity,
    const Real&      a_artificialViscosity,
    const Real&      a_currentTime,
    const Real&      a_dx,
    const Real&      a_dt,
    const Box&       a_box)
{
    CH_assert(isDefined());

    a_dU.setVal(0.0);

    for (int idir = 0; idir < SpaceDim; idir++)
    {
        // Get flux from WHalf
        getFlux(a_F[idir],a_WHalf[idir],idir,a_F[idir].box());

        if (a_useArtificialViscosity)
        {
            artVisc(a_F[idir],a_U,
                a_artificialViscosity,a_currentTime,
                idir,a_box);
        }

        // Compute flux difference fHi-fLo
        FArrayBox diff(a_dU.box(), a_dU.nComp());
        diff.setVal(0.0);

        FORT_FLUXDIFFF(CHF_FRA(diff),
            CHF_CONST_FRA(a_F[idir]),
            CHF_CONST_INT(idir),
            CHF_BOX(a_box));

        // Add flux difference to dU
        a_dU += diff;

        ((LEPhysIBC*)m_bc)->updateBoundary(a_WHalf[idir],idir,a_dt,a_dx,a_currentTime+a_dt,true);
    }

    // Multiply dU by dt/dx because that is what the output expects
    a_dU *= -a_dt / a_dx;
}