void MappedLevelFluxRegister::incrementFine(const FArrayBox& a_fineFlux, Real a_scale, const DataIndex& a_fineDataIndex, const Interval& a_srcInterval, const Interval& a_dstInterval, int a_dir, Side::LoHiSide a_sd) { CH_assert(isDefined()); if (!(m_isDefined & FluxRegFineDefined)) return; CH_assert(a_srcInterval.size() == a_dstInterval.size()); CH_TIME("MappedLevelFluxRegister::incrementFine"); // We cast away the constness in a_coarseFlux for the scope of this function. This // should be acceptable, since at the end of the day there is no change to it. -JNJ FArrayBox& fineFlux = const_cast<FArrayBox&>(a_fineFlux); // Muhahaha. fineFlux.shiftHalf(a_dir, sign(a_sd)); Real denom = 1.0; if (m_scaleFineFluxes) { denom = m_nRefine.product() / m_nRefine[a_dir]; } Real scale = sign(a_sd) * a_scale / denom; FArrayBox& cFine = m_fineFlux[a_fineDataIndex]; // FArrayBox cFineFortran(cFine.box(), cFine.nComp()); // cFineFortran.copy(cFine); Box clipBox = m_fineFlux.box(a_fineDataIndex); clipBox.refine(m_nRefine); Box fineBox; if (a_sd == Side::Lo) { fineBox = adjCellLo(clipBox, a_dir, 1); fineBox &= fineFlux.box(); } else { fineBox = adjCellHi(clipBox, a_dir, 1); fineBox &= fineFlux.box(); } #if 0 for (BoxIterator b(fineBox); b.ok(); ++b) { int s = a_srcInterval.begin(); int d = a_dstInterval.begin(); for (; s <= a_srcInterval.end(); ++s, ++d) { cFine(coarsen(b(), m_nRefine), d) += scale * fineFlux(b(), s); } } #else // shifting to ensure fineBox is in the positive quadrant, so IntVect coarening // is just integer division. const Box& box = coarsen(fineBox, m_nRefine); Vector<Real> regbefore(cFine.nComp()); Vector<Real> regafter(cFine.nComp()); if (s_verbose && (a_dir == debugdir) && box.contains(ivdebnoeb)) { for (int ivar = 0; ivar < cFine.nComp(); ivar++) { regbefore[ivar] = cFine(ivdebnoeb, ivar); } } const IntVect& iv = fineBox.smallEnd(); IntVect civ = coarsen(iv, m_nRefine); int srcComp = a_srcInterval.begin(); int destComp = a_dstInterval.begin(); int ncomp = a_srcInterval.size(); FORT_MAPPEDINCREMENTFINE(CHF_CONST_FRA_SHIFT(fineFlux, iv), CHF_FRA_SHIFT(cFine, civ), CHF_BOX_SHIFT(fineBox, iv), CHF_CONST_INTVECT(m_nRefine), CHF_CONST_REAL(scale), CHF_CONST_INT(srcComp), CHF_CONST_INT(destComp), CHF_CONST_INT(ncomp)); if (s_verbose && (a_dir == debugdir) && box.contains(ivdebnoeb)) { for (int ivar = 0; ivar < cFine.nComp(); ivar++) { regafter[ivar] = cFine(ivdebnoeb, ivar); } } if (s_verbose && (a_dir == debugdir) && box.contains(ivdebnoeb)) { pout() << "levelfluxreg::incrementFine: scale = " << scale << endl; Box refbox(ivdebnoeb, ivdebnoeb); refbox.refine(m_nRefine); refbox &= fineBox; if (!refbox.isEmpty()) { pout() << "fine fluxes = " << endl; for (BoxIterator bit(refbox); bit.ok(); ++bit) { for (int ivar = 0; ivar < cFine.nComp(); ivar++) { pout() << "iv = " << bit() << "("; for (int ivar = 0; ivar < cFine.nComp(); ivar++) { pout() << fineFlux(bit(), ivar); } pout() << ")" << endl; } } } for (int ivar = 0; ivar < cFine.nComp(); ivar++) { pout() << " reg before = " << regbefore[ivar] << ", "; pout() << " reg after = " << regafter[ivar] << ", "; } pout() << endl; } //fineBox.shift(-shift); // now, check that cFineFortran and cFine are the same //fineBox.coarsen(m_nRefine); // for (BoxIterator b(fineBox); b.ok(); ++b) // { // if (cFineFortran(b(),0) != cFine(b(),0)) // { // MayDay::Error("Fortran doesn't match C++"); // } // } // need to shift boxes back to where they were on entry. // cFine.shift(-shift/m_nRefine); #endif fineFlux.shiftHalf(a_dir, - sign(a_sd)); }
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 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; } } }