void MCLinOp::prepareForLevel (int level) { if (level == 0) return; MCLinOp::prepareForLevel(level-1); if (h.size() > level) return; // // Assume from here down that this is a new level one coarser than existing // BL_ASSERT(h.size() == level); h.resize(level+1); int i; for (i = 0; i < BL_SPACEDIM; ++i) h[level][i] = h[level-1][i]*2.0; geomarray.resize(level+1); Box curdomain = Box( geomarray[level-1].Domain() ).coarsen(2); geomarray[level].define( curdomain ); // // Add a box to the new coarser level (assign removes old BoxArray) // gbox.resize(level+1); gbox[level] = BoxArray(gbox[level-1]).coarsen(2); // // Add the BndryRegister of relax values to the new coarser level. // BL_ASSERT(undrrelxr.size() == level); undrrelxr.resize(level+1); undrrelxr[level] = new BndryRegister(gbox[level], 1, 0, 0, numcomp); // // Add the BndryRegister to hold tagential derivatives to the new // coarser level. // BL_ASSERT(tangderiv.size() == level); tangderiv.resize(level+1); // // Figure out how many components. // const FabSet& samplefs = (*tangderiv[level-1])[Orientation(0,Orientation::low)]; tangderiv[level] = new BndryRegister(gbox[level],0,1,0,samplefs.nComp()); // // Add an Array of Array of maskvals to the new coarser level // For each orientation, build NULL masks, then use distributed allocation // Initial masks for coarse levels, ignore outside_domain possibility since // we always solve homogeneous equation on coarse levels. // BL_ASSERT(maskvals.size() == level); maskvals.resize(level+1); Array<IntVect> pshifts(27); std::vector< std::pair<int,Box> > isects; // // Use bgb's distribution map for masks. // We note that all orientations of the FabSets have the same distribution. // We'll use the low 0 side as the model. // for (FabSetIter bndryfsi(bgb[Orientation(0,Orientation::low)]); bndryfsi.isValid(); ++bndryfsi) { const int gn = bndryfsi.index(); MaskTuple& msk = maskvals[level][gn]; for (OrientationIter oitr; oitr; ++oitr) { const Orientation face = oitr(); Box bx_k = BoxLib::adjCell(gbox[level][gn], face, 1); // // Extend box in directions orthogonal to face normal. // for (int dir = 0; dir < BL_SPACEDIM; dir++) if (dir != face) bx_k.grow(dir,1); msk[face] = new Mask(bx_k, 1); Mask& curmask = *(msk[face]); curmask.setVal(BndryData::not_covered); gbox[level].intersections(bx_k,isects); for (int ii = 0, N = isects.size(); ii < N; ii++) if (isects[ii].first != gn) curmask.setVal(BndryData::covered, isects[ii].second, 0); // // Now take care of periodic wraparounds. // Geometry& curgeom = geomarray[level]; if (curgeom.isAnyPeriodic() && !curdomain.contains(bx_k)) { curgeom.periodicShift(curdomain, bx_k, pshifts); for (int iiv = 0, M = pshifts.size(); iiv < M; iiv++) { curmask.shift(pshifts[iiv]); gbox[level].intersections(curmask.box(),isects); for (int ii = 0, N = isects.size(); ii < N; ii++) curmask.setVal(BndryData::covered, isects[ii].second, 0); curmask.shift(-pshifts[iiv]); } } } } gbox[level].clear_hash_bin(); }
void LinOp::prepareForLevel (int level) { BL_PROFILE("LinOp::prepareForLevel()"); if (level == 0) return; LinOp::prepareForLevel(level-1); if (h.size() > level) return; // // Assume from here down that this is a new level one coarser than existing // BL_ASSERT(h.size() == level); h.resize(level+1); for (int i = 0; i < BL_SPACEDIM; ++i) { h[level][i] = h[level-1][i]*2.0; } geomarray.resize(level+1); geomarray[level].define(BoxLib::coarsen(geomarray[level-1].Domain(),2)); const Box& curdomain = geomarray[level].Domain(); // // Add a box to the new coarser level (assign removes old BoxArray). // gbox.resize(level+1); gbox[level] = gbox[level-1]; gbox[level].coarsen(2); // // Add the BndryRegister of relax values to the new coarser level. // BL_ASSERT(undrrelxr.size() == level); undrrelxr.resize(level+1); undrrelxr[level] = new BndryRegister(gbox[level], 1, 0, 0, 1); // // Add an Array of Array of maskvals to the new coarser level // For each orientation, build NULL masks, then use distributed allocation // Initial masks for coarse levels, ignore outside_domain possibility since // we always solve homogeneous equation on coarse levels. // BL_ASSERT( maskvals.size() == level); BL_ASSERT(lmaskvals.size() == level); maskvals.resize(level+1); lmaskvals.resize(level+1); Array<IntVect> pshifts(27); std::vector< std::pair<int,Box> > isects; // // Use bgb's distribution map for masks. // We note that all orientations of the FabSets have the same distribution. // We'll use the low 0 side as the model. // maskvals[level].reserve((*bgb)[Orientation(0,Orientation::low)].local_size()); lmaskvals[level].reserve((*bgb)[Orientation(0,Orientation::low)].local_size()); for (FabSetIter bndryfsi((*bgb)[Orientation(0,Orientation::low)]); bndryfsi.isValid(); ++bndryfsi) { const int gn = bndryfsi.index(); MaskTuple& ma = maskvals[level][gn]; MaskTuple& lma = lmaskvals[level][gn]; for (OrientationIter oitr; oitr; ++oitr) { const Orientation face = oitr(); const Box& bx_k = BoxLib::adjCell(gbox[level][gn], face, 1); ma[face] = new Mask(bx_k,1); lma[face] = new Mask(bx_k,1); Mask& curmask = *( ma[face]); Mask& lcurmask = *(lma[face]); curmask.setVal(BndryData::not_covered); lcurmask.setVal(BndryData::not_covered); gbox[level].intersections(bx_k,isects); for (int ii = 0, N = isects.size(); ii < N; ii++) { if (isects[ii].first != gn) { curmask.setVal(BndryData::covered, isects[ii].second, 0); lcurmask.setVal(BndryData::covered, isects[ii].second, 0); } } // // Now take care of periodic wraparounds. // Geometry& curgeom = geomarray[level]; if (curgeom.isAnyPeriodic() && !curdomain.contains(bx_k)) { curgeom.periodicShift(curdomain, bx_k, pshifts); for (int iiv = 0, M = pshifts.size(); iiv < M; iiv++) { curmask.shift(pshifts[iiv]); lcurmask.shift(pshifts[iiv]); BL_ASSERT(curmask.box() == lcurmask.box()); gbox[level].intersections(curmask.box(),isects); for (int ii = 0, N = isects.size(); ii < N; ii++) { curmask.setVal(BndryData::covered, isects[ii].second, 0); lcurmask.setVal(BndryData::covered, isects[ii].second, 0); } curmask.shift(-pshifts[iiv]); lcurmask.shift(-pshifts[iiv]); } } } } gbox[level].clear_hash_bin(); }