// --------------------------------------------------------- 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()); }
// 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); }
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; } } } }
// --------------------------------------------------------- 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)); } } }
/// 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)); } }
// ----------------------------------------------------------------------------- // 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); } } } }
// --------------------------------------------------------- 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()); }
// ---------------------------------------------------------------- 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()]); } }
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)); } } } }
void EBPoissonOp:: GSColorAllIrregular(LevelData<EBCellFAB>& a_phi, const LevelData<EBCellFAB>& a_rhs, const IntVect& a_color, const bool& a_homogeneousPhysBC, int icolor) { CH_TIME("EBPoissonOp::GSColorAllIrregular"); for (DataIterator dit = a_phi.dataIterator(); dit.ok(); ++dit) { EBCellFAB& phifab = a_phi[dit()]; const EBCellFAB& rhsfab = a_rhs[dit()]; //phi = (I-lambda*L)phiOld m_colorEBStencil[icolor][dit()]->apply(phifab, phifab, false); //apply EB bcs to (I-lambda*L)phi (already done in colorStencil += fluxStencil, and hom only here)) int comp = 0; const BaseIVFAB<Real>& curAlphaWeight = m_alphaDiagWeight[dit()]; const BaseIVFAB<Real>& curBetaWeight = m_betaDiagWeight[dit()]; //apply domain bcs to (I-lambda*L)phi for (int idir = 0; idir < SpaceDim; idir++) { for (m_vofItIrregColorDomLo[icolor][idir][dit()].reset(); m_vofItIrregColorDomLo[icolor][idir][dit()].ok(); ++m_vofItIrregColorDomLo[icolor][idir][dit()]) { Real flux; const VolIndex& vof = m_vofItIrregColorDomLo[icolor][idir][dit()](); Real weightIrreg = m_alpha*curAlphaWeight(vof,0) + m_beta*curBetaWeight(vof,0); m_domainBC->getFaceFlux(flux,vof,comp,a_phi[dit()], m_origin,m_dx,idir,Side::Lo, dit(), m_time, a_homogeneousPhysBC); phifab(vof,comp) -= -(1./weightIrreg) * flux * m_beta*m_invDx[idir]; } for (m_vofItIrregColorDomHi[icolor][idir][dit()].reset(); m_vofItIrregColorDomHi[icolor][idir][dit()].ok(); ++m_vofItIrregColorDomHi[icolor][idir][dit()]) { Real flux; const VolIndex& vof = m_vofItIrregColorDomHi[icolor][idir][dit()](); Real weightIrreg = m_alpha*curAlphaWeight(vof,0) + m_beta*curBetaWeight(vof,0); m_domainBC->getFaceFlux(flux,vof,comp,a_phi[dit()], m_origin,m_dx,idir,Side::Hi,dit(), m_time, a_homogeneousPhysBC); phifab(vof,comp) += -(1./weightIrreg) * flux * m_beta*m_invDx[idir]; } } //phi += lambda*rhsfab m_rhsColorEBStencil[icolor][dit()]->apply(phifab, rhsfab, true); } }
void EBPoissonOp:: colorGS(LevelData<EBCellFAB>& a_phi, const LevelData<EBCellFAB>& a_rhs, const IntVect& a_color, int icolor) { CH_TIME("EBPoissonOp::colorGS"); //this is a multigrid operator so only homogeneous CF BC and null coar level CH_assert(a_rhs.ghostVect() == m_ghostCellsRHS); CH_assert(a_phi.ghostVect() == m_ghostCellsPhi); a_phi.exchange(); Real weight = m_alpha; for (int idir = 0; idir < SpaceDim; idir++) { weight += -2.0 * m_beta * m_invDx2[idir]; } weight = 1.0 / weight; for (DataIterator dit = a_phi.dataIterator(); dit.ok(); ++dit) { EBCellFAB& phifab = a_phi[dit()]; m_colorEBStencil[icolor][dit()]->cache(phifab); } GSColorAllRegular( a_phi, a_rhs, a_color, weight, true); for (DataIterator dit = a_phi.dataIterator(); dit.ok(); ++dit) { EBCellFAB& phifab = a_phi[dit()]; m_colorEBStencil[icolor][dit()]->uncache(phifab); } GSColorAllIrregular(a_phi, a_rhs, a_color, true, icolor); }
void initData(LevelData<FArrayBox>& a_data, Real a_dx) { // for now, set phi to 1 everywhere Real phiVal = 1.0; DataIterator dit = a_data.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { a_data[dit].setVal(phiVal); } }
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 }
/// 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 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 Mask::buildMasks(LevelData<BaseFab<int> >& a_masks, const ProblemDomain& a_dProblem, const BoxLayout& a_grids, const BoxLayout* a_fineGridsPtr, int a_nRefFine) { // simply iterate over boxes and call single-basefab function DataIterator dit = a_masks.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { buildMask(a_masks[dit()], a_dProblem, a_grids, a_fineGridsPtr, a_nRefFine); } }
void EBPoissonOp:: residual(LevelData<EBCellFAB>& a_residual, const LevelData<EBCellFAB>& a_phi, const LevelData<EBCellFAB>& a_rhs, bool a_homogeneousPhysBC) { CH_TIME("EBPoissonOp::residual"); //this is a multigrid operator so only homogeneous CF BC //and null coar level CH_assert(a_residual.ghostVect() == m_ghostCellsRHS); CH_assert(a_phi.ghostVect() == m_ghostCellsPhi); DataIterator dit = a_residual.dataIterator(); applyOp(a_residual,a_phi, a_homogeneousPhysBC, dit ); axby(a_residual,a_residual,a_rhs,-1.0, 1.0); }
// ---------------------------------------------------------- // this function is shamelessly based on the ANAG CoarseAverage // (cell-centered) version void CoarseAverageEdge::averageToCoarse(LevelData<FluxBox>& a_coarseData, const LevelData<FluxBox>& a_fineData) { CH_assert(isDefined()); DataIterator dit = a_fineData.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { FluxBox& coarsenedFine = m_coarsenedFineData[dit()]; const FluxBox& fine = a_fineData[dit()]; // coarsen from the entire fine grid onto the entire coarse grid averageGridData(coarsenedFine, fine); } m_coarsenedFineData.copyTo(m_coarsenedFineData.interval(), a_coarseData, a_coarseData.interval()); }
void setValue(LevelData<EBCellFAB>& phase, const BaseBCValue& value, const Box& domain, const RealVect& dx, const RealVect& origin, bool useKappa) { RealVect loc; IntVect originIV = domain.smallEnd(); DataIterator dit = phase.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { EBCellFAB& efab = phase[dit]; FArrayBox& fab = efab.getFArrayBox(); ForAllX(Real, fab) { D_EXPR(loc[0]=iR+nR-nR+originIV[0], loc[1]=jR+originIV[1], loc[2]=kR+originIV[2]); loc+=0.5; loc*=dx; loc+=origin; fabR = value.value(loc, RealVect::Zero, 1.e99,0); } EndFor ; if (useKappa) { const EBISBox& ebox = efab.getEBISBox(); IntVectSet ivs = ebox.getIrregIVS(efab.getRegion()); IVSIterator it(ivs); for (; it.ok(); ++it) { const IntVect iv = it(); VolIndex vi(iv,0); if (ebox.bndryArea(vi) != 0) { loc = iv; loc+=0.5; loc+= ebox.centroid(vi); loc*=dx; loc+=origin; efab(vi, 0) = value.value(loc, RealVect::Zero, 1.e99,0)*ebox.volFrac(vi); } } } }
void TimeInterpolatorRK4::interpolate(/// interpolated solution on this level coarsened LevelData<FArrayBox>& a_U, /// time interpolation coefficient in range [0:1] const Real& a_timeInterpCoeff, /// interval of a_U to fill in const Interval& a_intvl) { CH_assert(m_defined); CH_assert(m_gotFullTaylorPoly); CH_assert(a_U.nComp() == m_numStates); LevelData<FArrayBox> UComp; aliasLevelData(UComp, &a_U, a_intvl); // For i in 0:m_numCoeffs-1, // coeffFirst[i] is index of first component of m_taylorCoeffs // that corresponds to a coefficient of t^i. Vector<int> coeffFirst(m_numCoeffs); int intervalLength = a_intvl.size(); for (int i = 0; i < m_numCoeffs; i++) { coeffFirst[i] = a_intvl.begin() + i * m_numStates; } DataIterator dit = UComp.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { FArrayBox& UFab = UComp[dit]; const FArrayBox& taylorFab = m_taylorCoeffs[dit]; // Evaluate a0 + a1*t + a2*t^2 + a3*t^3 // as a0 + t * (a1 + t * (a2 + t * a3)). UFab.copy(taylorFab, coeffFirst[m_numCoeffs-1], 0, intervalLength); for (int ind = m_numCoeffs - 2; ind >=0; ind--) { UFab *= a_timeInterpCoeff; UFab.plus(taylorFab, coeffFirst[ind], 0, intervalLength); } } // dummy statement in order to get around gdb bug int dummy_unused = 0; dummy_unused = 0; }
// Set up initial conditions void RampIBC::initialize(LevelData<FArrayBox>& a_U) { CH_assert(m_isFortranCommonSet == true); CH_assert(m_isDefined == true); // Iterator of all grids in this level for (DataIterator dit = a_U.dataIterator(); dit.ok(); ++dit) { // Storage for current grid FArrayBox& U = a_U[dit]; // Box of current grid Box uBox = U.box(); uBox &= m_domain; // Set up initial condition in this grid FORT_RAMPINITF(CHF_FRA(U), CHF_CONST_REAL(m_dx), CHF_BOX(uBox)); } }
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(); // linear profile //localVal = a_dx*(D_TERM(loc[0]+0.5, // + loc[1]+0.5, // + loc[2]+0.5)); // quadratic profile localVal = a_dx*a_dx*(D_TERM6((loc[0]+0.5)*(loc[0]+0.5), + (loc[1]+0.5)*(loc[1]+0.5), + (loc[2]+0.5)*(loc[2]+0.5), + (loc[3]+0.5)*(loc[3]+0.5), + (loc[4]+0.5)*(loc[4]+0.5), + (loc[5]+0.5)*(loc[5]+0.5))); localData(loc) = localVal; } } }
void TimeInterpolatorRK4::intermediate(/// intermediate RK4 solution on this level coarsened LevelData<FArrayBox>& a_U, /// time interpolation coefficient in range [0:1] const Real& a_timeInterpCoeff, /// which RK4 stage: 0, 1, 2, 3 const int& a_stage, /// interval of a_U to fill in const Interval& a_intvl) const { CH_assert(m_defined); CH_assert(m_gotFullTaylorPoly); CH_assert(a_U.nComp() == m_numStates); CH_assert(a_stage >= 0); CH_assert(a_stage < 4); Real rinv = 1. / Real(m_refineCoarse); Vector<Real> intermCoeffs(4); // 0 is coefficient of m_taylorCoeffs[0] = Ucoarse(0) // 1 is coefficient of m_taylorCoeffs[1] = K1 // 2 is coefficient of m_taylorCoeffs[2] = 1/2 * (-3*K1 + 2*K2 + 2*K3 - K4) // 3 is coefficient of m_taylorCoeffs[3] = 2/3 * ( K1 - K2 - K3 + K4) Real diff12Coeffs; // coefficient of m_diff12 = - K2 + K3 switch (a_stage) { case 0: intermCoeffs[0] = 1.; intermCoeffs[1] = a_timeInterpCoeff; intermCoeffs[2] = a_timeInterpCoeff * a_timeInterpCoeff; intermCoeffs[3] = a_timeInterpCoeff * a_timeInterpCoeff * a_timeInterpCoeff; diff12Coeffs = 0.; break; case 1: intermCoeffs[0] = 1.; intermCoeffs[1] = 0.5*rinv + a_timeInterpCoeff; intermCoeffs[2] = a_timeInterpCoeff * (rinv + a_timeInterpCoeff); intermCoeffs[3] = a_timeInterpCoeff * a_timeInterpCoeff * (1.5*rinv + a_timeInterpCoeff); diff12Coeffs = 0.; break; case 2: intermCoeffs[0] = 1.; intermCoeffs[1] = 0.5*rinv + a_timeInterpCoeff; intermCoeffs[2] = 0.5*rinv*rinv + a_timeInterpCoeff * (rinv + a_timeInterpCoeff); intermCoeffs[3] = 0.375*rinv*rinv*rinv + a_timeInterpCoeff * (1.5*rinv*rinv + a_timeInterpCoeff * (1.5*rinv + a_timeInterpCoeff)); diff12Coeffs = -0.25 * rinv * rinv; break; case 3: intermCoeffs[0] = 1.; intermCoeffs[1] = rinv + a_timeInterpCoeff; intermCoeffs[2] = rinv*rinv + a_timeInterpCoeff * (2.*rinv + a_timeInterpCoeff); intermCoeffs[3] = 0.75*rinv*rinv*rinv + a_timeInterpCoeff * (3.*rinv*rinv + a_timeInterpCoeff * (3.*rinv + a_timeInterpCoeff)); diff12Coeffs = 0.5 * rinv * rinv; break; default: MayDay::Error("TimeInterpolatorRK4::intermediate must have a_stage in range 0:3"); } LevelData<FArrayBox> UComp; aliasLevelData(UComp, &a_U, a_intvl); // For i in 0:m_numCoeffs-1, // coeffFirst[i] is index of first component of m_taylorCoeffs // that corresponds to a coefficient of t^i. Vector<int> coeffFirst(m_numCoeffs); int intervalLength = a_intvl.size(); for (int i = 0; i < m_numCoeffs; i++) { coeffFirst[i] = a_intvl.begin() + i * m_numStates; } DataIterator dit = UComp.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { FArrayBox& UFab = UComp[dit]; const FArrayBox& taylorFab = m_taylorCoeffs[dit]; // WAS: Evaluate a0 + a1*t + a2*t^2 + a3*t^3 // as a0 + t * (a1 + t * (a2 + t * a3)): // that is, set UFab to // a3, t*a3 + a2, t*(t*a3 + a2) + a1, t*(t*(t*a3 + a2) + a1) * a0. // NEW: Evaluate a0*c0 + a1*c1 + a2*c2 + a3*c3, // where c0, c1, c2, c3 are scalars, // and c0 = intermCoeffs[0] = 1. UFab.copy(taylorFab, coeffFirst[0], 0, intervalLength); for (int ind = 1; ind < 4; ind++) { UFab.plus(taylorFab, intermCoeffs[ind], coeffFirst[ind], 0, intervalLength); } const FArrayBox& diff12Fab = m_diff12[dit]; UFab.plus(diff12Fab, diff12Coeffs, 0, 0, intervalLength); } // dummy statement in order to get around gdb bug int dummy_unused = 0; dummy_unused = 0; }
void VCAMRPoissonOp2::restrictResidual(LevelData<FArrayBox>& a_resCoarse, LevelData<FArrayBox>& a_phiFine, const LevelData<FArrayBox>& a_rhsFine) { CH_TIME("VCAMRPoissonOp2::restrictResidual"); homogeneousCFInterp(a_phiFine); const DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout(); for (DataIterator dit = a_phiFine.dataIterator(); dit.ok(); ++dit) { FArrayBox& phi = a_phiFine[dit]; m_bc(phi, dblFine[dit()], m_domain, m_dx, true); } a_phiFine.exchange(a_phiFine.interval(), m_exchangeCopier); for (DataIterator dit = a_phiFine.dataIterator(); dit.ok(); ++dit) { FArrayBox& phi = a_phiFine[dit]; const FArrayBox& rhs = a_rhsFine[dit]; FArrayBox& res = a_resCoarse[dit]; const FArrayBox& thisACoef = (*m_aCoef)[dit]; const FluxBox& thisBCoef = (*m_bCoef)[dit]; Box region = dblFine.get(dit()); const IntVect& iv = region.smallEnd(); IntVect civ = coarsen(iv, 2); res.setVal(0.0); #if CH_SPACEDIM == 1 FORT_RESTRICTRESVC1D #elif CH_SPACEDIM == 2 FORT_RESTRICTRESVC2D #elif CH_SPACEDIM == 3 FORT_RESTRICTRESVC3D #else This_will_not_compile! #endif (CHF_FRA_SHIFT(res, civ), CHF_CONST_FRA_SHIFT(phi, iv), CHF_CONST_FRA_SHIFT(rhs, iv), CHF_CONST_REAL(m_alpha), CHF_CONST_FRA_SHIFT(thisACoef, iv), CHF_CONST_REAL(m_beta), #if CH_SPACEDIM >= 1 CHF_CONST_FRA_SHIFT(thisBCoef[0], iv), #endif #if CH_SPACEDIM >= 2 CHF_CONST_FRA_SHIFT(thisBCoef[1], iv), #endif #if CH_SPACEDIM >= 3 CHF_CONST_FRA_SHIFT(thisBCoef[2], iv), #endif #if CH_SPACEDIM >= 4 This_will_not_compile! #endif CHF_BOX_SHIFT(region, iv), CHF_CONST_REAL(m_dx)); } }
// // VCAMRPoissonOp2::reflux() // There are currently the new version (first) and the old version (second) // in this file. Brian asked to preserve the old version in this way for // now. - TJL (12/10/2007) // void VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>& a_phiFine, const LevelData<FArrayBox>& a_phi, LevelData<FArrayBox>& a_residual, AMRLevelOp<LevelData<FArrayBox> >* a_finerOp) { CH_TIMERS("VCAMRPoissonOp2::reflux"); m_levfluxreg.setToZero(); Interval interv(0,a_phi.nComp()-1); CH_TIMER("VCAMRPoissonOp2::reflux::incrementCoarse", t2); CH_START(t2); DataIterator dit = a_phi.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { const FArrayBox& coarfab = a_phi[dit]; const FluxBox& coarBCoef = (*m_bCoef)[dit]; const Box& gridBox = a_phi.getBoxes()[dit]; if (m_levfluxreg.hasCF(dit())) { for (int idir = 0; idir < SpaceDim; idir++) { FArrayBox coarflux; Box faceBox = surroundingNodes(gridBox, idir); getFlux(coarflux, coarfab, coarBCoef, faceBox, idir); Real scale = 1.0; m_levfluxreg.incrementCoarse(coarflux, scale,dit(), interv, interv, idir); } } } CH_STOP(t2); // const cast: OK because we're changing ghost cells only LevelData<FArrayBox>& phiFineRef = ( LevelData<FArrayBox>&)a_phiFine; VCAMRPoissonOp2* finerAMRPOp = (VCAMRPoissonOp2*) a_finerOp; QuadCFInterp& quadCFI = finerAMRPOp->m_interpWithCoarser; quadCFI.coarseFineInterp(phiFineRef, a_phi); // I'm pretty sure this is not necessary. bvs -- flux calculations use // outer ghost cells, but not inner ones // phiFineRef.exchange(a_phiFine.interval()); IntVect phiGhost = phiFineRef.ghostVect(); int ncomps = a_phiFine.nComp(); CH_TIMER("VCAMRPoissonOp2::reflux::incrementFine", t3); CH_START(t3); DataIterator ditf = a_phiFine.dataIterator(); const DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout(); for (ditf.reset(); ditf.ok(); ++ditf) { const FArrayBox& phifFab = a_phiFine[ditf]; const FluxBox& fineBCoef = (*(finerAMRPOp->m_bCoef))[ditf]; const Box& gridbox = dblFine.get(ditf()); for (int idir = 0; idir < SpaceDim; idir++) { //int normalGhost = phiGhost[idir]; SideIterator sit; for (sit.begin(); sit.ok(); sit.next()) { if (m_levfluxreg.hasCF(ditf(), sit())) { Side::LoHiSide hiorlo = sit(); Box fluxBox = bdryBox(gridbox,idir,hiorlo,1); FArrayBox fineflux(fluxBox,ncomps); getFlux(fineflux, phifFab, fineBCoef, fluxBox, idir, m_refToFiner); Real scale = 1.0; m_levfluxreg.incrementFine(fineflux, scale, ditf(), interv, interv, idir, hiorlo); } } } } CH_STOP(t3); Real scale = 1.0/m_dx; m_levfluxreg.reflux(a_residual, scale); }
void VCAMRPoissonOp2::reflux(const LevelData<FArrayBox>& a_phiFine, const LevelData<FArrayBox>& a_phi, LevelData<FArrayBox>& a_residual, AMRLevelOp<LevelData<FArrayBox> >* a_finerOp) { CH_TIME("VCAMRPoissonOp2::reflux"); int ncomp = 1; ProblemDomain fineDomain = refine(m_domain, m_refToFiner); LevelFluxRegister levfluxreg(a_phiFine.disjointBoxLayout(), a_phi.disjointBoxLayout(), fineDomain, m_refToFiner, ncomp); levfluxreg.setToZero(); Interval interv(0,a_phi.nComp()-1); DataIterator dit = a_phi.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { const FArrayBox& coarfab = a_phi[dit]; const FluxBox& coarBCoef = (*m_bCoef)[dit]; const Box& gridBox = a_phi.getBoxes()[dit]; for (int idir = 0; idir < SpaceDim; idir++) { FArrayBox coarflux; Box faceBox = surroundingNodes(gridBox, idir); getFlux(coarflux, coarfab, coarBCoef , faceBox, idir); Real scale = 1.0; levfluxreg.incrementCoarse(coarflux, scale,dit(), interv,interv,idir); } } LevelData<FArrayBox>& p = ( LevelData<FArrayBox>&)a_phiFine; // has to be its own object because the finer operator // owns an interpolator and we have no way of getting to it VCAMRPoissonOp2* finerAMRPOp = (VCAMRPoissonOp2*) a_finerOp; QuadCFInterp& quadCFI = finerAMRPOp->m_interpWithCoarser; quadCFI.coarseFineInterp(p, a_phi); // p.exchange(a_phiFine.interval()); // BVS is pretty sure this is not necesary. IntVect phiGhost = p.ghostVect(); DataIterator ditf = a_phiFine.dataIterator(); const DisjointBoxLayout& dblFine = a_phiFine.disjointBoxLayout(); for (ditf.reset(); ditf.ok(); ++ditf) { const FArrayBox& phifFab = a_phiFine[ditf]; const FluxBox& fineBCoef = (*(finerAMRPOp->m_bCoef))[ditf]; const Box& gridbox = dblFine.get(ditf()); for (int idir = 0; idir < SpaceDim; idir++) { int normalGhost = phiGhost[idir]; SideIterator sit; for (sit.begin(); sit.ok(); sit.next()) { Side::LoHiSide hiorlo = sit(); Box fabbox; Box facebox; // assumption here that the stencil required // to compute the flux in the normal direction // is 2* the number of ghost cells for phi // (which is a reasonable assumption, and probably // better than just assuming you need one cell on // either side of the interface // (dfm 8-4-06) if (sit() == Side::Lo) { fabbox = adjCellLo(gridbox,idir, 2*normalGhost); fabbox.shift(idir, 1); facebox = bdryLo(gridbox, idir,1); } else { fabbox = adjCellHi(gridbox,idir, 2*normalGhost); fabbox.shift(idir, -1); facebox = bdryHi(gridbox, idir, 1); } // just in case we need ghost cells in the transverse direction // (dfm 8-4-06) for (int otherDir=0; otherDir<SpaceDim; ++otherDir) { if (otherDir != idir) { fabbox.grow(otherDir, phiGhost[otherDir]); } } CH_assert(!fabbox.isEmpty()); FArrayBox phifab(fabbox, a_phi.nComp()); phifab.copy(phifFab); FArrayBox fineflux; getFlux(fineflux, phifab, fineBCoef, facebox, idir, m_refToFiner); Real scale = 1.0; levfluxreg.incrementFine(fineflux, scale, ditf(), interv, interv, idir, hiorlo); } } } Real scale = 1.0/m_dx; levfluxreg.reflux(a_residual, scale); }
void VCAMRPoissonOp2::looseGSRB(LevelData<FArrayBox>& a_phi, const LevelData<FArrayBox>& a_rhs) { CH_TIME("VCAMRPoissonOp2::looseGSRB"); #if 1 MayDay::Abort("VCAMRPoissonOp2::looseGSRB - Not implemented"); #else // This implementation converges at half the rate of "levelGSRB" in // multigrid solves CH_assert(a_phi.isDefined()); CH_assert(a_rhs.isDefined()); CH_assert(a_phi.ghostVect() >= IntVect::Unit); CH_assert(a_phi.nComp() == a_rhs.nComp()); // Recompute the relaxation coefficient if needed. resetLambda(); const DisjointBoxLayout& dbl = a_phi.disjointBoxLayout(); DataIterator dit = a_phi.dataIterator(); // fill in intersection of ghostcells and a_phi's boxes { CH_TIME("VCAMRPoissonOp2::looseGSRB::homogeneousCFInterp"); homogeneousCFInterp(a_phi); } { CH_TIME("VCAMRPoissonOp2::looseGSRB::exchange"); a_phi.exchange(a_phi.interval(), m_exchangeCopier); } // now step through grids... for (dit.begin(); dit.ok(); ++dit) { // invoke physical BC's where necessary { CH_TIME("VCAMRPoissonOp2::looseGSRB::BCs"); m_bc(a_phi[dit], dbl[dit()], m_domain, m_dx, true); } const Box& region = dbl.get(dit()); const FluxBox& thisBCoef = (*m_bCoef)[dit]; int whichPass = 0; #if CH_SPACEDIM == 1 FORT_GSRBHELMHOLTZVC1D #elif CH_SPACEDIM == 2 FORT_GSRBHELMHOLTZVC2D #elif CH_SPACEDIM == 3 FORT_GSRBHELMHOLTZVC3D #else This_will_not_compile! #endif (CHF_FRA(a_phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_BOX(region), CHF_CONST_REAL(m_dx), 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_CONST_FRA(m_lambda[dit]), CHF_CONST_INT(whichPass)); whichPass = 1; #if CH_SPACEDIM == 1 FORT_GSRBHELMHOLTZVC1D #elif CH_SPACEDIM == 2 FORT_GSRBHELMHOLTZVC2D #elif CH_SPACEDIM == 3 FORT_GSRBHELMHOLTZVC3D #else This_will_not_compile! #endif (CHF_FRA(a_phi[dit]), CHF_CONST_FRA(a_rhs[dit]), CHF_BOX(region), CHF_CONST_REAL(m_dx), 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_CONST_FRA(m_lambda[dit]), CHF_CONST_INT(whichPass)); } // end loop through grids #endif }
// --------------------------------------------------------------- // 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 LevelFluxRegisterEdge::refluxCurl(LevelData<FluxBox>& a_uCoarse, Real a_scale) { CH_assert(isDefined()); CH_assert(a_uCoarse.nComp() == m_nComp); SideIterator side; // idir is the normal direction to the coarse-fine interface for (int idir=0 ; idir<SpaceDim; ++idir) { for (side.begin(); side.ok(); ++side) { LevelData<FluxBox>& fineReg = m_fabFine[index(idir, side())]; // first, create temp LevelData<FluxBox> to hold "coarse flux" const DisjointBoxLayout coarseBoxes = m_regCoarse.getBoxes(); // this fills the place of what used to be m_fabCoarse in the old // implementation LevelData<FluxBox> coarReg(coarseBoxes, m_nComp, IntVect::Unit); // now fill the coarReg with the curl of the stored coarse-level // edge-centered flux DataIterator crseDit = coarseBoxes.dataIterator(); for (crseDit.begin(); crseDit.ok(); ++crseDit) { FluxBox& thisCoarReg = coarReg[crseDit]; thisCoarReg.setVal(0.0); EdgeDataBox& thisEdgeData = m_regCoarse[crseDit]; for (int edgeDir=0; edgeDir<SpaceDim; edgeDir++) { if (idir != edgeDir) { FArrayBox& crseEdgeDataDir = thisEdgeData[edgeDir]; for (int faceDir = 0; faceDir<SpaceDim; faceDir++) { if (faceDir != edgeDir) { FArrayBox& faceData = thisCoarReg[faceDir]; int shiftDir = -1; for (int i=0; i<SpaceDim; i++) { if ((i != faceDir) && (i != edgeDir) ) { shiftDir = i; } } CH_assert(shiftDir >= 0); crseEdgeDataDir.shiftHalf(shiftDir, sign(side())); // scaling already taken care of in incrementCrse Real scale = 1.0; faceData.plus(crseEdgeDataDir, scale, 0, 0, faceData.nComp()); crseEdgeDataDir.shiftHalf(shiftDir, -sign(side())); } // end if not normal direction } // end loop over face directions } // end if edgeDir != idir } // end loop over edge directions } // end loop over crse boxes // first, we need to create a temp LevelData<FluxBox> // to make a local copy in the coarse layout space of // the fine register increments LevelData<FluxBox> fineRegLocal(coarReg.getBoxes(), m_nComp, IntVect::Unit); fineReg.copyTo(fineReg.interval(), fineRegLocal, fineRegLocal.interval(), m_crseCopiers[index(idir,side())]); for (DataIterator it = a_uCoarse.dataIterator(); it.ok(); ++it) { // loop over flux components here for (int fluxComp=0; fluxComp < SpaceDim; fluxComp++) { // we don't do anything in the normal direction if (fluxComp != idir) { // fluxDir is the direction of the face-centered flux FArrayBox& U = a_uCoarse[it()][fluxComp]; // set up IntVectSet to avoid double counting of updates Box coarseGridBox = U.box(); // transfer to Cell-centered, then create IVS coarseGridBox.shiftHalf(fluxComp,1); IntVectSet nonUpdatedEdges(coarseGridBox); // remember, we want to take the curl here // also recall that fluxComp is the component // of the face-centered curl (not the edge-centered // vector field that we're refluxing, which is why // the sign may seem like it's the opposite of what // you might expect! Real local_scale = -sign(side())*a_scale; //int testDir = (fluxComp+1)%(SpaceDim); if (((fluxComp+1)%(SpaceDim)) == idir) local_scale *= -1; Vector<IntVectSet>& ivsV = m_refluxLocations[index(idir, side())][it()][fluxComp]; Vector<DataIndex>& indexV = m_coarToCoarMap[index(idir, side())][it()]; IVSIterator iv; for (int i=0; i<ivsV.size(); ++i) { iv.define(ivsV[i]); const FArrayBox& coar = coarReg[indexV[i]][fluxComp]; const FArrayBox& fine = fineRegLocal[indexV[i]][fluxComp]; for (iv.begin(); iv.ok(); ++iv) { IntVect thisIV = iv(); if (nonUpdatedEdges.contains(thisIV)) { for (int comp=0; comp <m_nComp; ++comp) { //Real coarVal = coar(thisIV, comp); //Real fineVal = fine(thisIV, comp); U(thisIV, comp) -= local_scale*(coar(thisIV, comp) +fine(thisIV, comp)); } nonUpdatedEdges -= thisIV; } } } } // end if not normal face } // end loop over fluxbox directions } // end loop over coarse boxes } // end loop over sides } // end loop over directions }