/// 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)); } }
void EBPoissonOp:: applyOpRegularAllDirs(Box * a_loBox, Box * a_hiBox, int * a_hasLo, int * a_hasHi, Box & a_curDblBox, Box & a_curPhiBox, int a_nComps, BaseFab<Real> & a_curOpPhiFAB, const BaseFab<Real> & a_curPhiFAB, bool a_homogeneousPhysBC, const DataIndex& a_dit, const Real& a_beta) { CH_TIME("EBPoissonOp::applyOpRegularAllDirs"); CH_assert(m_domainBC != NULL); //need to monkey with the ghost cells to account for boundary conditions BaseFab<Real>& phiFAB = (BaseFab<Real>&) a_curPhiFAB; applyDomainFlux(a_loBox, a_hiBox, a_hasLo, a_hasHi, a_curDblBox, a_nComps, phiFAB, a_homogeneousPhysBC, a_dit,m_beta); for (int comp = 0; comp<a_nComps; comp++) { FORT_REGGET1DLAPLACIAN_INPLACE(CHF_FRA1(a_curOpPhiFAB,comp), CHF_CONST_FRA1(a_curPhiFAB,comp), CHF_CONST_REAL(a_beta), CHF_CONST_REALVECT(m_dx), CHF_BOX(a_curDblBox)); } }
void CellToEdge(const FArrayBox& a_cellData, FluxBox& a_edgeData) { // loop over components -- assumption is that in cell-centered // data, direction changes faster than component int cellcomp; for (int comp = 0; comp < a_edgeData.nComp(); comp++) { // loop over directions for (int dir = 0; dir < SpaceDim; dir++) { // define faces over which we can do averaging Box edgeBox = surroundingNodes(a_cellData.box(), dir); edgeBox.grow(dir,-1); edgeBox &= a_edgeData[dir].box(); if (a_cellData.nComp() == a_edgeData.nComp()) { // straightforward cell->edge averaging cellcomp = comp; } else { // each cell comp represents a different spatial direction cellcomp = SpaceDim*comp + dir; } FORT_CELLTOEDGE(CHF_CONST_FRA1(a_cellData, cellcomp), CHF_FRA1(a_edgeData[dir], comp), CHF_BOX(edgeBox), CHF_CONST_INT(dir)); } } }
// ------------------------------------------------------------ void CellToEdge(const FArrayBox& a_cellData, FArrayBox& a_edgeData, const int a_dir) { Box edgeBox = surroundingNodes(a_cellData.box(), a_dir); edgeBox.grow(a_dir,-1); edgeBox &= a_edgeData.box(); int cellComp; for (int comp = 0; comp < a_edgeData.nComp(); comp++) { if (a_cellData.nComp() == a_edgeData.nComp()) { // straightforward cell->edge averaging cellComp = comp; } else { // each cell comp represents a different spatial direction cellComp = SpaceDim*comp + a_dir; } FORT_CELLTOEDGE(CHF_CONST_FRA1(a_cellData, cellComp), CHF_FRA1(a_edgeData, comp), CHF_BOX(edgeBox), CHF_CONST_INT(a_dir)); } }
void EBMGAverage::averageFAB(EBCellFAB& a_coar, const Box& a_boxCoar, const EBCellFAB& a_refCoar, const DataIndex& a_datInd, const Interval& a_variables) const { CH_TIMERS("EBMGAverage::average"); CH_TIMER("regular_average", t1); CH_TIMER("irregular_average", t2); CH_assert(isDefined()); const Box& coarBox = a_boxCoar; //do all cells as if they were regular Box refBox(IntVect::Zero, IntVect::Zero); refBox.refine(m_refRat); int numFinePerCoar = refBox.numPts(); BaseFab<Real>& coarRegFAB = a_coar.getSingleValuedFAB(); const BaseFab<Real>& refCoarRegFAB = a_refCoar.getSingleValuedFAB(); //set to zero because the fortran is a bit simpleminded //and does stuff additively a_coar.setVal(0.); CH_START(t1); for (int comp = a_variables.begin(); comp <= a_variables.end(); comp++) { FORT_REGAVERAGE(CHF_FRA1(coarRegFAB,comp), CHF_CONST_FRA1(refCoarRegFAB,comp), CHF_BOX(coarBox), CHF_BOX(refBox), CHF_CONST_INT(numFinePerCoar), CHF_CONST_INT(m_refRat)); } CH_STOP(t1); //this is really volume-weighted averaging even though it does //not look that way. //so (in the traditional sense) we want to preserve //rhoc * volc = sum(rhof * volf) //this translates to //volfrac_C * rhoC = (1/numFinePerCoar)(sum(volFrac_F * rhoF)) //but the data input to this routine is all kappa weigthed so //the volumefractions have already been multiplied //which means // rhoC = (1/numFinePerCoar)(sum(rhoF)) //which is what this does CH_START(t2); for (int comp = a_variables.begin(); comp <= a_variables.end(); comp++) { m_averageEBStencil[a_datInd]->apply(a_coar, a_refCoar, false, comp); } CH_STOP(t2); }
void EdgeToCell(const FluxBox& a_edgeData, const int a_edgeComp, FArrayBox& a_cellData, const int a_cellComp, const Box& a_cellBox, const int a_dir) { FORT_EDGETOCELL(CHF_CONST_FRA1(a_edgeData[a_dir],a_edgeComp), CHF_FRA1(a_cellData, a_cellComp), CHF_BOX(a_cellBox), CHF_CONST_INT(a_dir)); }
void EdgeToCellMax(const FluxBox& a_edgeData, const int a_edgeComp, FArrayBox& a_cellData, const int a_cellComp, const int a_dir) { const Box& cellBox = a_cellData.box(); FORT_EDGETOCELLMAX(CHF_CONST_FRA1(a_edgeData[a_dir],a_edgeComp), CHF_FRA1(a_cellData, a_cellComp), CHF_BOX(cellBox), CHF_CONST_INT(a_dir)); }
void EBPoissonOp:: GSColorAllRegular(LevelData<EBCellFAB>& a_phi, const LevelData<EBCellFAB>& a_rhs, const IntVect& a_color, const Real& a_weight, const bool& a_homogeneousPhysBC) { CH_TIME("EBPoissonOp::GSColorAllRegular"); CH_assert(a_rhs.ghostVect() == m_ghostCellsRHS); CH_assert(a_phi.ghostVect() == m_ghostCellsPhi); int nComps = a_phi.nComp(); for (DataIterator dit = a_phi.dataIterator(); dit.ok(); ++dit) { Box dblBox(m_eblg.getDBL().get(dit())); BaseFab<Real>& phiFAB = (a_phi[dit()] ).getSingleValuedFAB(); const BaseFab<Real>& rhsFAB = (a_rhs[dit()] ).getSingleValuedFAB(); Box loBox[SpaceDim],hiBox[SpaceDim]; int hasLo[SpaceDim],hasHi[SpaceDim]; applyDomainFlux(loBox, hiBox, hasLo, hasHi, dblBox, nComps, phiFAB, a_homogeneousPhysBC, dit(),m_beta); IntVect loIV = dblBox.smallEnd(); IntVect hiIV = dblBox.bigEnd(); for (int idir = 0; idir < SpaceDim; idir++) { if (loIV[idir] % 2 != a_color[idir]) { loIV[idir]++; } } if (loIV <= hiIV) { Box coloredBox(loIV, hiIV); for (int comp=0; comp<a_phi.nComp(); comp++) { FORT_DOALLREGULARMULTICOLOR(CHF_FRA1(phiFAB,comp), CHF_CONST_FRA1(rhsFAB,comp), CHF_CONST_REAL(a_weight), CHF_CONST_REAL(m_alpha), CHF_CONST_REAL(m_beta), CHF_CONST_REALVECT(m_dx), CHF_BOX(coloredBox)); } } } }
// Set up initial conditions void AdvectTestIBC::initialize(LevelData<FArrayBox>& a_U) { DisjointBoxLayout grids = a_U.disjointBoxLayout(); for (DataIterator dit = grids.dataIterator(); dit.ok(); ++dit) { const Box& grid = grids.get(dit()); FORT_ADVECTINITF(CHF_FRA1(a_U[dit()],0), CHF_CONST_REALVECT(m_center), CHF_CONST_REAL(m_size), CHF_CONST_REAL(m_dx), CHF_BOX(grid)); } }
// --------------------------------------------------------- void AMRNavierStokes::computeKineticEnergy(LevelData<FArrayBox>& a_energy) const { // this is simple since no BC's need to be set. const LevelData<FArrayBox>& levelVel = *m_vel_new_ptr; const DisjointBoxLayout& levelGrids = levelVel.getBoxes(); DataIterator dit = a_energy.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { FORT_KINETICENERGY(CHF_FRA1(a_energy[dit],0), CHF_CONST_FRA(levelVel[dit]), CHF_BOX(levelGrids[dit])); } }
// ------------------------------------------------------------ void CellToEdge(const FArrayBox& a_cellData, const int a_cellComp, FArrayBox& a_edgeData, const int a_edgeComp, const int a_dir) { Box edgeBox = surroundingNodes(a_cellData.box(),a_dir); edgeBox.grow(a_dir, -1); edgeBox &= a_edgeData.box(); FORT_CELLTOEDGE(CHF_CONST_FRA1(a_cellData,a_cellComp), CHF_FRA1(a_edgeData,a_edgeComp), CHF_BOX(edgeBox), CHF_CONST_INT(a_dir)); }
void EBMGInterp::pwcInterpFAB(EBCellFAB& a_refCoar, const Box& a_coarBox, const EBCellFAB& a_coar, const DataIndex& a_datInd, const Interval& a_variables) const { CH_TIMERS("EBMGInterp::interp"); CH_TIMER("regular_interp", t1); CH_TIMER("irregular_interp", t2); CH_assert(isDefined()); const Box& coarBox = a_coarBox; for (int ivar = a_variables.begin(); ivar <= a_variables.end(); ivar++) { m_interpEBStencil[a_datInd]->cache(a_refCoar, ivar); //do all cells as if they were regular Box refBox(IntVect::Zero, IntVect::Zero); refBox.refine(m_refRat); const BaseFab<Real>& coarRegFAB = a_coar.getSingleValuedFAB(); BaseFab<Real>& refCoarRegFAB = a_refCoar.getSingleValuedFAB(); CH_START(t1); FORT_REGPROLONG(CHF_FRA1(refCoarRegFAB,ivar), CHF_CONST_FRA1(coarRegFAB,ivar), CHF_BOX(coarBox), CHF_BOX(refBox), CHF_CONST_INT(m_refRat)); CH_STOP(t1); m_interpEBStencil[a_datInd]->uncache(a_refCoar, ivar); CH_START(t2); m_interpEBStencil[a_datInd]->apply(a_refCoar, a_coar, true, ivar); CH_STOP(t2); } }
// ---------------------------------------------------------------- void EdgeToCell(const FluxBox& a_edgeData, FArrayBox& a_cellData) { // loop over components -- assumption is that in cell-centered // data, direction changes faster than component. for (int comp = 0; comp<a_edgeData.nComp(); comp++) { // loop over directions for (int dir = 0; dir < SpaceDim; dir++) { Box cellBox = a_cellData.box(); cellBox &= a_edgeData.box(); int cellcomp = SpaceDim*comp + dir; FORT_EDGETOCELL(CHF_CONST_FRA1(a_edgeData[dir],comp), CHF_FRA1(a_cellData, cellcomp), CHF_BOX(cellBox), CHF_CONST_INT(dir)); } // end loop over directions } // end loop over components }
void NewPoissonOp:: levelRelaxColor(FArrayBox& a_phi, const FArrayBox& a_rhs, const IntVect& a_color, const Real& a_weight, const bool& a_homogeneousPhysBC) { CH_assert(a_phi.nComp() == 1); Box dblBox = a_rhs.box(); //apply domain boundary condtions m_bc(a_phi, m_domain.domainBox(), m_domain, m_dx[0], a_homogeneousPhysBC); //find box over which we are iterating IntVect loIV = dblBox.smallEnd(); IntVect hiIV = dblBox.bigEnd(); for (int idir = 0; idir < SpaceDim; idir++) { if (loIV[idir] % 2 != a_color[idir]) { loIV[idir]++; } } if (loIV <= hiIV) { Box coloredBox(loIV, hiIV); int comp = 0; Real alpha = 0; Real beta = 1.; FORT_AMRPMULTICOLOR(CHF_FRA1(a_phi,comp), CHF_CONST_FRA1(a_rhs,comp), CHF_CONST_REAL(a_weight), CHF_CONST_REAL(alpha), CHF_CONST_REAL(beta), CHF_CONST_REALVECT(m_dx), CHF_BOX(coloredBox)); } }
void TraceState(/// state at time t+dt/2 on edges in direction dir FArrayBox& a_stateHalf, /// cell-centered state at time t const FArrayBox& a_state, /// cell-centered velocity at time t const FArrayBox& a_cellVel, /// edge-centered advection velocity at time t+dt/2 const FluxBox& a_advectionVel, /// cell-centered source const FArrayBox& a_source, /// Physical domain const ProblemDomain& a_dProblem, /// interior of grid patch const Box& a_gridBox, /// timeStep const Real a_dt, /// cell-spacing const Real a_dx, /// direction in which to perform tracing const int a_dir, /// which components to trace const Interval& a_srcComps, /// where to put traced components in a_stateHalf, const Interval& a_destComps) { int ncomp = a_srcComps.size(); CH_assert (ncomp == a_destComps.size()); int offset = a_destComps.begin() - a_srcComps.begin(); Box edgeBox = a_gridBox; edgeBox.surroundingNodes(a_dir); #ifdef SIMPLEUPWIND // simple cell-to-edge averaging may be causing us problems -- // instead do simple upwinding for (int comp=a_srcComps.begin(); comp <= a_srcComps.end(); comp++) { int destcomp = comp+offset; FORT_UPWINDCELLTOEDGE(CHF_FRA1(a_stateHalf, destComp), CHF_CONST_FRA1(a_state,comp), CHF_CONST_FRA(a_advectionVel[a_dir]), CHF_BOX(edgeBox), CHF_CONST_INT(a_dir)); } #else // first compute slopes Box slopesBox = grow(a_gridBox,1); // these are debugging changes to sync with old code #ifdef MATCH_OLDCODE FluxBox tempEdgeVel(slopesBox,1); tempEdgeVel.setVal(0.0); FArrayBox tempCellVel(slopesBox,SpaceDim); tempCellVel.setVal(0.0); CellToEdge(a_cellVel, tempEdgeVel); EdgeToCell(tempEdgeVel, tempCellVel); tempEdgeVel.clear(); // done with this, so reclaim memory EdgeToCell(a_advectionVel, tempCellVel); #endif FArrayBox delS(slopesBox,1); FArrayBox sHat(slopesBox,1); FArrayBox sTilde(a_state.box(),1); for (int comp=a_srcComps.begin(); comp<=a_srcComps.end(); comp++) { int destComp = comp+offset; #ifdef SET_BOGUS_VALUES delS.setVal(BOGUS_VALUE); sHat.setVal(BOGUS_VALUE); sTilde.setVal(BOGUS_VALUE); #endif // compute van leer limited slopes in the normal direction // for now, always limit slopes, although might want to make // this a parameter int limitSlopes = 1; FORT_SLOPES(CHF_FRA1(delS,0), CHF_CONST_FRA1(a_state,comp), CHF_BOX(slopesBox), CHF_CONST_INT(a_dir), CHF_CONST_INT(limitSlopes)); // this is a way to incorporate the minion correction -- // stateTilde = state + (dt/2)*source sTilde.copy(a_source,comp,0,1); Real sourceFactor = a_dt/2.0; sTilde *= sourceFactor; sTilde.plus(a_state, comp,0,1); sHat.copy(sTilde,slopesBox); // now loop over directions, adding transverse components for (int localDir=0; localDir < SpaceDim; localDir++) { if (localDir != a_dir) { // add simple transverse components FORT_TRANSVERSE(CHF_FRA1(sHat,0), CHF_CONST_FRA1(sTilde,0), #ifdef MATCH_OLDCODE CHF_CONST_FRA1(tempCellVel, localDir), #else CHF_CONST_FRA1(a_cellVel,localDir), #endif CHF_BOX(slopesBox), CHF_CONST_REAL(a_dt), CHF_CONST_REAL(a_dx), CHF_CONST_INT(localDir)); //CHF_FRA1(temp,0)); // not used in function } else if (SpaceDim == 3) { // only add cross derivative transverse piece if we're in 3D // note that we need both components of velocity for this one FORT_TRANSVERSECROSS(CHF_FRA1(sHat,0), CHF_CONST_FRA1(sTilde,0), CHF_CONST_FRA(a_cellVel), CHF_BOX(slopesBox), CHF_CONST_REAL(a_dt), CHF_CONST_REAL(a_dx), CHF_CONST_INT(localDir)); } } // end loop over directions // now compute left and right states and resolve the Reimann // problem to get single set of edge-centered values FORT_PREDICT(CHF_FRA1(a_stateHalf,destComp), CHF_CONST_FRA1(sHat,0), CHF_CONST_FRA1(delS,0), CHF_CONST_FRA1(a_cellVel,a_dir), CHF_CONST_FRA1(a_advectionVel[a_dir],0), CHF_BOX(edgeBox), CHF_CONST_REAL(a_dt), CHF_CONST_REAL(a_dx), CHF_CONST_INT(a_dir)); } // end loop over components #endif }
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; } }
void EBCoarseAverage::averageFAB(EBCellFAB& a_coar, const EBCellFAB& a_fine, const DataIndex& a_datInd, const Interval& a_variables) const { CH_TIME("EBCoarseAverage::averageFAB(EBCellFAB)"); CH_assert(isDefined()); //do all cells as if they were regular BaseFab<Real>& coarRegFAB = a_coar.getSingleValuedFAB(); const BaseFab<Real>& fineRegFAB = a_fine.getSingleValuedFAB(); Box refbox(IntVect::Zero, (m_refRat-1)*IntVect::Unit); const Box& coarBox = m_eblgCoFi.getDBL().get(a_datInd); #ifndef NDEBUG Box fineBox = refine(coarBox, m_refRat); CH_assert(coarRegFAB.box().contains(coarBox)); CH_assert(fineRegFAB.box().contains(fineBox)); #endif for (int ivar = a_variables.begin(); ivar <= a_variables.end(); ivar++) { FORT_EBAVERAGE(CHF_FRA1(coarRegFAB,ivar), CHF_CONST_FRA1(fineRegFAB,ivar), CHF_BOX(coarBox), CHF_CONST_INT(m_refRat), CHF_BOX(refbox)); } //overwrite irregular cells //recall that datInd is from the fine layout. const EBISBox& ebisBoxCoar = m_eblgCoFi.getEBISL()[a_datInd]; const EBISBox& ebisBoxFine = m_eblgFine.getEBISL()[a_datInd]; IntVectSet coarIrregIVS = ebisBoxCoar.getIrregIVS(coarBox); //fine cell volume is normalized to one. //compute coarse volume Real dxCoar = Real(m_refRat); Real cellVolCoar = 1.0; for (int idir = 0; idir < SpaceDim; idir++) cellVolCoar *= dxCoar; for (VoFIterator vofitCoar(coarIrregIVS, ebisBoxCoar.getEBGraph()); vofitCoar.ok(); ++vofitCoar) { const VolIndex& coarVoF = vofitCoar(); Vector<VolIndex> fineVoFs = m_eblgCoFi.getEBISL().refine(coarVoF, m_refRat, a_datInd); Real volCoar = cellVolCoar*ebisBoxCoar.volFrac(coarVoF); for (int ivar = a_variables.begin(); ivar <= a_variables.end(); ivar++) { Real dataVal = 0.0; if (volCoar > 0.) { for (int ifine = 0; ifine < fineVoFs.size(); ifine++) { const VolIndex& fineVoF = fineVoFs[ifine]; //fine cell volume is normalized to one... Real volFine = ebisBoxFine.volFrac(fineVoF); Real fineVal = a_fine(fineVoF, ivar); if (volFine > 0.) { dataVal += fineVal*volFine; } } dataVal /= volCoar; } else { //if there is no real volume, just take the ave //of fine values for (int ifine = 0; ifine < fineVoFs.size(); ifine++) { const VolIndex& fineVoF = fineVoFs[ifine]; Real fineVal = a_fine(fineVoF, ivar); dataVal += fineVal; } if (fineVoFs.size() > 0) { dataVal /= Real(fineVoFs.size()); } } a_coar(coarVoF, ivar) = dataVal; } } }
void EBGradDivFilter:: cellGradient(EBCellFAB& a_gradDiv, const EBCellFAB& a_gradVel, const EBCellFAB& a_vel, const EBFluxFAB& a_fluxVel, const EBFluxFAB& a_div, const Box& a_grid, const EBISBox& a_ebisBox, const DataIndex& a_dataIndex, bool a_multiplyByLambda, bool a_noExtrapToCovered) { CH_TIME("EBGradDivFilter::cellGradient"); int icomp = 0; EBCellFAB& lambdaFAB = m_lambda[a_dataIndex]; IntVectSet irregIVS = a_ebisBox.getIrregIVS(a_grid); for (int faceDir = 0; faceDir < SpaceDim; faceDir++) { const EBFaceFAB& faceDiv = a_div[faceDir]; const BaseFab<Real>& regFaceDiv = faceDiv.getSingleValuedFAB(); const BaseFab<Real>& regLambda = lambdaFAB.getSingleValuedFAB(); BaseFab<Real>& regGradDiv = a_gradDiv.getSingleValuedFAB(); int imultByLambda = 0; if (a_multiplyByLambda) { imultByLambda = 1; } FORT_EBGDFCELLGRAD(CHF_FRA1(regGradDiv, faceDir), CHF_CONST_FRA1(regFaceDiv, icomp), CHF_CONST_FRA1(regLambda, icomp), CHF_BOX(a_grid), CHF_CONST_REAL(m_dxFine[faceDir]), CHF_CONST_INT(faceDir), CHF_CONST_INT(imultByLambda)); //nonconservative gradient for (VoFIterator vofit(irregIVS, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real gradVal = 0.0; Vector<FaceIndex> facesHi = a_ebisBox.getFaces(vof, faceDir, Side::Hi); Vector<FaceIndex> facesLo = a_ebisBox.getFaces(vof, faceDir, Side::Lo); bool zeroGrad = a_noExtrapToCovered && ((facesHi.size() == 0) || (facesLo.size() == 0)); if (zeroGrad) { gradVal = 0; } else { Real valHi= 0; if (facesHi.size() > 0) { for (int iface = 0; iface < facesHi.size(); iface++) { valHi += faceDiv(facesHi[iface], icomp); } valHi /= facesHi.size(); } else { valHi = ccpGetCoveredExtrapValue(vof, faceDir, Side::Hi, faceDiv, a_ebisBox, a_grid, m_domainFine, m_dxFine, icomp); } Real valLo= 0; if (facesLo.size() > 0) { for (int iface = 0; iface < facesLo.size(); iface++) { valLo += faceDiv(facesLo[iface], 0); } valLo /= facesLo.size(); } else { valLo = ccpGetCoveredExtrapValue(vof, faceDir, Side::Lo , faceDiv, a_ebisBox, a_grid, m_domainFine, m_dxFine, icomp); } gradVal = (valHi-valLo)/(m_dxFine[faceDir]); //multiply the lambda in since we have the area fractions lying about if (a_multiplyByLambda) { Real lambda = lambdaFAB(vof, 0); gradVal *= lambda; } } a_gradDiv(vof, faceDir) = gradVal; } } }
// --------------------------------------------------------------- // tag cells for regridding void AMRNavierStokes::tagCells(IntVectSet & a_tags) { if (s_verbosity >= 3) { pout () << "AMRNavierStokes::tagCells " << m_level << endl; } IntVectSet local_tags; // create tags based on something or other // for now, don't do anything const DisjointBoxLayout& level_domain = newVel().getBoxes(); if (s_tag_vorticity) { LevelData<FArrayBox> vorticity; LevelData<FArrayBox> mag_vorticity; if (SpaceDim == 2) { vorticity.define(level_domain,1); } else if (SpaceDim == 3) { vorticity.define(level_domain,SpaceDim); mag_vorticity.define(level_domain,1); } computeVorticity(vorticity); Interval vortInterval(0,0); if (SpaceDim == 3) { vortInterval = Interval(0,SpaceDim-1); } Real tagLevel = norm(vorticity, vortInterval, 0); // Real tagLevel = 1.0; //tagLevel *= s_vort_factor/m_dx; // actually tag where vort*dx > s_vort_factor*max(vort) tagLevel = s_vort_factor/m_dx; if (tagLevel > 0) { // now tag where vorticity magnitude is greater than or equal // to tagLevel DataIterator dit = vorticity.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { FArrayBox& vortFab = vorticity[dit]; // this only needs to be done in 3d... if (SpaceDim==3) { FArrayBox& magVortFab = mag_vorticity[dit]; FORT_MAGVECT(CHF_FRA1(magVortFab,0), CHF_CONST_FRA(vortFab), CHF_BOX(level_domain[dit])); } BoxIterator bit(vortFab.box()); for (bit.begin(); bit.ok(); ++bit) { const IntVect& iv = bit(); if (SpaceDim == 2) { if (abs(vortFab(iv)) >= tagLevel) { local_tags |= iv; } } else if (SpaceDim == 3) { FArrayBox& magVortFab = mag_vorticity[dit]; if (abs(magVortFab(iv)) >= tagLevel) { local_tags |= iv; } } // end if DIM=3 } // end loop over interior of box } // loop over grids } // if taglevel > 0 } // if tagging on vorticity a_tags = local_tags; }
void EBCoarseAverage::averageFAB(EBFaceFAB& a_coar, const EBFaceFAB& a_fine, const DataIndex& a_datInd, const Interval& a_variables, const int& a_dir) const { CH_TIME("EBCoarseAverage::averageFAB(EBFaceFAB)"); CH_assert(isDefined()); //do all cells as if they were regular BaseFab<Real>& coarRegFAB = a_coar.getSingleValuedFAB(); const BaseFab<Real>& fineRegFAB = a_fine.getSingleValuedFAB(); Box refbox(IntVect::Zero, (m_refRat-1)*IntVect::Unit); refbox.surroundingNodes(a_dir); const Box& coarDBLBox = m_eblgCoFi.getDBL().get(a_datInd); Box coarFaceBox = coarDBLBox; coarFaceBox.surroundingNodes(a_dir); #ifndef NDEBUG Box fineBox = refine(coarFaceBox, m_refRat); CH_assert(coarRegFAB.box().contains(coarFaceBox)); CH_assert(fineRegFAB.box().contains(fineBox)); #endif for (int ivar = a_variables.begin(); ivar <= a_variables.end(); ivar++) { FORT_EBAVERAGEFACE(CHF_FRA1(coarRegFAB,ivar), CHF_CONST_FRA1(fineRegFAB,ivar), CHF_BOX(coarFaceBox), CHF_CONST_INT(m_refRat), CHF_BOX(refbox), CHF_CONST_INT(a_dir)); } //overwrite irregular cells //recall that datInd is from the fine layout. const EBISBox& ebisBoxCoar = m_eblgCoFi.getEBISL()[a_datInd]; const EBISBox& ebisBoxFine = m_eblgFine.getEBISL()[a_datInd]; IntVectSet coarIrregIVS = ebisBoxCoar.getIrregIVS(coarDBLBox); //fine face area is normalized to one. //compute coarse volume Real dxCoar = Real(m_refRat); Real faceAreaCoar = 1.0; for (int idir = 0; idir < (SpaceDim - 1); idir++) faceAreaCoar *= dxCoar; for (FaceIterator faceitCoar(coarIrregIVS, ebisBoxCoar.getEBGraph(),a_dir, FaceStop::SurroundingWithBoundary); faceitCoar.ok(); ++faceitCoar) { const FaceIndex& coarFace = faceitCoar(); Vector<FaceIndex> fineFaces = m_eblgCoFi.getEBISL().refine(coarFace,m_refRat,a_datInd); Real areaCoar = faceAreaCoar*ebisBoxCoar.areaFrac(coarFace); for (int ivar = a_variables.begin(); ivar <= a_variables.end(); ivar++) { Real dataVal = 0.0; if (areaCoar > 0.) { for (int ifine = 0; ifine < fineFaces.size(); ifine++) { const FaceIndex& fineFace = fineFaces[ifine]; //fine face area is normalized to one... Real areaFine = ebisBoxFine.areaFrac(fineFace); Real fineVal = a_fine(fineFace, ivar); if (areaFine > 0.) { dataVal += fineVal*areaFine; } } dataVal /= areaCoar; } else { //if there is no real area, just take the ave //of fine values for (int ifine = 0; ifine < fineFaces.size(); ifine++) { const FaceIndex& fineFace = fineFaces[ifine]; Real fineVal = a_fine(fineFace, ivar); dataVal += fineVal; } if (fineFaces.size() > 0) { dataVal /= Real(fineFaces.size()); } } a_coar(coarFace, ivar) = dataVal; } } }
void EBCoarsen::coarsenFAB(EBCellFAB& a_coar, const EBCellFAB& a_fine, const DataIndex& a_datInd, const Interval& a_variables) { CH_assert(isDefined()); //do all cells as if they were regular BaseFab<Real>& coarRegFAB = a_coar.getSingleValuedFAB(); const BaseFab<Real>& fineRegFAB = a_fine.getSingleValuedFAB(); //this is how much we need to grow a coarse box to get a fine box that // only has the fine iv's that are neighbors of the coarse iv const int fac = 1 - m_refRat/2;//NOTE: fac = 0 for refRat==2... Box refbox(IntVect::Zero, (m_refRat-1)*IntVect::Unit); refbox.grow(fac); Box coarBox = m_coarsenedFineGrids.get(a_datInd); Box fineBox = refine(coarBox, m_refRat); CH_assert(coarRegFAB.box().contains(coarBox)); CH_assert(fineRegFAB.box().contains(fineBox)); for (int ivar = a_variables.begin(); ivar <= a_variables.end(); ivar++) { BaseFab<Real> laplFine(fineBox, 1); laplFine.setVal(0.); for (int idir = 0; idir < SpaceDim; idir++) { Box loBox, hiBox, centerBox; int hasLo, hasHi; EBArith::loHiCenter(loBox, hasLo, hiBox, hasHi, centerBox, m_domainFine, fineBox, idir, &((*m_cfivsPtr)[a_datInd])); FORT_H2LAPL1DADDITIVE(CHF_FRA1(laplFine, 0), CHF_FRA1(fineRegFAB, ivar), CHF_CONST_INT(idir), CHF_BOX(loBox), CHF_CONST_INT(hasLo), CHF_BOX(hiBox), CHF_CONST_INT(hasHi), CHF_BOX(centerBox)); } FORT_EBCOARSEN(CHF_FRA1(coarRegFAB,ivar), CHF_CONST_FRA1(fineRegFAB,ivar), CHF_CONST_FRA1(laplFine, 0), CHF_BOX(coarBox), CHF_CONST_INT(m_refRat), CHF_BOX(refbox)); } //overwrite irregular vofs and coarse vofs next to the cfivs if refRat<4, // for these vofs we coarsen based on // taylor expansions from fine vofs to the coarse cell center coarsenIrreg(a_coar,a_fine,a_datInd,a_variables); }
void EBMGInterp::pwlInterpFAB(EBCellFAB& a_refCoar, const Box& a_coarBox, const EBCellFAB& a_coar, const DataIndex& a_datInd, const Interval& a_variables) const { CH_TIMERS("EBMGInterp::pwlinterpfab"); CH_TIMER("regular_interp", t1); CH_TIMER("irregular_interp", t2); CH_assert(isDefined()); //first interpolate piecewise constant. pwcInterpFAB(a_refCoar, a_coarBox, a_coar, a_datInd, a_variables); //then add in slope*distance. const Box& coarBox = a_coarBox; for (int ivar = a_variables.begin(); ivar <= a_variables.end(); ivar++) { //save stuff at irreg cells because fortran result will be garbage //and this is an incremental process m_linearEBStencil[a_datInd]->cache(a_refCoar, ivar); //do all cells as if they were regular Box refBox(IntVect::Zero, IntVect::Zero); refBox.refine(m_refRat); const BaseFab<Real>& coarRegFAB = a_coar.getSingleValuedFAB(); BaseFab<Real>& refCoarRegFAB = a_refCoar.getSingleValuedFAB(); CH_START(t1); Real dxf = 1.0/m_coarDomain.size(0); Real dxc = 2.0*dxf; //do every cell as regular for (int idir = 0; idir < SpaceDim; idir++) { FORT_PROLONGADDSLOPE(CHF_FRA1(refCoarRegFAB,ivar), CHF_CONST_FRA1(coarRegFAB,ivar), CHF_BOX(coarBox), CHF_BOX(refBox), CHF_INT(idir), CHF_REAL(dxf), CHF_REAL(dxc), CHF_CONST_INT(m_refRat)); } CH_STOP(t1); //replace garbage fortran put in with original values (at irregular cells) m_linearEBStencil[a_datInd]->uncache(a_refCoar, ivar); CH_START(t2); //do what fortran should have done at irregular cells. m_linearEBStencil[a_datInd]->apply(a_refCoar, a_coar, true, ivar); CH_STOP(t2); } }
// --------------------------------------------------------- void AMRNavierStokes::computeVorticity(LevelData<FArrayBox>& a_vorticity) const { // this breaks the "const"-ness of the function, // but is necessary to ensure that boundary // conditions are properly set. LevelData<FArrayBox>& vel = *(const_cast<LevelData<FArrayBox>*>(m_vel_new_ptr)); const DisjointBoxLayout& grids = vel.getBoxes(); if (m_level > 0) { // do quadratic C/F BC's // for now, assume that BC's are with new velocity // (may need to be changed for fine-level regridding) LevelData<FArrayBox>& crseVel = crseNSPtr()->newVel(); const DisjointBoxLayout& crseGrids = crseVel.getBoxes(); int nRefCrse = crseNSPtr()->refRatio(); QuadCFInterp interpolator(grids, &crseGrids, m_dx, nRefCrse, SpaceDim, m_problem_domain); interpolator.coarseFineInterp(vel, crseVel); } Interval velComps(0,SpaceDim-1); vel.exchange(velComps); DataIterator dit = vel.dataIterator(); // at the moment, do extrap at physical boundaries // (same effect as one-sided differencing) BCHolder vortVelBC = m_physBCPtr->extrapFuncBC(1); for (dit.reset(); dit.ok(); ++dit) { // apply physical BC's vortVelBC(vel[dit], grids[dit], m_problem_domain, m_dx, true); // homogeneous if (SpaceDim == 3) { for (int dir=0; dir<SpaceDim; dir++) { // and then compute vorticity FORT_COMPUTEVORT(CHF_FRA1(a_vorticity[dit],dir), CHF_CONST_FRA(vel[dit]), CHF_BOX(grids[dit]), CHF_CONST_REAL(m_dx), CHF_CONST_INT(dir)); } } else if (SpaceDim == 2) { int dir = 2; FORT_COMPUTEVORT(CHF_FRA1(a_vorticity[dit],0), CHF_CONST_FRA(vel[dit]), CHF_BOX(grids[dit]), CHF_CONST_REAL(m_dx), CHF_CONST_INT(dir)); } // end dimensionality choice } // end loop over grids }
void EBPoissonOp:: applyDomainFlux(Box * a_loBox, Box * a_hiBox, int * a_hasLo, int * a_hasHi, Box & a_dblBox, int a_nComps, BaseFab<Real> & a_phiFAB, bool a_homogeneousPhysBC, const DataIndex& a_dit, const Real& a_beta) { CH_TIME("EBPoissonOp::applyDomainFlux"); CH_assert(m_domainBC != NULL); for (int idir=0; idir<SpaceDim; idir++) { EBArith::loHi(a_loBox[idir], a_hasLo[idir], a_hiBox[idir], a_hasHi[idir], m_eblg.getDomain(), a_dblBox, idir); for (int comp = 0; comp<a_nComps; comp++) { if (a_hasLo[idir] == 1) { Box lbox=a_loBox[idir]; lbox.shift(idir,-1); BaseFab<Real> loFaceFlux(a_loBox[idir],a_nComps); int side = -1; m_domainBC->getFaceFlux(loFaceFlux,a_phiFAB,m_origin,m_dx,idir,Side::Lo,a_dit,m_time,a_homogeneousPhysBC); FORT_REGAPPLYDOMAINFLUX_INPLACE(CHF_FRA1(a_phiFAB,comp), CHF_CONST_FRA1(loFaceFlux,comp), CHF_CONST_REAL(m_dx[idir]), CHF_CONST_INT(side), CHF_CONST_INT(idir), CHF_BOX(lbox)); } if (a_hasHi[idir] == 1) { Box hbox=a_hiBox[idir]; hbox.shift(idir,1); BaseFab<Real> hiFaceFlux(a_hiBox[idir],a_nComps); int side = 1; m_domainBC->getFaceFlux(hiFaceFlux,a_phiFAB,m_origin,m_dx,idir,Side::Hi,a_dit,m_time,a_homogeneousPhysBC); FORT_REGAPPLYDOMAINFLUX_INPLACE(CHF_FRA1(a_phiFAB,comp), CHF_CONST_FRA1(hiFaceFlux,comp), CHF_CONST_REAL(m_dx[idir]), CHF_CONST_INT(side), CHF_CONST_INT(idir), CHF_BOX(hbox)); } } } }
void EBGradDivFilter:: gradVel(EBCellFAB& a_gradVel, const EBCellFAB& a_vel, const Box& a_grid, const EBISBox& a_ebisBox, bool a_lowOrderOneSide) { CH_TIME("EBGradDivFilter::gradVel"); CH_assert(a_gradVel.nComp() == SpaceDim*SpaceDim); CH_assert(a_vel.nComp() == SpaceDim); int iLowOrderOneSide = 0; if (a_lowOrderOneSide) { iLowOrderOneSide = 1; } for (int derivDir = 0; derivDir < SpaceDim; derivDir++) { Box loBox, hiBox, centerBox; int hasLo, hasHi; EBArith::loHiCenter(loBox, hasLo, hiBox, hasHi, centerBox, m_domainFine, a_grid, derivDir); for (int velDir = 0; velDir < SpaceDim; velDir++) { BaseFab<Real>& regGradVel = a_gradVel.getSingleValuedFAB(); const BaseFab<Real>& regVel = a_vel.getSingleValuedFAB(); int gradcomp = getGradComp(velDir, derivDir); FORT_EBGDFGRADVEL(CHF_FRA1(regGradVel, gradcomp), CHF_CONST_FRA1(regVel, velDir), CHF_BOX(loBox), CHF_INT(hasLo), CHF_BOX(hiBox), CHF_INT(hasHi), CHF_BOX(centerBox), CHF_CONST_REAL(m_dxFine[derivDir]), CHF_CONST_INT(derivDir), CHF_CONST_INT(iLowOrderOneSide)); IntVectSet ivsIrreg = a_ebisBox.getIrregIVS(a_grid); if (!a_lowOrderOneSide) { ivsIrreg.grow(1); ivsIrreg &= a_grid; } for (VoFIterator vofit(ivsIrreg, a_ebisBox.getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); bool hasHi, hasLo; VolIndex vofHi, vofLo; Vector<FaceIndex> facesHi = a_ebisBox.getFaces(vof, derivDir, Side::Hi); Vector<FaceIndex> facesLo = a_ebisBox.getFaces(vof, derivDir, Side::Lo); hasHi = (facesHi.size() == 1) && (!facesHi[0].isBoundary()); hasLo = (facesLo.size() == 1) && (!facesLo[0].isBoundary()); if (hasLo) { vofLo = facesLo[0].getVoF(Side::Lo); } if (hasHi) { vofHi = facesHi[0].getVoF(Side::Hi); } Real gradVal; if (hasHi && hasLo) { gradVal = (a_vel(vofHi, velDir) - a_vel(vofLo, velDir))/(2.*m_dxFine[derivDir]); } else if (hasHi || hasLo) { //do one-sided diff CH_assert(!(hasHi && hasLo)); Side::LoHiSide side; VolIndex vofNear; if (hasLo) { side = Side::Lo; vofNear = vofLo; } else { side = Side::Hi; vofNear = vofHi; } int isign = sign(side); Vector<FaceIndex> facesFar = a_ebisBox.getFaces(vofNear, derivDir, side); bool hasVoFFar = (facesFar.size()==1) && (!facesFar[0].isBoundary()); Real valStart = a_vel(vof, velDir); Real valNear = a_vel(vofNear, velDir); if (hasVoFFar && !a_lowOrderOneSide) { VolIndex vofFar = facesFar[0].getVoF(side); Real valFar = a_vel(vofFar, velDir); gradVal = (4*(valNear - valStart)- (valFar-valStart))/(2.*isign*m_dxFine[derivDir]); } else { //do not have another point for stencil or specified low order one-sided. //drop order of derivative gradVal = (valNear - valStart)/(isign*m_dxFine[derivDir]); } } else { //only have one point, can only set gradient to zero gradVal = 0.0; } a_gradVel(vof, gradcomp) = gradVal; } } } }
/// Set up initial conditions void RSIBC::initializeBdry(LevelData<FArrayBox>& a_B) { const Real tmpVal = 0.0; const Real tmpVal2 = 1e10; 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,RX_VX), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_VZ), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_SXY), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_SYZ), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_V), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_DX), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_DZ), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_DT), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_RT), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal2)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_SYY), CHF_BOX(bBox), CHF_CONST_REAL(tmpVal)); FORT_LINELASTSETFAB(CHF_FRA1(B,RX_PSI), CHF_BOX(bBox), CHF_CONST_REAL(m_psi)); } }
void EBGradDivFilter:: faceDivergence(EBFaceFAB& a_divVel, const EBCellFAB& a_gradVel, const EBCellFAB& a_vel, const EBFluxFAB& a_fluxVel, const Box& a_grid, const EBISBox& a_ebisBox, const int& a_faceDir) { CH_TIME("EBGradDivFilter::faceDivergence"); CH_assert(a_divVel.nComp() == 1); CH_assert(a_vel.nComp() == SpaceDim); a_divVel.setVal(0.0); BaseFab<Real>& regDivVel = a_divVel.getSingleValuedFAB(); const BaseFab<Real>& regVel = a_vel.getSingleValuedFAB(); const BaseFab<Real>& regGradVel= a_gradVel.getSingleValuedFAB(); Box interiorFaceBox = a_grid; interiorFaceBox.grow(a_faceDir, 1); interiorFaceBox &= m_domainFine; interiorFaceBox.grow(a_faceDir, -1); interiorFaceBox.surroundingNodes(a_faceDir); for (int divDir = 0; divDir < SpaceDim; divDir++) { FORT_EBGDFFACEDIVINCR(CHF_FRA1(regDivVel, 0), CHF_FRA(regVel), CHF_FRA(regGradVel), CHF_BOX(interiorFaceBox), CHF_REAL(m_dxFine[divDir]), CHF_INT(a_faceDir), CHF_INT(divDir)); } IntVectSet irregIVS = a_ebisBox.getIrregIVS(a_grid); FaceStop::WhichFaces stopCrit; if (m_domainFine.isPeriodic(a_faceDir)) { stopCrit = FaceStop::SurroundingWithBoundary; } else { stopCrit = FaceStop::SurroundingNoBoundary; } for (FaceIterator faceit(irregIVS, a_ebisBox.getEBGraph(), a_faceDir, stopCrit); faceit.ok(); ++faceit) { Real divVal = 0.0; for (int divDir=0; divDir<SpaceDim; divDir++) { if (divDir == a_faceDir) { divVal += (a_vel(faceit().getVoF(Side::Hi), a_faceDir) - a_vel(faceit().getVoF(Side::Lo), a_faceDir))/m_dxFine[divDir]; } else { // take average of cell-centered tangential derivatives // and increment div //so this is partial (vel_divdir)/partial (x_divdir) int velcomp = divDir; int gradcomp = getGradComp(velcomp, divDir); divVal += 0.5*(a_gradVel(faceit().getVoF(Side::Hi), gradcomp) + a_gradVel(faceit().getVoF(Side::Lo), gradcomp)); } } a_divVel(faceit(), 0) = divVal; } // end loop over interior irregular faces if (!m_domainFine.isPeriodic(a_faceDir)) { //set the boundary face divergence to an extrapolation of the neighboring face divergences for (SideIterator sit; sit.ok(); ++sit) { Box bndryBox = adjCellBox(a_grid, a_faceDir, sit(), 1); int ishift = -sign(sit()); bndryBox.shift(a_faceDir, ishift); IntVectSet bndryIVS(bndryBox); for (FaceIterator faceit(bndryIVS, a_ebisBox.getEBGraph(), a_faceDir, FaceStop::AllBoundaryOnly); faceit.ok(); ++faceit) { Real faceDiv = getDomainDivergence(a_gradVel, a_vel, a_fluxVel, a_grid, a_ebisBox, a_faceDir, faceit(), sit()); a_divVel(faceit(), 0) = faceDiv; } } } }