void Box::next (IntVect& p) const { BL_ASSERT(contains(p)); p.shift(0,1); #if BL_SPACEDIM==2 if (!(p <= bigend)) { p.setVal(0,smallend[0]); p.shift(1,1); } #elif BL_SPACEDIM==3 if (!(p <= bigend)) { p.setVal(0,smallend[0]); p.shift(1,1); if (!(p <= bigend)) { p.setVal(1,smallend[1]); p.shift(2,1); } } #endif }
void Box::next (IntVect& p, const int* shv) const { BL_ASSERT(contains(p)); #if BL_SPACEDIM==1 p.shift(0,shv[0]); #elif BL_SPACEDIM==2 p.shift(0,shv[0]); if (!(p <= bigend)) { // // Reset 1 coord is on edge, and 2 coord is incremented. // p.setVal(0,smallend[0]); p.shift(1,shv[1]); } #elif BL_SPACEDIM==3 p.shift(0,shv[0]); if (!(p <= bigend)) { // // Reset 1 coord is on edge, and 2 coord is incremented. // p.setVal(0,smallend[0]); p.shift(1,shv[1]); if(!(p <= bigend)) { p.setVal(1,smallend[1]); p.shift(2,shv[2]); } } #endif }
int main(int argc ,char *argv[] ) { #ifdef CH_MPI MPI_Init(&argc, &argv); #endif parseTestOptions(argc, argv); // establish periodic domain -- first multiply periodic in all directions int status = 0; int baseDomainSize = 8; int numGhost = 2; IntVect ghostVect(numGhost*IntVect::Unit); Box baseDomBox(IntVect::Zero, (baseDomainSize-1)*IntVect::Unit); ProblemDomain baseDomain(baseDomBox); // set periodic in all directions for (int dir=0; dir<SpaceDim; dir++) { baseDomain.setPeriodic(dir, true); } // quick check // should be (3^SpaceDim) -1 vectors int numVect =0; if (verbose) pout() << "ShiftIterator shift vectors:" << endl; ShiftIterator sit1 = baseDomain.shiftIterator(); for (sit1.begin(); sit1.ok(); ++sit1) { numVect++; if (verbose) pout() << " " << sit1() << endl; } Real exact = pow(3.0,SpaceDim) -1; Real eps = 0.0001; if ((exact - numVect) > eps) { //fail if (verbose) { pout() << "failed ShiftIterator count test " << endl; } status += 1; } ShiftIterator sit2 = baseDomain.shiftIterator(); { // first try a single box on this level if (verbose) pout() << "Single box test -- " << endl; Vector<Box> levelBoxes(1, baseDomBox); Vector<int> procAssign(1, 0); DisjointBoxLayout levelGrids(levelBoxes,procAssign, baseDomain); LevelData<FArrayBox> tester(levelGrids, 1, ghostVect); Real dx = 1.0/baseDomainSize; initData(tester, dx); // test exchange in this case -- should fill ghost cells with // periodically copied data if (verbose) pout() << " begin exchange..." << endl; Interval comps = tester.interval(); tester.exchange(comps); if (verbose) pout() << " done exchange..." << endl; DataIterator dit = tester.dataIterator(); for (dit.begin(); dit.ok(); ++dit) { FArrayBox& testFab = tester[dit()]; // now check to be sure that this passed for (int dir=0; dir<SpaceDim; dir++) { if (verbose) pout() << "check lo cells in dir " << dir << endl; Box loGhostBox = adjCellLo(baseDomBox, dir, numGhost); BoxIterator loBit(loGhostBox); for (loBit.begin(); loBit.ok(); ++loBit) { const IntVect iv = loBit(); IntVect validLoc = iv; validLoc.shift(dir, baseDomBox.size(dir)); for (int comp=0; comp<tester.nComp(); comp++) { Real validVal = dataVal(validLoc, comp); if (testFab(iv, comp) != validVal) { if (verbose) { pout() << "failed single-box exchange test at " << iv << endl; } status += 10; } } } // end loop over lo ghost cells if (verbose) pout() << "check hi cells in dir " << dir << endl; Box hiGhostBox = adjCellHi(baseDomBox, dir, numGhost); BoxIterator hiBit(hiGhostBox); for (hiBit.begin(); hiBit.ok(); ++hiBit) { const IntVect iv = hiBit(); IntVect validLoc = iv; validLoc.shift(dir, -baseDomBox.size(dir)); for (int comp=0; comp<tester.nComp(); comp++) { Real validVal = dataVal(validLoc, comp); if (testFab(iv, comp) != validVal) { if (verbose) { pout() << "failed single-box exchange test at " << iv << endl; } status += 100; } } } // end loop over hi ghost cells } // end loop over directions } // end loop over boxes if (verbose) pout() << "done single-box test" << endl; } // end single-box test // now try refining things, this time look at 2 boxes baseDomain.refine(2); { if (verbose) pout() << "2-box test..." << endl; const Box domainBox = baseDomain.domainBox(); Vector<Box> levelBoxes1(1, domainBox); Vector<int> procAssign1(1,0); DisjointBoxLayout levelGrids1(levelBoxes1, procAssign1, baseDomain); LevelData<FArrayBox> tester0(levelGrids1, 1, IntVect::Zero); LevelData<FArrayBox> tester1(levelGrids1, 1, ghostVect); Real dx = 1.0/(2.0*baseDomainSize); initData(tester1, dx); initData(tester0, dx); // first test exchange for single box Interval comps = tester1.interval(); Copier ex; ex.exchangeDefine(levelGrids1, ghostVect); pout() << "copier = " << ex << endl; tester1.exchange(comps, ex); // now try multiple boxes Vector<Box> levelBoxes2(3); Vector<int> procAssign2(3); if (SpaceDim == 1) { // do this a little differently in 1d levelBoxes2[0] = Box(IntVect::Zero, 9*IntVect::Unit); levelBoxes2[1] = Box(10*IntVect::Unit, 11*IntVect::Unit); levelBoxes2[2] = Box(14*IntVect::Unit, 15*IntVect::Unit); } else { levelBoxes2[0] = Box(IntVect::Zero, 9*IntVect::Unit); levelBoxes2[1] = Box(IntVect(D_DECL6(7,10,10,10,10,10)), 15*IntVect::Unit); // this box should fail the disjointness test //levelBoxes2[1] = Box(IntVect(D_DECL6(7,10,10,10,10,10)),17*IntVect::Unit); levelBoxes2[2] = Box(IntVect(D_DECL6(11,0,0,0,0,0)), IntVect(D_DECL6(15,7,7,7,7,7))); } int loadbalancestatus = LoadBalance(procAssign2, levelBoxes2); CH_assert (loadbalancestatus == 0); DisjointBoxLayout levelGrids2; levelGrids2.define(levelBoxes2, procAssign2, baseDomain); LevelData<FArrayBox> tester2(levelGrids2, 1, ghostVect); if (verbose) pout() << " begin copyTo test" << endl; tester0.copyTo(comps, tester2, comps); if (verbose) pout() << " done copyTo, now test values" << endl; // check that periodic copies worked OK: DataIterator dit2 = tester2.dataIterator(); for (dit2.begin(); dit2.ok(); ++dit2) { const Box& thisBox = tester2[dit2()].box(); if (!domainBox.contains(thisBox)) { FArrayBox& destFab = tester2[dit2]; for (int dir=0; dir<SpaceDim; dir++) { if (verbose) { pout() << " check lo cells in dir " << dir << endl; } Box loGhost = adjCellLo(domainBox, dir, numGhost); loGhost &= thisBox; if (!loGhost.isEmpty()) { BoxIterator loBit(loGhost); for (loBit.begin(); loBit.ok(); ++loBit) { IntVect iv = loBit(); IntVect srcIV = iv; srcIV.shift(dir, domainBox.size(dir)); for (int comp=0; comp<destFab.nComp(); comp++) { Real validVal = dataVal(srcIV, comp); if (validVal != destFab(iv, comp)) { if (verbose) { pout() << "failed multi-box copy test at " << iv << endl; } status += 1000; } // end if we fail test } // end loop over components } // end loop over ghost cells outside domain } // end if there are lo-end ghost cells if (verbose) { pout() << " check hi cells in dir " << dir << endl; } Box hiGhost = adjCellHi(domainBox, dir, numGhost); hiGhost &= thisBox; if (!hiGhost.isEmpty()) { BoxIterator hiBit(hiGhost); for (hiBit.begin(); hiBit.ok(); ++hiBit) { IntVect iv = hiBit(); IntVect srcIV = iv; srcIV.shift(dir, -domainBox.size(dir)); for (int comp=0; comp<destFab.nComp(); comp++) { Real validVal = dataVal(srcIV, comp); if (validVal != destFab(iv, comp)) { if (verbose) { pout() << "failed multi-box copy test at " << iv << endl; } status += 10000; } // end if we fail test } // end loop over components } // end loop over high-end ghost cells } // end if there are hi-end ghost cells } // end loop over directions } // end if there are ghost cells } // end loop over grids in destination if (verbose) pout() << "done 2-box test" << endl; } // this last test makes no sense in 1D if (SpaceDim > 1) { if (verbose) pout() << "partially-periodic case" << endl; // now test partially periodic case (also coarsen back to original domain) baseDomain.coarsen(2); baseDomain.setPeriodic(0,false); // try similar tests to the second case, only coarsened const Box domainBox = baseDomain.domainBox(); Vector<Box> levelBoxes1(1, domainBox); Vector<int> procAssign1(1,0); DisjointBoxLayout levelGrids1(levelBoxes1, procAssign1, baseDomain); LevelData<FArrayBox> tester0(levelGrids1, 1, IntVect::Zero); LevelData<FArrayBox> tester1(levelGrids1, 1, ghostVect); Real dx = 1.0/(baseDomainSize); initData(tester1, dx); initData(tester0, dx); if (verbose) pout() << " partially-periodic exchange..." << endl; // first test exchange for single box Interval comps = tester1.interval(); tester1.exchange(comps); if (verbose) pout() << " .... done" << endl; if (verbose) pout() << " multi-box partially periodic case" << endl; // now try multiple boxes Vector<Box> levelBoxes2(3); Vector<int> procAssign2(3); levelBoxes2[0] = Box(IntVect::Zero, 4*IntVect::Unit); levelBoxes2[1] = Box(IntVect(D_DECL6(3,5,5,5,5,5)), 7*IntVect::Unit); // this box should fail the disjointness test //levelBoxes2[1] = Box(IntVect(D_DECL6(3,5,5)), 10*IntVect::Unit); levelBoxes2[2] = Box(IntVect(D_DECL6(6,0,0,0,0,0)), IntVect(D_DECL6(7,1,1,1,1,1))); int loadbalancestatus = LoadBalance(procAssign2, levelBoxes2); CH_assert (loadbalancestatus == 0); DisjointBoxLayout levelGrids2(levelBoxes2, procAssign2, baseDomain); LevelData<FArrayBox> tester2(levelGrids2, 1, ghostVect); tester0.copyTo(comps, tester2, comps); if (verbose) pout() << "done partially-periodic case" << endl; // We don't care about the results of these -- just want to see if they compile: if ( argc == 12345 ) { tester0.apply( leveldataApplyFunc ); tester0.apply( LevelDataApplyFunctor(3.14159) ); } } // I'm thinking all pout()'s should be before MPI_Finalize... (ndk) pout() << indent << pgmname << ": " << ( (status == 0) ? "passed all tests" : "failed at least one test,") << endl; #ifdef CH_MPI MPI_Finalize(); #endif return status ; }
// clean out BC from stencil of cell a_iv void PetscCompGridVTO::applyBCs( IntVect a_iv, int a_ilev, const DataIndex &di_dummy, Box a_dombox, StencilTensor &a_sten ) { CH_TIME("PetscCompGridVTO::applyBCs"); Vector<Vector<StencilNode> > new_vals; // StencilTensorValue RefCountedPtr<BCFunction> bc = m_bc.getBCFunction(); CompGridVTOBC *mybc = dynamic_cast<CompGridVTOBC*>(&(*bc)); // count degrees, add to 'corners' Vector<IntVectSet> corners(CH_SPACEDIM); StencilTensor::const_iterator end2 = a_sten.end(); for (StencilTensor::const_iterator it = a_sten.begin(); it != end2; ++it) { const IntVect &jiv = it->first.iv(); if (!a_dombox.contains(jiv) && it->first.level()==a_ilev) // a BC { int degree = CH_SPACEDIM-1; for (int dir=0;dir<CH_SPACEDIM;++dir) { if (jiv[dir] >= a_dombox.smallEnd(dir) && jiv[dir] <= a_dombox.bigEnd(dir)) degree--; } CH_assert(degree>=0); corners[degree] |= jiv; } } // move ghosts starting at with high degree corners and cascade to lower degree for (int ideg=CH_SPACEDIM-1;ideg>=0;ideg--) { // iterate through list for (IVSIterator ivit(corners[ideg]); ivit.ok(); ++ivit) { const IntVect &jiv = ivit(); // get rid of this bc ghost // get layer of ghost Box gbox(IntVect::Zero,IntVect::Zero); gbox.shift(jiv); Box inter = a_dombox & gbox; CH_assert(inter.numPts()==0); int igid = -1; // find which layer of ghost I am do{ igid++; gbox.grow(1); inter = a_dombox & gbox; }while (inter.numPts()==0); if (igid!=0) MayDay::Error("PetscCompGridVTO::applyBCs layer???"); for (int dir=0;dir<CH_SPACEDIM;++dir) { if (jiv[dir] < a_dombox.smallEnd(dir) || jiv[dir] > a_dombox.bigEnd(dir)) { // have a BC, get coefs on demand int iside = 1; // hi int isign = 1; if (jiv[dir] < a_dombox.smallEnd(dir)) isign = -1; if (jiv[dir] < a_dombox.smallEnd(dir)) iside = 0; // lo if (!mybc) MayDay::Error("PetscCompGridVTO::applyBCs: wrong BC!!!!"); new_vals.resize(1); new_vals[0].resize(1); //new_vals[i][j].second.setValue(mybc->getCoef(j,i)); for (int comp=0; comp<SpaceDim; comp++) { new_vals[0][0].second.define(1); if (mybc->m_bcDiri[dir][iside][comp]) new_vals[0][0].second.setValue(comp,comp,-1.); // simple diagonal else new_vals[0][0].second.setValue(comp,comp,1.); } // end loop over components new_vals[0][0].first.setLevel(a_ilev); IndexML kill(jiv,a_ilev); IntVect biv = jiv; biv.shift(dir,-isign*(igid+1)); new_vals[igid][0].first.setIV(biv); if (ideg>0 && !a_dombox.contains(biv)) // this could be a new stencil value for high order BCs { corners[ideg-1] |= biv; // send down to lower list for later removal } else CH_assert(a_dombox.contains(biv)); StencilProject(kill,new_vals[igid],a_sten); int nrm = a_sten.erase(kill); CH_assert(nrm==1); break; } // BC } // spacedim } // ghosts } // degree }