Esempio n. 1
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);

}
Esempio n. 2
0
void
setToExactDivF(EBCellFAB&     a_exactDivF,
               const EBISBox& a_ebisBox,
               const Box&     a_region,
               const Real&    a_dx)
{
    a_exactDivF.setVal(0.);
    IntVectSet ivsregion(a_region);
    for (VoFIterator vofit(ivsregion, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit)
    {
        const VolIndex& vof = vofit();
        RealVect xval;
        IntVect iv = vof.gridIndex();
        for (int idir = 0; idir < SpaceDim; idir++)
        {
            xval[idir] = (Real(iv[idir]) + 0.5)*a_dx;
        }
        Real solnrv = exactDivergence(xval);
        Real kappa = a_ebisBox.volFrac(vof);
        a_exactDivF(vof,0) = kappa*solnrv;
    }
}
Esempio n. 3
0
void
kappaDivergence(EBCellFAB&             a_divF,
                const EBFluxFAB&       a_flux,
                const EBISBox&         a_ebisBox,
                const Box&             a_box,
                const Real&            a_dx)
{
    //set the divergence initially to zero
    //then loop through directions and increment the divergence
    //with each directions flux difference.
    a_divF.setVal(0.0);
    BaseFab<Real>&       regDivF = a_divF.getSingleValuedFAB();
    regDivF.setVal(0.);
    for (int idir = 0; idir < SpaceDim; idir++)
    {
        //update for the regular vofs in the nonconservative
        //case  works for all single valued vofs.
        /* do the regular vofs */
        /**/
        const EBFaceFAB& fluxDir = a_flux[idir];
        const BaseFab<Real>& regFluxDir = fluxDir.getSingleValuedFAB();
        int ncons = 1;
        FORT_DIVERGEF( CHF_BOX(a_box),
                       CHF_FRA(regDivF),
                       CHF_CONST_FRA(regFluxDir),
                       CHF_CONST_INT(idir),
                       CHF_CONST_INT(ncons),
                       CHF_CONST_REAL(a_dx));
        /**/
    }
    //update the irregular vofs using conservative diff
    IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(a_box);
    for (VoFIterator vofit(ivsIrreg, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit)
    {
        const VolIndex& vof = vofit();
        //divergence was set in regular update.  we reset it
        // to zero and recalc.
        Real update = 0.;
        for ( int idir = 0; idir < SpaceDim; idir++)
        {
            const EBFaceFAB& fluxDir = a_flux[idir];
            for (SideIterator sit; sit.ok(); ++sit)
            {
                int isign = sign(sit());
                Vector<FaceIndex> faces =
                    a_ebisBox.getFaces(vof, idir, sit());
                for (int iface = 0; iface < faces.size(); iface++)
                {
                    const FaceIndex& face = faces[iface];
                    Real areaFrac = a_ebisBox.areaFrac(face);
                    Real faceFlux =fluxDir(face, 0);
                    update += isign*areaFrac*faceFlux;

                }
            }
        }
        //add EB boundary condtions in divergence
        const IntVect& iv = vof.gridIndex();
        Real bndryArea = a_ebisBox.bndryArea(vof);
        RealVect bndryCent = a_ebisBox.bndryCentroid(vof);
        RealVect normal = a_ebisBox.normal(vof);
        RealVect bndryLoc;
        RealVect exactF;
        for (int idir = 0; idir < SpaceDim; idir++)
        {
            bndryLoc[idir] = a_dx*(iv[idir] + 0.5 + bndryCent[idir]);
        }
        for (int idir = 0; idir < SpaceDim; idir++)
        {
            exactF[idir] = exactFlux(bndryLoc, idir);
        }
        Real bndryFlux = PolyGeom::dot(exactF, normal);

        update -= bndryFlux*bndryArea;
        update /= a_dx; //note NOT divided by volfrac

        a_divF(vof, 0) = update;
    }
}