示例#1
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));
    }
}
示例#2
0
// ----------------------------------------------------------
void
CoarseAverageEdge::averageGridData(FluxBox& a_coarsenedFine,
                                   const FluxBox& a_fine) const
{
  for (int dir=0; dir<SpaceDim; dir++)
    {
      FArrayBox& coarseFab = a_coarsenedFine[dir];
      const FArrayBox& fineFab = a_fine[dir];

      const Box& coarseBox = coarseFab.box();

      // set up refinement box
      int boxHi = m_nRef-1;
      IntVect hiVect(D_DECL(boxHi,boxHi,boxHi));
      // don't want to index at all in dir direction --
      // instead, want to just march along edge.
      hiVect.setVal(dir,0);
      IntVect loVect(D_DECL(0,0,0));
      Box refBox(loVect, hiVect);

      FORT_AVERAGEEDGE( CHF_FRA(coarseFab),
                        CHF_CONST_FRA(fineFab),
                        CHF_BOX(coarseBox),
                        CHF_CONST_INT(dir),
                        CHF_CONST_INT(m_nRef),
                        CHF_BOX(refBox));
    }
}
示例#3
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));
    }
  }
}
示例#4
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);

}
示例#5
0
EBPlanarShockIBC::
EBPlanarShockIBC(const Real&     a_gamma,
                 const Real&     a_ms,
                 const Real&     a_center,
                 const int&      a_shocknorm,
                 const bool&     a_shockbackward,
                 const bool&     a_doRZCoords)
  :EBPhysIBC()
{
  int ishockback = 0;
  if(a_shockbackward)
    {
      ishockback = 1;
    }
  /**/
  Real preshockpress = 1.0;
  ParmParse pp;
  if(pp.contains("preshockpress"))
    {
      pp.get("preshockpress", preshockpress);
    }
  Real preshockdense  = a_gamma;
  if(pp.contains("preshockdense"))
    {
      pp.get("preshockdense", preshockdense);
    }
  Real postshocktemp;
  pp.get("post_shock_temperature", postshocktemp);


  FORT_SETPLANARSHOCK(CHF_CONST_REAL(postshocktemp),
                      CHF_CONST_REAL(a_gamma),
                      CHF_CONST_REAL(a_ms),
                      CHF_CONST_REAL(a_center),
                      CHF_CONST_REAL(preshockpress),
                      CHF_CONST_REAL(preshockdense),
                      CHF_CONST_INT(a_shocknorm),
                      CHF_CONST_INT(ishockback));
  /**/
  m_doRZCoords    = a_doRZCoords;
  m_gamma         = a_gamma;
  m_ms            = a_ms;
  m_center        = a_center;
  m_shocknorm     = a_shocknorm;
  m_shockbackward = a_shockbackward;

  m_isFortranCommonSet = true;
  m_isDefined = false;
}
示例#6
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));
        }
    }
}
示例#7
0
// ---------------------------------------------------------
void
NodeMGInterp::define(const DisjointBoxLayout& a_grids,
                     int a_numcomps,
                     int a_refRatio,
                     const ProblemDomain& a_domain)
{
  m_refRatio = a_refRatio;
  m_domain = a_domain;
  m_grids = a_grids;

  m_boxRef = Box(IntVect::Zero, (m_refRatio-1)*IntVect::Unit);
  Box corners(IntVect::Zero, IntVect::Unit);
  m_weights.define(corners, m_boxRef.numPts());
  FORT_NODEINTERPMG_GETWEIGHTS(CHF_CONST_INT(m_refRatio),
                               CHF_BOX(m_boxRef),
                               CHF_FRA(m_weights));

  // create the work array
  DisjointBoxLayout coarsenedGrids;
  coarsen(coarsenedGrids, a_grids, m_refRatio);

  m_coarsenedFine.define(coarsenedGrids, a_numcomps);

  is_defined = true;
}
示例#8
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));
    }

}
示例#9
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
}
示例#10
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));
    }
  }
}
示例#11
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);
}
示例#12
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));
}
示例#13
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 VelIBC::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))
    {
      // This needs to be fixed
      // CH_assert(m_isSlopeValSet);

      Box loBox,hiBox,centerBox,domain;
      int hasLo,hasHi;
      Box slopeBox = a_dW.box()&m_domain;

      Real loVal = m_slopeVal[a_dir][0];
      Real hiVal = m_slopeVal[a_dir][1];

      // Generate the domain boundary boxes, loBox and hiBox, if there are
      // domain boundaries 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_REAL(m_dx),
                         CHF_CONST_INT(a_dir),
                         CHF_CONST_REAL(loVal),
                         CHF_BOX(loBox),
                         CHF_CONST_INT(hasLo),
                         CHF_CONST_REAL(hiVal),
                         CHF_BOX(hiBox),
                         CHF_CONST_INT(hasHi));
        }
    }
}
示例#14
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));
}
示例#15
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 RampIBC::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);

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

  // 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_RAMPSLOPEBCSF(CHF_FRA(a_dW),
                             CHF_CONST_FRA(a_W),
                             CHF_CONST_REAL(m_dx),
                             CHF_CONST_INT(a_dir),
                             CHF_BOX(loBox),
                             CHF_CONST_INT(hasLo),
                             CHF_BOX(hiBox),
                             CHF_CONST_INT(hasHi));
        }
    }
}
示例#16
0
void PolytropicPhysics::charSynthesis(FArrayBox&       a_dW,
                                      const FArrayBox& a_W,
                                      const int&       a_dir,
                                      const Box&       a_box)
{
    CH_assert(isDefined());

    FORT_CHARSYNTHESISF(CHF_FRA(a_dW),
                        CHF_CONST_FRA(a_W),
                        CHF_CONST_INT(a_dir),
                        CHF_BOX(a_box));
}
示例#17
0
void PolytropicPhysics::charValues(FArrayBox&       a_lambda,
                                   const FArrayBox& a_W,
                                   const int&       a_dir,
                                   const Box&       a_box)
{
    CH_assert(isDefined());

    FORT_CHARVALUESF(CHF_FRA(a_lambda),
                     CHF_CONST_FRA(a_W),
                     CHF_CONST_INT(a_dir),
                     CHF_BOX(a_box));
}
示例#18
0
void PolytropicPhysics::getFlux(FArrayBox&       a_flux,
                                const FArrayBox& a_whalf,
                                const int&       a_dir,
                                const Box&       a_box)
{
    CH_assert(isDefined());

    FORT_GETFLUXF(CHF_FRA(a_flux),
                  CHF_CONST_FRA(a_whalf),
                  CHF_CONST_INT(a_dir),
                  CHF_BOX(a_box));
}
示例#19
0
/**
  On input, a_dW contains the increments of the characteristic variables.
  On output, it contains the increments in the primitive variables.

  IMPORTANT NOTE: It is assumed that the characteristic analysis puts the
  smallest eigenvalue first, the largest eigenvalue last, and orders the
  characteristic variables accordingly.
  */
void LinElastPhysics::charSynthesis(FArrayBox&       a_dW,
    const FArrayBox& a_W,
    const int&       a_dir,
    const Box&       a_box)
{
    //JK pout() << "LinElastPhysics::charSynthesis" << endl;
    CH_assert(isDefined());

    FORT_CHARSYNTHESISF(CHF_FRA(a_dW),
        CHF_CONST_FRA(a_W),
        CHF_CONST_INT(a_dir),
        CHF_BOX(a_box));
}
示例#20
0
void LinElastPhysics::getFlux(FArrayBox&       a_flux,
    const FArrayBox& a_whalf,
    const int&       a_dir,
    const Box&       a_box)
{
    //JK pout() << "LinElastPhysics::getFlux :: " << a_dir << endl;
    CH_assert(isDefined());

    FORT_GETFLUXF(CHF_FRA(a_flux),
        CHF_CONST_FRA(a_whalf),
        CHF_CONST_INT(a_dir),
        CHF_BOX(a_box));
}
示例#21
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);
}
示例#22
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));
}
示例#23
0
/**
  On input, a_dW contains the increments of the primitive variables. On
  output, it contains the increments in the characteristic variables.

  IMPORTANT NOTE: It is assumed that the characteristic analysis puts the
  smallest eigenvalue first, the largest eigenvalue last, and orders the
  characteristic variables accordingly.
  */
void LinElastPhysics::charAnalysis(FArrayBox&       a_dW,
    const FArrayBox& a_W,
    const int&       a_dir,
    const Box&       a_box)
{
    //JK pout() << "LinElastPhysics::charAnalysis" << endl;
    CH_assert(isDefined());

    /*
     * This routine assumes that cp >= cs
     */
    FORT_CHARANALYSISF(CHF_FRA(a_dW),
        CHF_CONST_FRA(a_W),
        CHF_CONST_INT(a_dir),
        CHF_BOX(a_box));
}
示例#24
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));
}
示例#25
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;
}
示例#26
0
void LinElastPhysics::quasilinearUpdate(FArrayBox&       a_dWdx,
    const FArrayBox& a_wHalf,
    const FArrayBox& a_W,
    const Real&      a_scale,
    const int&       a_dir,
    const Box&       a_box)
{
    //JK pout() << "LinElastPhysics::quasilinear" << endl;
    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));
}
示例#27
0
// ---------------------------------------------------------
// interpolate from coarse level to fine level
void
NodeMGInterp::interpToFine(LevelData<NodeFArrayBox>& a_fine,
                           const LevelData<NodeFArrayBox>& a_coarse,
                           bool a_sameGrids) // a_sameGrids default false
{
  CH_assert(is_defined);
  const int nComp = a_fine.nComp();
  CH_assert(a_coarse.nComp() == nComp);

  // Copy a_coarse to m_coarsenedFine on grids of m_coarsenedFine.

  // petermc, 15 Nov 2002:
  // You don't need a Copier for this copyTo, because
  // the grid layout of the destination, m_coarsenedFine,
  // will be contained in that of the source, a_coarse.
  if (! a_sameGrids)
    {
      a_coarse.copyTo(a_coarse.interval(),
                      m_coarsenedFine,
                      m_coarsenedFine.interval() );
    }

  for (DataIterator dit = m_grids.dataIterator(); dit.ok(); ++dit)
    {
      Box fineBox = m_grids.get(dit());
      Box crseBox = coarsen(fineBox, m_refRatio);

      const FArrayBox& crseFab = (a_sameGrids) ?
        a_coarse[dit()].getFab() : m_coarsenedFine[dit()].getFab();

      FArrayBox& fineFab = a_fine[dit()].getFab();

      FORT_NODEINTERPMG(CHF_FRA(fineFab),
                        CHF_CONST_FRA(crseFab),
                        CHF_BOX(crseBox),
                        CHF_CONST_INT(m_refRatio),
                        CHF_BOX(m_boxRef),
                        CHF_FRA(m_weights));

      // dummy statement in order to get around gdb bug
      int dummy_unused = 0; dummy_unused = 0;
    }
}
示例#28
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);
    }
}
示例#29
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));
}
示例#30
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
}