void EBPlanarShockIBC:: initialize(LevelData<EBCellFAB>& a_conState, const EBISLayout& a_ebisl) const { CH_assert(m_isDefined); CH_assert(m_isFortranCommonSet); // Iterator of all grids in this level for(DataIterator dit = a_conState.dataIterator(); dit.ok(); ++dit) { const EBISBox& ebisBox = a_ebisl[dit()]; // Storage for current grid EBCellFAB& conFAB = a_conState[dit()]; BaseFab<Real>& regConFAB = conFAB.getSingleValuedFAB(); // Box of current grid Box uBox = regConFAB.box(); uBox &= m_domain; // Set up initial condition in this grid /**/ FORT_PLANARSHOCKINIT(CHF_CONST_FRA(regConFAB), CHF_CONST_REAL(m_dx), CHF_BOX(uBox)); /**/ //now for the multivalued cells. Since it is pointwise, //the regular calc is correct for all single-valued cells. IntVectSet ivs = ebisBox.getMultiCells(uBox); for(VoFIterator vofit(ivs, ebisBox.getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); const IntVect& iv = vof.gridIndex(); RealVect momentum; Real energy, density; /**/ FORT_POINTPLANARSHOCKINIT(CHF_REAL(density), CHF_REALVECT(momentum), CHF_REAL(energy), CHF_CONST_INTVECT(iv), CHF_CONST_REAL(m_dx)); /**/ conFAB(vof, CRHO) = density; conFAB(vof, CENG) = energy; for(int idir = 0; idir < SpaceDim; idir++) { conFAB(vof, CMOMX+idir) = momentum[idir]; } }//end loop over multivalued cells } //end loop over boxes }
Real TrigBCBetaValue::beta(const RealVect& a_point, const Real& a_time) const { CH_assert(m_isDefined); Real value; FORT_GETBETAPOINT(CHF_REAL(value), CHF_CONST_INTVECT(m_trig), CHF_CONST_REALVECT(a_point), CHF_CONST_REAL(a_time)); return value; }
Real SphericalHarmonicBCBetaValue::beta(const RealVect& a_point, const Real& a_time) const { CH_assert(m_isDefined); Real value; FORT_GETBETAPOINT(CHF_REAL(value), CHF_CONST_INTVECT(m_lmphase), CHF_CONST_REALVECT(a_point), CHF_CONST_REAL(a_time)); return value; }
Real TrigBCBetaValue::value(const RealVect& a_point, const RealVect& a_normal, const Real& a_time, const int& a_comp) const { CH_assert(m_isDefined); Real value; FORT_GETPHIPOINT(CHF_REAL(value), CHF_CONST_INTVECT(m_trig), CHF_CONST_REALVECT(a_point), CHF_CONST_REAL(a_time)); return value; }
Real SphericalHarmonicBCBetaValue::value(const RealVect& a_point, const RealVect& a_normal, const Real& a_time, const int& a_comp) const { CH_assert(m_isDefined); Real value; FORT_GETSHPHIPOINT(CHF_REAL(value), CHF_CONST_INTVECT(m_lmphase), CHF_CONST_REALVECT(a_point), CHF_CONST_REAL(a_time)); return value; }
// ----------------------------------------------------------------------------- // Adds coarse cell values directly to all overlying fine cells. // ----------------------------------------------------------------------------- void ConstInterpPS::prolongIncrement (LevelData<FArrayBox>& a_phiThisLevel, const LevelData<FArrayBox>& a_correctCoarse) { CH_TIME("ConstInterpPS::prolongIncrement"); // Gather grids, domains, refinement ratios... const DisjointBoxLayout& fineGrids = a_phiThisLevel.getBoxes(); const DisjointBoxLayout& crseGrids = a_correctCoarse.getBoxes(); CH_assert(fineGrids.compatible(crseGrids)); const ProblemDomain& fineDomain = fineGrids.physDomain(); const ProblemDomain& crseDomain = crseGrids.physDomain(); const IntVect mgRefRatio = fineDomain.size() / crseDomain.size(); CH_assert(mgRefRatio.product() > 1); DataIterator dit = fineGrids.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { // Create references for convenience FArrayBox& fineFAB = a_phiThisLevel[dit]; const FArrayBox& crseFAB = a_correctCoarse[dit]; const Box& fineValid = fineGrids[dit]; // To make things easier, we will offset the // coarse and fine data boxes to zero. const IntVect& fiv = fineValid.smallEnd(); const IntVect civ = coarsen(fiv, mgRefRatio); // Correct the fine data FORT_CONSTINTERPPS ( CHF_FRA_SHIFT(fineFAB, fiv), CHF_CONST_FRA_SHIFT(crseFAB, civ), CHF_BOX_SHIFT(fineValid, fiv), CHF_CONST_INTVECT(mgRefRatio)); } }
// Sets parameters in a common block used by Fortran routines: // a_smallPressure - Lower limit for pressure (returned) // a_gamma - Gamma for polytropic, gamma-law gas // a_ambientDensity - Ambient density add to the plane-wave // a_deltaDensity - Mean of the plane-wave // a_pressure - If 0, use isentropic pressure // if 1, use the constant pressure of 1.0 // a_waveNumber - The wave number of the plane-wave // a_velocity - Initial velocity of the gas // a_center - Position of a maximum of the plane-wave // a_artvisc - Artificial viscosity coefficient void WaveIBC::setFortranCommon(Real& a_smallPressure, const Real& a_gamma, const Real& a_ambientDensity, const Real& a_deltaDensity, const int& a_pressure, const IntVect& a_waveNumber, const RealVect& a_center, const RealVect& a_velocity, const Real& a_artvisc) { CH_assert(m_isFortranCommonSet == false); FORT_WAVESETF(CHF_REAL(a_smallPressure), CHF_CONST_REAL(a_gamma), CHF_CONST_REAL(a_ambientDensity), CHF_CONST_REAL(a_deltaDensity), CHF_CONST_INT(a_pressure), CHF_CONST_INTVECT(a_waveNumber), CHF_CONST_REALVECT(a_center), CHF_CONST_REALVECT(a_velocity), CHF_CONST_REAL(a_artvisc)); m_isFortranCommonSet = true; }
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)); }
// ----------------------------------------------------------------------------- // Adds coarse cell values directly to all overlying fine cells, // then removes the average from the fine result. // ----------------------------------------------------------------------------- void ZeroAvgConstInterpPS::prolongIncrement (LevelData<FArrayBox>& a_phiThisLevel, const LevelData<FArrayBox>& a_correctCoarse) { CH_TIME("ZeroAvgConstInterpPS::prolongIncrement"); // Gather grids, domains, refinement ratios... const DisjointBoxLayout& fineGrids = a_phiThisLevel.getBoxes(); const DisjointBoxLayout& crseGrids = a_correctCoarse.getBoxes(); CH_assert(fineGrids.compatible(crseGrids)); const ProblemDomain& fineDomain = fineGrids.physDomain(); const ProblemDomain& crseDomain = crseGrids.physDomain(); const IntVect mgRefRatio = fineDomain.size() / crseDomain.size(); CH_assert(mgRefRatio.product() > 1); // These will accumulate averaging data. Real localSum = 0.0; Real localVol = 0.0; CH_assert(!m_CCJinvPtr.isNull()); CH_assert(m_dxProduct > 0.0); DataIterator dit = fineGrids.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { // Create references for convenience FArrayBox& fineFAB = a_phiThisLevel[dit]; const FArrayBox& crseFAB = a_correctCoarse[dit]; const Box& fineValid = fineGrids[dit]; const FArrayBox& JinvFAB = (*m_CCJinvPtr)[dit]; // To make things easier, we will offset the // coarse and fine data boxes to zero. const IntVect& fiv = fineValid.smallEnd(); const IntVect civ = coarsen(fiv, mgRefRatio); // Correct the fine data FORT_CONSTINTERPWITHAVGPS ( CHF_FRA_SHIFT(fineFAB, fiv), CHF_CONST_FRA_SHIFT(crseFAB, civ), CHF_BOX_SHIFT(fineValid, fiv), CHF_CONST_INTVECT(mgRefRatio), CHF_CONST_FRA1_SHIFT(JinvFAB,0,fiv), CHF_CONST_REAL(m_dxProduct), CHF_REAL(localVol), CHF_REAL(localSum)); } // Compute global sum (this is where the MPI communication happens) #ifdef CH_MPI Real globalSum = 0.0; int result = MPI_Allreduce(&localSum, &globalSum, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm); if (result != MPI_SUCCESS) { MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement"); } Real globalVol = 0.0; result = MPI_Allreduce(&localVol, &globalVol, 1, MPI_CH_REAL, MPI_SUM, Chombo_MPI::comm); if (result != MPI_SUCCESS) { MayDay::Error("Sorry, but I had a communication error in ZeroAvgConstInterpPS::prolongIncrement"); } #else Real globalSum = localSum; Real globalVol = localVol; #endif // Remove the average from phi. Real avgPhi = globalSum / globalVol; for (dit.reset(); dit.ok(); ++dit) { a_phiThisLevel[dit] -= avgPhi; } }