예제 #1
0
void
EBCoarseAverage::average(LevelData<EBFluxFAB>&       a_coarData,
                         const LevelData<EBFluxFAB>& a_fineData,
                         const Interval& a_variables)
{
  CH_TIME("EBCoarseAverage::average(LD<EBFluxFAB>)");
  LevelData<EBFluxFAB> coarFiData;
  LevelData<EBFluxFAB> fineBuffer;
  CH_assert(isDefined());
  {
    CH_TIME("buffer allocation");
    EBFluxFactory factCoFi(m_eblgCoFi.getEBISL());
    coarFiData.define(  m_eblgCoFi.getDBL(), m_nComp, IntVect::Zero, factCoFi);
    if (m_useFineBuffer)
      {
        EBFluxFactory    factFine(m_eblgFine.getEBISL());
        fineBuffer.define(m_eblgFine.getDBL(), m_nComp, IntVect::Zero, factFine);
      }
  }

  if (m_useFineBuffer)
    {
      CH_TIME("fine_copy");
      a_fineData.copyTo(a_variables, fineBuffer, a_variables);
    }

  {
    CH_TIME("averaging");
    for (DataIterator dit = m_eblgFine.getDBL().dataIterator(); dit.ok(); ++dit)
      {
        const EBFluxFAB* fineFABPtr = NULL;
        if (m_useFineBuffer)
          {
            fineFABPtr = &fineBuffer[dit()];
          }
        else
          {
            fineFABPtr = &a_fineData[dit()];
          }
        EBFluxFAB&       cofiFAB = coarFiData[dit()];
        const EBFluxFAB& fineFAB = *fineFABPtr;
        for (int idir = 0; idir < SpaceDim; idir++)
          {
            averageFAB(cofiFAB[idir],
                       fineFAB[idir],
                       dit(),
                       a_variables,
                       idir);

          }
      }
  }
  {
    CH_TIME("copy_coar");
    coarFiData.copyTo(a_variables, a_coarData, a_variables);
  }
}
예제 #2
0
void
EBCoarseAverage::average(LevelData<BaseIVFAB<Real> >&        a_coarData,
                         const LevelData<BaseIVFAB<Real> >&  a_fineData,
                         const Interval&                     a_variables)
{
  CH_TIME("EBCoarseAverage::average(LD<BaseIVFAB>)");
  LevelData<BaseIVFAB<Real> > coarFiData;
  LevelData<BaseIVFAB<Real> > fineBuffer;
  CH_assert(isDefined());
  {
    CH_TIME("buffer allocation");
    BaseIVFactory<Real> factCoFi(m_eblgCoFi.getEBISL(), m_irregSetsCoFi);
    coarFiData.define(m_eblgCoFi.getDBL(), m_nComp, IntVect::Zero, factCoFi);
    if (m_useFineBuffer)
      {
        BaseIVFactory<Real> factFine(m_eblgFine.getEBISL(), m_irregSetsFine);
        coarFiData.define(m_eblgFine.getDBL(), m_nComp, IntVect::Zero, factFine);
      }
  }

  if (m_useFineBuffer)
  {
    CH_TIME("fine_copy");
    a_fineData.copyTo(a_variables, fineBuffer, a_variables);
  }

  {
    CH_TIME("averaging");
    int ifnerg = 0;
    for (DataIterator dit = m_eblgFine.getDBL().dataIterator(); dit.ok(); ++dit)
      {
        const BaseIVFAB<Real>* fineFABPtr = NULL;
        if (m_useFineBuffer)
          {
            fineFABPtr = &fineBuffer[dit()];
          }
        else
          {
            fineFABPtr = &a_fineData[dit()];
          }
        BaseIVFAB<Real>&       cofiFAB = coarFiData[dit()];
        const BaseIVFAB<Real>& fineFAB = *fineFABPtr;
        averageFAB(cofiFAB,
                   fineFAB,
                   dit(),
                   a_variables);

        ifnerg++;
      }
  }
  {
    CH_TIME("copy_coar");
    coarFiData.copyTo(a_variables, a_coarData, a_variables);
  }
}
예제 #3
0
void
EBCoarseAverage::average(LevelData<EBCellFAB>& a_coarData,
                         const LevelData<EBCellFAB>& a_fineData,
                         const Interval& a_variables)
{
  CH_TIME("EBCoarseAverage::average(LD<EBCellFAB>)");
  LevelData<EBCellFAB> coarFiData;
  LevelData<EBCellFAB> fineBuffer;
  CH_assert(isDefined());
  {
    CH_TIME("buffer allocation");
    EBCellFactory  factCoFi(m_eblgCoFi.getEBISL());
    coarFiData.define(  m_eblgCoFi.getDBL(), m_nComp, IntVect::Zero, factCoFi);
    if (m_useFineBuffer)
      {
        EBCellFactory    factFine(m_eblgFine.getEBISL());
        fineBuffer.define(m_eblgFine.getDBL(), m_nComp, IntVect::Zero, factFine);
      }
  }

  if (m_useFineBuffer)
    {
      CH_TIME("copy_fine");
      a_fineData.copyTo(a_variables, fineBuffer, a_variables);
    }

  {
    CH_TIME("averaging");
    for (DataIterator dit = m_eblgFine.getDBL().dataIterator(); dit.ok(); ++dit)
      {
        const EBCellFAB* fineFAB = NULL;
        if (m_useFineBuffer)
          {
            fineFAB = &fineBuffer[dit()];
          }
        else
          {
            fineFAB = &a_fineData[dit()];
          }
        averageFAB(coarFiData[dit()],
                   *fineFAB,
                   dit(),
                   a_variables);
      }
  }
  {
    CH_TIME("copy_coar");
    coarFiData.copyTo(a_variables, a_coarData, a_variables);
  }
}
예제 #4
0
void
EBCoarToFineRedist::
resetWeights(const LevelData<EBCellFAB>& a_modifierCoar,
             const int& a_ivar)
{
  CH_TIME("EBCoarToFineRedist::resetWeights");
  Interval srcInterv(a_ivar, a_ivar);
  Interval dstInterv(0,0);
  a_modifierCoar.copyTo(srcInterv, m_densityCedFine, dstInterv);

  //set the weights to mass weighting if the modifier
  //is the fine density.
  for (DataIterator dit = m_gridsFine.dataIterator(); dit.ok(); ++dit)
    {
      const IntVectSet& coarSet = m_setsCedFine[dit()];
      BaseIVFAB<VoFStencil>& massStenFAB = m_stenCedFine[dit()];
      const BaseIVFAB<VoFStencil>& volStenFAB  = m_volumeStenc[dit()];
      const BaseIVFAB<VoFStencil>& stanStenFAB  = m_standardStenc[dit()];

      const EBISBox& ebisBoxCoar = m_ebislCedFine[dit()];
      const EBCellFAB& modFAB = m_densityCedFine[dit()];

      for (VoFIterator vofit(coarSet, ebisBoxCoar.getEBGraph()); vofit.ok(); ++vofit)
        {
          const VolIndex& vofCoar = vofit();

          const VoFStencil& stanSten = stanStenFAB(vofCoar, 0);
          const VoFStencil& volSten  = volStenFAB(vofCoar, 0);
          VoFStencil newSten;
          for (int isten = 0; isten < volSten.size(); isten++)
            {
              const VolIndex& thatVoFCoar = volSten.vof(isten);
              Real weight = modFAB(thatVoFCoar, 0);
              //average fine weights onto coarse weight
              newSten.add(thatVoFCoar, weight);
            }
          //need normalize by the whole standard stencil
          Real sum = 0.0;
          for (int isten = 0; isten < stanSten.size(); isten++)
            {
              const VolIndex& thatVoFCoar = stanSten.vof(isten);
              Real weight = modFAB(thatVoFCoar, 0);
              Real volfrac = ebisBoxCoar.volFrac(thatVoFCoar);
              //it is weight*volfrac that is normalized
              sum += weight*volfrac;
            }
          if (Abs(sum) > 0.0)
            {
              Real scaling = 1.0/sum;
              newSten *= scaling;
            }
          massStenFAB(vofCoar, 0) = newSten;
        }
    }
}
예제 #5
0
void
EBMGInterp::pwlInterp(LevelData<EBCellFAB>&       a_fineData,
                      const LevelData<EBCellFAB>& a_coarData,
                      const Interval&             a_variables)
{
  CH_TIME("EBMGInterp::pwlInterp");
  CH_assert(a_fineData.ghostVect() == m_ghost);
  CH_assert(a_coarData.ghostVect() == m_ghost);
  CH_assert(m_doLinear); //otherwise stencils have not been defined

  if (m_layoutChanged)
    {
      if (m_coarsenable)
        {
          CH_TIME("EBMGInterp::pwlInterp::coarsenable");
          EBCellFactory ebcellfact(m_buffEBISL);
          LevelData<EBCellFAB> coarsenedFineData(m_buffGrids, m_nComp, m_ghost, ebcellfact);
          a_coarData.copyTo(a_variables, coarsenedFineData, a_variables);
          fillGhostCellsPWC(coarsenedFineData, m_buffEBISL, m_coarDomain);
          for (DataIterator dit = m_fineGrids.dataIterator(); dit.ok(); ++dit)
            {
              //does incrementonly = true
              pwlInterpFAB(a_fineData[dit()],
                           m_buffGrids[dit()],
                           coarsenedFineData[dit()],
                           dit(),
                           a_variables);
            }
        }
      else
        {
          CH_TIME("EBMGInterp::pwlInterp::uncoarsenable");
          EBCellFactory ebcellfact(m_buffEBISL);
          fillGhostCellsPWC((LevelData<EBCellFAB>&)a_coarData, m_coarEBISL, m_coarDomain);
          LevelData<EBCellFAB> refinedCoarseData(m_buffGrids, m_nComp, m_ghost, ebcellfact);
          for (DataIterator dit = m_coarGrids.dataIterator(); dit.ok(); ++dit)
            {
              refinedCoarseData[dit()].setVal(0.);
              pwlInterpFAB(refinedCoarseData[dit()],
                           m_coarGrids[dit()],
                           a_coarData[dit()],
                           dit(),
                           a_variables);
            }

          EBAddOp op;
          refinedCoarseData.copyTo(a_variables, a_fineData, a_variables, m_copierRCtoF, op);
        }
    }
  else
    {
      pwcInterpMG(a_fineData, a_coarData, a_variables);
    }
}
예제 #6
0
void TimeInterpolatorRK4::saveRHS(const LevelData<FArrayBox>&   a_rhs)
{
  CH_assert(m_defined);
  CH_assert(m_gotDt);
  CH_assert(m_gotInitialSoln);
  CH_assert(!m_gotFullTaylorPoly);
  CH_assert(m_countRHS >= 0);
  CH_assert(m_countRHS < 4);
  CH_assert(a_rhs.nComp() == m_numStates);

  // a_rhs is on the coarse layout;
  // m_rhsCopy is on the coarsened fine layout.
  a_rhs.copyTo(m_rhsCopy, m_copier);

  DataIterator dit = m_rhsCopy.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      const FArrayBox& rhsCopyFab = m_rhsCopy[dit];
      FArrayBox& taylorFab = m_taylorCoeffs[dit];

      for (int ind = 0; ind < m_numCoeffs; ind++)
        {
          Real multFactor = m_coeffs[ind][m_countRHS];
          if (multFactor != 0.)
            {
              taylorFab.plus(rhsCopyFab,
                             multFactor, // multiply rhsCopyFab by this
                             0, // start rhsCopyFab component
                             ind * m_numStates, // start taylorFab component
                             m_numStates); // number of components
            }
        }
      // These are for getting to RK4 intermediates:
      // diff12 = m_dt * (rhs[2] - rhs[1])
      if (m_countRHS == 1)
        {
          FArrayBox& diff12Fab = m_diff12[dit];
          diff12Fab.copy(rhsCopyFab);
        }
      if (m_countRHS == 2)
        {
          FArrayBox& diff12Fab = m_diff12[dit];
          diff12Fab -= rhsCopyFab;
          diff12Fab *= -m_dt;
        }
    }
  m_countRHS++;
  if (m_countRHS == 4)
    {
      m_taylorCoeffs.exchange();
      m_gotFullTaylorPoly = true;
    }
}
//-----------------------------------------------------------------------
void
EBConsBackwardEulerIntegrator::
computeDiffusion(LevelData<EBCellFAB>& a_diffusionTerm,
                 const LevelData<EBCellFAB>& a_oldTemperature,
                 Real a_specificHeat,
                 const LevelData<EBCellFAB>& a_oldDensity,
                 const LevelData<EBCellFAB>& a_newDensity,
                 const LevelData<EBCellFAB>& a_source,
                 Real a_time,
                 Real a_timeStep,
                 bool a_zeroTemp)
{
  // Allocate storage for the new temperature.
  LevelData<EBCellFAB> newTemp;
  EBCellFactory fact(m_eblg.getEBISL());
  newTemp.define(m_eblg.getDBL(), 1, 4*IntVect::Unit, fact);
  EBLevelDataOps::setVal(newTemp, 0.0);

  //          n+1
  // Compute T.
  updateSolution(newTemp, a_oldTemperature, a_specificHeat, a_oldDensity,
                 a_newDensity, a_source, a_time, a_timeStep, a_zeroTemp);

  //            n+1             n
  // ([rho Cv T]    - [rho Cv T] )
  // ----------------------------- - a_source -> a_diffusionTerm.
  //              dt
  a_oldTemperature.copyTo(a_diffusionTerm);
  for (DataIterator dit = m_eblg.getDBL().dataIterator(); dit.ok(); ++dit)
  {
    EBCellFAB& diff = a_diffusionTerm[dit()];

    //           n
    // [rho Cv T]   -> diff
    diff *= a_oldDensity[dit()];
    diff *= a_specificHeat;

    //           n+1
    // [rho Cv T]   -> newRhoCvT
    EBCellFAB& newRhoCvT = newTemp[dit()];
    newRhoCvT *= a_newDensity[dit()];
    newRhoCvT *= a_specificHeat;

    // Subtract newRhoCvT from diff, and divide by -dt.
    diff -= newRhoCvT;
    diff /= -a_timeStep;

    // Subtract off the source.
    diff -= a_source[dit()];
  }
}
예제 #8
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;
    }
}
예제 #9
0
void TimeInterpolatorRK4::saveInitialSoln(const LevelData<FArrayBox>&   a_soln)
{
  CH_assert(m_defined);
  CH_assert(m_gotDt);
  CH_assert(!m_gotInitialSoln);
  CH_assert(a_soln.nComp() == m_numStates);

  // First zero out taylorFab.
  DataIterator dit = m_taylorCoeffs.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      FArrayBox& taylorFab = m_taylorCoeffs[dit];
      taylorFab.setVal(0.);
    }

  // a_soln is on the coarse layout;
  // m_taylorCoeffs is on the coarsened fine layout.
  // Copy from a_soln to first m_numStates components of m_taylorCoeffs.
  const Interval& srcInt = a_soln.interval();
  a_soln.copyTo(srcInt, m_taylorCoeffs, srcInt, m_copier);

  m_gotInitialSoln = true;
}
예제 #10
0
void
EBLevelAdvect::
advectToFacesBCG(LevelData< EBFluxFAB >&                         a_extrapState,
                 const LevelData< EBCellFAB >&                   a_consState,
                 const LevelData< EBCellFAB >&                   a_normalVel,
                 const LevelData< EBFluxFAB >&                   a_advectionVel,
                 const LevelData< EBCellFAB >*                   a_consStateCoarseOld,
                 const LevelData< EBCellFAB >*                   a_consStateCoarseNew,
                 const LevelData< EBCellFAB >*                   a_normalVelCoarseOld,
                 const LevelData< EBCellFAB >*                   a_normalVelCoarseNew,
                 const Real&                                     a_timeCoarseOld,
                 const Real&                                     a_timeCoarseNew,
                 const Real&                                     a_timeFine,
                 const Real&                                     a_dt,
                 const LevelData<EBCellFAB>* const               a_source,
                 const LevelData<EBCellFAB>* const               a_sourceCoarOld,
                 const LevelData<EBCellFAB>* const               a_sourceCoarNew)
{
  CH_TIME("EBLevelAdvect::advectToFacesBCG (level)");
  CH_assert(isDefined());

  //create temp data with the correct number of ghost cells
  IntVect ivGhost = m_nGhost*IntVect::Unit;
  Interval consInterv(0, m_nVar-1);
  Interval intervSD(0, SpaceDim-1);

  // LevelData<EBCellFAB>& consTemp = (LevelData<EBCellFAB>&) a_consState;
  // LevelData<EBCellFAB>& veloTemp = (LevelData<EBCellFAB>&) a_normalVel;

  EBCellFactory factory(m_thisEBISL);
  LevelData<EBCellFAB> consTemp(m_thisGrids, m_nVar, ivGhost, factory);
  LevelData<EBCellFAB> veloTemp(m_thisGrids, SpaceDim, ivGhost, factory);
  for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit)
    {
      consTemp[dit()].setVal(0.);
    }

  a_consState.copyTo(consInterv, consTemp, consInterv);
  a_normalVel.copyTo(intervSD, veloTemp, intervSD);
  // Fill ghost cells using fillInterp, and copyTo.
  if (m_hasCoarser)
    {
      CH_TIME("fillPatch");
      m_fillPatch.interpolate(consTemp,
                              *a_consStateCoarseOld,
                              *a_consStateCoarseNew,
                              a_timeCoarseOld,
                              a_timeCoarseNew,
                              a_timeFine,
                              consInterv);

      m_fillPatchVel.interpolate(veloTemp,
                                 *a_normalVelCoarseOld,
                                 *a_normalVelCoarseNew,
                                 a_timeCoarseOld,
                                 a_timeCoarseNew,
                                 a_timeFine,
                                 intervSD);
    }
  // Exchange all the data between grids
  {
    CH_TIME("initial_exchange");
    consTemp.exchange(consInterv);
    veloTemp.exchange(intervSD);
  }

  LevelData<EBCellFAB>* srcTmpPtr = NULL;
  if (a_source != NULL)
    {
      // srcTmpPtr = (LevelData<EBCellFAB>*) a_source;

      srcTmpPtr = new LevelData<EBCellFAB>(m_thisGrids, m_nVar, ivGhost, factory);
      for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit)
        {
          (*srcTmpPtr)[dit()].setVal(0.);
        }
      a_source->copyTo(consInterv, *srcTmpPtr, consInterv);

      if ( (a_sourceCoarOld != NULL) &&
           (a_sourceCoarNew != NULL) &&
           (m_hasCoarser) )
        {
          CH_TIME("fillPatch");

          m_fillPatch.interpolate(*srcTmpPtr,
                                  *a_sourceCoarOld,
                                  *a_sourceCoarNew,
                                  a_timeCoarseOld,
                                  a_timeCoarseNew,
                                  a_timeFine,
                                  consInterv);
          {
            CH_TIME("initial_exchange");
            srcTmpPtr->exchange(consInterv);
          }
        }
    }

  {
    CH_TIME("advectToFaces");
    int ibox = 0;
    for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit)
      {
        const Box& cellBox = m_thisGrids.get(dit());
        const EBISBox& ebisBox = m_thisEBISL[dit()];
        if (!ebisBox.isAllCovered())
          {
            //the viscous term goes into here
            EBCellFAB dummy;
            EBCellFAB* srcPtr = &dummy;
            if (srcTmpPtr != NULL)
              {
                srcPtr = (EBCellFAB*)(&((*srcTmpPtr)[dit()]));
              }

            const EBCellFAB& source = *srcPtr;
            //unused in this case
            BaseIVFAB<Real> boundaryPrim;
            bool doBoundaryPrim = false;

            EBFluxFAB& extrapFAB  = a_extrapState[dit()];
            advectToFacesBCG(extrapFAB,
                             boundaryPrim,
                             consTemp[dit()],
                             veloTemp[dit()],
                             a_advectionVel[dit()],
                             cellBox,
                             ebisBox,
                             a_dt,
                             a_timeFine,
                             source,
                             dit(),
                             doBoundaryPrim);



            ibox++;
          }
      }
  }
  if (srcTmpPtr != NULL)
    {
      delete srcTmpPtr;
    }
}
예제 #11
0
// Advance the solution by "a_dt" by using an unsplit method.
// "a_finerFluxRegister" is the flux register with the next finer level.
// "a_coarseFluxRegister" is flux register with the next coarser level.
// If source terms do not exist, "a_S" should be null constructed and not
// defined (i.e. its define() should not be called).
Real OldLevelGodunov::step(LevelData<FArrayBox>&       a_U,
                           LevelData<FArrayBox>        a_flux[CH_SPACEDIM],
                           LevelFluxRegister&          a_finerFluxRegister,
                           LevelFluxRegister&          a_coarserFluxRegister,
                           const LevelData<FArrayBox>& a_S,
                           const LevelData<FArrayBox>& a_UCoarseOld,
                           const Real&                 a_TCoarseOld,
                           const LevelData<FArrayBox>& a_UCoarseNew,
                           const Real&                 a_TCoarseNew,
                           const Real&                 a_time,
                           const Real&                 a_dt)
{
  // Make sure everything is defined
  CH_assert(m_defined);

  // Clear flux registers with next finer level
  if (m_hasFiner)
    {
      a_finerFluxRegister.setToZero();
    }

  // Setup an interval corresponding to the conserved variables
  Interval UInterval(0,m_numCons-1);

  // Create temporary storage with a layer of "m_numGhost" ghost cells
  IntVect ivGhost = m_numGhost*IntVect::Unit;
  LevelData<FArrayBox> U(m_grids,m_numCons,ivGhost);

  for (DataIterator dit = U.dataIterator(); dit.ok(); ++dit)
    {
      U[dit()].setVal(0.);
    }

  // Copy the current conserved variables into the temporary storage
  a_U.copyTo(UInterval,U,UInterval);

  // Fill U's ghost cells using fillInterp
  if (m_hasCoarser)
    {
      // Truncate the fraction to the range [0,1] to remove floating-point
      // subtraction roundoff effects
      Real eps = 0.04 * a_dt / m_refineCoarse;

      // check for current time too far outside the coarse time range
      if ( a_time+eps < a_TCoarseOld || a_time-eps > a_TCoarseNew )
      {
        pout() << "error: OldLevelGodunov::step: a_time [" << a_time
               << "] is outside the old,new range of coarse level times ["
               << a_TCoarseOld << "," << a_TCoarseNew << "]" << endl ;
        MayDay::Error( "OldLevelGodunov::step: new time is outside acceptable range" );
      }
      // if just a little outside the range (e.g. roundoff errors), just fix it
      Real curtime = a_time ;
      if ( a_time < a_TCoarseOld ) curtime = a_TCoarseOld ;
      if ( a_time > a_TCoarseNew ) curtime = a_TCoarseNew ;

      // "time" falls in the range of the old and the new coarse times
      Real alpha = (curtime - a_TCoarseOld) / (a_TCoarseNew - a_TCoarseOld);

      // Interpolate ghost cells from next coarser level using both space
      // and time interpolation
      m_patcher.fillInterp(U,
                           a_UCoarseOld,
                           a_UCoarseNew,
                           alpha,
                           0,0,m_numCons);
    }

  // Exchange all the data between grids at this level
  // I don't think this is necessary
  //U.exchange(UInterval);

  // Potentially used in boundary conditions
  m_patchGodunov->setCurrentTime(a_time);

  // Dummy source used if source term passed in is empty
  FArrayBox zeroSource;

  // Use to restrict maximum wave speed away from zero
  Real maxWaveSpeed = 1.0e-12;

  // Beginning of loop through patches/grids.
  for (DataIterator dit = m_grids.dataIterator(); dit.ok(); ++dit)
    {
      // The current box
      Box curBox = m_grids.get(dit());

    // The current grid of conserved variables
      FArrayBox& curU = U[dit()];

      // The current source terms if they exist
      const FArrayBox* source = &zeroSource;
      if (a_S.isDefined())
        {
          source = &a_S[dit()];
        }

      // The fluxes computed for this grid - used for refluxing and returning
      // other face centered quantities
      FArrayBox flux[SpaceDim];

    // Set the current box for the patch integrator
      m_patchGodunov->setCurrentBox(curBox);

      Real maxWaveSpeedGrid;

    // Update the current grid's conserved variables, return the final
    // fluxes used for this, and the maximum wave speed for this grid
      m_patchGodunov->updateState(curU,
                                  flux,
                                  maxWaveSpeedGrid,
                                  *source,
                                  a_dt,
                                  curBox);

      // Clamp away from zero
      maxWaveSpeed = Max(maxWaveSpeed,maxWaveSpeedGrid);

      // Do flux register updates
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          // Increment coarse flux register between this level and the next
          // finer level - this level is the next coarser level with respect
          // to the next finer level
          if (m_hasFiner)
            {
              a_finerFluxRegister.incrementCoarse(flux[idir],a_dt,dit(),
                                                  UInterval,
                                                  UInterval,idir);
            }

          // Increment fine flux registers between this level and the next
          // coarser level - this level is the next finer level with respect
          // to the next coarser level
          if (m_hasCoarser)
            {
              a_coarserFluxRegister.incrementFine(flux[idir],a_dt,dit(),
                                                  UInterval,
                                                  UInterval,idir,Side::Lo);
              a_coarserFluxRegister.incrementFine(flux[idir],a_dt,dit(),
                                                  UInterval,
                                                  UInterval,idir,Side::Hi);
            }
        }
    }

  // Now that we have completed the updates of all the patches, we copy the
  // contents of temporary storage, U, into the permanent storage, a_U.
  // U.copyTo(UInterval,a_U,UInterval);

  for (DataIterator dit = U.dataIterator(); dit.ok(); ++dit)
    {
      a_U[dit()].copy(U[dit()]);
    }

  // Find the minimum of dt's over this level
  Real local_dtNew = m_dx / maxWaveSpeed;
  Real dtNew;

#ifdef CH_MPI
  int result = MPI_Allreduce(&local_dtNew, &dtNew, 1, MPI_CH_REAL,
                                 MPI_MIN, Chombo_MPI::comm);
  if (result != MPI_SUCCESS)
  {
    MayDay::Error("sorry, but I had a communcation error on new dt");
  }
#else
  dtNew = local_dtNew;
#endif

  // Return the maximum stable time step
  return dtNew;
}
예제 #12
0
void
EBMGAverage::average(LevelData<EBCellFAB>&       a_coarData,
                     const LevelData<EBCellFAB>& a_fineData,
                     const Interval&             a_variables)
{
  CH_TIMERS("EBMGAverage::average");
  CH_TIMER("layout_changed_coarsenable", t1);
  CH_TIMER("layout_changed_not_coarsenable", t2);
  CH_TIMER("not_layout_changed", t3);
  CH_assert(a_fineData.ghostVect() == m_ghost);
  //CH_assert(a_coarData.ghostVect() == m_ghost);

  CH_assert(isDefined());

  if (m_layoutChanged)
    {
      if (m_coarsenable)
        {
          CH_START(t1);
          EBCellFactory ebcellfact(m_buffEBISL);
          LevelData<EBCellFAB> coarsenedFineData(m_buffGrids, m_nComp, m_ghost, ebcellfact);
          EBLevelDataOps::setVal(coarsenedFineData, 0.0);

          for (DataIterator dit = m_fineGrids.dataIterator(); dit.ok(); ++dit)
            {
              averageFAB(coarsenedFineData[dit()],
                         m_buffGrids[dit()],
                         a_fineData[dit()],
                         dit(),
                         a_variables);
            }
          coarsenedFineData.copyTo(a_variables, a_coarData, a_variables, m_copier);
          CH_STOP(t1);
        }
      else
        {
          CH_START(t2);
          EBCellFactory ebcellfact(m_buffEBISL);
          LevelData<EBCellFAB> refinedCoarseData(m_buffGrids, m_nComp, m_ghost, ebcellfact);
          EBLevelDataOps::setVal(refinedCoarseData, 0.0);

          a_fineData.copyTo(a_variables, refinedCoarseData, a_variables, m_copier);

          for (DataIterator dit = m_coarGrids.dataIterator(); dit.ok(); ++dit)
            {
              averageFAB(a_coarData[dit()],
                         m_coarGrids[dit()],
                         refinedCoarseData[dit()],
                         dit(),
                         a_variables);
            }
          CH_STOP(t2);
        }
    }
  else
    {
      CH_START(t3);
      averageMG(a_coarData, a_fineData, a_variables);
      CH_STOP(t3);
    }
}
예제 #13
0
void
EBFineToCoarRedist::
resetWeights(const LevelData<EBCellFAB>& a_modifierCoar,
             const int& a_ivar)
{
  CH_TIME("EBFineToCoarRedist::resetWeights");
  //set the weights to mass weighting if the modifier
  //is the coarse density.
  Interval srcInterv(a_ivar, a_ivar);
  Interval dstInterv(0,0);
  a_modifierCoar.copyTo(srcInterv, m_densityCoar, dstInterv);
  for (DataIterator dit = m_gridsCoar.dataIterator(); dit.ok(); ++dit)
    {
      const IntVectSet& fineSet = m_setsRefCoar[dit()];
      BaseIVFAB<VoFStencil>& massStenFAB = m_stenRefCoar[dit()];
      const BaseIVFAB<VoFStencil>& volStenFAB  = m_volumeStenc[dit()];
      const BaseIVFAB<VoFStencil>& stanStenFAB  = m_standardStenc[dit()];
      const EBISBox& ebisBoxFine = m_ebislRefCoar[dit()];
      const EBCellFAB& modFAB = m_densityCoar[dit()];

      for (VoFIterator vofit(fineSet, ebisBoxFine.getEBGraph()); vofit.ok(); ++vofit)
        {
          const VolIndex& vofFine = vofit();

          const VoFStencil& oldSten = volStenFAB(vofFine, 0);
          const VoFStencil& stanSten = stanStenFAB(vofFine, 0);

          VoFStencil newSten;
          for (int isten = 0; isten < oldSten.size(); isten++)
            {
              const VolIndex& thatVoFFine = oldSten.vof(isten);
              VolIndex refCoarVoF =
                m_ebislRefCoar.coarsen(thatVoFFine, m_refRat, dit());

              Real weight = modFAB(refCoarVoF, a_ivar);

              //it is weight*volfrac that is normalized
              newSten.add(thatVoFFine, weight);
            }
          //have to normalize using the whole stencil
          Real sum = 0.0;
          for (int isten = 0; isten < stanSten.size(); isten++)
            {
              const VolIndex& thatVoFFine = stanSten.vof(isten);
              VolIndex refCoarVoF =
                m_ebislRefCoar.coarsen(thatVoFFine, m_refRat, dit());

              Real weight = modFAB(refCoarVoF, a_ivar);

              Real volfrac = ebisBoxFine.volFrac(thatVoFFine);
              //it is weight*volfrac that is normalized
              sum += weight*volfrac;
            }
          if (Abs(sum) > 0.0)
            {
              Real scaling = 1.0/sum;
              newSten *= scaling;
            }
          massStenFAB(vofFine, 0) = newSten;

        }
    }
}