예제 #1
0
// -----------------------------------------------------------------------------
// 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);
            }
        }
    }
}
예제 #2
0
파일: SWIBC.cpp 프로젝트: jkozdon/tetemoko
/// Set up initial conditions
void SWIBC::initializeBdry(LevelData<FArrayBox>& a_B)
{
    const Real tmpVal  =  0.0;
    const Real tmpVal2 = 100;
    for (DataIterator dit = a_B.dataIterator(); dit.ok(); ++dit)
    {
        // Storage for current grid
        FArrayBox& B = a_B[dit()];

        // Box of current grid
        Box bBox = B.box();
        bBox &= m_domain;

        // Set up initial condition in this grid
        FORT_LINELASTSETFAB(CHF_FRA1(B,4),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,5),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal));
        FORT_LINELASTSETFAB(CHF_FRA1(B,6),
            CHF_BOX(bBox),
            CHF_CONST_REAL(tmpVal2));
    }
}
예제 #3
0
// ---------------------------------------------------------
void
AMRNavierStokes::computeLapVel(LevelData<FArrayBox>& a_lapVel,
                               LevelData<FArrayBox>& a_vel,
                               const LevelData<FArrayBox>* a_crseVelPtr)
{
  // set BC's
  VelBCHolder velBC(m_physBCPtr->viscousVelFuncBC());
  bool isHomogeneous = false;
  m_velocityAMRPoissonOp.applyOp(a_lapVel, a_vel, a_crseVelPtr,
                                 isHomogeneous, velBC);

  // may need to extend lapVel to cover ghost cells as well
  {
    BCHolder viscBC = m_physBCPtr->viscousFuncBC();
    const DisjointBoxLayout& grids = a_lapVel.getBoxes();
    DataIterator dit = a_lapVel.dataIterator();
    for (dit.reset(); dit.ok(); ++dit)
      {
        viscBC(a_lapVel[dit], grids[dit],
               m_problem_domain, m_dx,
               false); // not homogeneous
      }
  }

  // finally, do exchange
  a_lapVel.exchange(a_lapVel.interval());
}
예제 #4
0
void EBPoissonOp::
getJacobiRelaxCoeff(LevelData<EBCellFAB>& a_relaxCoeff)
{

  // Diagonal weight for Jacobi on regular grid
  Real weightBase = m_alpha;
  for (int idir = 0; idir < SpaceDim; idir++)
    {
      weightBase += -2.0 * m_beta * m_invDx2[idir];
    }
  weightBase = 1.0 / weightBase;       // Weight for plain (non-weighted) Jacobi
  Real weightRegular = EBPOISSONOP_JACOBI_OMEGA * weightBase; // ... for weighted Jacobi

  for (DataIterator dit = m_eblg.getDBL().dataIterator(); dit.ok(); ++dit)
    {
      // Most of the grid is regular, so set the regular weighting by default
      a_relaxCoeff[dit()].setVal(weightRegular);

      // Walk the EB cells, and correct their weighting
      const BaseIVFAB<Real>&      curAlphaWeight = m_alphaDiagWeight[dit()];
      const BaseIVFAB<Real>&      curBetaWeight  = m_betaDiagWeight[dit()];

      VoFIterator& ebvofit = m_vofItIrreg[dit()];
      for (ebvofit.reset(); ebvofit.ok(); ++ebvofit)
        {
          const VolIndex& vof = ebvofit();
          Real weightIrreg = EBPOISSONOP_JACOBI_OMEGA / (m_alpha*curAlphaWeight(vof, 0) + m_beta*curBetaWeight(vof, 0));
          a_relaxCoeff[dit()](vof, 0) = weightIrreg;
        }
    }
}
예제 #5
0
// ---------------------------------------------------------
void
AMRNavierStokes::computeLapScal(LevelData<FArrayBox>& a_lapScal,
                                LevelData<FArrayBox>& a_scal,
                                const BCHolder& a_physBC,
                                const LevelData<FArrayBox>* a_crseScalPtr)
{
  m_scalarsAMRPoissonOp.setBC(a_physBC);
  bool isHomogeneous = false;
  if (a_crseScalPtr != NULL)
    {
      m_scalarsAMRPoissonOp.AMROperatorNF(a_lapScal, a_scal, *a_crseScalPtr,
                                          isHomogeneous);
    }
  else
    {
      m_scalarsAMRPoissonOp.applyOpI(a_lapScal, a_scal,
                                     isHomogeneous);
    }

  BCHolder viscBC = m_physBCPtr->viscousFuncBC();

  DataIterator dit = a_lapScal.dataIterator();
  const DisjointBoxLayout& grids = a_lapScal.getBoxes();
  for (dit.reset(); dit.ok(); ++dit)
    {
      viscBC(a_lapScal[dit],
             grids[dit],
             m_problem_domain, m_dx,
             false); // not homogeneous
    }

  // finally, do exchange
  a_lapScal.exchange(a_lapScal.interval());
}
예제 #6
0
int scopingTest()
{
  Vector<Box> boxes;
  int retflag = 0;
  setGrids(boxes);

  LevelData<FArrayBox> levelFab;
  makeLevelData(boxes, levelFab);
  const DisjointBoxLayout& dbl = levelFab.getBoxes();
  DataIterator dit = dbl.dataIterator();
  int ivec = 0;
  for (dit.begin(); dit.ok(); ++dit)
    {
      if (!dbl.check(dit()))
        {
          if (verbose)
            pout() << indent2 << pgmname
                 << ": failed at box " << ivec << endl;
          retflag = 1;
        }
      else
        {
          levelFab[dit].setVal(0.);
        }
      if (retflag > 0) break;
      ivec++;
    }
  return retflag;
}
예제 #7
0
void
initData(LevelData<FArrayBox>& a_data, const Real a_dx)
{

  DataIterator dit = a_data.dataIterator();
  const DisjointBoxLayout& interiorBoxes = a_data.getBoxes();

  for (dit.begin(); dit.ok(); ++dit)
    {
      // first set to a bogus value which will persist in ghost cells
      // after initialization
      a_data[dit()].setVal(1.0e9);

      // this will be slow, but who cares?
      FArrayBox& localData = a_data[dit()];
      BoxIterator boxIt(interiorBoxes[dit()]);
      Real localVal;
      for (boxIt.begin(); boxIt.ok(); ++boxIt)
        {
          const IntVect& loc = boxIt();
          for (int comp=0; comp<localData.nComp(); comp++)
            {
              localVal = dataVal(loc, comp);
              localData(loc, comp) = localVal;
            }
        }

    }
}
예제 #8
0
void
NoFlowVortex::
initializeVelocity(LevelData<EBCellFAB>&    a_velocity,
                   const DisjointBoxLayout& a_grids,
                   const EBISLayout&        a_ebisl,
                   const ProblemDomain&     a_domain,
                   const RealVect&          a_origin,
                   const Real&              a_time,
                   const RealVect&          a_dx) const
{
  Real pi = 4.0*atan(1.0);
  for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
    {
      IntVectSet ivsBox(a_grids.get(dit()));
      for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit)
        {
          RealVect xval, velpt;
          getXVal(xval, a_origin,vofit(), a_dx);
          getVelPt(velpt, xval, pi);
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              a_velocity[dit()](vofit(), idir) = velpt[idir];
            }
        }
    }
}
예제 #9
0
void LevelPluto::setGridLevel()
{

 CH_TIME("LevelPluto::setGrid");

 m_structs_grid.define(m_grids);

 #if GEOMETRY != CARTESIAN
  m_dV.define(m_grids,CHOMBO_NDV,m_numGhost*IntVect::Unit);
 #endif

 Real dlMinLoc = 1.e30;

 for (DataIterator dit = m_grids.dataIterator(); dit.ok(); ++dit)
   {
      // The current box
      Box curBox = m_grids.get(dit());
      struct GRID* grid = m_structs_grid[dit].getGrid();

      #if GEOMETRY != CARTESIAN 
       FArrayBox& curdV = m_dV[dit()];    
      #else
       FArrayBox  curdV; 
      #endif
       
      m_patchPluto->setGrid(curBox, grid, curdV);           
       
      for (int idir = 0; idir < SpaceDim; idir++) dlMinLoc = Min(dlMinLoc,grid[idir].dl_min);   
   }

#if (GEOMETRY == CARTESIAN) || (GEOMETRY == CYLINDRICAL)

   D_EXPAND(m_dl_min = m_dx; ,
예제 #10
0
// ---------------------------------------------------------
void levelDivergenceMAC(LevelData<FArrayBox>& a_div,
                        const LevelData<FluxBox>& a_uEdge,
                        const Real a_dx)
{

  // silly way to do this until i figure out a better
  // way to make this dimensionally-independent
  CH_assert (a_uEdge.nComp() >= a_div.nComp());


  DataIterator dit = a_div.dataIterator();
  for (dit.reset(); dit.ok(); ++dit)
  {
    a_div[dit()].setVal(0.0);

    const FluxBox& thisFluxBox = a_uEdge[dit()];
    Box cellBox(thisFluxBox.box());
    // just to be sure we don't accidentally trash memory...
    cellBox &= a_div[dit()].box();

    // now loop over coordinate directions and add to divergence
    for (int dir=0; dir<SpaceDim; dir++)
    {
      const FArrayBox& uEdgeDir = thisFluxBox[dir];

      FORT_DIVERGENCE(CHF_CONST_FRA(uEdgeDir),
                      CHF_FRA(a_div[dit()]),
                      CHF_BOX(cellBox),
                      CHF_CONST_REAL(a_dx),
                      CHF_INT(dir));
    }

  }

}
예제 #11
0
void
EBLevelAdvect::
computeNormalVel(LevelData<EBCellFAB>&                          a_normalVel,
                 const LevelData<EBFluxFAB>&                    a_advectionVel,
                 const LayoutData<Vector<BaseIVFAB<Real> * > >& a_coveredVeloLo,
                 const LayoutData<Vector<BaseIVFAB<Real> * > >& a_coveredVeloHi,
                 const LayoutData<Vector<Vector<VolIndex> > >&  a_coveredFaceLo,
                 const LayoutData<Vector<Vector<VolIndex> > >&  a_coveredFaceHi) const
{
  CH_TIME("EBLevelAdvect::computeNormalVel");
  for (DataIterator dit = m_thisGrids.dataIterator(); dit.ok(); ++dit)
    {
      const Box& cellBox = m_thisGrids.get(dit());
      Box  grownBox = grow(cellBox, 1);
      grownBox &= m_domain;
      m_ebPatchAdvect[dit]->averageVelToCC(a_normalVel[dit()],
                                           a_advectionVel[dit()],
                                           a_coveredVeloLo[dit()],
                                           a_coveredVeloHi[dit()],
                                           a_coveredFaceLo[dit()],
                                           a_coveredFaceHi[dit()],
                                           grownBox);
    }

}
예제 #12
0
//-----------------------------------------------------------------------
// AMR Factory define function, with coefficient data allocated automagically
// for operators.
void
VCAMRPoissonOp2Factory::
define(const ProblemDomain& a_coarseDomain,
       const Vector<DisjointBoxLayout>& a_grids,
       const Vector<int>& a_refRatios,
       const Real& a_coarsedx,
       BCHolder a_bc,
       const IntVect& a_ghostVect)
{
  // This just allocates coefficient data, sets alpha = beta = 1, and calls
  // the other define() method.
  Vector<RefCountedPtr<LevelData<FArrayBox> > > aCoef(a_grids.size());
  Vector<RefCountedPtr<LevelData<FluxBox> > > bCoef(a_grids.size());
  for (int i = 0; i < a_grids.size(); ++i)
  {
    aCoef[i] = RefCountedPtr<LevelData<FArrayBox> >(
                 new LevelData<FArrayBox>(a_grids[i], 1, a_ghostVect));
    bCoef[i] = RefCountedPtr<LevelData<FluxBox> >(
                 new LevelData<FluxBox>(a_grids[i], 1, a_ghostVect));

    // Initialize the a and b coefficients to 1 for starters.
    for (DataIterator dit = aCoef[i]->dataIterator(); dit.ok(); ++dit)
    {
      (*aCoef[i])[dit()].setVal(1.0);
      for (int idir = 0; idir < SpaceDim; ++idir)
        (*bCoef[i])[dit()][idir].setVal(1.0);
    }
  }
  Real alpha = 1.0, beta = 1.0;
  define(a_coarseDomain, a_grids, a_refRatios, a_coarsedx, a_bc,
         alpha, aCoef, beta, bCoef);
}
예제 #13
0
// ---------------------------------------------------------
// 27 March 2003:
// This is called by other functions, and should not be called directly.
Real
maxnorm(const BoxLayoutData<NodeFArrayBox>& a_layout,
        const Interval& a_interval,
        bool a_verbose)
{
  Real normTotal = 0.;
  // a_p == 0:  max norm
  for (DataIterator it = a_layout.dataIterator(); it.ok(); ++it)
    {
      const Box& thisBox(a_layout.box(it())); // CELL-centered
      const NodeFArrayBox& thisNfab = a_layout[it()];
      Real thisNfabNorm =
        maxnorm(thisNfab, thisBox, a_interval.begin(), a_interval.size());
      if (a_verbose)
        cout << "maxnorm(" << thisBox << ") = " << thisNfabNorm << endl;
      normTotal = Max(normTotal, thisNfabNorm);
    }
# ifdef CH_MPI
  Real recv;
  int result = MPI_Allreduce(&normTotal, &recv, 1, MPI_CH_REAL,
                             MPI_MAX, Chombo_MPI::comm);
  if (result != MPI_SUCCESS)
    { //bark!!!
      MayDay::Error("sorry, but I had a communication error on maxnorm");
    }
  normTotal = recv;
# endif
  return normTotal;
}
예제 #14
0
// this preconditioner first initializes phihat to (IA)phihat = rhshat
// (diagonization of L -- A is the matrix version of L)
// then smooths with a couple of passes of levelGSRB
void VCAMRPoissonOp2::preCond(LevelData<FArrayBox>&       a_phi,
                              const LevelData<FArrayBox>& a_rhs)
{
  CH_TIME("VCAMRPoissonOp2::preCond");

  // diagonal term of this operator in:
  //
  //       alpha * a(i)
  //     + beta  * sum_over_dir (b(i-1/2*e_dir) + b(i+1/2*e_dir)) / (dx*dx)
  //
  // The inverse of this is our initial multiplier.

  int ncomp = a_phi.nComp();

  CH_assert(m_lambda.isDefined());
  CH_assert(a_rhs.nComp()    == ncomp);
  CH_assert(m_bCoef->nComp() == ncomp);

  // Recompute the relaxation coefficient if needed.
  resetLambda();

  // don't need to use a Copier -- plain copy will do
  DataIterator dit = a_phi.dataIterator();
  for (dit.begin(); dit.ok(); ++dit)
    {
      // also need to average and sum face-centered bCoefs to cell-centers
      Box gridBox = a_rhs[dit].box();

      // approximate inverse
      a_phi[dit].copy(a_rhs[dit]);
      a_phi[dit].mult(m_lambda[dit], gridBox, 0, 0, ncomp);
    }

  relax(a_phi, a_rhs, 2);
}
// -----------------------------------------------------------------------------
// Semi-implicitly handles the gravity forcing and projection.
// The old* inputs should be the values at t^n.
// The new* inputs should be the updated values from the TGA solver.
// -----------------------------------------------------------------------------
void AMRNavierStokes::doCCIGProjection (LevelData<FArrayBox>&       a_newVel,
                                        LevelData<FArrayBox>&       a_newB,
                                        const LevelData<FArrayBox>& a_oldVel,
                                        const LevelData<FArrayBox>& a_oldB,
                                        const LevelData<FluxBox>&   a_advVel,
                                        const Real                  a_oldTime,
                                        const Real                  a_dt,
                                        const bool                  a_doProj)
{
    CH_TIME("AMRNavierStokes::doCCIGProjection");

    const Real halfTime = a_oldTime + 0.5 * a_dt;
    const Real newTime  = a_oldTime + 1.0 * a_dt;
    const Real dummyTime = -1.0e300;
    const GeoSourceInterface& geoSource = *(m_levGeoPtr->getGeoSourcePtr());
    const RealVect& dx = m_levGeoPtr->getDx();
    const DisjointBoxLayout& grids = a_newVel.getBoxes();
    DataIterator dit = grids.dataIterator();


    // 1. Compute the background buoyancy, N, Dinv, etc...

    // Fill the FC background buoyancy field.
    LevelData<FluxBox> bbar(grids, 1, 2*IntVect::Unit);
    for (dit.reset(); dit.ok(); ++dit) {
        FluxBox& bbarFB = bbar[dit];

        D_TERM(m_physBCPtr->setBackgroundScalar(bbarFB[0], 0, *m_levGeoPtr, dit(), dummyTime);,
               m_physBCPtr->setBackgroundScalar(bbarFB[1], 0, *m_levGeoPtr, dit(), dummyTime);,
예제 #16
0
void
EBCoarToFineRedist::
defineDataHolders()
{
  CH_TIME("EBCoarToFineRedist::defineDataHolders");
  //make mass buffers
  BaseIVFactory<Real> factCoar(m_ebislCoar, m_setsCoar);
  IntVect noghost = IntVect::Zero;
  m_regsCoar.define(m_gridsCoar, m_nComp, noghost, factCoar);

  BaseIVFactory<Real> factCedFine(m_ebislCedFine, m_setsCedFine);
  m_regsCedFine.define(m_gridsCedFine, m_nComp, m_redistRad*IntVect::Unit, factCedFine);

  EBCellFactory ebcellfact(m_ebislCedFine);
  m_densityCedFine.define(m_gridsCedFine, 1, 2*m_redistRad*IntVect::Unit, ebcellfact);

  //define the stencils with volume weights.
  //if you want mass weights or whatever, use reset weights
  m_stenCedFine.define(m_gridsCedFine);
  m_volumeStenc.define(m_gridsCedFine);
  m_standardStenc.define(m_gridsCedFine);
  RedistStencil stenCedFine(m_gridsCedFine, m_ebislCedFine,
                            m_domainCoar, m_redistRad);

  for (DataIterator ditCedF = m_gridsCedFine.dataIterator();
      ditCedF.ok(); ++ditCedF)
    {
      BaseIVFAB<VoFStencil>& stenFAB = m_stenCedFine[ditCedF()];
      BaseIVFAB<VoFStencil>& volStenFAB = m_volumeStenc[ditCedF()];
      BaseIVFAB<VoFStencil>& stanStenFAB = m_standardStenc[ditCedF()];
      const EBISBox& ebisBox = m_ebislCedFine[ditCedF()];
      const IntVectSet& ivs  = m_setsCedFine[ditCedF()];
      const BaseIVFAB<VoFStencil>& rdStenFAB = stenCedFine[ditCedF()];
      const Box& gridCedFine = m_gridsCedFine.get(ditCedF());
      stenFAB.define(ivs, ebisBox.getEBGraph(), 1);
      volStenFAB.define(ivs, ebisBox.getEBGraph(), 1);
      stanStenFAB.define(ivs, ebisBox.getEBGraph(), 1);

      for (VoFIterator vofit(ivs, ebisBox.getEBGraph()); vofit.ok(); ++vofit)
        {
          const VolIndex& srcVoF = vofit();
          VoFStencil newStencil;
          const VoFStencil& stanSten = rdStenFAB(srcVoF, 0);
          for (int istan = 0; istan < stanSten.size(); istan++)
            {
              const VolIndex& dstVoF = stanSten.vof(istan);
              const Real& weight = stanSten.weight(istan);
              if (gridCedFine.contains(dstVoF.gridIndex()))
                {
                  newStencil.add(dstVoF, weight);
                }
            }
          stenFAB(srcVoF, 0)    = newStencil;
          //need to keep these around to get mass redist right
          volStenFAB(srcVoF, 0) = newStencil;
          stanStenFAB(srcVoF,0) = stanSten;

        }
    }
}
예제 #17
0
// ---------------------------------------------------------
// 28 March 2003:
// This is called by other functions, and should not be called directly.
Real
integral(const BoxLayoutData<NodeFArrayBox>& a_layout,
         const Real a_dx,
         const Interval& a_interval,
         bool a_verbose)
{
  Real integralTotal = 0.;

  for (DataIterator it = a_layout.dataIterator(); it.ok(); ++it)
    {
      const NodeFArrayBox& thisNfab = a_layout[it()];
      const Box& thisBox(a_layout.box(it())); // CELL-centered
      Real thisNfabIntegral =
        integral(thisNfab, a_dx, thisBox,
                 a_interval.begin(), a_interval.size());
      integralTotal += thisNfabIntegral;
    }
# ifdef CH_MPI
  Real recv;
  // add up
  int result = MPI_Allreduce(&integralTotal, &recv, 1, MPI_CH_REAL,
                             MPI_SUM, Chombo_MPI::comm);
  if (result != MPI_SUCCESS)
    { //bark!!!
      MayDay::Error("sorry, but I had a communication error on integral");
    }
  integralTotal = recv;
# endif
  return integralTotal;
}
예제 #18
0
void
PoisselleTube::
initializeVelocity(LevelData<EBCellFAB>&    a_velocity,
                   const DisjointBoxLayout& a_grids,
                   const EBISLayout&        a_ebisl,
                   const ProblemDomain&     a_domain,
                   const RealVect&          a_origin,
                   const Real&              a_time,
                   const RealVect&          a_dx) const
{
  for (DataIterator dit = a_grids.dataIterator(); dit.ok(); ++dit)
    {
      IntVectSet ivsBox(a_grids.get(dit()));
      for (VoFIterator vofit(ivsBox, a_ebisl[dit()].getEBGraph()); vofit.ok(); ++vofit)
        {
          RealVect xval = EBArith::getVofLocation(vofit() , a_dx, RealVect::Zero);
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              //bogus values for normal and time because they do not matter
              Real velComp = m_bcval[idir].value(xval, RealVect::Zero, a_time, idir);
              a_velocity[dit()](vofit(), idir) = velComp;
            }
        }
    }
}
예제 #19
0
// ---------------------------------------------------------
void
NodeQCFI::coarseFineInterp(LevelData<NodeFArrayBox>& a_phiFine,
                           const LevelData<NodeFArrayBox>& a_phiCoarse,
                           bool a_inhomogeneous)
{
  CH_assert(isDefined());
  CH_assert(a_phiFine.nComp() == m_ncomp);
  CH_assert(a_phiCoarse.nComp() == m_ncomp);

  if (m_coarsenings == 1)
    {
      m_qcfi2[0]->coarseFineInterp(a_phiFine, a_phiCoarse);
    }
  else // m_coarsenings >= 2
    {
      // if m_coarsenings == 2:
      // m_qcfi2[1] = new NodeQuadCFInterp2(a_grids, true);
      // m_qcfi2[0] = new NodeQuadCFInterp2(a_grids.coarsen(2), false);
      // m_inter[0] = new LevelData(a_grids.coarsen(2));

      // m_qcfi2[0] interpolates m_inter[0] from a_phiCoarse on all of it.
      // m_qcfi2[1] interpolates a_phiFine from m_inter[0] on interface only.

      m_qcfi2[0]->coarseFineInterp(*m_inter[0], a_phiCoarse);
      m_inter[0]->exchange(m_inter[0]->interval());

      // Set domain and dx for coarsest level refined by 2.
      ProblemDomain domain(m_domainPenultimate);
      Real dx = m_dxPenultimate;

      bool homogeneous = !a_inhomogeneous;
      const DisjointBoxLayout& dbl0 = m_inter[0]->disjointBoxLayout();
      for (DataIterator dit = dbl0.dataIterator(); dit.ok(); ++dit)
        {
          m_bc((*m_inter[0])[dit()],  dbl0.get(dit()), domain,  dx, homogeneous);
        }

      for (int interlev = 1; interlev < m_coarsenings - 1; interlev++)
        {
          m_qcfi2[interlev]->coarseFineInterp(*m_inter[interlev],
                                              *m_inter[interlev-1]);

          m_inter[interlev]->exchange(m_inter[interlev]->interval());

          domain.refine(2);
          dx *= 0.5;
          const DisjointBoxLayout& dbl = m_inter[interlev]->disjointBoxLayout();
          for (DataIterator dit = dbl.dataIterator(); dit.ok(); ++dit)
            {
              m_bc((*m_inter[interlev])[dit()],  dbl.get(dit()), domain,  dx, homogeneous);
            }
        }

      m_qcfi2[m_coarsenings-1]->coarseFineInterp(a_phiFine,
                                                 *m_inter[m_coarsenings-2]);
      // Don't need to set boundary conditions for a_phiFine
      // because the calling function will do that.
    }
}
예제 #20
0
void
EBCompositeCCProjector::
averageVelocityToFaces(Vector<LevelData<EBFluxFAB>* >&  a_macVeloc,
                       Vector<LevelData<EBCellFAB>* >&  a_velocity)
{
  CH_TIME("EBCompositeCCProjector::averageVelocityToFaces");
  //interpolate and then send stuff on through to level function
  // int ncomp = a_velocity[0]->nComp();
  Interval interv(0, SpaceDim-1);
  Vector<LevelData<EBCellFAB> *> amrPhi = m_macProjector->getPhi();
  //  Real time = 0.;
  for (int ilev = 0; ilev < m_numLevels; ilev++)
    {
      if (ilev > 0)
        {
          //so it can be reused quadcfi is a one-variable animal
          //when we have ebalias, we can accomplish this without copies.
          //for now, tough luck
          //use phi for scratch space
          LevelData<EBCellFAB>& phiCoar = *amrPhi[ilev-1];
          LevelData<EBCellFAB>& phiFine = *amrPhi[ilev  ];
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              Interval phiInterv(0, 0);
              Interval velInterv(idir, idir);
              a_velocity[ilev-1]->copyTo(velInterv, phiCoar, phiInterv);
              a_velocity[ilev  ]->copyTo(velInterv, phiFine, phiInterv);
              m_quadCFI[ilev]->interpolate(phiFine,
                                           phiCoar,
                                           phiInterv);
              // m_pwlCFI[ilev]->interpolate(phiFine,
              //                             phiCoar,
              //                             phiCoar,
              //                             time,
              //                             time,
              //                             time,
              //                             phiInterv);

              //on copy back, we need ghost cells, so do the data iterator loop
              for (DataIterator dit = phiFine.dataIterator(); dit.ok(); ++dit)
                {
                  Box region = phiFine[dit()].getRegion(); //includes ghost cells
                  (*a_velocity[ilev])[dit()].copy(region, velInterv, region, phiFine[dit()], phiInterv);
                }

              EBLevelDataOps::setVal(phiFine, 0.0);
              EBLevelDataOps::setVal(phiCoar, 0.0);
            }
        }
      a_velocity[ilev]->exchange(interv);
      ccpAverageVelocityToFaces(*a_macVeloc[ilev],
                                *a_velocity[ilev],
                                m_eblg[ilev].getDBL(),
                                m_eblg[ilev].getEBISL(),
                                m_eblg[ilev].getDomain(),
                                m_dx[ilev],
                                *m_eblg[ilev].getCFIVS());
    }
}
예제 #21
0
void VCAMRPoissonOp2::residualI(LevelData<FArrayBox>&       a_lhs,
                               const LevelData<FArrayBox>& a_phi,
                               const LevelData<FArrayBox>& a_rhs,
                               bool                        a_homogeneous)
{
  CH_TIME("VCAMRPoissonOp2::residualI");

  LevelData<FArrayBox>& phi = (LevelData<FArrayBox>&)a_phi;
  Real dx = m_dx;
  const DisjointBoxLayout& dbl = a_lhs.disjointBoxLayout();
  DataIterator dit = phi.dataIterator();
  {
    CH_TIME("VCAMRPoissonOp2::residualIBC");

    for (dit.begin(); dit.ok(); ++dit)
    {
      m_bc(phi[dit], dbl[dit()],m_domain, dx, a_homogeneous);
    }
  }

  phi.exchange(phi.interval(), m_exchangeCopier);

  for (dit.begin(); dit.ok(); ++dit)
    {
      const Box& region = dbl[dit()];
      const FluxBox& thisBCoef = (*m_bCoef)[dit];

#if CH_SPACEDIM == 1
      FORT_VCCOMPUTERES1D
#elif CH_SPACEDIM == 2
      FORT_VCCOMPUTERES2D
#elif CH_SPACEDIM == 3
      FORT_VCCOMPUTERES3D
#else
      This_will_not_compile!
#endif
                         (CHF_FRA(a_lhs[dit]),
                          CHF_CONST_FRA(phi[dit]),
                          CHF_CONST_FRA(a_rhs[dit]),
                          CHF_CONST_REAL(m_alpha),
                          CHF_CONST_FRA((*m_aCoef)[dit]),
                          CHF_CONST_REAL(m_beta),
#if CH_SPACEDIM >= 1
                          CHF_CONST_FRA(thisBCoef[0]),
#endif
#if CH_SPACEDIM >= 2
                          CHF_CONST_FRA(thisBCoef[1]),
#endif
#if CH_SPACEDIM >= 3
                          CHF_CONST_FRA(thisBCoef[2]),
#endif
#if CH_SPACEDIM >= 4
                          This_will_not_compile!
#endif
                          CHF_BOX(region),
                          CHF_CONST_REAL(m_dx));
    } // end loop over boxes
}
예제 #22
0
void
EBCoarseAverage::average(LevelData<EBFluxFAB>&       a_coarData,
                         const LevelData<EBFluxFAB>& a_fineData,
                         const Interval& a_variables)
{
  CH_TIME("EBCoarseAverage::average(LD<EBFluxFAB>)");
  LevelData<EBFluxFAB> coarFiData;
  LevelData<EBFluxFAB> fineBuffer;
  CH_assert(isDefined());
  {
    CH_TIME("buffer allocation");
    EBFluxFactory factCoFi(m_eblgCoFi.getEBISL());
    coarFiData.define(  m_eblgCoFi.getDBL(), m_nComp, IntVect::Zero, factCoFi);
    if (m_useFineBuffer)
      {
        EBFluxFactory    factFine(m_eblgFine.getEBISL());
        fineBuffer.define(m_eblgFine.getDBL(), m_nComp, IntVect::Zero, factFine);
      }
  }

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

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

          }
      }
  }
  {
    CH_TIME("copy_coar");
    coarFiData.copyTo(a_variables, a_coarData, a_variables);
  }
}
예제 #23
0
int
EBCompositeMACProjector::
project(Vector<LevelData<EBFluxFAB>* >&              a_velocity,
        Vector<LevelData<EBFluxFAB>* >&              a_gradient,
        const Real&                                  a_gradCoef,
        const Real&                                  a_divuCoef,
        const Vector<LevelData<BaseIVFAB<Real> >* >* a_boundaryVelo)

{
  CH_TIME("EBCompositeMACProjector::project");
  //compute divergence everywhere.  This includes refluxing at coarse-fine boundaries
  kappaDivergence(m_divu, a_velocity, a_boundaryVelo);

  EBAMRDataOps::scale(m_divu,a_divuCoef);

  //make an initial guess
  initialize(m_phi);

  //solve laplacian phi = div u
  //zeroPhi=false is inconsequential in solveNoInit because of initialize above
  bool zeroPhi = false;
  m_solver.solveNoInit(m_phi, m_divu, m_numLevels-1, 0, zeroPhi);

  //compute grad phi.  This includes replacing coarse grad phi
  //with average of fine at coarse-fine boundaries
  gradient(a_gradient, m_phi);
  enforceGradientBC(a_gradient,m_phi);

  EBAMRDataOps::scale(a_gradient,a_gradCoef);

  //average the gradient down to coarser levels
  EBAMRDataOps::averageDown(a_gradient,m_eblg,m_refRat);

  if (m_subtractOffMean)
    {
      //Subtract off mean of pressure so that convergence tests can make sense.
      //This is also useful if you are using initial guesses for m_phi with all Neumann bcs
      EBAMRDataOps::subtractOffMean(m_phi, m_eblg, m_refRat);
    }

  //u := u - grad phi
  for (int ilev = 0; ilev < m_numLevels; ilev++)
    {
      for (DataIterator dit = m_eblg[ilev].getDBL().dataIterator(); dit.ok(); ++dit)
        {
          for (int idir = 0; idir < SpaceDim; idir++)
            {
              EBFaceFAB&         velFAB = (*a_velocity[ilev])[dit()][idir];
              const EBFaceFAB&  gradFAB = (*a_gradient[ilev])[dit()][idir];
              velFAB -= gradFAB;
            }
        }
    }

  return m_solver.m_exitStatus;
}
예제 #24
0
// ----------------------------------------------------------------
void EdgeToCell(const LevelData<FluxBox>& a_edgeData,
                LevelData<FArrayBox>& a_cellData)
{
  // this is just a wrapper around the single-grid version
  DataIterator dit = a_edgeData.dataIterator();
  for (dit.reset(); dit.ok(); ++dit)
    {
      EdgeToCell(a_edgeData[dit()], a_cellData[dit()]);
    }
}
예제 #25
0
void
EBCoarseAverage::average(LevelData<BaseIVFAB<Real> >&        a_coarData,
                         const LevelData<BaseIVFAB<Real> >&  a_fineData,
                         const Interval&                     a_variables)
{
  CH_TIME("EBCoarseAverage::average(LD<BaseIVFAB>)");
  LevelData<BaseIVFAB<Real> > coarFiData;
  LevelData<BaseIVFAB<Real> > fineBuffer;
  CH_assert(isDefined());
  {
    CH_TIME("buffer allocation");
    BaseIVFactory<Real> factCoFi(m_eblgCoFi.getEBISL(), m_irregSetsCoFi);
    coarFiData.define(m_eblgCoFi.getDBL(), m_nComp, IntVect::Zero, factCoFi);
    if (m_useFineBuffer)
      {
        BaseIVFactory<Real> factFine(m_eblgFine.getEBISL(), m_irregSetsFine);
        coarFiData.define(m_eblgFine.getDBL(), m_nComp, IntVect::Zero, factFine);
      }
  }

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

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

        ifnerg++;
      }
  }
  {
    CH_TIME("copy_coar");
    coarFiData.copyTo(a_variables, a_coarData, a_variables);
  }
}
예제 #26
0
// Set up data on this level after regridding
void AMRLevelPluto::regrid(const Vector<Box>& a_newGrids)
{
  CH_assert(allDefined());

  if (s_verbosity >= 3)
  {
    pout() << "AMRLevelPluto::regrid " << m_level << endl;
  }

  // Save original grids and load balance
  m_level_grids = a_newGrids;
  m_grids = loadBalance(a_newGrids);

  if (s_verbosity >= 4)
  {
    // Indicate/guarantee that the indexing below is only for reading
    // otherwise an error/assertion failure occurs
    const DisjointBoxLayout& constGrids = m_grids;

    pout() << "new grids: " << endl;

    for (LayoutIterator lit = constGrids.layoutIterator(); lit.ok(); ++lit)
    {
      pout() << constGrids[lit()] << endl;
    }
  }

  // Save data for later
  DataIterator dit = m_UNew.dataIterator();
  for(;dit.ok(); ++dit){
	m_UOld[dit()].copy(m_UNew[dit()]);
  }

  // Reshape state with new grids
  IntVect ivGhost = m_numGhost*IntVect::Unit;
  m_UNew.define(m_grids,m_numStates,ivGhost);


  // Set up data structures
  levelSetup();

  // Interpolate from coarser level
  if (m_hasCoarser)
  {
    AMRLevelPluto* amrGodCoarserPtr = getCoarserLevel();
    m_fineInterp.interpToFine(m_UNew,amrGodCoarserPtr->m_UNew);
  }

  // Copy from old state
  m_UOld.copyTo(m_UOld.interval(),
                m_UNew,
                m_UNew.interval());

  m_UOld.define(m_grids,m_numStates,ivGhost);
} 
예제 #27
0
void
EBCoarToFineRedist::
resetWeights(const LevelData<EBCellFAB>& a_modifierCoar,
             const int& a_ivar)
{
  CH_TIME("EBCoarToFineRedist::resetWeights");
  Interval srcInterv(a_ivar, a_ivar);
  Interval dstInterv(0,0);
  a_modifierCoar.copyTo(srcInterv, m_densityCedFine, dstInterv);

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

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

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

          const VoFStencil& stanSten = stanStenFAB(vofCoar, 0);
          const VoFStencil& volSten  = volStenFAB(vofCoar, 0);
          VoFStencil newSten;
          for (int isten = 0; isten < volSten.size(); isten++)
            {
              const VolIndex& thatVoFCoar = volSten.vof(isten);
              Real weight = modFAB(thatVoFCoar, 0);
              //average fine weights onto coarse weight
              newSten.add(thatVoFCoar, weight);
            }
          //need normalize by the whole standard stencil
          Real sum = 0.0;
          for (int isten = 0; isten < stanSten.size(); isten++)
            {
              const VolIndex& thatVoFCoar = stanSten.vof(isten);
              Real weight = modFAB(thatVoFCoar, 0);
              Real volfrac = ebisBoxCoar.volFrac(thatVoFCoar);
              //it is weight*volfrac that is normalized
              sum += weight*volfrac;
            }
          if (Abs(sum) > 0.0)
            {
              Real scaling = 1.0/sum;
              newSten *= scaling;
            }
          massStenFAB(vofCoar, 0) = newSten;
        }
    }
}
예제 #28
0
// ---------------------------------------------------------
// 27 March 2003:
// This is called by other functions, and should not be called directly.
Real
norm(const BoxLayoutData<NodeFArrayBox>& a_layout,
     const Real a_dx,
     const int a_p,
     const Interval& a_interval,
     bool a_verbose)
{
  if (a_p == 0)
    return maxnorm(a_layout, a_interval, a_verbose);

  Real normTotal = 0.;

  for (DataIterator it = a_layout.dataIterator(); it.ok(); ++it)
    {
      const NodeFArrayBox& thisNfab = a_layout[it()];
      const Box& thisBox(a_layout.box(it())); // CELL-centered
      Real thisNfabNorm = norm(thisNfab, a_dx, thisBox, a_p,
                               a_interval.begin(), a_interval.size());
      if (a_verbose)
        cout << a_p << "norm(" << thisBox << ") = " << thisNfabNorm << endl;

      if (a_p == 1)
        {
          normTotal += thisNfabNorm;
        }
      else if (a_p == 2)
        {
          normTotal += thisNfabNorm * thisNfabNorm;
        }
      else
        {
          normTotal += pow(thisNfabNorm, Real(a_p));
        }
    }
# ifdef CH_MPI
  Real recv;
  // add up (a_p is not 0)
  int result = MPI_Allreduce(&normTotal, &recv, 1, MPI_CH_REAL,
                             MPI_SUM, Chombo_MPI::comm);
  if (result != MPI_SUCCESS)
    { //bark!!!
      MayDay::Error("sorry, but I had a communication error on norm");
    }
  normTotal = recv;
# endif
  // now do sqrt, etc
  if (a_p == 2)
    normTotal = sqrt(normTotal);
  else
    if ((a_p != 0) && (a_p != 1))
      normTotal = pow(normTotal, (Real)1.0/Real(a_p));

  return normTotal;
}
예제 #29
0
void
EBMGInterp::pwlInterp(LevelData<EBCellFAB>&       a_fineData,
                      const LevelData<EBCellFAB>& a_coarData,
                      const Interval&             a_variables)
{
  CH_TIME("EBMGInterp::pwlInterp");
  CH_assert(a_fineData.ghostVect() == m_ghost);
  CH_assert(a_coarData.ghostVect() == m_ghost);
  CH_assert(m_doLinear); //otherwise stencils have not been defined

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

          EBAddOp op;
          refinedCoarseData.copyTo(a_variables, a_fineData, a_variables, m_copierRCtoF, op);
        }
    }
  else
    {
      pwcInterpMG(a_fineData, a_coarData, a_variables);
    }
}
예제 #30
0
void
EBLevelAdvect::
resetBCs(const RefCountedPtr<EBPhysIBCFactory>&  a_advectBC)
{
  if (m_isDefined)
    {
      for (DataIterator dit = m_ebPatchAdvect.dataIterator(); dit.ok(); ++dit)
        {
          m_ebPatchAdvect[dit()]->setEBPhysIBC(*a_advectBC);
        }
    }
}