Пример #1
0
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));
}
Пример #2
0
void
EBCoarseAverage::averageFAB(EBFaceFAB&       a_coar,
                            const EBFaceFAB& a_fine,
                            const DataIndex& a_datInd,
                            const Interval&  a_variables,
                            const int&       a_dir) const
{
  CH_TIME("EBCoarseAverage::averageFAB(EBFaceFAB)");
  CH_assert(isDefined());

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

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

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

  //overwrite irregular cells

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

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

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

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

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

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

  Box coarBox = m_coarsenedFineGrids.get(a_datInd);

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

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

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

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

  //overwrite irregular vofs and coarse vofs next to the cfivs if refRat<4,
  //  for these vofs we coarsen based on
  //  taylor expansions from fine vofs to the coarse cell center
  coarsenIrreg(a_coar,a_fine,a_datInd,a_variables);
}
Пример #4
0
void
EBCoarseAverage::averageFAB(EBCellFAB&       a_coar,
                            const EBCellFAB& a_fine,
                            const DataIndex& a_datInd,
                            const Interval&  a_variables) const
{
  CH_TIME("EBCoarseAverage::averageFAB(EBCellFAB)");
  CH_assert(isDefined());
  //do all cells as if they were regular
  BaseFab<Real>& coarRegFAB =  a_coar.getSingleValuedFAB();
  const BaseFab<Real>& fineRegFAB = a_fine.getSingleValuedFAB();
  Box refbox(IntVect::Zero, (m_refRat-1)*IntVect::Unit);

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

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

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

  //overwrite irregular cells

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

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

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

      Real volCoar = cellVolCoar*ebisBoxCoar.volFrac(coarVoF);
      for (int ivar = a_variables.begin();
          ivar <= a_variables.end(); ivar++)
        {
          Real dataVal = 0.0;
          if (volCoar > 0.)
            {
              for (int ifine = 0; ifine < fineVoFs.size(); ifine++)
                {
                  const VolIndex& fineVoF = fineVoFs[ifine];
                  //fine cell volume is normalized to one...
                  Real volFine  = ebisBoxFine.volFrac(fineVoF);
                  Real fineVal =  a_fine(fineVoF, ivar);
                  if (volFine > 0.)
                    {
                      dataVal += fineVal*volFine;
                    }
                }
              dataVal /= volCoar;
            }
          else
            {
              //if there is no real volume, just take the ave
              //of fine values
              for (int ifine = 0; ifine < fineVoFs.size(); ifine++)
                {
                  const VolIndex& fineVoF = fineVoFs[ifine];
                  Real fineVal =  a_fine(fineVoF, ivar);
                  dataVal += fineVal;
                }
              if (fineVoFs.size() > 0)
                {
                  dataVal /= Real(fineVoFs.size());
                }
            }
          a_coar(coarVoF, ivar) = dataVal;
        }
    }
}