Exemplo n.º 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);
  }
}
Exemplo n.º 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);
  }
}
Exemplo n.º 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);
  }
}
Exemplo n.º 4
0
void EBPoissonOp::
create(LevelData<EBCellFAB>&       a_lhs,
       const LevelData<EBCellFAB>& a_rhs)
{
  int ncomp = a_rhs.nComp();
  EBCellFactory ebcellfact(m_eblg.getEBISL());
  a_lhs.define(m_eblg.getDBL(), ncomp, a_rhs.ghostVect(), ebcellfact);
}
Exemplo n.º 5
0
void
makeLevelData(const Vector<Box>& boxes,
              LevelData<FArrayBox>& levelFab)
{
  Vector<int> procIDs(boxes.size());
  LoadBalance(procIDs, boxes);

  DisjointBoxLayout dbl1(boxes, procIDs);
  levelFab.define(dbl1, 1);
}
//-----------------------------------------------------------------------
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()];
  }
}
Exemplo n.º 7
0
void EBPoissonOp::
createCoarser(LevelData<EBCellFAB>&       a_coar,
              const LevelData<EBCellFAB>& a_fine,
              bool                        a_ghosted)
{
  CH_assert(a_fine.nComp() == 1);
  const DisjointBoxLayout& dbl = m_eblgCoarMG.getDBL();
  ProblemDomain coarDom = coarsen(m_eblg.getDomain(), 2);

  int nghost = a_fine.ghostVect()[0];
  EBISLayout coarEBISL;

  const EBIndexSpace* const ebisPtr = Chombo_EBIS::instance();
  ebisPtr->fillEBISLayout(coarEBISL,
                          dbl, coarDom, nghost);

  EBCellFactory ebcellfact(coarEBISL);
  a_coar.define(dbl, 1,a_fine.ghostVect(),ebcellfact);
}
Exemplo n.º 8
0
void
getError(LevelData<EBCellFAB>&       a_error,
         const EBISLayout&           a_ebisl,
         const DisjointBoxLayout&    a_dbl,
         const Real&                 a_dx)
{
    EBCellFactory ebcellfact(a_ebisl);
    EBFluxFactory ebfluxfact(a_ebisl);
    a_error.define(a_dbl, 1, IntVect::Zero,   ebcellfact);
    LevelData<EBCellFAB> divFCalc(a_dbl, 1, IntVect::Zero,   ebcellfact);
    LevelData<EBCellFAB> divFExac(a_dbl, 1, IntVect::Zero,   ebcellfact);
    LevelData<EBFluxFAB> faceFlux(a_dbl, 1, IntVect::Zero,   ebfluxfact);

    for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
    {
        a_error[dit()].setVal(0.);
        divFCalc[dit()].setVal(0.);
        divFExac[dit()].setVal(0.);
    }

    setToExactDivFLD(divFExac,  a_ebisl, a_dbl, a_dx);
    setToExactFluxLD(faceFlux,  a_ebisl, a_dbl, a_dx);

    Interval interv(0, 0);
    faceFlux.exchange(interv);

    kappaDivergenceLD(divFCalc, faceFlux, a_ebisl, a_dbl, a_dx);

    for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit)
    {
        EBCellFAB& errorFAB = a_error[dit()];
        EBCellFAB& exactFAB = divFExac[dit()];
        EBCellFAB& calcuFAB = divFCalc[dit()];

        errorFAB += calcuFAB;
        errorFAB -= exactFAB;
    }
}
Exemplo n.º 9
0
// ---------------------------------------------------------------
// tag cells for regridding
void
AMRNavierStokes::tagCells(IntVectSet & a_tags)
{
  if (s_verbosity >= 3)
    {
      pout () << "AMRNavierStokes::tagCells " << m_level << endl;
    }

  IntVectSet local_tags;

  // create tags based on something or other
  // for now, don't do anything
  const DisjointBoxLayout& level_domain = newVel().getBoxes();

  if (s_tag_vorticity)
    {
      LevelData<FArrayBox> vorticity;
      LevelData<FArrayBox> mag_vorticity;
      if (SpaceDim == 2)
        {
          vorticity.define(level_domain,1);
        }
      else if (SpaceDim == 3)
        {
          vorticity.define(level_domain,SpaceDim);
          mag_vorticity.define(level_domain,1);
        }
      computeVorticity(vorticity);

      Interval vortInterval(0,0);
      if (SpaceDim == 3)
        {
          vortInterval = Interval(0,SpaceDim-1);
        }
      Real tagLevel = norm(vorticity, vortInterval, 0);
      // Real tagLevel = 1.0;
      //tagLevel *= s_vort_factor/m_dx;
      // actually tag where vort*dx > s_vort_factor*max(vort)
      tagLevel = s_vort_factor/m_dx;

      if (tagLevel > 0)
        {
          // now tag where vorticity magnitude is greater than or equal
          // to tagLevel
          DataIterator dit = vorticity.dataIterator();
          for (dit.reset(); dit.ok(); ++dit)
            {
              FArrayBox& vortFab = vorticity[dit];

              // this only needs to be done in 3d...
              if (SpaceDim==3)
                {
                  FArrayBox& magVortFab = mag_vorticity[dit];
                  FORT_MAGVECT(CHF_FRA1(magVortFab,0),
                               CHF_CONST_FRA(vortFab),
                               CHF_BOX(level_domain[dit]));
                }

              BoxIterator bit(vortFab.box());
              for (bit.begin(); bit.ok(); ++bit)
                {
                  const IntVect& iv = bit();
                  if (SpaceDim == 2)
                    {
                      if (abs(vortFab(iv)) >= tagLevel)
                        {
                          local_tags |= iv;
                        }
                    }
                  else if (SpaceDim == 3)
                    {
                      FArrayBox& magVortFab = mag_vorticity[dit];
                      if (abs(magVortFab(iv)) >= tagLevel)
                        {
                          local_tags |= iv;
                        }
                    } // end if DIM=3
                } // end loop over interior of box
            } // loop over grids
        } // if taglevel > 0
    } // if tagging on vorticity

  a_tags = local_tags;
}
Exemplo n.º 10
0
// ---------------------------------------------------------
int main(int argc, char* argv[])
{
  int status = 0; // number of errors detected.
  // Do nothing if DIM > 3.
#if (CH_SPACEDIM <= 3)
#ifdef CH_MPI
  MPI_Init (&argc, &argv);
#endif
  //scoping trick
  {
    // test parameters
    const int testOrder = 4; // expected order of convergence

    // A test is considered as a failure
    //  if its convergence rate is smaller than below.
    Real targetConvergeRate = testOrder*0.9;
#ifdef CH_USE_FLOAT
    targetConvergeRate = testOrder*0.89;
#endif

    // number of ghost cells being interpolated
    int numGhost = 5;

    // refinement ratio between coarse and fine levels
    int refRatio = 4;

    Vector<Interval> fixedDimsAll;
    if (SpaceDim == 3)
      {
        fixedDimsAll.push_back(Interval(SpaceDim-1, SpaceDim-1));
      }
    // Always include empty interval, meaning NO fixed dimensions.
    fixedDimsAll.push_back(Interval());

    // real domain has length 1. in every dimension
    RealVect physLength = RealVect::Unit;

    for (int ifixed = 0; ifixed < fixedDimsAll.size(); ifixed++)
      {
        const Interval& fixedDims = fixedDimsAll[ifixed];
        int nfixed = fixedDims.size();

        IntVect interpUnit = IntVect::Unit;
        IntVect refineVect = refRatio * IntVect::Unit;
        for (int dirf = fixedDims.begin(); dirf <= fixedDims.end(); dirf++)
          {
            interpUnit[dirf] = 0;
            refineVect[dirf] = 1;
          }

        // No ghost cells in fixed dimensions.
        IntVect ghostVect = numGhost * interpUnit;

#ifdef CH_USE_FLOAT
        // Single precision doesn't get us very far.
#if (CH_SPACEDIM == 1)
        int domainLengthMin = 16;
        int domainLengthMax = 32;
#else
        int domainLengthMin = 32;
        int domainLengthMax = 64;
#endif
#endif

#ifdef CH_USE_DOUBLE
        int domainLengthMin = 32;
#if CH_SPACEDIM >= 3
        int domainLengthMax = 64;
        if (nfixed > 0) domainLengthMax = 128;
#else
        int domainLengthMax = 512;
#endif
#endif

        Vector<int> domainLengths;
        int len = domainLengthMin;
        while (len <= domainLengthMax)
          {
            domainLengths.push_back(len);
            len *= 2;
          }
        int nGrids = domainLengths.size();

        if (nGrids > 0)
          {
            pout() << endl
                   << "Testing FourthOrderFillPatch DIM=" << SpaceDim;
            if (nfixed > 0)
              {
                pout() << " fixing " << fixedDims.begin()
                       << ":" << fixedDims.end();
              }
            pout() << endl;
            pout() << "size  "
                   << "max diff   rate";
            pout() << endl;
          }

        Real diffMaxCoarser;
        for (int iGrid = 0; iGrid < nGrids; iGrid++)
          {
            int domainLength = domainLengths[iGrid];
            IntVect lenCoarse = domainLength * IntVect::Unit;

            RealVect dxCoarseVect = physLength / RealVect(lenCoarse);
            RealVect dxFineVect = dxCoarseVect / RealVect(refineVect);

            Box coarDomain, fineDomain;
            Vector<Box> coarBoxes, fineBoxes;
            setHierarchy(lenCoarse,
                         refineVect,
                         coarBoxes,
                         fineBoxes,
                         coarDomain,
                         fineDomain);

            mortonOrdering(coarBoxes);
            mortonOrdering(fineBoxes);

            Vector<int> procCoar(coarBoxes.size());
            Vector<int> procFine(fineBoxes.size());
            LoadBalance(procCoar, coarBoxes);
            LoadBalance(procFine, fineBoxes);

            DisjointBoxLayout dblCoar(coarBoxes, procCoar);
            DisjointBoxLayout dblFine(fineBoxes, procFine);

            ProblemDomain probCoar(coarDomain);
            ProblemDomain probFine(fineDomain);

            FourthOrderFillPatch interpolator;
            int ncomp = 1;
            // Set coarseGhostsFill = ceil(numGhosts / refRatio).
            // int coarseGhostsFill = numGhost / refRatio;
            // if (coarseGhostsFill * refRatio < numGhost) coarseGhostsFill++;
            bool fixedTime = true;
            interpolator.define(dblFine, dblCoar, ncomp,
                                probCoar, refRatio, numGhost, fixedTime,
                                fixedDims);
                                
            LevelData<FArrayBox> exactCoarse(dblCoar, ncomp);

            // Set exact value of function on coarse level.
            for (DataIterator dit = exactCoarse.dataIterator(); dit.ok(); ++dit)
              {
                CH_TIME("computing exactCoarse on FAB");
                FArrayBox& exactCoarseFab = exactCoarse[dit];
                const Box& bx = exactCoarseFab.box();
                // Get average of function on each cell.
                for (BoxIterator bit(bx); bit.ok(); ++bit)
                  {
                    const IntVect& iv = bit();
                    RealVect cellLo = RealVect(iv) * dxCoarseVect;
                    RealVect cellHi = cellLo + dxCoarseVect;
                    exactCoarseFab(iv, 0) = avgFunVal(cellLo, cellHi, physLength);
                  }
              }
            
            /*
              Define data holders on fine level.
            */
            Interval intvlExact(0, ncomp-1);
            Interval intvlCalc(ncomp, 2*ncomp-1);
            Interval intvlDiff(2*ncomp, 3*ncomp-1);
            LevelData<FArrayBox> allFine;
            LevelData<FArrayBox> exactFine, calcFine, diffFine;
            { CH_TIME("allocate allFine");
              allFine.define(dblFine, 3*ncomp, ghostVect);
              
              aliasLevelData(exactFine, &allFine, intvlExact);
              aliasLevelData(calcFine, &allFine, intvlCalc);
              aliasLevelData(diffFine, &allFine, intvlDiff);
            }
            
            /*
              Fill in data holders on fine level.
            */

            // Set exact value of function on fine level.
            Real exactMax = 0.;
            for (DataIterator dit = exactFine.dataIterator(); dit.ok(); ++dit)
              {
                CH_TIME("computing exactFine on FAB");
                FArrayBox& exactFineFab = exactFine[dit];
                const Box& bx = exactFineFab.box();
                // Get average of function on each cell.
                for (BoxIterator bit(bx); bit.ok(); ++bit)
                  {
                    const IntVect& iv = bit();
                    RealVect cellLo = RealVect(iv) * dxFineVect;
                    RealVect cellHi = cellLo + dxFineVect;
                    exactFineFab(iv, 0) = avgFunVal(cellLo, cellHi, physLength);
                  }
                Real exactFabMax = exactFineFab.norm(0);
                if (exactFabMax > exactMax) exactMax = exactFabMax;
              }
#ifdef CH_MPI
            reduceReal(exactMax, MPI_MAX);
#endif

            // Fill in valid cells of calcFine by copying from exact.
            for (DataIterator dit = dblFine.dataIterator(); dit.ok(); ++dit)
              {
                const FArrayBox& exactFineFab = exactFine[dit];
                FArrayBox& calcFineFab = calcFine[dit];
                const Box& bx = dblFine[dit];
                calcFineFab.copy(exactFineFab, bx);
              }

            // Fill in ghost cells of calcFine by copying where possible.
            calcFine.exchange();

            // Fill in ghost cells of calcFine by interpolation where necessary.
            interpolator.fillInterp(calcFine, exactCoarse, 0, 0, ncomp);

            /*
              Got results.  Now take differences,
              diffFine = calcFine - exactFine.
            */
            Real diffMax = 0.;
            for (DataIterator dit = diffFine.dataIterator(); dit.ok(); ++dit)
              { CH_TIME("calculating diffFine");
                FArrayBox& diffFineFab = diffFine[dit];
                const FArrayBox& exactFineFab = exactFine[dit];
                const FArrayBox& calcFineFab = calcFine[dit];

                Box bxWithin(diffFineFab.box());
                bxWithin &= probFine;
                diffFineFab.setVal(0.);
                diffFineFab.copy(exactFineFab, bxWithin);
                diffFineFab.minus(calcFineFab, bxWithin, 0, 0, ncomp);

                Real diffFabMax = diffFineFab.norm(0);
                if (diffFabMax > diffMax) diffMax = diffFabMax;
                // dummy statement in order to get around gdb bug
                int dummy_unused = 0; dummy_unused = 0;
              }
#ifdef CH_MPI
            reduceReal(diffMax, MPI_MAX);
#endif

            pout() << setw(4) << domainLength;
            pout() << "  " << scientific << setprecision(4)
                   << diffMax;
            if (iGrid > 0)
              {
                Real ratio = diffMaxCoarser / diffMax;
                Real rate = log(ratio) / log(2.0);
                pout () << " " << fixed << setprecision(2) << rate;
                if (rate < targetConvergeRate)
                  {
                    status += 1;
                  }
              }
            pout() << endl;
            
            diffMaxCoarser = diffMax;
          } // end loop over grid sizes
      } // end loop over which dimensions are fixed
    if (status==0)
      {
        pout() <<  "All tests passed!\n";
      }
    else
      {
        pout() <<  status << " tests failed!\n";
      }
  } // end scoping trick
#ifdef CH_MPI
  CH_TIMER_REPORT();
  MPI_Finalize();
#endif
#endif

  return status;
}
Exemplo n.º 11
0
void EBPoissonOp::
restrictResidual(LevelData<EBCellFAB>&       a_resCoar,
                 LevelData<EBCellFAB>&       a_phiThisLevel,
                 const LevelData<EBCellFAB>& a_rhsThisLevel)
{
  CH_TIME("EBPoissonOp::restrictResidual");

  CH_assert(a_resCoar.nComp() == 1);
  CH_assert(a_phiThisLevel.nComp() == 1);
  CH_assert(a_rhsThisLevel.nComp() == 1);

  LevelData<EBCellFAB> resThisLevel;
  bool homogeneous = true;

  EBCellFactory ebcellfactTL(m_eblg.getEBISL());
  IntVect ghostVec = a_rhsThisLevel.ghostVect();

  resThisLevel.define(m_eblg.getDBL(), 1, ghostVec, ebcellfactTL);

  // Get the residual on the fine grid
  residual(resThisLevel,a_phiThisLevel,a_rhsThisLevel,homogeneous);

  // now use our nifty averaging operator
  Interval variables(0, 0);
  CH_assert(m_hasMGObjects);
  m_ebAverageMG.average(a_resCoar, resThisLevel, variables);

#ifdef DO_EB_RHS_CORRECTION
  // Apply error-correction modification to restricted RHS
  // Right now this only works with Dirichlet BC's, and only makes sense for the EB

  int correctionType = 0;    // Change this to activate RHS correction

  if (correctionType != 0)
    {
      for (DataIterator dit = a_resCoar.disjointBoxLayout().dataIterator(); dit.ok(); ++dit)
        {
          EBCellFAB&       resFAB = a_resCoar[dit()];                      // Extract the FAB for this box
          const EBISBox&   ebis   = resFAB.getEBISBox();                   // Get the set of all IntVect indices

          // Iterate over the parts of the RHS corresponding to the irregular cells,
          // correcting the RHS in each cell
          VoFIterator ebvofit(ebis.getIrregIVS(ebis.getRegion()), ebis.getEBGraph());
          for (ebvofit.reset(); ebvofit.ok(); ++ebvofit)
            {
              for (int icomp = 0; icomp < resFAB.nComp(); ++icomp)    // For each component of the residual on this VoF
                {
                  if (correctionType == 1)
                    {
                      // Setting the residual to zero on the irregular cells gives convergence,
                      // though the rate isn't as good as the full correction
                      resFAB(ebvofit(), icomp) = 0.0;
                    }
                  else if (correctionType == 2)
                    {
                      // Kludge valid only for pseudo-1D test case.  May not work for you.
                      Real kappa = ebis.volFrac(ebvofit());
                      kappa = (kappa > 0.5 ? kappa : 0.5);    // Floor on kappa to prevent dividing by a tiny number
                      Real rhoCoeff = (kappa + 0.5)/(2.0*kappa);
                      resFAB(ebvofit(), icomp) *= (1.0 - rhoCoeff);
                    }
                  // else silently do nothing
                }
            }
        }
    }
#endif
}