bool ParticleBase::FineToCrse (const ParticleBase& p, int flev, const ParGDBBase* gdb, const Array<IntVect>& fcells, const BoxArray& fvalid, const BoxArray& compfvalid_grown, Array<IntVect>& ccells, Array<Real>& cfracs, Array<int>& which, Array<int>& cgrid, Array<IntVect>& pshifts, std::vector< std::pair<int,Box> >& isects) { BL_ASSERT(gdb != 0); BL_ASSERT(flev > 0); // // We're in AssignDensity(). We want to know whether or not updating // with a particle we'll cross a fine->crse boundary. Note that crossing // a periodic boundary, where the periodic shift lies in our valid region, // is not considered a Fine->Crse crossing. // const int M = fcells.size(); which.resize(M); cgrid.resize(M); ccells.resize(M); cfracs.resize(M); for (int i = 0; i < M; i++) { cgrid[i] = -1; which[i] = 0; } const Box& ibx = BoxLib::grow(gdb->ParticleBoxArray(flev)[p.m_grid],-1); BL_ASSERT(ibx.ok()); if (ibx.contains(p.m_cell)) // // We're strictly contained in our valid box. // We can't cross a fine->crse boundary. // return false; if (!compfvalid_grown.contains(p.m_cell)) // // We're strictly contained in our "valid" region. Note that the valid // region contains any periodically shifted ghost cells that intersect // valid region. // return false; // // Otherwise ... // const Geometry& cgm = gdb->Geom(flev-1); const IntVect& rr = gdb->refRatio(flev-1); const BoxArray& cba = gdb->ParticleBoxArray(flev-1); ParticleBase::CIC_Cells_Fracs(p, cgm.ProbLo(), cgm.CellSize(), cfracs, ccells); bool result = false; for (int i = 0; i < M; i++) { IntVect ccell_refined = ccells[i]*rr; // // We've got to protect against the case when we're at the low // end of the domain because coarsening & refining don't work right // when indices go negative. // for (int dm = 0; dm < BL_SPACEDIM; dm++) ccell_refined[dm] = std::max(ccell_refined[dm], -1); if (!fvalid.contains(ccell_refined)) { result = true; which[i] = 1; Box cbx(ccells[i],ccells[i]); if (!cgm.Domain().contains(ccells[i])) { // // We must be at a periodic boundary. // Find valid box into which we can be periodically shifted. // BL_ASSERT(cgm.isAnyPeriodic()); cgm.periodicShift(cbx, cgm.Domain(), pshifts); BL_ASSERT(pshifts.size() == 1); cbx -= pshifts[0]; ccells[i] -= pshifts[0]; BL_ASSERT(cbx.ok()); BL_ASSERT(cgm.Domain().contains(cbx)); } // // Which grid at the crse level do we need to update? // cba.intersections(cbx,isects,true); BL_ASSERT(!isects.empty()); cgrid[i] = isects[0].first; // The grid ID at crse level that we hit. } } return result; }
bool BoxList::contains (const BoxArray& ba) const { BoxArray tba(*this); return ba.contains(tba); }
bool ParticleBase::CrseToFine (const BoxArray& cfba, const Array<IntVect>& cells, Array<IntVect>& cfshifts, const Geometry& gm, Array<int>& which, Array<IntVect>& pshifts) { // // We're in AssignDensity(). We want to know whether or not updating // with a particle, will we cross a crse->fine boundary of the level // with coarsened fine BoxArray "cfba". "cells" are as calculated from // CIC_Cells_Fracs(). // const int M = cells.size(); which.resize(M); cfshifts.resize(M); for (int i = 0; i < M; i++) which[i] = 0; bool result = false; for (int i = 0; i < M; i++) { if (cfba.contains(cells[i])) { result = true; which[i] = 1; cfshifts[i] = IntVect::TheZeroVector(); } else if (!gm.Domain().contains(cells[i])) { BL_ASSERT(gm.isAnyPeriodic()); // // Can the cell be shifted into cfba? // const Box bx(cells[i],cells[i]); gm.periodicShift(bx, gm.Domain(), pshifts); if (!pshifts.empty()) { BL_ASSERT(pshifts.size() == 1); const Box& dbx = bx - pshifts[0]; BL_ASSERT(dbx.ok()); if (cfba.contains(dbx)) { // // Note that pshifts[0] is from the coarse perspective. // We'll later need to multiply it by ref ratio to use // at the fine level. // result = true; which[i] = 1; cfshifts[i] = pshifts[0]; } } } } return result; }