Exemple #1
0
void
EBPlanarShockIBC::
initialize(LevelData<EBCellFAB>& a_conState,
           const EBISLayout& a_ebisl) const
{
 CH_assert(m_isDefined);
 CH_assert(m_isFortranCommonSet);

  // Iterator of all grids in this level
  for(DataIterator dit = a_conState.dataIterator(); dit.ok(); ++dit)
    {
      const EBISBox& ebisBox = a_ebisl[dit()];
      // Storage for current grid
      EBCellFAB& conFAB = a_conState[dit()];

      BaseFab<Real>& regConFAB = conFAB.getSingleValuedFAB();
      // Box of current grid
      Box uBox = regConFAB.box();
      uBox &= m_domain;
      // Set up initial condition in this grid
      /**/
      FORT_PLANARSHOCKINIT(CHF_CONST_FRA(regConFAB),
                           CHF_CONST_REAL(m_dx),
                           CHF_BOX(uBox));
      /**/

      //now for the multivalued cells.  Since it is pointwise,
      //the regular calc is correct for all single-valued cells.
      IntVectSet ivs = ebisBox.getMultiCells(uBox);
      for(VoFIterator vofit(ivs, ebisBox.getEBGraph()); vofit.ok(); ++vofit)
        {
          const VolIndex& vof = vofit();
          const IntVect& iv = vof.gridIndex();
          RealVect momentum;
          Real energy, density;
          /**/
          FORT_POINTPLANARSHOCKINIT(CHF_REAL(density),
                                    CHF_REALVECT(momentum),
                                    CHF_REAL(energy),
                                    CHF_CONST_INTVECT(iv),
                                    CHF_CONST_REAL(m_dx));
          /**/
          conFAB(vof, CRHO) = density;
          conFAB(vof, CENG) = energy;
          for(int idir = 0; idir < SpaceDim; idir++)
            {
              conFAB(vof, CMOMX+idir) = momentum[idir];
            }
        }//end loop over multivalued cells
    } //end loop over boxes
}
Real TrigBCBetaValue::beta(const RealVect& a_point,
                           const Real&     a_time) const
{
 CH_assert(m_isDefined);

  Real value;

  FORT_GETBETAPOINT(CHF_REAL(value),
                    CHF_CONST_INTVECT(m_trig),
                    CHF_CONST_REALVECT(a_point),
                    CHF_CONST_REAL(a_time));

  return value;
}
Real SphericalHarmonicBCBetaValue::beta(const RealVect& a_point,
                                        const Real&     a_time) const
{
 CH_assert(m_isDefined);

  Real value;

  FORT_GETBETAPOINT(CHF_REAL(value),
                    CHF_CONST_INTVECT(m_lmphase),
                    CHF_CONST_REALVECT(a_point),
                    CHF_CONST_REAL(a_time));

  return value;
}
Real TrigBCBetaValue::value(const RealVect& a_point,
                            const RealVect& a_normal,
                            const Real&     a_time,
                            const int&      a_comp) const
{
 CH_assert(m_isDefined);

  Real value;

  FORT_GETPHIPOINT(CHF_REAL(value),
                   CHF_CONST_INTVECT(m_trig),
                   CHF_CONST_REALVECT(a_point),
                   CHF_CONST_REAL(a_time));

  return value;
}
Real SphericalHarmonicBCBetaValue::value(const RealVect& a_point,
                                         const RealVect& a_normal,
                                         const Real&     a_time,
                                         const int&      a_comp) const
{
 CH_assert(m_isDefined);

  Real value;

  FORT_GETSHPHIPOINT(CHF_REAL(value),
                     CHF_CONST_INTVECT(m_lmphase),
                     CHF_CONST_REALVECT(a_point),
                     CHF_CONST_REAL(a_time));

  return value;
}
// -----------------------------------------------------------------------------
// Adds coarse cell values directly to all overlying fine cells.
// -----------------------------------------------------------------------------
void ConstInterpPS::prolongIncrement (LevelData<FArrayBox>&       a_phiThisLevel,
                                      const LevelData<FArrayBox>& a_correctCoarse)
{
    CH_TIME("ConstInterpPS::prolongIncrement");

    // Gather grids, domains, refinement ratios...
    const DisjointBoxLayout& fineGrids = a_phiThisLevel.getBoxes();
    const DisjointBoxLayout& crseGrids = a_correctCoarse.getBoxes();
    CH_assert(fineGrids.compatible(crseGrids));

    const ProblemDomain& fineDomain = fineGrids.physDomain();
    const ProblemDomain& crseDomain = crseGrids.physDomain();

    const IntVect mgRefRatio = fineDomain.size() / crseDomain.size();
    CH_assert(mgRefRatio.product() > 1);

    DataIterator dit = fineGrids.dataIterator();
    for (dit.reset(); dit.ok(); ++dit) {
        // Create references for convenience
        FArrayBox& fineFAB = a_phiThisLevel[dit];
        const FArrayBox& crseFAB = a_correctCoarse[dit];
        const Box& fineValid = fineGrids[dit];

        // To make things easier, we will offset the
        // coarse and fine data boxes to zero.
        const IntVect& fiv = fineValid.smallEnd();
        const IntVect civ = coarsen(fiv, mgRefRatio);

        // Correct the fine data
        FORT_CONSTINTERPPS (
            CHF_FRA_SHIFT(fineFAB, fiv),
            CHF_CONST_FRA_SHIFT(crseFAB, civ),
            CHF_BOX_SHIFT(fineValid, fiv),
            CHF_CONST_INTVECT(mgRefRatio));
    }
}
Exemple #7
0
// Sets parameters in a common block used by Fortran routines:
//   a_smallPressure  - Lower limit for pressure (returned)
//   a_gamma          - Gamma for polytropic, gamma-law gas
//   a_ambientDensity - Ambient density add to the plane-wave
//   a_deltaDensity   - Mean of the plane-wave
//   a_pressure       - If 0, use isentropic pressure
//                      if 1, use the constant pressure of 1.0
//   a_waveNumber     - The wave number of the plane-wave
//   a_velocity       - Initial velocity of the gas
//   a_center         - Position of a maximum of the plane-wave
//   a_artvisc        - Artificial viscosity coefficient
void WaveIBC::setFortranCommon(Real&           a_smallPressure,
                               const Real&     a_gamma,
                               const Real&     a_ambientDensity,
                               const Real&     a_deltaDensity,
                               const int&      a_pressure,
                               const IntVect&  a_waveNumber,
                               const RealVect& a_center,
                               const RealVect& a_velocity,
                               const Real&     a_artvisc)
{
  CH_assert(m_isFortranCommonSet == false);

  FORT_WAVESETF(CHF_REAL(a_smallPressure),
                CHF_CONST_REAL(a_gamma),
                CHF_CONST_REAL(a_ambientDensity),
                CHF_CONST_REAL(a_deltaDensity),
                CHF_CONST_INT(a_pressure),
                CHF_CONST_INTVECT(a_waveNumber),
                CHF_CONST_REALVECT(a_center),
                CHF_CONST_REALVECT(a_velocity),
                CHF_CONST_REAL(a_artvisc));

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

    CH_TIME("MappedLevelFluxRegister::incrementFine");

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

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

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

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

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

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


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


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

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

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

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

    }


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

    //  cFine.shift(-shift/m_nRefine);
#endif
    fineFlux.shiftHalf(a_dir, - sign(a_sd));
}
// -----------------------------------------------------------------------------
// Adds coarse cell values directly to all overlying fine cells,
// then removes the average from the fine result.
// -----------------------------------------------------------------------------
void ZeroAvgConstInterpPS::prolongIncrement (LevelData<FArrayBox>&       a_phiThisLevel,
                                             const LevelData<FArrayBox>& a_correctCoarse)
{
    CH_TIME("ZeroAvgConstInterpPS::prolongIncrement");

    // Gather grids, domains, refinement ratios...
    const DisjointBoxLayout& fineGrids = a_phiThisLevel.getBoxes();
    const DisjointBoxLayout& crseGrids = a_correctCoarse.getBoxes();
    CH_assert(fineGrids.compatible(crseGrids));

    const ProblemDomain& fineDomain = fineGrids.physDomain();
    const ProblemDomain& crseDomain = crseGrids.physDomain();

    const IntVect mgRefRatio = fineDomain.size() / crseDomain.size();
    CH_assert(mgRefRatio.product() > 1);

    // These will accumulate averaging data.
    Real localSum = 0.0;
    Real localVol = 0.0;
    CH_assert(!m_CCJinvPtr.isNull());
    CH_assert(m_dxProduct > 0.0);

    DataIterator dit = fineGrids.dataIterator();
    for (dit.reset(); dit.ok(); ++dit) {
        // Create references for convenience
        FArrayBox& fineFAB = a_phiThisLevel[dit];
        const FArrayBox& crseFAB = a_correctCoarse[dit];
        const Box& fineValid = fineGrids[dit];
        const FArrayBox& JinvFAB = (*m_CCJinvPtr)[dit];

        // To make things easier, we will offset the
        // coarse and fine data boxes to zero.
        const IntVect& fiv = fineValid.smallEnd();
        const IntVect civ = coarsen(fiv, mgRefRatio);

        // Correct the fine data
        FORT_CONSTINTERPWITHAVGPS (
            CHF_FRA_SHIFT(fineFAB, fiv),
            CHF_CONST_FRA_SHIFT(crseFAB, civ),
            CHF_BOX_SHIFT(fineValid, fiv),
            CHF_CONST_INTVECT(mgRefRatio),
            CHF_CONST_FRA1_SHIFT(JinvFAB,0,fiv),
            CHF_CONST_REAL(m_dxProduct),
            CHF_REAL(localVol),
            CHF_REAL(localSum));
    }

    // Compute global sum (this is where the MPI communication happens)
#ifdef CH_MPI
    Real globalSum = 0.0;
    int result = MPI_Allreduce(&localSum, &globalSum, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm);

    if (result != MPI_SUCCESS) {
        MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement");
    }

    Real globalVol = 0.0;
    result = MPI_Allreduce(&localVol, &globalVol, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm);

    if (result != MPI_SUCCESS) {
        MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement");
    }

#else
    Real globalSum = localSum;
    Real globalVol = localVol;
#endif

    // Remove the average from phi.
    Real avgPhi = globalSum / globalVol;
    for (dit.reset(); dit.ok(); ++dit) {
        a_phiThisLevel[dit] -= avgPhi;
    }
}