コード例 #1
1
ファイル: EBPoissonOp.cpp プロジェクト: dtgraves/EBAMRCNS
void EBPoissonOp::
getOpVoFStencil(VoFStencil&             a_stencil,
                const int&              a_idir,
                const Vector<VolIndex>& a_allMonotoneVoFs,
                const EBISBox&          a_ebisbox,
                const VolIndex&         a_VoF,
                const bool&             a_lowOrder)
{

  for (SideIterator sit; sit.ok(); ++sit)
    {
      Side::LoHiSide side = sit();
      Vector<FaceIndex> faces;

      faces = a_ebisbox.getFaces(a_VoF,a_idir,side);

      for (int iface = 0; iface < faces.size(); iface++)
        {
          FaceIndex face = faces[iface];
          VoFStencil faceStencil;

          getOpFaceStencil(faceStencil,a_allMonotoneVoFs,a_ebisbox,a_VoF,
                           a_idir,side,face,a_lowOrder);

          a_stencil += faceStencil;
        }
    }
}
コード例 #2
0
ファイル: HomogeneousCFInterp.cpp プロジェクト: UNC-CFD/somar
// -----------------------------------------------------------------------------
// Interpolate ghosts at CF interface using zeros on coarser grids.
// -----------------------------------------------------------------------------
void homogeneousCFInterp (LevelData<FArrayBox>& a_phif,
                          const RealVect&       a_fineDx,
                          const RealVect&       a_crseDx,
                          const CFRegion&       a_cfRegion,
                          const IntVect&        a_applyDirs)
{
    CH_TIME("homogeneousCFInterp (full level)");

    // Loop over grids, directions, and sides and call the worker function.
    DataIterator dit = a_phif.dataIterator();
    for (dit.begin(); dit.ok(); ++dit) {
        if (a_phif[dit].box().isEmpty()) continue;

        for (int dir = 0; dir < SpaceDim; ++dir) {
            if (a_applyDirs[dir] == 0) continue;

            SideIterator sit;
            for (sit.begin(); sit.ok(); sit.next()) {
                homogeneousCFInterp(a_phif,
                                    dit(),
                                    dir,
                                    sit(),
                                    a_fineDx[dir],
                                    a_crseDx[dir],
                                    a_cfRegion);
            }
        }
    }
}
コード例 #3
0
void 
CompGridVTOBC::operator()( FArrayBox&           a_state,
			   const Box&           a_valid,
			   const ProblemDomain& a_domain,
			   Real                 a_dx,
			   bool                 a_homogeneous)
{
  const Box& domainBox = a_domain.domainBox();
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      if (!a_domain.isPeriodic(idir))
        {
          for (SideIterator sit; sit.ok(); ++sit)
            {
              Side::LoHiSide side = sit();              
              if (a_valid.sideEnd(side)[idir] == domainBox.sideEnd(side)[idir])
                {
                  // Dirichlet BC
                  int isign = sign(side);
                  Box toRegion = adjCellBox(a_valid, idir, side, 1);
                  // include corner cells if possible by growing toRegion in transverse direction
                  toRegion.grow(1);
                  toRegion.grow(idir, -1);
                  toRegion &= a_state.box();
                  for (BoxIterator bit(toRegion); bit.ok(); ++bit)
                    {
                      IntVect ivTo = bit();                     
                      IntVect ivClose = ivTo - isign*BASISV(idir);
                      for (int ighost=0;ighost<m_nGhosts[0];ighost++,ivTo += isign*BASISV(idir))
                        {
                          //for (int icomp = 0; icomp < a_state.nComp(); icomp++) a_state(ivTo, icomp) = 0.0;
                          IntVect ivFrom = ivClose;
                          
                          // hardwire to linear BCs for now
                          for (int icomp = 0; icomp < a_state.nComp() ; icomp++)
                            {
                              if (m_bcDiri[idir][side][icomp]) 
                                {
                                  a_state(ivTo, icomp) = (-1.0)*a_state(ivFrom, icomp);
                                }
                              else 
                                {
                                  a_state(ivTo, icomp) = (1.0)*a_state(ivFrom, icomp);
                                }
                            }   
                        }
                    } // end loop over cells
                } // if ends match
            } // end loop over sides
        } // if not periodic in this direction
    } // end loop over directions    
}
コード例 #4
0
ファイル: NodeBCFunc.cpp プロジェクト: dtgraves/EBAMRCNS
void NodeNeumBC(NodeFArrayBox&  a_state,
                const Box&      a_valid,
                Real            a_dx,
                bool            a_homogeneous,
                BCValueHolder   a_value)
{
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      for (SideIterator sit; sit.ok(); ++sit)
        {
          NodeNeumBC(a_state, a_valid, a_dx, a_homogeneous, a_value, idir,sit());
        }
    }
}
コード例 #5
0
void
EBCompositeMACProjector::
correctVelocityComponent(Vector<LayoutData< Vector< BaseIVFAB<Real> * > >* >      &  a_coveredVelLo,
                         Vector<LayoutData< Vector< BaseIVFAB<Real> * > >* >      &  a_coveredVelHi,
                         const Vector< LayoutData< Vector< Vector<VolIndex> > >* >&  a_coveredFaceLo,
                         const Vector< LayoutData< Vector< Vector<VolIndex> > >* >&  a_coveredFaceHi,
                         const Vector< LayoutData< Vector< IntVectSet > >* >      &  a_coveredSetsLo,
                         const Vector< LayoutData< Vector< IntVectSet > >* >      &  a_coveredSetsHi,
                         const Vector<LevelData<EBFluxFAB>* >                     &  a_macGradient,
                         int                                                         a_coveredFaceDir,
                         int                                                         a_velComp)
{
  CH_TIME("EBCompositeMACProjector::correctVelocityComponent");
  for (int ilev = 0; ilev < m_numLevels; ilev++)
    {
      for (SideIterator sit; sit.ok(); ++sit)
        {
          LayoutData<Vector<BaseIVFAB<Real>* > >*        velPtr = NULL;
          const LayoutData<Vector<Vector<VolIndex> > >* facePtr = NULL;
          const LayoutData<Vector<IntVectSet>  >*       setsPtr = NULL;
          if (sit() == Side::Lo)
            {
              velPtr  =  a_coveredVelLo[ilev];
              facePtr = a_coveredFaceLo[ilev];
              setsPtr = a_coveredSetsLo[ilev];
            }
          else
            {
              velPtr  =  a_coveredVelHi[ilev];
              facePtr = a_coveredFaceHi[ilev];
              setsPtr = a_coveredSetsHi[ilev];
            }

          const LevelData<EBFluxFAB>& macGradient = *a_macGradient[ilev];
          for (DataIterator dit = m_eblg[ilev].getDBL().dataIterator(); dit.ok(); ++dit)
            {
              const EBFluxFAB       & macGradFAB  = macGradient[dit()];
              const Vector<VolIndex>& coveredFace =  (*facePtr)[dit()][a_coveredFaceDir];
              const IntVectSet      & coveredSets =  (*setsPtr)[dit()][a_coveredFaceDir];
              BaseIVFAB<Real>       & coveredVel  = *((*velPtr)[dit()][a_coveredFaceDir]);
              const EBISBox& ebisBox = m_eblg[ilev].getEBISL()[dit()];

              correctVelocityComponent(coveredVel, coveredFace, coveredSets, macGradFAB, ebisBox,
                                       a_coveredFaceDir, sit(), a_velComp);
            }
        }
    }
}
コード例 #6
0
void
LevelFluxRegisterEdge::incrementFine(
                                     FArrayBox& a_fineFlux,
                                     Real a_scale,
                                     const DataIndex& a_fineDataIndex,
                                     const Interval& a_srcInterval,
                                     const Interval& a_dstInterval)
{
  CH_assert(isDefined());
  CH_assert(!a_fineFlux.box().isEmpty());
  CH_assert(a_srcInterval.size() == a_dstInterval.size());
  CH_assert(a_srcInterval.begin() >= 0);
  CH_assert(a_srcInterval.end() < a_fineFlux.nComp());
  CH_assert(a_dstInterval.begin() >= 0);
  CH_assert(a_dstInterval.end() < m_nComp);

  int edgeDir = -1;
  for (int sideDir = 0; sideDir<SpaceDim; sideDir++)
    {
      if (a_fineFlux.box().type(sideDir) == IndexType::CELL)
        {
          edgeDir = sideDir;
        }
    }
  CH_assert(edgeDir >= 0);
  CH_assert(edgeDir < SpaceDim);

  for (int faceDir=0; faceDir<SpaceDim; faceDir++)
    {
      if (faceDir != edgeDir)
        {

          SideIterator sit;
          for (sit.begin(); sit.ok(); ++sit)
            {
              incrementFine(a_fineFlux,
                            a_scale,
                            a_fineDataIndex,
                            a_srcInterval,
                            a_dstInterval,
                            faceDir,
                            sit());
            }
        }
    }
}
コード例 #7
0
ファイル: correct1d2dTest.cpp プロジェクト: rsnemmen/Chombo
void setBorkedFlux(EBFluxFAB&          a_flux,
                   const EBISBox&      a_ebisBox,
                   const Box&          a_box,
                   const RealVect&     a_fluxVal,
                   const BaseFab<int>& a_map)
{
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      Real bogval = 0;
      //the bogus value will be zero so it will not
      //do to have the correct value be zero
      if (Abs(a_fluxVal[idir]) < 1.0e-3) bogval = 1.0;

      a_flux[idir].setVal(a_fluxVal[idir]);
      //if i am in a 1d box and the box next to me
      //is 2d, set the border flux to
      for (SideIterator sit; sit.ok(); ++sit)
        {
          Box borderBox;
          if (sit() == Side::Lo)
            {
              borderBox = adjCellLo(a_box, idir,  -1);
            }
          else
            {
              borderBox = adjCellHi(a_box, idir,  -1);
            }
          for (BoxIterator bit(borderBox); bit.ok(); ++bit)
            {
              const IntVect& thisIV = bit();
              IntVect thatIV = thisIV + sign(sit())*BASISV(idir);
              if ((a_map(thisIV, 0) == 1) && (a_map(thatIV, 0) == 2))
                {
                  Vector<FaceIndex> faces = a_ebisBox.getAllFaces(thisIV, idir, sit());
                  for (int iface = 0; iface < faces.size(); iface++)
                    {
                      a_flux[idir](faces[iface],0) = bogval;
                    }
                }
            }
        }
    }

}
コード例 #8
0
void
EBFluxRegister::
incrementCoarseIrregular(const BaseIFFAB<Real>& a_coarFlux,
                         const Real&            a_scale,
                         const DataIndex&       a_coarDatInd,
                         const Interval&        a_variables,
                         const int&             a_dir)
{
  if (m_hasEBCF)
    {
      EBFaceFAB facefab;
      bool hasCells = copyBIFFToEBFF(facefab, a_coarFlux, m_eblgCoar.getDBL()[a_coarDatInd], m_eblgCoar.getEBISL()[a_coarDatInd]);
      if (hasCells)
        {
          for (SideIterator sit; sit.ok(); ++sit)
            {
              incrementCoarIrreg(facefab, a_scale, a_coarDatInd, a_variables, a_dir, sit());
            }
        }
    }
}
コード例 #9
0
void
LevelFluxRegisterEdge::setToZero()
{

  for (DataIterator dit = m_regCoarse.dataIterator(); dit.ok(); ++dit)
    m_regCoarse[dit()].setVal(0.0);


  SideIterator side;
  for (int idir=0 ; idir<SpaceDim; ++idir)
  {
    for (side.begin(); side.ok(); ++side)
    {
      LevelData<FluxBox>& fineReg = m_fabFine[index(idir, side())];


      for (DataIterator dit = fineReg.dataIterator(); dit.ok(); ++dit)
        fineReg[dit()].setVal(0.0);

    }
  }
}
コード例 #10
0
ファイル: correct1d2dTest.cpp プロジェクト: rsnemmen/Chombo
Real
divergence(const EBFluxFAB&  a_func,
           const RealVect&   a_bndryFlux,
           const EBISBox&    a_ebisBox,
           const VolIndex&   a_vof,
           const Real&       a_dx)
{
  Real retval = 0;

  Real bndryArea = a_ebisBox.bndryArea(a_vof);
  RealVect normal = a_ebisBox.normal(a_vof);
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      Real bndryFlux    = a_bndryFlux[idir]; //normal already dealt with
      Real bndryContrib = -bndryFlux*bndryArea*normal[idir];
      Real openContrib = 0;
      if (bndryArea > 1.0e-3)
        {
          openContrib = 0;
        }
      for (SideIterator sit; sit.ok(); ++sit)
        {
          int isign = sign(sit());
          Real rsign = isign;
          Vector<FaceIndex> faces = a_ebisBox.getFaces(a_vof, idir, sit());
          for (int iface = 0; iface < faces.size(); ++iface)
            {
              Real areaFrac = a_ebisBox.areaFrac(faces[iface]);
              Real faceFlux = a_func[idir](faces[iface], 0);
              openContrib += rsign*faceFlux*areaFrac;
            }
        }
      retval += openContrib + bndryContrib;

    }
  retval /= a_dx;
  return retval;
}
コード例 #11
0
ファイル: levelDivTest.cpp プロジェクト: rsnemmen/Chombo
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;
    }
}
コード例 #12
0
ファイル: compare.cpp プロジェクト: rsnemmen/Chombo
// this function averages down the fine solution to the valid
// regions of the computed solution, then subtracts ir from
// the computed solution.  (error is exact-computed)
void computeAMRError(Vector<LevelData<FArrayBox>* >&       a_error,
                     const Vector<string>&                 a_errorVars,
                     const Vector<LevelData<FArrayBox>* >& a_computedSoln,
                     const Vector<string>&                 a_computedVars,
                     const Vector<DisjointBoxLayout>&      a_computedGrids,
                     const Real                            a_computedDx,
                     const Vector<int>&                    a_computedRefRatio,
                     const Vector<LevelData<FArrayBox>* >& a_exactSoln,
                     const Vector<string>&                 a_exactVars,
                     const Real                            a_exactDx,
                     Real                                  a_bogus_value,
                     bool                                  a_HOaverage,
                     bool                                  a_computeRelativeError)
{
  int numLevels = a_computedSoln.size();

  CH_assert(a_exactSoln.size() == 1);
  CH_assert(a_error.size() == numLevels);
  CH_assert(a_exactDx <= a_computedDx);
  CH_assert(a_computedRefRatio.size() >= numLevels - 1);

  if (a_exactDx == a_computedDx)
  {
    cerr << "Exact dx and computed dx are equal." << endl;
  }

  // check whether input file selects "sum all variables"
  bool sumAll = false;
  ParmParse pp;
  pp.query("sumAll",sumAll);
  
  // const DisjointBoxLayout& exactGrids = a_exactSoln[0]->getBoxes();

  Real dxLevel = a_computedDx;

  // do a bit of sleight-of-hand in the case where there are no
  // ghost cells in the exact solution -- allocate a temporary which
  // _has_ ghost cells, and do a copyTo
  LevelData<FArrayBox>* exactSolnPtr = NULL;
  bool allocatedMemory = false;
  if (a_exactSoln[0]->ghostVect() == IntVect::Zero)
    {
      exactSolnPtr = new LevelData<FArrayBox>(a_exactSoln[0]->getBoxes(),
                                              a_exactSoln[0]->nComp(),
                                              IntVect::Unit);
      a_exactSoln[0]->copyTo(*exactSolnPtr);

      allocatedMemory = true;
     }
   else
     {
       // if there are ghost cells, we can use the exactSoln as-is
       exactSolnPtr = a_exactSoln[0];
     }
   LevelData<FArrayBox>& exactSolnRef = *exactSolnPtr;

   // first need to set boundary conditions on exactsoln
   // this is for the Laplacian which is needed in AverageHO
   DataIterator ditFine = exactSolnRef.dataIterator();
   DomainGhostBC exactBC;
   Interval exactComps(0, a_exactVars.size() - 1);
   for (int dir = 0; dir < SpaceDim; dir++)
   {
     SideIterator sit;
     for (sit.reset(); sit.ok(); ++sit)
     {
       // use HO extrapolation at physical boundaries
       HOExtrapBC thisBC(dir, sit(), exactComps);
       exactBC.setBoxGhostBC(thisBC);
     }
   }

   for (ditFine.begin(); ditFine.ok(); ++ditFine)
   {
     FArrayBox& thisFineSoln = exactSolnRef[ditFine()];
     const Box& fineBox = exactSolnRef.getBoxes()[ditFine()];
     exactBC.applyInhomogeneousBCs(thisFineSoln, fineBox, a_exactDx);
   }
   exactSolnRef.exchange(exactComps);

   // outer loop is over levels
   for (int level = 0; level < numLevels; level++)
   {
     LevelData<FArrayBox>& thisLevelError = *a_error[level];
     LevelData<FArrayBox>& thisLevelComputed = *a_computedSoln[level];

     // compute refinement ratio between solution at this level
     // and exact solution
     Real nRefTemp = (dxLevel / a_exactDx);
     int nRefExact = (int) nRefTemp;

     // this is to do rounding properly if necessary
     if (nRefTemp - nRefExact > 0.5) nRefExact += 1;

     // make sure it's not zero
     if (nRefExact == 0) nRefExact =1;

     const DisjointBoxLayout levelGrids = a_error[level]->getBoxes();
     const DisjointBoxLayout fineGrids = a_exactSoln[0]->getBoxes();
     DisjointBoxLayout coarsenedFineGrids;

     // petermc, 14 Jan 2014: Replace this because fineGrids might
     // not be coarsenable by nRefExact.
     // coarsen(coarsenedFineGrids, fineGrids, nRefExact);
     int nCoarsenExact = nRefExact;
     while ( !fineGrids.coarsenable(nCoarsenExact) && (nCoarsenExact > 0) )
       {
         // Divide nCoarsenExact by 2 until fineGrids is coarsenable by it.
         nCoarsenExact /= 2;
       }
     if (nCoarsenExact == 0)
       {
         nCoarsenExact = 1;
       }
     coarsen(coarsenedFineGrids, fineGrids, nCoarsenExact);

     int numExact = a_exactVars.size();
     LevelData<FArrayBox> averagedExact(coarsenedFineGrids, numExact);

     Box fineRefBox(IntVect::Zero, (nCoarsenExact-1)*IntVect::Unit);

     // average fine solution down to coarsened-fine level
     // loop over grids and do HO averaging down
     //DataIterator crseExactDit = coarsenedFineGrids.dataIterator();
     for (ditFine.reset(); ditFine.ok(); ++ditFine)
       {
         const Box fineBox = exactSolnRef.getBoxes()[ditFine()];
         FArrayBox fineTemp(fineBox, 1);
         Box coarsenedFineBox(fineBox);
         coarsenedFineBox.coarsen(nCoarsenExact);
         if (a_exactDx < a_computedDx)
           {
             // loop over components
             for (int comp = 0; comp < numExact; comp++)
               {
                 Box coarseBox(coarsenedFineGrids.get(ditFine()));
                 coarseBox &= coarsenedFineBox;
                 
                 if (!coarseBox.isEmpty())
                   {
                     // for now, this is a quick and dirty way to avoid
                     // stepping out of bounds if there are no ghost cells.
                     // LapBox will be the box over which we are
                     // able to compute the Laplacian.
                     Box LapBox = exactSolnRef[ditFine()].box();
                     LapBox.grow(-1);
                     LapBox &= fineBox;
                     fineTemp.setVal(0.0);
                     int doHO = 0;
                     if (a_HOaverage)
                       { 
                         doHO = 1;
                       }
                     
                     // average by default
                     int doAverage = 1;
                     
                     if (sumAll || sumVar(a_exactVars[comp]))
                       {
                         doAverage = 0;
                       }
                     
                     // average or sum, based on booleans
                     FORT_AVERAGEHO(CHF_FRA1(averagedExact[ditFine], comp),
                                    CHF_CONST_FRA1(exactSolnRef[ditFine], comp),
                                    CHF_FRA1(fineTemp, 0),
                                    CHF_BOX(coarseBox),
                                    CHF_BOX(LapBox),
                                    CHF_CONST_INT(nCoarsenExact),
                                    CHF_BOX(fineRefBox),
                                    CHF_INT(doHO),
                                    CHF_INT(doAverage));
                   } // end if crseBox not empty
               } // end loop over comps
           }
         else
           {
             // if cell sizes are the same, then copy
             averagedExact[ditFine].copy(exactSolnRef[ditFine]);
           }
         
       } // end loop over exact solution boxes
     
     int nRefineComputed = nRefExact / nCoarsenExact;
     LevelData<FArrayBox>* thisLevelComputedRefinedPtr = &thisLevelComputed;
     LevelData<FArrayBox>* thisLevelErrorRefinedPtr = &thisLevelError;
     if (nRefineComputed > 1)
       {
         // Do piecewise constant interpolation (replication) by nRefineComputed
         // on thisLevelComputed.
         DisjointBoxLayout levelRefinedGrids;
         refine(levelRefinedGrids, levelGrids, nRefineComputed);
         int nCompComputed = thisLevelComputed.nComp();
         IntVect ghostVectComputed = nRefineComputed * thisLevelComputed.ghostVect();
         thisLevelComputedRefinedPtr =
           new LevelData<FArrayBox>(levelRefinedGrids, nCompComputed, ghostVectComputed);
         ProblemDomain levelDomain = levelRefinedGrids.physDomain();
         FineInterp interpolator(levelRefinedGrids, nCompComputed, nRefineComputed,
                                 levelDomain);
         interpolator.pwcinterpToFine(*thisLevelComputedRefinedPtr, thisLevelComputed);

         int nCompErr = thisLevelError.nComp();
         IntVect ghostVectErr = nRefineComputed * thisLevelError.ghostVect();
         thisLevelErrorRefinedPtr =
           new LevelData<FArrayBox>(levelRefinedGrids, nCompErr, ghostVectErr);
       }

     // initialize error to 0
     // also initialize error to a bogus value
     DataIterator levelDit = thisLevelError.dataIterator();
     for (levelDit.begin(); levelDit.ok(); ++levelDit)
       {
         (*thisLevelErrorRefinedPtr)[levelDit].setVal(a_bogus_value);
       }

     Box refComputedBox(IntVect::Zero, (nRefineComputed-1)*IntVect::Unit);
     // loop over variables
     for (int nErr = 0; nErr < a_errorVars.size(); nErr++)
       {
         string thisErrVar = a_errorVars[nErr];
         bool done = false;

         // first loop over exact variables
         for (int exactComp = 0; exactComp < a_exactVars.size(); exactComp++)
           {
             string thisExactVar = a_exactVars[exactComp];
             // check if this exact variable is "the one"
             if ((thisExactVar == thisErrVar) || nonAverageVar(thisErrVar))
               {
                 int computedComp = 0;
                 // now loop over computed variables
                 while (!done && (computedComp < a_computedVars.size()))
                   {
                     if (a_computedVars[computedComp] == thisErrVar)
                       {
                         if (!nonAverageVar(thisErrVar))
                           {
                             // copy averaged exact solution -> error
                             // and then subtract computed solution
                             Interval exactInterval(exactComp, exactComp);
                             Interval errorInterval(nErr, nErr);
                             averagedExact.copyTo(exactInterval, *thisLevelErrorRefinedPtr,
                                                  errorInterval);
                           }
                         
                         DataIterator levelDit = thisLevelError.dataIterator();
                         for (levelDit.reset(); levelDit.ok(); ++levelDit)
                           {
                             FArrayBox& thisComputedRefined = (*thisLevelComputedRefinedPtr)[levelDit];
                             FArrayBox& thisErrorRefined = (*thisLevelErrorRefinedPtr)[levelDit];
                             if (a_computeRelativeError)
                               {
                                 // do this a little strangely -- relative
                                 // error is one - computed/exact.
                                 thisErrorRefined.divide(thisComputedRefined, computedComp, nErr, 1);
                                 thisErrorRefined.invert(-1.0, nErr, 1);
                                 thisErrorRefined.plus(1.0, nErr, 1);
                               }
                             else
                               {
                                 thisErrorRefined.minus(thisComputedRefined, computedComp, nErr, 1);
                               }
                             if (nRefineComputed > 1)
                               {
                                 FArrayBox& thisError = thisLevelError[levelDit];
                                 Box coarseBox = thisError.box();
                                 // Average thisErrorRefined to thisError.
                                 int doHO = 0;
                                 if (a_HOaverage)
                                   { 
                                     doHO = 1;
                                   }
                                 CH_assert(doHO == 0);

                                 // for now, this is a quick and dirty way to avoid
                                 // stepping out of bounds if there are no ghost cells.
                                 // LapBox will be the box over which we are
                                 // able to compute the Laplacian.
                                 Box LapBox = thisErrorRefined.box();
                                 LapBox.grow(-1);
                                 // LapBox &= fineBox;
                                 FArrayBox fineTemp(thisErrorRefined.box(), 1);
                                 fineTemp.setVal(0.0);
                                 
                                 // average by default
                                 int doAverage = 1;
                                 // average or sum, based on booleans
                                 FORT_AVERAGEHO(CHF_FRA1(thisError, nErr),
                                                CHF_CONST_FRA1(thisErrorRefined, nErr),
                                                CHF_FRA1(fineTemp, 0),
                                                CHF_BOX(coarseBox),
                                                CHF_BOX(LapBox),
                                                CHF_CONST_INT(nRefineComputed),
                                                CHF_BOX(refComputedBox),
                                                CHF_INT(doHO),
                                                CHF_INT(doAverage));
                                 
                               }
                           } // end loop over coarse grids
                         
                         done = true;
                       } // if computedVar is a_errorVar
                     
                     computedComp += 1;
                   } // end loop over a_computedVars
                 
                 if (!done)
                   {
                     pout() << "Variable " << thisErrVar  << " not found!!!" << endl;
                     MayDay::Error();
                   }
               } // end if this exactVar is correct
           } // end loop over exact variables
       } // end loop over errors
     
     if (nRefineComputed > 1)
       {
         delete thisLevelComputedRefinedPtr;
         delete thisLevelErrorRefinedPtr;
       }
     
     // now need to set covered regions to 0
     if (level < numLevels - 1)
       {
         // will need to loop over all boxes in finer level, not just
         // those on this processor...
         const BoxLayout& finerGrids = a_computedSoln[level + 1]->boxLayout();
         LayoutIterator fineLit = finerGrids.layoutIterator();
         
         // outer loop over this level's grids, since there are fewer of them
         DataIterator levelDit = thisLevelError.dataIterator();
         for (levelDit.reset(); levelDit.ok(); ++levelDit)
           {
             const Box& coarseBox = levelGrids[levelDit()];
             FArrayBox& thisError = thisLevelError[levelDit()];
             int numError = thisError.nComp();
             
             for (fineLit.reset(); fineLit.ok(); ++fineLit)
               {
                 Box fineBox(finerGrids[fineLit()]);
                 // now coarsen box down to this level
                 fineBox.coarsen(a_computedRefRatio[level]);
                 // if coarsened fine box intersects error's box, set
                 // overlap to 0
                 fineBox &= coarseBox;
                 if (!fineBox.isEmpty())
                   {
                     thisError.setVal(0.0, fineBox, 0, numError);
                   }
               } // end loop over finer-level grids
           } // end loop over this-level grids
         
         // this is a good place to update dx as well
         dxLevel = dxLevel / a_computedRefRatio[level];
       } // end if there is a finer level
     
     thisLevelError.exchange();
   } // end loop over levels
   
   // clean up if we need to
   if (allocatedMemory)
     {
       delete exactSolnPtr;
       exactSolnPtr = NULL;
     }
}
コード例 #13
0
ファイル: EBLevelTGA.cpp プロジェクト: rsnemmen/Chombo
void
EBLevelTGA::
setSourceGhostCells(LevelData<EBCellFAB>&    a_src,
                    const DisjointBoxLayout& a_grids,
                    int a_lev)
{
  int ncomp = a_src.nComp();
  for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
    {
      const Box& grid   = a_grids.get(dit());
      const Box& srcBox = a_src[dit()].box();
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          for (SideIterator sit; sit.ok(); ++sit)
            {
              int iside = sign(sit());
              Box bc_box = adjCellBox(grid, idir, sit(), 1);

              for (int jdir = 0; jdir < SpaceDim; jdir++)
                {
                  //want corners too
                  if (jdir != idir)
                    {
                      bc_box.grow(jdir, 1);
                    }
                }

              //if fails might not have a ghost cell.
              bc_box &= m_eblg[a_lev].getDomain().domainBox();

              CH_assert(srcBox.contains(bc_box));
              if (grid.size(idir) >= 4)
                {
                  FORT_HORESGHOSTBC(CHF_FRA(a_src[dit()].getSingleValuedFAB()),
                                    CHF_BOX(bc_box),
                                    CHF_CONST_INT(idir),
                                    CHF_CONST_INT(iside),
                                    CHF_CONST_INT(ncomp));
                }
              else
                {
                  // valid region not wide enough to apply HOExtrap -- drop
                  // to linear extrap
                  FORT_RESGHOSTBC(CHF_FRA(a_src[dit()].getSingleValuedFAB()),
                                  CHF_BOX(bc_box),
                                  CHF_CONST_INT(idir),
                                  CHF_CONST_INT(iside),
                                  CHF_CONST_INT(ncomp));
                }
              IntVectSet ivs = m_eblg[a_lev].getEBISL()[dit()].getIrregIVS(bc_box);
              for (VoFIterator vofit(ivs, m_eblg[a_lev].getEBISL()[dit()].getEBGraph()); vofit.ok(); ++vofit)
                {
                  for (int icomp = 0; icomp < ncomp; icomp++)
                    {
                      Real valNeigh = 0;
                      Vector<FaceIndex> faces = m_eblg[a_lev].getEBISL()[dit()].getFaces(vofit(), idir, flip(sit()));
                      for (int iface = 0; iface < faces.size(); iface++)
                        {
                          VolIndex vofNeigh = faces[iface].getVoF(flip(sit()));
                          valNeigh += a_src[dit()](vofNeigh, icomp);
                        }
                      if (faces.size() > 1) valNeigh /= faces.size();
                      a_src[dit()](vofit(), icomp) = valNeigh;
                    }
                }
            }
        }
    }
}
コード例 #14
0
void
EBCompositeMACProjector::
kappaDivergence(Vector<LevelData<EBCellFAB>* >&              a_divu,
                Vector<LevelData<EBFluxFAB>* >&              a_velo,
                const Vector<LevelData<BaseIVFAB<Real> >* >* a_boundaryVelo)
{
  CH_TIME("EBCompositeMACProjector::kappaDivergence");
  for (int ilev = 0; ilev < m_numLevels; ilev++)
    {
      EBLevelMACProjector::setCurLevel(ilev);

      EBFluxFactory fluxfact(m_eblg[ilev].getEBISL());
      //need one ghost cell so that exchange is meaningful
      LevelData<EBFluxFAB> centroidVelocity(m_eblg[ilev].getDBL(), 1, IntVect::Unit, fluxfact);

      Interval interv(0, 0);
      LevelData<EBFluxFAB>& velExch = (LevelData<EBFluxFAB>&)(*a_velo[ilev]);
      velExch.exchange(interv);

      //interpolate velocity to face centroids
      EBArith::interpolateFluxToCentroids(centroidVelocity, *a_velo[ilev],
                                          m_eblg[ilev].getDBL(), m_eblg[ilev].getEBISL(), m_eblg[ilev].getDomain());

      centroidVelocity.exchange(interv);
      LevelData<BaseIVFAB<Real> >*  levelBoundaryVel = NULL;
      if (a_boundaryVelo != NULL)
        {
          levelBoundaryVel = (*a_boundaryVelo)[ilev];
        }
      //compute the divergence igoring other levels
      macKappaDivergence(*a_divu[ilev], centroidVelocity,
                         m_eblg[ilev].getDBL(), m_eblg[ilev].getEBISL(),
                         m_eblg[ilev].getDomain(),   m_dx[ilev],
                         levelBoundaryVel);

      //use flux registers to correct divergence
      //at coarse-fine interface with velocity from finer
      //level
      if (ilev < (m_numLevels-1))
        {
          Real incrScale = 1.0;
          m_fluxReg[ilev]->setToZero();
          //increment with coarse values
          for (DataIterator dit = m_eblg[ilev].getDBL().dataIterator();dit.ok(); ++dit)
            {
              const EBFluxFAB& veloFlux = (*a_velo[ilev])[dit()];
              for (int idir = 0; idir < SpaceDim; idir++)
                {
                  // This assumes that embedded boundaries and coarse-fine boundaries do not cross.
                  // To remove this assumption use incrementCoarseBoth.
                  m_fluxReg[ilev]->incrementCoarseRegular(veloFlux[idir], incrScale, dit(), interv, idir);
                }
            }
          //increment with fine velocities
          for (DataIterator dit = m_eblg[ilev+1].getDBL().dataIterator();dit.ok(); ++dit)
            {
              const EBFluxFAB& veloFlux = (*a_velo[ilev+1])[dit()];
              for (int idir = 0; idir < SpaceDim; idir++)
                {
                  for (SideIterator sit; sit.ok(); ++sit)
                    {
                      // This assumes that embedded boundaries and coarse-fine boundaries do not cross.
                      // To remove this assumption use incrementFineBoth.
                      m_fluxReg[ilev]->incrementFineRegular(veloFlux[idir], incrScale, dit(), interv, idir, sit());
                    }
                }
            }
          //reflux
          Real reflScale = 1.0/m_dx[ilev][0];
          m_fluxReg[ilev]->reflux(*a_divu[ilev], interv, reflScale);
        }
    }
}
コード例 #15
0
void
EBFluxRegister::
incrementRedistRegister(EBCoarToCoarRedist& a_register,
                        const Interval&     a_variables,
                        const Real&         a_scale)
{
  if (m_hasEBCF)
    {
      LevelData<BaseIVFAB<Real> >& registerMass = a_register.m_regsCoar;
      LayoutData<IntVectSet>&      registerSets = a_register.m_setsCoar;
      //reflux into an empty LevelData<EBCellFAB>
      //Multiply this by (kappa)(1-kappa)
      //add result into register mass
      EBCellFactory ebcfCoar(m_eblgCoar.getEBISL());
      LevelData<EBCellFAB> increment(m_eblgCoar.getDBL(), m_nComp, m_saveCoar.ghostVect(), ebcfCoar);
      EBLevelDataOps::clone (increment, m_saveCoar);
      EBLevelDataOps::setVal(increment, 0.0);

      reflux(increment, a_variables, a_scale, true);

      for (DataIterator dit = m_eblgCoar.getDBL().dataIterator(); dit.ok(); ++dit)
        {
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              for (SideIterator sit; sit.ok(); ++sit)
                {
                  int iindex = index(idir, sit());
                  Vector<IntVectSet> setsCoar = (m_setsCoar[iindex])[dit()];
                  for (int iset = 0; iset < setsCoar.size(); iset++)
                    {
                      const IntVectSet& setCoa  = registerSets[dit()];
                      const IntVectSet& setReg  = setsCoar[iset];
                      IntVectSet set = setCoa;
                      set &= setReg;
                      const EBISBox& ebisBox =m_eblgCoar.getEBISL()[dit()];
                      for (VoFIterator vofit(set, ebisBox.getEBGraph()); vofit.ok(); ++vofit)
                        {
                          const VolIndex& vof = vofit();

                          int ibleck = 0;
                          if ((vof.gridIndex() == ivdebugfr) && EBFastFR::s_verbose)
                            {
                              ibleck = 1;
                              pout()    << setprecision(10)
                                        << setiosflags(ios::showpoint)
                                        << setiosflags(ios::scientific);
                              pout() << "incrcotoco:" << endl;

                            }

                          for (int icomp = a_variables.begin(); icomp <= a_variables.end(); icomp++)
                            {
                              Real extraMass = increment[dit()](vofit(), icomp);
                              Real oldMass   =  registerMass[dit()](vofit(), icomp);
                              Real newMass   = oldMass + extraMass;
                              Real diff = extraMass;
                              if (ibleck == 1)
                                {
                                  pout() << "( " << oldMass << ", " << newMass << ", "  << diff << ")";
                                }

                              registerMass[dit()](vofit(), icomp) += extraMass;

                              //set increment to zero in case it gets
                              //hit twice (more than one direction or
                              //whatever
                              increment[dit()](vof, icomp) = 0;

                            } //loop over comps
                          if (ibleck == 1)
                            {
                              ibleck = 0;
                              pout() << endl;
                            }
                        }//loop over vofs in the set
                    }//loop over sets in this coarse box
                } //loop over sides
            } //loop over directions
        } //dataiterator loop
    } //You are using Bonetti's defense against me, uh?
} //I thought it fitting, considering the rocky terrain.
コード例 #16
0
ファイル: fluxRegisterTest.cpp プロジェクト: rsnemmen/Chombo
int fluxRegTest()
{
#ifdef CH_USE_HDF5
  writeLevel(NULL);
#endif
  int retflag = 0;

  int nref;
  Vector<Box> fineboxes;
  Vector<Box> coarboxes;
  Box domf, domc;

  //set coarse and fine grid boxes
  setDefaults(nref, coarboxes,  fineboxes, domc, domf);

  {
    // first do nonperiodic test

    Interval interv(0,0);

    //set up coarse and fine grids
    DisjointBoxLayout dblFineCell,dblCoarCell;
    Vector<int> procAssignCoar(coarboxes.size(), 0);
    Vector<int> procAssignFine(fineboxes.size(), 0);
    LoadBalance(procAssignCoar, coarboxes);
    LoadBalance(procAssignFine, fineboxes);

    dblCoarCell.define(coarboxes, procAssignCoar);
    dblFineCell.define(fineboxes, procAssignFine);

    dblCoarCell.close();
    dblFineCell.close();

    LevelData<FArrayBox> coarData(dblCoarCell, 1);
    LevelData<FArrayBox> fineData(dblFineCell, 1);

    DataIterator coarIt = coarData.dataIterator();
    DataIterator fineIt = fineData.dataIterator();

    LevelFluxRegister fluxReg(dblFineCell,
                              dblCoarCell,
                              domf, nref,
                              1);

    //set data and flux registers to zero
    for (coarIt.reset(); coarIt.ok(); ++coarIt)
      coarData[coarIt()].setVal(0.);

    fluxReg.setToZero();

    //increment and decrement
    //flux registers with equal size fluxes
    Real scale = 1.0;
    Real fluxVal = 4.77;
    for (coarIt.reset(); coarIt.ok(); ++coarIt)
      {
        const Box&  cellBoxCoar = dblCoarCell.get(coarIt());
        for (int idir = 0; idir < SpaceDim; idir++)
          {
            Box edgeBoxCoar = surroundingNodes(cellBoxCoar, idir);
            FArrayBox edgeFlux(edgeBoxCoar,1);
            edgeFlux.setVal(fluxVal);
            DataIndex dataIndGlo = coarIt();
            fluxReg.incrementCoarse(edgeFlux, scale,
                                    dataIndGlo, interv, interv, idir);
          }
      }

    for (fineIt.reset(); fineIt.ok(); ++fineIt)
      {
        const Box&  cellBoxFine = dblFineCell.get(fineIt());
        for (int idir = 0; idir < SpaceDim; idir++)
          {
            Box edgeBoxFine = surroundingNodes(cellBoxFine, idir);
            FArrayBox edgeFlux(edgeBoxFine,1);
            edgeFlux.setVal(fluxVal);
            SideIterator sit;
            DataIndex dataIndGlo = fineIt();
            for (sit.reset(); sit.ok(); ++sit)
              {
                fluxReg.incrementFine(edgeFlux, scale,
                                      dataIndGlo,  interv, interv, idir, sit());
              }
          }
      }

    //reflux what ought to be zero into zero and the result should be zero
    fluxReg.reflux(coarData, scale);

    DataIterator datIt = coarData.dataIterator();
    for (datIt.reset(); datIt.ok(); ++datIt)
      {
        const FArrayBox& data = coarData[datIt()];
        Real rmax = Abs(data.max());
        Real rmin = Abs(data.min());
        if ((rmax > 1.0e-10)||(rmin > 1.0e-10))
          {
            pout() << indent << pgmname
                 << ": fluxRegister failed the nonperiodic conservation test = " << endl;
            retflag = 1;
          }
      }
  }
  // end non-periodic test

  // now do the same thing all over again, this time with a periodic domain
  {
    ProblemDomain coarseDomain(domc);
    ProblemDomain fineDomain(domf);
    for (int dir=0; dir<SpaceDim; dir++)
      {
        coarseDomain.setPeriodic(dir, true);
        fineDomain.setPeriodic(dir, true);
      }

    Interval interv(0,0);

    //set up coarse and fine grids
    DisjointBoxLayout dblFineCell,dblCoarCell;
    Vector<int> procAssignCoar(coarboxes.size(), 0);
    Vector<int> procAssignFine(fineboxes.size(), 0);
    LoadBalance(procAssignCoar, coarboxes);
    LoadBalance(procAssignFine, fineboxes);

    dblCoarCell.define(coarboxes, procAssignCoar, coarseDomain);
    dblFineCell.define(fineboxes, procAssignFine, fineDomain);

    dblCoarCell.close();
    dblFineCell.close();

    LevelData<FArrayBox> coarData(dblCoarCell, 1);
    LevelData<FArrayBox> fineData(dblFineCell, 1);

    DataIterator coarIt = coarData.dataIterator();
    DataIterator fineIt = fineData.dataIterator();

    LevelFluxRegister fluxReg(dblFineCell,
                              dblCoarCell,
                              fineDomain, nref,
                              1);

    //set data and flux registers to zero
    for (coarIt.reset(); coarIt.ok(); ++coarIt)
      coarData[coarIt()].setVal(0.);

    fluxReg.setToZero();

    //increment and decrement
    //flux registers with equal size fluxes
    Real scale = 1.0;
    Real fluxVal = 4.77;
    for (coarIt.reset(); coarIt.ok(); ++coarIt)
      {
        const Box&  cellBoxCoar = dblCoarCell.get(coarIt());
        for (int idir = 0; idir < SpaceDim; idir++)
          {
            Box edgeBoxCoar = surroundingNodes(cellBoxCoar, idir);
            FArrayBox edgeFlux(edgeBoxCoar,1);
            edgeFlux.setVal(fluxVal);
            DataIndex dataIndGlo = coarIt();
            fluxReg.incrementCoarse(edgeFlux, scale,
                                    dataIndGlo, interv, interv, idir);
          }
      }

    for (fineIt.reset(); fineIt.ok(); ++fineIt)
      {
        const Box&  cellBoxFine = dblFineCell.get(fineIt());
        for (int idir = 0; idir < SpaceDim; idir++)
          {
            Box edgeBoxFine = surroundingNodes(cellBoxFine, idir);
            FArrayBox edgeFlux(edgeBoxFine,1);
            edgeFlux.setVal(fluxVal);
            SideIterator sit;
            DataIndex dataIndGlo = fineIt();
            for (sit.reset(); sit.ok(); ++sit)
              {
                fluxReg.incrementFine(edgeFlux, scale,
                                      dataIndGlo,  interv, interv, idir, sit());
              }
          }
      }

    //reflux what ought to be zero into zero and the result should be zero
    fluxReg.reflux(coarData, scale);

    DataIterator datIt = coarData.dataIterator();
    for (datIt.reset(); datIt.ok(); ++datIt)
      {
        const FArrayBox& data = coarData[datIt()];
        Real rmax = Abs(data.max());
        Real rmin = Abs(data.min());
        if ((rmax > 1.0e-10)||(rmin > 1.0e-10))
          {
            pout() << indent << pgmname
                 << ": fluxRegister failed the periodic conservation test " << endl;
            retflag += 2;
          }
      }
  } // end periodic test

  return retflag;
}
コード例 #17
0
void
EBFluxRegister::
incrementRedistRegister(EBCoarToFineRedist& a_register,
                        const Interval&     a_variables,
                        const Real&         a_scale)
{
  if (m_hasEBCF)
    {
      LevelData<BaseIVFAB<Real> >& registerMass = a_register.m_regsCoar;
      LayoutData<IntVectSet>&      registerSets = a_register.m_setsCoar;
      //reflux into an empty LevelData<EBCellFAB>
      //Multiply this by (kappa)(1-kappa)
      //add result into register mass
      EBCellFactory ebcfCoar(m_eblgCoar.getEBISL());
      LevelData<EBCellFAB> increment(m_eblgCoar.getDBL(), m_nComp, m_saveCoar.ghostVect(), ebcfCoar);
      EBLevelDataOps::clone(increment, m_saveCoar);
      EBLevelDataOps::setVal(increment, 0.0);
      reflux(increment, a_variables, a_scale, true);

      for (DataIterator dit = m_eblgCoar.getDBL().dataIterator(); dit.ok(); ++dit)
        {
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              for (SideIterator sit; sit.ok(); ++sit)
                {
                  int iindex = index(idir, sit());
                  Vector<IntVectSet> setsCoar = (m_setsCoar[iindex])[dit()];
                  for (int iset = 0; iset < setsCoar.size(); iset++)
                    {
                      const IntVectSet& setCoa  = registerSets[dit()];
                      const IntVectSet& setReg  = setsCoar[iset];
                      IntVectSet set = setCoa;
                      set &= setReg;
                      const EBISBox& ebisBox =m_eblgCoar.getEBISL()[dit()];
                      for (VoFIterator vofit(set, ebisBox.getEBGraph()); vofit.ok(); ++vofit)
                        {
                          const VolIndex vof = vofit();
                          int ibleck = 0;
                          if ((vof.gridIndex() == ivdebugfr) && EBFastFR::s_verbose)
                            {
                              ibleck = 1;
                              pout()    << setprecision(10)
                                        << setiosflags(ios::showpoint)
                                        << setiosflags(ios::scientific);
                              pout() << "incrcotofi:" << endl;
                            }

                          for (int icomp = a_variables.begin(); icomp <= a_variables.end(); icomp++)
                            {
                              Real extraMass = increment[dit()](vofit(), icomp);

                              if ((ibleck == 1) && icomp == 0)
                                {
                                  //incrredist
                                  Real soluOld = registerMass[dit()](vof, icomp);
                                  Real soluNew = soluOld + extraMass;

                                  Real fluxDif = -extraMass;
                                  pout() << "(" << extraMass << ", " << soluOld << ", " << soluNew << ",  " << fluxDif << ")   " ;
                                }

                              registerMass[dit()](vof, icomp) += extraMass;

                              //set increment to zero in case it gets
                              //hit twice (more than one direction or
                              //whatever
                              increment[dit()](vof, icomp) = 0;

                            }
                          if (ibleck == 1)
                            {
                              pout() << endl;
                              ibleck = 0;
                            }

                        }
                    }
                }
            }
        }
    }
}
コード例 #18
0
// new define
void
LevelFluxRegisterEdge::define(
                              const DisjointBoxLayout& a_dbl,
                              const DisjointBoxLayout& a_dblCoarse,
                              const ProblemDomain& a_dProblem,
                              int a_nRefine,
                              int a_nComp)
{
  m_isDefined = true;
  CH_assert(a_nRefine > 0);
  CH_assert(a_nComp > 0);
  CH_assert(!a_dProblem.isEmpty());
  m_nComp = a_nComp;
  m_nRefine = a_nRefine;
  m_domainCoarse = coarsen(a_dProblem, a_nRefine);
  CH_assert (a_dblCoarse.checkPeriodic(m_domainCoarse));

  // allocate copiers
  m_crseCopiers.resize(SpaceDim*2);

  SideIterator side;

  // create a Vector<Box> of the fine boxes which also includes periodic images,
  // since we don't really care about the processor layouts, etc
  Vector<Box> periodicFineBoxes;
  CFStencil::buildPeriodicVector(periodicFineBoxes, a_dProblem, a_dbl);
  // now coarsen these boxes...
  for (int i=0; i<periodicFineBoxes.size(); i++)
    {
      periodicFineBoxes[i].coarsen(m_nRefine);
    }

  for (int idir=0 ; idir<SpaceDim; ++idir)
  {
    for (side.begin(); side.ok(); ++side)
    {
      // step one, build fineBoxes, flux register boxes
      // indexed by the fine level but in the coarse index
      // space
      DisjointBoxLayout fineBoxes,tmp;
      // first create coarsened dbl, then compute flux register boxes
      // adjacent to coarsened fine boxes
      coarsen(tmp, a_dbl, m_nRefine);
      if (side() == Side::Lo)
        {
          adjCellLo(fineBoxes, tmp, idir,1);
        }
      else
        {
          adjCellHi(fineBoxes, tmp, idir,1);
        }

      // now define the FluxBoxes of fabFine on this DisjointBoxLayout
      m_fabFine[index(idir, side())].define(fineBoxes, a_nComp);



      LayoutData<Vector<Vector<IntVectSet> > >& ivsetsVect
        = m_refluxLocations[index(idir, side())];
      ivsetsVect.define(a_dblCoarse);

      LayoutData<Vector<DataIndex> >& mapsV =
        m_coarToCoarMap[index(idir, side())];
      mapsV.define(a_dblCoarse);

      DisjointBoxLayout coarseBoxes = a_dblCoarse;
      DataIterator dit = a_dblCoarse.dataIterator();
      for (dit.begin(); dit.ok(); ++dit)
        {
          unsigned int thisproc = a_dblCoarse.procID(dit());
          if (thisproc == procID())
          {
            ivsetsVect[DataIndex(dit())].resize(SpaceDim);
          }
          const Box& coarseBox = a_dblCoarse[dit()];
          int count = 0;
          for (int i=0; i<periodicFineBoxes.size(); i++)
            {
              Box regBox;
              if (side() == Side::Lo)
                {
                  regBox = adjCellLo(periodicFineBoxes[i], idir, 1);
                }
              else
                {
                  regBox = adjCellHi(periodicFineBoxes[i], idir, 1);
                }

              // do this little dance in order to ensure that
              // we catch corner cells which might be in different
              // boxes.
              Box testBox(regBox);
              testBox.grow(1);
              testBox.grow(idir,-1);
              if (testBox.intersectsNotEmpty(coarseBox))
                {
                  testBox &= coarseBox;
                  ++count;
                  unsigned int proc = a_dblCoarse.procID(dit());
                  const DataIndex index = DataIndex(dit());
                  if (proc == procID())
                  {
                    mapsV[DataIndex(dit())].push_back(index);
                    // loop over face directions here
                    for (int faceDir=0; faceDir<SpaceDim; faceDir++)
                    {
                      // do nothing in normal direction
                      if (faceDir != idir)
                      {
                        // this should give us the face indices for the
                        // faceDir-centered faces adjacent to the coarse-fine
                        // interface which are contained in the current
                        // coarse box
                        Box intersectBox(regBox);
                        Box coarseEdgeBox(coarseBox);
                        coarseEdgeBox.surroundingNodes(faceDir);
                        intersectBox.surroundingNodes(faceDir);
                        intersectBox &= coarseEdgeBox;
                        intersectBox.shiftHalf(faceDir,1);
                        IntVectSet localIV(intersectBox);
                        ivsetsVect[DataIndex(dit())][faceDir].push_back(localIV);
                      }
                    }
                  }
                }
            } // end loop over boxes on coarse level
        }
      m_regCoarse.define(coarseBoxes, a_nComp, IntVect::Unit);

      // last thing to do is to define copiers
      m_crseCopiers[index(idir, side())].define(fineBoxes, coarseBoxes,
                                                IntVect::Unit);
    }
  }
}
コード例 #19
0
void
EBLevelTransport::
doRegularUpdate(LevelData<EBCellFAB>&         a_divF,
                LevelData<EBCellFAB>&         a_cons,
                const LevelData<EBCellFAB>&   a_normalVel,
                const LevelData<EBFluxFAB>&   a_advVel,
                const LayoutData< Vector <BaseIVFAB<Real> * > >& a_coveredAdvVelMinu,
                const LayoutData< Vector <BaseIVFAB<Real> * > >& a_coveredAdvVelPlus,
                EBFluxRegister&               a_fineFluxRegister,
                EBFluxRegister&               a_coarFluxRegister,
                const LevelData<EBCellFAB>&   a_source,
                Real a_time, Real a_dt)
{
  bool verbose = false;
  int ibox = 0;
  Interval consInterv(0, m_nCons-1);
  Interval fluxInterv(0, m_nFlux-1);

    for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit, ibox++)
    {
      const Box& cellBox = m_thisGrids.get(dit());
      const EBISBox& ebisBox = m_thisEBISL[dit()];
      if(!ebisBox.isAllCovered())
        {
          const IntVectSet& cfivs = m_cfIVS[dit()];

          EBCellFAB& consState = a_cons[dit()];
          m_ebPatchGodunov->setValidBox(cellBox, ebisBox, cfivs, a_time, a_dt); 
          //begin debug
          //int here = 0;
          //if(cellBox.contains(EBPatchGodunov::s_debugIV) && (EBPatchGodunov::s_whichLev==1))
          //  {
          //    here = 1;
          //  }
          //end debug

          const EBCellFAB& source = a_source[dit()];
          const EBCellFAB& normalVel = a_normalVel[dit()];
          const EBFluxFAB& advVel = a_advVel[dit()];
          const Vector<BaseIVFAB <Real>* >& coveredAdvVelMinu = a_coveredAdvVelMinu[dit()];
          const Vector<BaseIVFAB <Real>* >& coveredAdvVelPlus = a_coveredAdvVelPlus[dit()];

          m_ebPatchGodunov->setVelocities(normalVel, advVel, coveredAdvVelMinu, coveredAdvVelPlus);

          EBFluxFAB flux(ebisBox, cellBox, m_nFlux);
          BaseIVFAB<Real>& nonConsDiv    = m_nonConsDivergence[dit()];
          BaseIVFAB<Real>& ebIrregFlux   = m_ebIrregFaceFlux[dit()];
          flux.setVal(7.89);
          ebIrregFlux.setVal(7.89);
          const IntVectSet& ivsIrreg     = m_irregSetsSmall[dit()];
          const EBCellFAB& flatteningFAB = m_flattening[dit()];

          BaseIVFAB<Real>  coveredPrimMinu[SpaceDim];
          BaseIVFAB<Real>  coveredPrimPlus[SpaceDim];
          Vector<VolIndex> coveredFaceMinu[SpaceDim];
          Vector<VolIndex> coveredFacePlus[SpaceDim];
          EBFluxFAB facePrim;

          EBCellFAB& divFFAB = a_divF[dit()];
//          EBPatchTransport& patchTrans = (EBPatchTransport&) (*m_ebPatchGodunov);

          EBPatchGodunov::setCurComp(0);
          EBPatchGodunov::setDoingVel(0);
          EBPatchGodunov::setDoingAdvVel(0);


          m_ebPatchGodunov->primitivesAndDivergences(divFFAB, consState,
                                             facePrim,
                                             coveredPrimMinu,
                                             coveredPrimPlus,
                                             coveredFaceMinu,
                                             coveredFacePlus,
                                             flux, ebIrregFlux,
                                             nonConsDiv,flatteningFAB,
                                             source, cellBox, ivsIrreg,
                                             dit(),verbose);

          //do fluxregister cha-cha
          /*
            Coarse flux register is flux register with the coarse level.
            Fine flux register is the flux register with the fine level.
            To the finer level FR, this level is the coarse level.
            To the coarser level FR, this level is the fine level.
          */
          for(int idir = 0; idir < SpaceDim; idir++)
            {
              Real scale = a_dt;

              EBFaceFAB fluxRegFlux;
              if(m_hasFiner)
                {
                  a_fineFluxRegister.incrementCoarseRegular(flux[idir], scale,dit(),
                                                            consInterv, idir);
                }

              if(m_hasCoarser)
                {
                  for(SideIterator sit; sit.ok(); ++sit)
                    {
                      a_coarFluxRegister.incrementFineRegular(flux[idir],scale, dit(),
                                                              consInterv, idir,sit());
                    }
                }
            }

          //copy fluxes into sparse interpolant
          for(int faceDir = 0; faceDir < SpaceDim; faceDir++)
            {
              IntVectSet ivsIrregGrown = m_irregSetsGrown[faceDir][dit()];
              ivsIrregGrown &= cellBox;
              FaceStop::WhichFaces stopCrit = FaceStop::SurroundingWithBoundary;

              BaseIFFAB<Real>& interpol = m_fluxInterpolants[faceDir][dit()];
              interpol.setVal(7.7777e7);
              EBFaceFAB& fluxDir = flux[faceDir];
              for(FaceIterator faceit(ivsIrregGrown, ebisBox.getEBGraph(),
                                      faceDir, stopCrit);
                  faceit.ok(); ++faceit)
                {
                  for(int ivar = 0; ivar < m_nFlux; ivar++)
                    {
                      interpol(faceit(), ivar) = fluxDir(faceit(), ivar);
                    }
                }

            }
        }
    }

  for(int faceDir = 0; faceDir < SpaceDim; faceDir++)
    {
      m_fluxInterpolants[faceDir].exchange(fluxInterv);
    } 
}
コード例 #20
0
void
EBLevelTransport::
doIrregularUpdate(LevelData<EBCellFAB>&         a_divergeF,
                  LevelData<EBCellFAB>&         a_cons,
                  EBFluxRegister&               a_fineFluxRegister,
                  EBFluxRegister&               a_coarFluxRegister,
                  LevelData<BaseIVFAB<Real> >&  a_massDiff,
                  Real a_time, Real a_dt)
{
  //now do the irregular update
  int ibox = 0;
  Interval consInterv(0, m_nCons-1);
  Interval fluxInterv(0, m_nFlux-1);
  for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit, ibox++)
    {
      const Box& cellBox = m_thisGrids.get(dit());
      const EBISBox& ebisBox = m_thisEBISL[dit()];
      if(!ebisBox.isAllCovered())
        {
          const IntVectSet& cfivs = m_cfIVS[dit()];

          EBCellFAB& consState = a_cons[dit()];
          BaseIVFAB<Real>& redMass = a_massDiff[dit()];

          m_ebPatchGodunov->setValidBox(cellBox, ebisBox, cfivs, a_time, a_dt);
          //begin debug
          //int here = 0;
          //if(cellBox.contains(EBPatchGodunov::s_debugIV) && (EBPatchGodunov::s_whichLev==1))
          //  {
          //    here = 1;
          //  }
          //end debug

          BaseIFFAB<Real> centroidFlux[SpaceDim];
          const BaseIFFAB<Real>* interpolantGrid[SpaceDim];
          const IntVectSet& ivsIrregSmall = m_irregSetsSmall[dit()];
          for(int idir = 0; idir < SpaceDim; idir++)
            {
              const BaseIFFAB<Real>& interpol = m_fluxInterpolants[idir][dit()];
              interpolantGrid[idir] = &interpol;
              BaseIFFAB<Real>& fluxDir= centroidFlux[idir];
              fluxDir.define(ivsIrregSmall, ebisBox.getEBGraph(), idir, m_nFlux);
            }
          m_ebPatchGodunov->interpolateFluxToCentroids(centroidFlux,
                                                       interpolantGrid,
                                                       ivsIrregSmall);

          //update the state and interpolate the flux
          const BaseIVFAB<Real>& nonConsDiv = m_nonConsDivergence[dit()];
          const BaseIVFAB<Real>& ebIrregFlux = m_ebIrregFaceFlux[dit()];

          m_ebPatchGodunov->hybridDivergence(a_divergeF[dit()], consState,  redMass,
                                             centroidFlux, ebIrregFlux, nonConsDiv,
                                             cellBox, ivsIrregSmall);


          //do fluxregister mambo
          /*
            Coarse flux register is flux register with the coarse level.
            Fine flux register is the flux register with the fine level.
            To the finer level FR, this level is the coarse level.
            To the coarser level FR, this level is the fine level.
          */
          for(int idir = 0; idir < SpaceDim; idir++)
            {
              Real scale = a_dt;

              BaseIFFAB<Real> fluxRegFlux;
              if(m_hasFiner)
                {
                  a_fineFluxRegister.incrementCoarseIrregular(centroidFlux[idir],
                                                              scale,dit(),
                                                              consInterv, idir);
                }

              if(m_hasCoarser)
                {
                  for(SideIterator sit; sit.ok(); ++sit)
                    {
                      a_coarFluxRegister.incrementFineIrregular(centroidFlux[idir],
                                                                scale, dit(),
                                                                consInterv, idir,sit());
                    }
                }
            }
        }
    }// end of loop over grids.
}
コード例 #21
0
void
LevelFluxRegisterEdge::refluxCurl(LevelData<FluxBox>& a_uCoarse,
                                  Real a_scale)
{
  CH_assert(isDefined());
  CH_assert(a_uCoarse.nComp() == m_nComp);

  SideIterator side;
  // idir is the normal direction to the coarse-fine interface
  for (int idir=0 ; idir<SpaceDim; ++idir)
  {
    for (side.begin(); side.ok(); ++side)
    {
      LevelData<FluxBox>& fineReg = m_fabFine[index(idir, side())];

      // first, create temp LevelData<FluxBox> to hold "coarse flux"
      const DisjointBoxLayout coarseBoxes = m_regCoarse.getBoxes();

      // this fills the place of what used to be m_fabCoarse in the old
      // implementation
      LevelData<FluxBox> coarReg(coarseBoxes, m_nComp, IntVect::Unit);


      // now fill the coarReg with the curl of the stored coarse-level
      // edge-centered flux
      DataIterator crseDit = coarseBoxes.dataIterator();
      for (crseDit.begin(); crseDit.ok(); ++crseDit)
        {
          FluxBox& thisCoarReg = coarReg[crseDit];
          thisCoarReg.setVal(0.0);

          EdgeDataBox& thisEdgeData = m_regCoarse[crseDit];

          for (int edgeDir=0; edgeDir<SpaceDim; edgeDir++)
            {
              if (idir != edgeDir)
                {
                  FArrayBox& crseEdgeDataDir = thisEdgeData[edgeDir];
                  for (int faceDir = 0; faceDir<SpaceDim; faceDir++)
                    {
                      if (faceDir != edgeDir)
                        {
                          FArrayBox& faceData = thisCoarReg[faceDir];
                          int shiftDir = -1;
                          for (int i=0; i<SpaceDim; i++)
                            {
                              if ((i != faceDir) && (i != edgeDir) )
                                {
                                  shiftDir = i;
                                }
                            }
                          CH_assert(shiftDir >= 0);
                          crseEdgeDataDir.shiftHalf(shiftDir, sign(side()));
                          // scaling already taken care of in incrementCrse
                          Real scale = 1.0;
                          faceData.plus(crseEdgeDataDir, scale, 0, 0, faceData.nComp());
                          crseEdgeDataDir.shiftHalf(shiftDir, -sign(side()));
                        } // end if not normal direction
                    } // end loop over face directions
                } // end if edgeDir != idir
            } // end loop over edge directions
        } // end loop over crse boxes


      // first, we need to create a temp LevelData<FluxBox>
      // to make a local copy in the coarse layout space of
      // the fine register increments

      LevelData<FluxBox> fineRegLocal(coarReg.getBoxes(), m_nComp, IntVect::Unit);

      fineReg.copyTo(fineReg.interval(), fineRegLocal,
                     fineRegLocal.interval(),
                     m_crseCopiers[index(idir,side())]);

      for (DataIterator it = a_uCoarse.dataIterator(); it.ok(); ++it)
        {
          // loop over flux components here
          for (int fluxComp=0; fluxComp < SpaceDim; fluxComp++)
            {
              // we don't do anything in the normal direction
              if (fluxComp != idir)
                {
                  // fluxDir is the direction of the face-centered flux
                  FArrayBox& U = a_uCoarse[it()][fluxComp];
                  // set up IntVectSet to avoid double counting of updates
                  Box coarseGridBox = U.box();
                  // transfer to Cell-centered, then create IVS
                  coarseGridBox.shiftHalf(fluxComp,1);
                  IntVectSet nonUpdatedEdges(coarseGridBox);

                  // remember, we want to take the curl here
                  // also recall that fluxComp is the component
                  // of the face-centered curl (not the edge-centered
                  // vector field that we're refluxing, which is why
                  // the sign may seem like it's the opposite of what
                  // you might expect!
                  Real local_scale = -sign(side())*a_scale;
                  //int testDir = (fluxComp+1)%(SpaceDim);
                  if (((fluxComp+1)%(SpaceDim)) == idir)  local_scale *= -1;
                  Vector<IntVectSet>& ivsV =
                    m_refluxLocations[index(idir, side())][it()][fluxComp];
                  Vector<DataIndex>&  indexV =
                    m_coarToCoarMap[index(idir, side())][it()];
                  IVSIterator iv;

                  for (int i=0; i<ivsV.size(); ++i)
                    {
                      iv.define(ivsV[i]);
                      const FArrayBox& coar = coarReg[indexV[i]][fluxComp];
                      const FArrayBox& fine = fineRegLocal[indexV[i]][fluxComp];
                      for (iv.begin(); iv.ok(); ++iv)
                        {
                          IntVect thisIV = iv();
                          if (nonUpdatedEdges.contains(thisIV))
                          {
                            for (int comp=0; comp <m_nComp; ++comp)
                              {
                                //Real coarVal = coar(thisIV, comp);
                                //Real fineVal = fine(thisIV, comp);
                                U(thisIV, comp) -=
                                local_scale*(coar(thisIV, comp)
                                             +fine(thisIV, comp));
                              }
                            nonUpdatedEdges -= thisIV;
                          }
                        }

                    }
                } // end if not normal face
            } // end loop over fluxbox directions
        } // end loop over coarse boxes
    } // end loop over sides
  } // end loop over directions
}
コード例 #22
0
void ConstBCFunction::operator()(FArrayBox&           a_state,
                                 const Box&           a_valid,
                                 const ProblemDomain& a_domain,
                                 Real                 a_dx,
                                 bool                 a_homogeneous)
{
  const Box& domainBox = a_domain.domainBox();

  for (int idir = 0; idir < SpaceDim; idir++)
  {
    if (!a_domain.isPeriodic(idir))
    {
      for (SideIterator sit; sit.ok(); ++sit)
      {
        Side::LoHiSide side = sit();

        if (a_valid.sideEnd(side)[idir] == domainBox.sideEnd(side)[idir])
        {
          int  bcType;
          Real bcValue;

          if (side == Side::Lo)
          {
            bcType  = m_loSideType [idir];
            bcValue = m_loSideValue[idir];
          }
          else
          {
            bcType  = m_hiSideType [idir];
            bcValue = m_hiSideValue[idir];
          }

          if (bcType == 0)
          {
            // Neumann BC
            int isign = sign(side);

            Box toRegion = adjCellBox(a_valid, idir, side, 1);
            toRegion &= a_state.box();

            Box fromRegion = toRegion;
            fromRegion.shift(idir, -isign);

            a_state.copy(a_state, fromRegion, 0, toRegion, 0, a_state.nComp());

            if (!a_homogeneous)
            {
              for (BoxIterator bit(toRegion); bit.ok(); ++bit)
              {
                const IntVect& ivTo = bit();
                // IntVect ivClose = ivTo - isign*BASISV(idir);

                for (int icomp = 0; icomp < a_state.nComp(); icomp++)
                {
                  a_state(ivTo, icomp) += Real(isign)*a_dx*bcValue;
                }
              }
            }
          }
          else if (bcType == 1)
          {
            // Dirichlet BC
            int isign = sign(side);

            Box toRegion = adjCellBox(a_valid, idir, side, 1);
            toRegion &= a_state.box();

            for (BoxIterator bit(toRegion); bit.ok(); ++bit)
            {
              const IntVect& ivTo = bit();

              IntVect ivClose = ivTo -   isign*BASISV(idir);
              // IntVect ivFar   = ivTo - 2*isign*BASISV(idir);

              Real inhomogVal = 0.0;

              if (!a_homogeneous)
              {
                inhomogVal = bcValue;
              }

              for (int icomp = 0; icomp < a_state.nComp(); icomp++)
              {
                Real nearVal = a_state(ivClose, icomp);
                // Real farVal  = a_state(ivFar,   icomp);

                Real ghostVal = linearInterp(inhomogVal, nearVal);

                a_state(ivTo, icomp) = ghostVal;
              }
            }
          }
          else
          {
            MayDay::Abort("ConstBCFunction::operator() - unknown BC type");
          }
        } // if ends match
      } // end loop over sides
    } // if not periodic in this direction
  } // end loop over directions
}
コード例 #23
0
ファイル: EBPlanarShockIBC.cpp プロジェクト: rsnemmen/Chombo
void
EBPlanarShockIBC::
setBndrySlopes(EBCellFAB&       a_deltaPrim,
               const EBCellFAB& a_primState,
               const EBISBox&   a_ebisBox,
               const Box&       a_box,
               const int&       a_dir)
{
  // don't want to deal with the periodic case
 CH_assert(!m_domain.isPeriodic(a_dir));
 CH_assert(m_isDefined);
 CH_assert(m_isFortranCommonSet);

  Box loBox,hiBox,centerBox,domain;
  int hasLo,hasHi;
  Box slopeBox = a_deltaPrim.getRegion()&m_domain;
  int numSlop = a_deltaPrim.nComp();
  // Generate the domain boundary boxes, loBox and hiBox, if there are
  // domain boundarys there
  eblohicenter(loBox,hasLo,hiBox,hasHi,centerBox,domain,
             slopeBox,m_domain,a_dir);

  // Set the boundary slopes if necessary
  if ((hasLo != 0) || (hasHi != 0))
    {
      BaseFab<Real>& regDeltaPrim = a_deltaPrim.getSingleValuedFAB();
      const BaseFab<Real>& regPrimState = a_primState.getSingleValuedFAB();
      /**/
      FORT_SLOPEBCS(CHF_FRA(regDeltaPrim),
                    CHF_CONST_FRA(regPrimState),
                    CHF_CONST_REAL(m_dx),
                    CHF_CONST_INT(a_dir),
                    CHF_BOX(loBox),
                    CHF_CONST_INT(hasLo),
                    CHF_BOX(hiBox),
                    CHF_CONST_INT(hasHi));
      /**/
    }
  for(SideIterator sit; sit.ok(); ++sit)
    {
      bool doThisSide;
      Box thisBox;
      if(sit() == Side::Lo)
        {
          doThisSide = (hasLo != 0);
          thisBox = loBox;
        }
      else
        {
          doThisSide = (hasHi != 0);
          thisBox = hiBox;
        }
      if(doThisSide)
        {

          // the cells for which the regular calculation
          //are incorrect are the grown set of the multivalued
          //cells intersected with the appropriate bndry box
          //and added to the irregular cells on the boundary.
          Box boxGrown = thisBox;
          boxGrown.grow(a_dir, 1);
          boxGrown &= m_domain;
          IntVectSet ivs = a_ebisBox.getMultiCells(boxGrown);
          ivs &= loBox;
          IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(thisBox);
          ivs |= ivsIrreg;
          for(VoFIterator vofit(ivs, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit)
            {
              const VolIndex& vof = vofit();
              //all slopes at boundary get set to zero
              //except normal velocity.  just following the
              //fortran here
              int inormVelVar = a_dir + QVELX;
              for(int ivar = 0; ivar < numSlop; ivar++)
                {
                  if(ivar != inormVelVar)
                    {
                      a_deltaPrim(vof, ivar) = 0.0;
                    }
                }

              //for normal velocity
              //do strangely limited slope
              //just lifted from the fortran.
              Side::LoHiSide otherSide = flip(sit());
              Vector<FaceIndex> faces =
                a_ebisBox.getFaces(vof, a_dir, otherSide);

              Real thisVel = a_primState(vof, inormVelVar);
              Real otherVel = 0.;
              for(int iface = 0; iface < faces.size(); iface++)
                {
                  VolIndex otherVoF = faces[iface].getVoF(otherSide);
                  otherVel += a_primState(otherVoF,inormVelVar);
                }
              if(faces.size() > 0)
                {
                  otherVel /= Real(faces.size());
                  Real slope;
                  if(sit() == Side::Lo)
                    {
                      slope = otherVel - thisVel;
                    }
                  else
                    {
                      slope = thisVel  - otherVel;
                    }
                  //trick to make sure state will not change sign
                  if(slope*thisVel < 0)
                    {
                      a_deltaPrim(vof, inormVelVar) = 0.0;
                    }
                  else
                    { //slope and vel same sign
                      Real rsign = 1.0;
                      if(thisVel < 0.0)
                        rsign = -1.0;
                      //told you this was odd.
                      Real dvmin = Min(Abs(slope), Abs((Real)2.*thisVel));
                      a_deltaPrim(vof, inormVelVar) = rsign*dvmin;
                    }
                }
              else //no faces on high side of low boundary vof
                {
                  a_deltaPrim(vof, inormVelVar) = 0.0;
                }
            } //end loop over irregular vofs at boundary
        }
    } //end loop over boundary sides
}
コード例 #24
0
ファイル: VCAMRPoissonOp2.cpp プロジェクト: dtgraves/EBAMRCNS
//
// VCAMRPoissonOp2::reflux()
//   There are currently the new version (first) and the old version (second)
//   in this file.  Brian asked to preserve the old version in this way for
//   now. - TJL (12/10/2007)
//
void VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>&        a_phiFine,
                            const LevelData<FArrayBox>&        a_phi,
                            LevelData<FArrayBox>&              a_residual,
                            AMRLevelOp<LevelData<FArrayBox> >* a_finerOp)
{
  CH_TIMERS("VCAMRPoissonOp2::reflux");

  m_levfluxreg.setToZero();
  Interval interv(0,a_phi.nComp()-1);

  CH_TIMER("VCAMRPoissonOp2::reflux::incrementCoarse", t2);
  CH_START(t2);

  DataIterator dit = a_phi.dataIterator();
  for (dit.reset(); dit.ok(); ++dit)
  {
    const FArrayBox& coarfab   = a_phi[dit];
    const FluxBox&   coarBCoef = (*m_bCoef)[dit];
    const Box&       gridBox   = a_phi.getBoxes()[dit];

    if (m_levfluxreg.hasCF(dit()))
    {
      for (int idir = 0; idir < SpaceDim; idir++)
      {
        FArrayBox coarflux;
        Box faceBox = surroundingNodes(gridBox, idir);

        getFlux(coarflux, coarfab, coarBCoef, faceBox, idir);

        Real scale = 1.0;
        m_levfluxreg.incrementCoarse(coarflux, scale,dit(),
            interv, interv, idir);
      }
    }
  }

  CH_STOP(t2);

  // const cast:  OK because we're changing ghost cells only
  LevelData<FArrayBox>& phiFineRef = ( LevelData<FArrayBox>&)a_phiFine;

  VCAMRPoissonOp2* finerAMRPOp = (VCAMRPoissonOp2*) a_finerOp;
  QuadCFInterp& quadCFI = finerAMRPOp->m_interpWithCoarser;

  quadCFI.coarseFineInterp(phiFineRef, a_phi);
  // I'm pretty sure this is not necessary. bvs -- flux calculations use
  // outer ghost cells, but not inner ones
  // phiFineRef.exchange(a_phiFine.interval());
  IntVect phiGhost = phiFineRef.ghostVect();
  int ncomps = a_phiFine.nComp();

  CH_TIMER("VCAMRPoissonOp2::reflux::incrementFine", t3);
  CH_START(t3);

  DataIterator ditf = a_phiFine.dataIterator();
  const DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout();
  for (ditf.reset(); ditf.ok(); ++ditf)
    {
      const FArrayBox& phifFab   = a_phiFine[ditf];
      const FluxBox&   fineBCoef = (*(finerAMRPOp->m_bCoef))[ditf];
      const Box&       gridbox   = dblFine.get(ditf());

      for (int idir = 0; idir < SpaceDim; idir++)
        {
          //int normalGhost = phiGhost[idir];
          SideIterator sit;
          for (sit.begin(); sit.ok(); sit.next())
            {
              if (m_levfluxreg.hasCF(ditf(), sit()))
                {
                  Side::LoHiSide hiorlo = sit();
                  Box fluxBox = bdryBox(gridbox,idir,hiorlo,1);

                  FArrayBox fineflux(fluxBox,ncomps);
                  getFlux(fineflux, phifFab, fineBCoef, fluxBox, idir,
                          m_refToFiner);

                  Real scale = 1.0;
                  m_levfluxreg.incrementFine(fineflux, scale, ditf(),
                                             interv, interv, idir, hiorlo);
                }
            }
        }
    }

  CH_STOP(t3);

  Real scale = 1.0/m_dx;
  m_levfluxreg.reflux(a_residual, scale);
}
コード例 #25
0
ファイル: fluxRegTest.cpp プロジェクト: rsnemmen/Chombo
int fluxRegTest()
{
  int nref = 2;
  int eekflag = 0;
  ParmParse pp;

  Box domainCoar, domainFine;
  eekflag = makeGeometry(domainFine);
  if (eekflag != 0)
    return eekflag;
  domainCoar = coarsen(domainFine, nref);

  DisjointBoxLayout dblFine,dblCoar;
  eekflag = makeLayouts(dblCoar, dblFine, domainCoar, domainFine);

  Interval interv(0,0);

  EBISLayout ebislFine, ebislCoar;
  int nghost = 3;
  makeEBISL(ebislFine, dblFine, domainFine, nghost);
  makeEBISL(ebislCoar, dblCoar, domainCoar, nghost);

  EBCellFactory factFine(ebislFine);
  EBCellFactory factCoar(ebislCoar);
  IntVect ivghost = IntVect::Unit;

  LevelData<EBCellFAB> fineData(dblFine, 1,ivghost, factFine);
  LevelData<EBCellFAB> coarData(dblCoar, 1,ivghost, factCoar);

  LevelData<EBCellFAB> extraDense(dblCoar, 1,ivghost, factCoar);

  //set data and flux registers to zero
  for (DataIterator coarIt = coarData.dataIterator();
      coarIt.ok(); ++coarIt)
      coarData[coarIt()].setVal(0.);
  for (DataIterator fineIt = fineData.dataIterator();
      fineIt.ok(); ++fineIt)
    fineData[fineIt()].setVal(0.);
  {
    //    pout() << "before constructor" << endl;
    EBFluxRegister fluxReg(dblFine,
                           dblCoar,
                           ebislFine,
                           ebislCoar,
                           domainCoar,
                           nref, 1, Chombo_EBIS::instance());
    //    pout() << "after constructor" << endl;
    fluxReg.setToZero();
    //    pout() << "after settozero" << endl;
    //loop through directions
    Real scale = 1.0;
    Real fluxVal = 4.77;
    for (int idir = 0; idir < SpaceDim; idir++)
      {

        //        pout() << "idir = " << idir <<  endl;
        //        MPI_Barrier(Chombo_MPI::comm);
        //increment and decrement
        //flux registers with equal size fluxes
        for (DataIterator coarIt = coarData.dataIterator();
            coarIt.ok(); ++coarIt)
          {
            const Box&  boxCoar = dblCoar.get(coarIt());
            const EBISBox& ebisBox = ebislCoar[coarIt()];
            IntVectSet ivsBC(boxCoar);
            EBFaceFAB edgeFluxReg(ebisBox, boxCoar, idir, 1);
            BaseIFFAB<Real> edgeFluxIrr(ivsBC, ebisBox.getEBGraph(), idir, 1);
            edgeFluxReg.setVal(fluxVal);
            edgeFluxIrr.setVal(fluxVal);
            fluxReg.incrementCoarseRegular(edgeFluxReg, scale,
                                           coarIt(), interv, idir);
            //        pout() << "after increment coar regular"<< endl;
            fluxReg.incrementCoarseIrregular(edgeFluxIrr, scale,
                                             coarIt(), interv, idir);

            //        pout() << "after increment coar irregular"<< endl;
          }
        //        pout() << "after increment coar"<< endl;
        //        MPI_Barrier(Chombo_MPI::comm);
        for (DataIterator fineIt = fineData.dataIterator();
            fineIt.ok(); ++fineIt)
          {
            const Box&  boxFine = dblFine.get(fineIt());
            const EBISBox& ebisBox = ebislFine[fineIt()];
            IntVectSet ivsBF(boxFine);
            EBFaceFAB edgeFluxReg(ebisBox, boxFine, idir, 1);
            BaseIFFAB<Real> edgeFluxIrr(ivsBF, ebisBox.getEBGraph(), idir, 1);
            edgeFluxReg.setVal(fluxVal);
            edgeFluxIrr.setVal(fluxVal);

            for (SideIterator sit; sit.ok(); ++sit)
              {
                fluxReg.incrementFineRegular(edgeFluxReg, scale,
                                             fineIt(),  interv, idir, sit());

                fluxReg.incrementFineIrregular(edgeFluxIrr, scale,
                                               fineIt(),  interv, idir, sit());

              }
          }
        //        pout() << "after increment fine"<< endl;
        //        MPI_Barrier(Chombo_MPI::comm);
      }

    //reflux what ought to be zero into zero and the result should be zero
    //except where the coarse-fine boundary gets crossed by the embedded
    //boundary.  That should get fixed by the extramass thing.
    fluxReg.reflux(coarData, interv, scale);
    //    pout() << "after reflux"<< endl;

    for (DataIterator coarIt = coarData.dataIterator();
        coarIt.ok(); ++coarIt)
      extraDense[coarIt()].setVal(0.);

    // now add extra density to soltuion
    //in the end the solution should return to zero
    fluxReg.incrementDensityArray(extraDense, interv, scale);
  }
  //  pout() << "after fluxreg destruction" << endl;
  //  pout() << "after incementDensityArray"<< endl;
  for (DataIterator coarIt = coarData.dataIterator();
      coarIt.ok(); ++coarIt)
    coarData[coarIt()] += extraDense[coarIt()];
  //  MPI_Barrier(Chombo_MPI::comm);
  //  pout() << "after  += operation "<< endl;
  DataIterator datIt = coarData.dataIterator();
  for (datIt.reset(); datIt.ok(); ++datIt)
    {
      const EBCellFAB& data = coarData[datIt()];
      IntVectSet ivsBox(dblCoar.get(datIt()));
      const EBISBox& ebisBox = ebislCoar[datIt()];
      Real rmax = 0.;
      Real rmin = 0.;
      for (VoFIterator vofit(ivsBox, ebisBox.getEBGraph());
          vofit.ok(); ++vofit)
        {
          const VolIndex& vof = vofit();
          rmax = Max(rmax, Abs(data(vof, 0)));
          rmin = Min(rmax, Abs(data(vof, 0)));

#ifdef CH_USE_FLOAT
          Real tolerance = 1.0e-6;
#else
          Real tolerance = 1.0e-10;
#endif
          if ((rmax > tolerance)||(rmin > tolerance))
            {
              pout() << "EBFluxRegister failed the test at  "
                     << " vof = " << vof << endl;
              pout() << "   rmax: "      << rmax      << ", or"
                     <<   " rmin: "      << rmin      << " >"
                     <<   " tolerance: " << tolerance << ")" << endl;
              eekflag = 42;
              return eekflag;
            }
        }
    }

  //  pout() << "about to return "<< endl;
  return eekflag;
}
コード例 #26
0
ファイル: VCAMRPoissonOp2.cpp プロジェクト: dtgraves/EBAMRCNS
void VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>&        a_phiFine,
                            const LevelData<FArrayBox>&        a_phi,
                            LevelData<FArrayBox>&              a_residual,
                            AMRLevelOp<LevelData<FArrayBox> >* a_finerOp)
{
  CH_TIME("VCAMRPoissonOp2::reflux");

  int ncomp = 1;
  ProblemDomain fineDomain = refine(m_domain, m_refToFiner);
  LevelFluxRegister levfluxreg(a_phiFine.disjointBoxLayout(),
                               a_phi.disjointBoxLayout(),
                               fineDomain,
                               m_refToFiner,
                               ncomp);

  levfluxreg.setToZero();
  Interval interv(0,a_phi.nComp()-1);

  DataIterator dit = a_phi.dataIterator();
  for (dit.reset(); dit.ok(); ++dit)
    {
      const FArrayBox& coarfab = a_phi[dit];
      const FluxBox& coarBCoef  = (*m_bCoef)[dit];
      const Box& gridBox = a_phi.getBoxes()[dit];

      for (int idir = 0; idir < SpaceDim; idir++)
        {
          FArrayBox coarflux;
          Box faceBox = surroundingNodes(gridBox, idir);
          getFlux(coarflux, coarfab, coarBCoef , faceBox, idir);

          Real scale = 1.0;
          levfluxreg.incrementCoarse(coarflux, scale,dit(),
                                     interv,interv,idir);
        }
    }
  LevelData<FArrayBox>& p = ( LevelData<FArrayBox>&)a_phiFine;

  // has to be its own object because the finer operator
  // owns an interpolator and we have no way of getting to it
  VCAMRPoissonOp2* finerAMRPOp = (VCAMRPoissonOp2*) a_finerOp;
  QuadCFInterp& quadCFI = finerAMRPOp->m_interpWithCoarser;

  quadCFI.coarseFineInterp(p, a_phi);
  // p.exchange(a_phiFine.interval()); // BVS is pretty sure this is not necesary.
  IntVect phiGhost = p.ghostVect();

  DataIterator ditf = a_phiFine.dataIterator();
  const  DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout();
  for (ditf.reset(); ditf.ok(); ++ditf)
    {
      const FArrayBox& phifFab = a_phiFine[ditf];
      const FluxBox& fineBCoef  = (*(finerAMRPOp->m_bCoef))[ditf];
      const Box& gridbox = dblFine.get(ditf());
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          int normalGhost = phiGhost[idir];
          SideIterator sit;
          for (sit.begin(); sit.ok(); sit.next())
            {
              Side::LoHiSide hiorlo = sit();
              Box fabbox;
              Box facebox;

              // assumption here that the stencil required
              // to compute the flux in the normal direction
              // is 2* the number of ghost cells for phi
              // (which is a reasonable assumption, and probably
              // better than just assuming you need one cell on
              // either side of the interface
              // (dfm 8-4-06)
              if (sit() == Side::Lo)
                {
                  fabbox = adjCellLo(gridbox,idir, 2*normalGhost);
                  fabbox.shift(idir, 1);
                  facebox = bdryLo(gridbox, idir,1);
                }
              else
                {
                  fabbox = adjCellHi(gridbox,idir, 2*normalGhost);
                  fabbox.shift(idir, -1);
                  facebox = bdryHi(gridbox, idir, 1);
                }

              // just in case we need ghost cells in the transverse direction
              // (dfm 8-4-06)
              for (int otherDir=0; otherDir<SpaceDim; ++otherDir)
                {
                  if (otherDir != idir)
                    {
                      fabbox.grow(otherDir, phiGhost[otherDir]);
                    }
                }
              CH_assert(!fabbox.isEmpty());

              FArrayBox phifab(fabbox, a_phi.nComp());
              phifab.copy(phifFab);

              FArrayBox fineflux;
              getFlux(fineflux, phifab, fineBCoef, facebox, idir,
                      m_refToFiner);

              Real scale = 1.0;
              levfluxreg.incrementFine(fineflux, scale, ditf(),
                                       interv, interv, idir, hiorlo);
            }
        }
    }

  Real scale =  1.0/m_dx;
  levfluxreg.reflux(a_residual, scale);
}
コード例 #27
0
void
EBCompositeMACProjector::
correctTangentialVelocity(EBFaceFAB&        a_velocity,
                          const EBFaceFAB&  a_gradient,
                          const Box&        a_grid,
                          const EBISBox&    a_ebisBox,
                          const IntVectSet& a_cfivs)
{
  CH_TIME("EBCompositeMACProjector::correctTangentialVelocity");
  int velDir = a_velocity.direction();
  int gradDir = a_gradient.direction();
  //veldir is the face on which the velocity lives
  //graddir is the direction of the component
  //and the face on which the mac gradient lives
  CH_assert(velDir != gradDir);
  CH_assert(a_velocity.nComp() == 1);
  CH_assert(a_gradient.nComp() == 1);

  //updating in place in fortran so we have to save a acopy
  EBFaceFAB velSave(a_ebisBox, a_velocity.getCellRegion(),  velDir, 1);
  velSave.copy(a_velocity);

  //interior box is the box where all of the stencil can be reached
  //without going out of the domain
  ProblemDomain domainBox = a_ebisBox.getDomain();
  Box interiorBox = a_grid;
  interiorBox.grow(1);
  interiorBox &= domainBox;
  interiorBox.grow(-1);
  Box interiorFaceBox = surroundingNodes(interiorBox, velDir);

  if (!interiorBox.isEmpty())
    {
      BaseFab<Real>&       regVel  = a_velocity.getSingleValuedFAB();
      const BaseFab<Real>& regGrad = a_gradient.getSingleValuedFAB();
      FORT_REGCORRECTTANVEL(CHF_FRA1(regVel,0),
                            CHF_CONST_FRA1(regGrad,0),
                            CHF_BOX(interiorFaceBox),
                            CHF_INT(velDir),
                            CHF_INT(gradDir));
    }

  //do only irregular and boundary cells pointwise
  IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(a_grid);
  IntVectSet ivsGrid(a_grid);
  ivsGrid -= interiorBox;
  ivsGrid |= ivsIrreg;
  FaceIterator faceit(ivsGrid, a_ebisBox.getEBGraph(), velDir, FaceStop::SurroundingWithBoundary);
  for (faceit.reset(); faceit.ok(); ++faceit)
    {
      //average neighboring grads in grad dir direction
      int numGrads = 0;
      Real gradAve = 0.0;
      const FaceIndex& velFace = faceit();
      for (SideIterator sitVel; sitVel.ok(); ++sitVel)
        {
          const VolIndex& vofSide = velFace.getVoF(sitVel());
          const IntVect&   ivSide = vofSide.gridIndex();
          //do not include stuff over coarse-fine interface and inside the domain
          //cfivs includes cells just outside domain
          if (!a_cfivs.contains(ivSide) && domainBox.contains(ivSide))
            {
              for (SideIterator sitGrad; sitGrad.ok(); ++sitGrad)
                {
                  Vector<FaceIndex> gradFaces = a_ebisBox.getFaces(vofSide, gradDir, sitGrad());
                  for (int iface = 0; iface < gradFaces.size(); iface++)
                    {
                      if (!gradFaces[iface].isBoundary())
                        {
                          numGrads++;
                          gradAve += a_gradient(gradFaces[iface], 0);
                        }
                    }
                }//end loop over gradient sides
            }//end cfivs check
          else
            {
              // inside coarse/fine interface or at domain boundary. extrapolate from neighboring vofs to get the gradient
              const Side::LoHiSide inSide    = flip(sitVel());
              const VolIndex&      inSideVof = velFace.getVoF(inSide);
              const IntVect&       inSideIV  = inSideVof.gridIndex();

              IntVect inSideFarIV = inSideIV;
              inSideFarIV[velDir] += sign(inSide);
              if (domainBox.contains(inSideIV) && domainBox.contains(inSideFarIV))
                {
                  Vector<VolIndex> farVofs = a_ebisBox.getVoFs(inSideFarIV);
                  if (farVofs.size()  == 1)
                    {
                      const VolIndex& inSideFarVof = farVofs[0];
                      for (SideIterator sitGrad; sitGrad.ok(); ++sitGrad)
                        {
                          //get the grad for the face adjoining inSideVof on the sitGrad side, in the gradDir direction
                          Vector<FaceIndex> gradFaces    = a_ebisBox.getFaces(inSideVof   , gradDir, sitGrad());
                          Vector<FaceIndex> gradFarFaces = a_ebisBox.getFaces(inSideFarVof, gradDir, sitGrad());
                          if ( (gradFaces.size() == 1) && (gradFarFaces.size() == 1) )
                            {
                              // if ( (!gradFaces[0].isBoundary()) && (!gradFarFaces[0].isBoundary()) )
                              //   {
                                  const Real& inSideGrad    = a_gradient(gradFaces[0], 0);
                                  const Real& inSideFarGrad = a_gradient(gradFarFaces[0], 0);
                                  Real extrapGrad = 2.0*inSideGrad - inSideFarGrad;
                                  gradAve += extrapGrad;
                                  numGrads++;
                                // }
                            }
                        }
                    }
                }
            }//end cfivs check
        }//end loop over sides of velocity face
      if (numGrads > 1)
        {
          gradAve /= Real(numGrads);
        }

      //remember that the fortran updated the velocity  in place so
      //we have to use the saved velocity
      a_velocity(velFace, 0) = velSave(velFace, 0) - gradAve;
    }
}
コード例 #28
0
ファイル: EBMGInterp.cpp プロジェクト: rsnemmen/Chombo
void
EBMGInterp::fillGhostCellsPWC(LevelData<EBCellFAB>& a_data,
                              const EBISLayout&     a_ebisl,
                              const ProblemDomain&  a_dom)
{
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      if (m_ghost[idir] < 1)
        {
          MayDay::Error("EBMGInterp:I need a ghost cell for linear interpolation");
        }
    }
  //extrapolate to every ghost cell
  const DisjointBoxLayout& dbl = a_data.disjointBoxLayout();
  for (DataIterator dit = dbl.dataIterator(); dit.ok(); ++dit)
    {
      const Box& grid = dbl.get(dit());
      const EBGraph& ebgraph = a_ebisl[dit()].getEBGraph();
      for (int idir = 0; idir < SpaceDim; idir++)
        {
          for (SideIterator sit; sit.ok(); ++sit)
            {
              Side::LoHiSide flipSide = flip(sit());
              Box ghostBox = adjCellBox(grid, idir, sit(), 1);

              for (BoxIterator boxit(ghostBox); boxit.ok(); ++boxit)
                {
                  if (a_dom.contains(boxit()))
                    {
                      Vector<VolIndex> vofs = ebgraph.getVoFs(boxit());
                      for (int ivof = 0; ivof < vofs.size(); ivof++)
                        {
                          Real extrapVal = 0;
                          Vector<FaceIndex> faces = ebgraph.getFaces(vofs[ivof], idir, flipSide);
                          for (int ivar = 0; ivar < a_data.nComp(); ivar++)
                            {
                              for (int iface = 0; iface < faces.size(); iface++)
                                {
                                  const VolIndex& flipVoF = faces[iface].getVoF(flipSide);
                                  extrapVal += a_data[dit()](flipVoF, ivar);
                                }
                              if (faces.size() > 1) extrapVal /= faces.size();
                              a_data[dit()](vofs[ivof], ivar) = extrapVal;
                            }
                        }

                    }
                  else
                    {
                      //just put in the single valued part of the data holder something sensible
                      //if not inside domain
                      int isign = sign(flipSide);
                      BaseFab<Real>& bfdata = a_data[dit()].getSingleValuedFAB();
                      IntVect otherIV = boxit() + isign*BASISV(idir);
                      for (int ivar = 0; ivar < a_data.nComp(); ivar++)
                        {
                          bfdata(boxit(), ivar) = bfdata(otherIV, ivar);
                        }
                    }
                }
            }
        }
    }
  //do exchange to overwrite ghost cells where there exists real data
  a_data.exchange();
}
コード例 #29
0
ファイル: SlabService.cpp プロジェクト: dtgraves/EBAMRCNS
void
SlabService::fillGraph(BaseFab<int>&      a_regIrregCovered,
                       Vector<IrregNode>& a_nodes,
                       const Box&         a_validRegion,
                       const Box&         a_ghostRegion,
                       const ProblemDomain&         a_domain,
                       const RealVect&    a_origin,
                       const Real&        a_dx) const
{
  Box grownCovBox = grow(m_coveredRegion, 1);
  grownCovBox &= a_ghostRegion;
  IntVectSet ivsIrreg(grownCovBox);
  ivsIrreg -= m_coveredRegion;
  ivsIrreg &= a_domain;

  //set regirregcoverred flags
  CH_assert(a_regIrregCovered.box().contains(a_ghostRegion));

  //set every cell to regular
  a_regIrregCovered.setVal(1);
  for (BoxIterator bit(a_ghostRegion); bit.ok(); ++bit)
    {
      if (m_coveredRegion.contains(bit()))
        {
          //set covered cells to -1
          a_regIrregCovered(bit(), 0) = -1;
        }
      else if (ivsIrreg.contains(bit()))
        {
          //set irreg cells to 0
          a_regIrregCovered(bit(), 0) = 0;
        }
    }

  //now loop through irreg cells and make Nodes for them
  a_nodes.resize(0);
  for (IVSIterator ivsit(ivsIrreg); ivsit.ok(); ++ivsit)
    {
      const IntVect& iv = ivsit();
      if (a_validRegion.contains(iv))
        {
          IrregNode node;
          //first the obvious
          node.m_cell = iv;
          node.m_volFrac = 1.0;
          node.m_cellIndex = 0;
          node.m_volCentroid    = RealVect::Zero;
          //any time the next cell over is in the covered
          //region, there is no face.  If there is a cell
          //but it is outside the domain, the arc=-1 to signify
          //a boundary face.  Otherwise, the arc is -2 if it
          //is to a regular cell and 0 if it is to an irregular cell
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              for (SideIterator sit; sit.ok(); ++sit)
                {
                  int arcIndex = node.index(idir, sit());
                  Vector<int>&      arcs     = node.m_arc[arcIndex];
                  Vector<Real>&     areaFracs= node.m_areaFrac[arcIndex];
                  Vector<RealVect>& faceCents= node.m_faceCentroid[arcIndex];
                  IntVect otherIV = iv + sign(sit())*BASISV(idir);
                  if (m_coveredRegion.contains(otherIV))
                    {
                      //do nothing, covered face. leave the vector empty
                    }
                  else
                    {
                      int otherCellIndex;
                      if (ivsIrreg.contains(otherIV))
                        {
                          //arc irregular cell inside the domain
                          otherCellIndex = 0;
                        }
                      else if (!a_domain.contains(otherIV))
                        {
                          //boundary face
                          otherCellIndex = -1;
                        }
                      else
                        {
                          //arc to regular cell
                          otherCellIndex = -2;
                        }
                      arcs.push_back(otherCellIndex);
                      Real     areaFrac = 1.0;
                      RealVect faceCent = RealVect::Zero;

                      areaFracs.push_back(areaFrac);
                      faceCents.push_back(faceCent);
                    } //end otherIV not covered
                }
            }
          //the boundary centroid and normal
          //depend on which side is covered

          for (int idir = 0; idir < SpaceDim; idir++)
            {
              for (SideIterator sit; sit.ok(); ++sit)
                {
                  int arcIndex = node.index(idir, sit());
                  Vector<int>& arcs = node.m_arc[arcIndex];
                  if (arcs.size() == 0)
                    {
                      int isign = sign(sit());
                      node.m_bndryCentroid[idir] = Real(isign)*0.5;
                    }
                }
            }
          a_nodes.push_back(node);
        }
    }
}
コード例 #30
0
void
EBFineToCoarRedist::
define(const DisjointBoxLayout& a_dblFine,
       const DisjointBoxLayout& a_dblCoar,
       const EBISLayout& a_ebislFine,
       const EBISLayout& a_ebislCoar,
       const Box& a_domainCoar,
       const int& a_nref,
       const int& a_nvar,
       int a_redistRad,
       const EBIndexSpace* const a_ebisPtr)
{
  CH_TIME("EBFineToCoarRedist::stardard_define");
  m_isDefined = true;
  m_nComp = a_nvar;
  m_refRat = a_nref;
  m_domainCoar = a_domainCoar;
  m_gridsFine = a_dblFine;
  m_gridsCoar = a_dblCoar;
  m_ebislFine = a_ebislFine;
  m_ebislCoar = a_ebislCoar;
  m_redistRad = a_redistRad;
  //created the coarsened fine layout
  m_gridsRefCoar = DisjointBoxLayout();
  refine(m_gridsRefCoar, m_gridsCoar, m_refRat);

  CH_assert(a_ebisPtr->isDefined());
  int nghost = 3*m_redistRad;
  Box domainFine = refine(m_domainCoar, m_refRat);
  a_ebisPtr->fillEBISLayout(m_ebislRefCoar, m_gridsRefCoar,
                            domainFine, nghost);
  m_ebislRefCoar.setMaxCoarseningRatio(m_refRat,a_ebisPtr);

  //define the intvectsets over which the objects live
  m_setsFine.define(m_gridsFine);
  m_setsRefCoar.define(m_gridsCoar);

  //make sets
  //global set consists of redistrad on the fine side of the coarse-fine
  //interface
  //the fine set is that within one fine box.
  //the refcoar set is that set within one refined coarse box.
  {
    CH_TIME("make_fine_sets");
    for (DataIterator dit =
          m_gridsFine.dataIterator(); dit.ok(); ++dit)
      {
        const Box& fineBox = m_gridsFine.get(dit());
        IntVectSet& fineSet = m_setsFine[dit()];
        //add entire fine box
        fineSet = IntVectSet(fineBox);
        IntVectSet irregIVS = m_ebislFine[dit()].getIrregIVS(fineBox);
        fineSet &= irregIVS;
        //subtract fine box shrunk by the redistribution radius
        fineSet -= grow(fineBox, -m_redistRad);
        //subtract all other the fine boxes shifted in all
        //directions
        for (LayoutIterator lit =
              m_gridsFine.layoutIterator(); lit.ok(); ++lit)
          {
            const Box& otherBox = m_gridsFine.get(lit());
            if (otherBox != fineBox)
              {
                for (int idir = 0; idir < SpaceDim; idir++)
                  {
                    for (SideIterator sit; sit.ok(); ++sit)
                      {
                        Box shiftBox = otherBox;
                        shiftBox.shift(idir, sign(sit())*m_redistRad);
                        fineSet -= shiftBox;
                      }
                  }
              }
          }
      }
  }
  {
    CH_TIME("make_coar_sets");
    for (DataIterator dit =
          m_gridsCoar.dataIterator(); dit.ok(); ++dit)
      {
        Box grownBox = grow(m_gridsRefCoar.get(dit()), m_redistRad);
        grownBox &= domainFine;
        //find the complement of what we really want
        IntVectSet ivsComplement(grownBox);
        for (LayoutIterator litFine =
              m_gridsFine.layoutIterator(); litFine.ok(); ++litFine)
          {
            const Box& fineBox = m_gridsFine.get(litFine());
            IntVectSet fineSet(fineBox);
            //add entire fine box
            fineSet = IntVectSet(fineBox);
            Box interiorBox = grow(fineBox, -m_redistRad);
            //subtract fine box shrunk by the redistribution radius
            fineSet -= interiorBox;
            //subtract all other the fine boxes shifted in all
            //directions
            for (LayoutIterator lit =
                  m_gridsFine.layoutIterator(); lit.ok(); ++lit)
              {
                const Box& otherBox = m_gridsFine.get(lit());
                if (otherBox != fineBox)
                  {
                    for (int idir = 0; idir < SpaceDim; idir++)
                      {
                        for (SideIterator sit; sit.ok(); ++sit)
                          {
                            Box shiftBox = otherBox;
                            shiftBox.shift(idir, sign(sit())*m_redistRad);
                            fineSet -= shiftBox;
                          }
                      }
                  }
              }
            //subtract the fine set from the complement
            ivsComplement -= fineSet;
          }
        //now the set we want is the grownbox - complement
        IntVectSet& refCoarSet = m_setsRefCoar[dit()];
        refCoarSet = IntVectSet(grownBox);
        refCoarSet -= ivsComplement;
        IntVectSet irregIVS = m_ebislRefCoar[dit()].getIrregIVS(grownBox);
        refCoarSet &= irregIVS;
      }
  }
  defineDataHolders();
  setToZero();
}