void EBCompositeCCProjector:: averageFaceToCells(Vector<LevelData<EBCellFAB>* >& a_cellData, const Vector<LevelData<EBFluxFAB>* >& a_faceData) { CH_TIME("EBCompositeCCProjector::averageGradientToCells"); //average the face gradients to cell centers Interval interv(0,0); for (int ilev = 0; ilev < m_numLevels; ilev++) { LevelData<EBFluxFAB>& faceData = (LevelData<EBFluxFAB>&) *a_faceData[ilev]; faceData.exchange(interv); ccpExtrapolateToDomainBoundaries(faceData, m_eblg[ilev].getDBL(), m_eblg[ilev].getEBISL(), m_eblg[ilev].getDomain(), m_dx[ilev]); } for (int ilev = 0; ilev < m_numLevels; ilev++) { ccpAverageFaceToCells(*a_cellData[ilev], *a_faceData[ilev], m_eblg[ilev].getDBL(), m_eblg[ilev].getEBISL(), m_eblg[ilev].getDomain(), m_dx[ilev]); } }
void EBCompositeCCProjector:: averageVelocityToFaces(Vector<LevelData<EBFluxFAB>* >& a_macVeloc, Vector<LevelData<EBCellFAB>* >& a_velocity) { CH_TIME("EBCompositeCCProjector::averageVelocityToFaces"); //interpolate and then send stuff on through to level function // int ncomp = a_velocity[0]->nComp(); Interval interv(0, SpaceDim-1); Vector<LevelData<EBCellFAB> *> amrPhi = m_macProjector->getPhi(); // Real time = 0.; for (int ilev = 0; ilev < m_numLevels; ilev++) { if (ilev > 0) { //so it can be reused quadcfi is a one-variable animal //when we have ebalias, we can accomplish this without copies. //for now, tough luck //use phi for scratch space LevelData<EBCellFAB>& phiCoar = *amrPhi[ilev-1]; LevelData<EBCellFAB>& phiFine = *amrPhi[ilev ]; for (int idir = 0; idir < SpaceDim; idir++) { Interval phiInterv(0, 0); Interval velInterv(idir, idir); a_velocity[ilev-1]->copyTo(velInterv, phiCoar, phiInterv); a_velocity[ilev ]->copyTo(velInterv, phiFine, phiInterv); m_quadCFI[ilev]->interpolate(phiFine, phiCoar, phiInterv); // m_pwlCFI[ilev]->interpolate(phiFine, // phiCoar, // phiCoar, // time, // time, // time, // phiInterv); //on copy back, we need ghost cells, so do the data iterator loop for (DataIterator dit = phiFine.dataIterator(); dit.ok(); ++dit) { Box region = phiFine[dit()].getRegion(); //includes ghost cells (*a_velocity[ilev])[dit()].copy(region, velInterv, region, phiFine[dit()], phiInterv); } EBLevelDataOps::setVal(phiFine, 0.0); EBLevelDataOps::setVal(phiCoar, 0.0); } } a_velocity[ilev]->exchange(interv); ccpAverageVelocityToFaces(*a_macVeloc[ilev], *a_velocity[ilev], m_eblg[ilev].getDBL(), m_eblg[ilev].getEBISL(), m_eblg[ilev].getDomain(), m_dx[ilev], *m_eblg[ilev].getCFIVS()); } }
void getError(LevelData<EBCellFAB>& a_error, const EBISLayout& a_ebisl, const DisjointBoxLayout& a_dbl, const Real& a_dx) { EBCellFactory ebcellfact(a_ebisl); EBFluxFactory ebfluxfact(a_ebisl); a_error.define(a_dbl, 1, IntVect::Zero, ebcellfact); LevelData<EBCellFAB> divFCalc(a_dbl, 1, IntVect::Zero, ebcellfact); LevelData<EBCellFAB> divFExac(a_dbl, 1, IntVect::Zero, ebcellfact); LevelData<EBFluxFAB> faceFlux(a_dbl, 1, IntVect::Zero, ebfluxfact); for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { a_error[dit()].setVal(0.); divFCalc[dit()].setVal(0.); divFExac[dit()].setVal(0.); } setToExactDivFLD(divFExac, a_ebisl, a_dbl, a_dx); setToExactFluxLD(faceFlux, a_ebisl, a_dbl, a_dx); Interval interv(0, 0); faceFlux.exchange(interv); kappaDivergenceLD(divFCalc, faceFlux, a_ebisl, a_dbl, a_dx); for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { EBCellFAB& errorFAB = a_error[dit()]; EBCellFAB& exactFAB = divFExac[dit()]; EBCellFAB& calcuFAB = divFCalc[dit()]; errorFAB += calcuFAB; errorFAB -= exactFAB; } }
void drawline(int i, int cl, int cr, int lintype, int noheight, int shortl) { char *exhr, *exhl, *lnch; int lcount, ln, linpos, oldpos, nodata; lcount=0; exhr=exhl= ""; switch(lintype) { case '-': lcount=1;break; case '=': lcount = pr1403? 1 : 2; break; case SHORTLINE: lcount=1; break; } if (lcount<=0) return; nodata = cr-cl>=ncol || noheight || allh(i); if (!nodata) fprintf(tabout, "\\v'-.5m'"); for(ln=oldpos=0; ln<lcount; ln++) { linpos = 2*ln - lcount +1; if (linpos != oldpos) fprintf(tabout, "\\v'%dp'", linpos-oldpos); oldpos=linpos; if (shortl==0) { tohcol(cl); if (lcount>1) { switch(interv(i,cl)) { case TOP: exhl = ln==0 ? "1p" : "-1p"; break; case BOT: exhl = ln==1 ? "1p" : "-1p"; break; case THRU: exhl = "1p"; break; } if (exhl[0]) fprintf(tabout, "\\h'%s'", exhl); } else if (lcount==1) { switch(interv(i,cl)) { case TOP: case BOT: exhl = "-1p"; break; case THRU: exhl = "1p"; break; } if (exhl[0]) fprintf(tabout, "\\h'%s'", exhl); } if (lcount>1) { switch(interv(i,cr+1)) { case TOP: exhr = ln==0 ? "-1p" : "+1p"; break; case BOT: exhr = ln==1 ? "-1p" : "+1p"; break; case THRU: exhr = "-1p"; break; } } else if (lcount==1) { switch(interv(i,cr+1)) { case TOP: case BOT: exhr = "+1p"; break; case THRU: exhr = "-1p"; break; } } } else fprintf(tabout, "\\h'|\\n(%du'", cl+CLEFT); fprintf(tabout, "\\s\\n(%d",LSIZE); if (linsize) fprintf(tabout, "\\v'-\\n(%dp/6u'", LSIZE); if (shortl) fprintf(tabout, "\\l'|\\n(%du'", cr+CRIGHT); else { lnch = "\\(ul"; if (pr1403) lnch = lintype==2 ? "=" : "\\(ru"; if (cr+1>=ncol) fprintf(tabout, "\\l'|\\n(TWu%s%s'", exhr,lnch); else fprintf(tabout, "\\l'(|\\n(%du+|\\n(%du)/2u%s%s'", cr+CRIGHT, cr+1+CLEFT, exhr, lnch); } if (linsize) fprintf(tabout, "\\v'\\n(%dp/6u'", LSIZE); fprintf(tabout, "\\s0"); } if (oldpos!=0) fprintf(tabout, "\\v'%dp'", -oldpos); if (!nodata) fprintf(tabout, "\\v'+.5m'"); }
int checkIrregFabCopy(const Box& a_domain) { int eekflag = 0; int nvar = 1; Interval interv(0,0); int nghost= 0; IntVect ivgh= IntVect::Zero; Real tolerance = PolyGeom::getTolerance(); const EBIndexSpace* const ebisPtr = Chombo_EBIS::instance(); int numlevels = ebisPtr->numLevels(); Box levelDomain = a_domain; for (int ilev = 0; ilev < numlevels-1; ilev++) { DisjointBoxLayout dblOne, dblTwo; int maxsizeOne = 4; int maxsizeTwo = 2; makeLayout(dblOne, levelDomain, maxsizeOne); makeLayout(dblTwo, levelDomain, maxsizeTwo); EBISLayout ebislOne, ebislTwo; makeEBISL(ebislOne, dblOne, levelDomain, nghost); makeEBISL(ebislTwo, dblTwo, levelDomain, nghost); LayoutData<IntVectSet> ldIVSOne(dblOne); LayoutData<IntVectSet> ldIVSTwo(dblTwo); for (DataIterator dit = dblOne.dataIterator(); dit.ok(); ++dit) ldIVSOne[dit()] = IntVectSet(dblOne.get(dit())); for (DataIterator dit = dblTwo.dataIterator(); dit.ok(); ++dit) ldIVSTwo[dit()] = IntVectSet(dblTwo.get(dit())); BaseIVFactory<Real> factOne(ebislOne, ldIVSOne); BaseIVFactory<Real> factTwo(ebislTwo, ldIVSTwo); LevelData<BaseIVFAB<Real> > dataOne(dblOne, nvar, ivgh, factOne); LevelData<BaseIVFAB<Real> > dataTwo(dblTwo, nvar, ivgh, factTwo); for (DataIterator dit = dblOne.dataIterator(); dit.ok(); ++dit) dataOne[dit()].setVal(1); for (DataIterator dit = dblTwo.dataIterator(); dit.ok(); ++dit) dataTwo[dit()].setVal(2); //copy dataone into datatwo. then all datatwo should hold are ones dataOne.copyTo(interv, dataTwo, interv); Real rightVal = 1.0; for (DataIterator dit = dblTwo.dataIterator(); dit.ok(); ++dit) { const EBISBox& ebisBox = ebislTwo[dit()]; const IntVectSet& ivs = ldIVSTwo[dit()]; const BaseIVFAB<Real>& fab = dataTwo[dit()]; for (VoFIterator vofit(ivs, ebisBox.getEBGraph()); vofit.ok(); ++vofit) { Real thisVal = fab(vofit(), 0); if (Abs(thisVal - rightVal) > tolerance) { eekflag = 3; return eekflag; } } } levelDomain.coarsen(2); } return eekflag; }
void EBCompositeMACProjector:: kappaDivergence(Vector<LevelData<EBCellFAB>* >& a_divu, Vector<LevelData<EBFluxFAB>* >& a_velo, const Vector<LevelData<BaseIVFAB<Real> >* >* a_boundaryVelo) { CH_TIME("EBCompositeMACProjector::kappaDivergence"); for (int ilev = 0; ilev < m_numLevels; ilev++) { EBLevelMACProjector::setCurLevel(ilev); EBFluxFactory fluxfact(m_eblg[ilev].getEBISL()); //need one ghost cell so that exchange is meaningful LevelData<EBFluxFAB> centroidVelocity(m_eblg[ilev].getDBL(), 1, IntVect::Unit, fluxfact); Interval interv(0, 0); LevelData<EBFluxFAB>& velExch = (LevelData<EBFluxFAB>&)(*a_velo[ilev]); velExch.exchange(interv); //interpolate velocity to face centroids EBArith::interpolateFluxToCentroids(centroidVelocity, *a_velo[ilev], m_eblg[ilev].getDBL(), m_eblg[ilev].getEBISL(), m_eblg[ilev].getDomain()); centroidVelocity.exchange(interv); LevelData<BaseIVFAB<Real> >* levelBoundaryVel = NULL; if (a_boundaryVelo != NULL) { levelBoundaryVel = (*a_boundaryVelo)[ilev]; } //compute the divergence igoring other levels macKappaDivergence(*a_divu[ilev], centroidVelocity, m_eblg[ilev].getDBL(), m_eblg[ilev].getEBISL(), m_eblg[ilev].getDomain(), m_dx[ilev], levelBoundaryVel); //use flux registers to correct divergence //at coarse-fine interface with velocity from finer //level if (ilev < (m_numLevels-1)) { Real incrScale = 1.0; m_fluxReg[ilev]->setToZero(); //increment with coarse values for (DataIterator dit = m_eblg[ilev].getDBL().dataIterator();dit.ok(); ++dit) { const EBFluxFAB& veloFlux = (*a_velo[ilev])[dit()]; for (int idir = 0; idir < SpaceDim; idir++) { // This assumes that embedded boundaries and coarse-fine boundaries do not cross. // To remove this assumption use incrementCoarseBoth. m_fluxReg[ilev]->incrementCoarseRegular(veloFlux[idir], incrScale, dit(), interv, idir); } } //increment with fine velocities for (DataIterator dit = m_eblg[ilev+1].getDBL().dataIterator();dit.ok(); ++dit) { const EBFluxFAB& veloFlux = (*a_velo[ilev+1])[dit()]; for (int idir = 0; idir < SpaceDim; idir++) { for (SideIterator sit; sit.ok(); ++sit) { // This assumes that embedded boundaries and coarse-fine boundaries do not cross. // To remove this assumption use incrementFineBoth. m_fluxReg[ilev]->incrementFineRegular(veloFlux[idir], incrScale, dit(), interv, idir, sit()); } } } //reflux Real reflScale = 1.0/m_dx[ilev][0]; m_fluxReg[ilev]->reflux(*a_divu[ilev], interv, reflScale); } } }
int testIFFAB(const DisjointBoxLayout& a_dbl, const EBISLayout & a_ebisl, const Box & a_domain, const Real & a_dx ) { int faceDir = 0; int nFlux = 1; LayoutData<IntVectSet> irregSetsGrown; LevelData< BaseIFFAB<Real> > fluxInterpolant; EBArith::defineFluxInterpolant(fluxInterpolant, irregSetsGrown, a_dbl, a_ebisl, a_domain, nFlux, faceDir); //set source fab to right ans over set only on grids interior cells int ibox = 0; for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()]; srcFab.setVal(-1.0); IntVectSet ivsSmall = irregSetsGrown[dit()]; const Box& grid = a_dbl.get(dit()); ivsSmall &= grid; for (FaceIterator faceit(ivsSmall, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary); faceit.ok(); ++faceit) { srcFab(faceit(), 0) = rightAns(faceit()); } ibox++; } //diagnostics if (g_diagnosticMode) { pout() << " diagnostics for processor " << procID() << endl; for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { const IntVectSet& ivsGrown = irregSetsGrown[dit()]; const Box& grid = a_dbl.get(dit()); pout() << "============" << endl; pout() << " box = " << grid; pout() << ", full ivs = " ; dumpIVS(&ivsGrown); pout() << "============" << endl; for (LayoutIterator lit = a_dbl.layoutIterator(); lit.ok(); ++lit) { const Box& grid2 = a_dbl.get(lit()); IntVectSet ivsIntersect = ivsGrown; ivsIntersect &= grid2; pout() << "intersection with box " << grid2 << " = "; dumpIVS(&ivsIntersect); pout() << "============" << endl; } } } BaseIFFAB<Real>::setVerbose(true); //do the evil exchange Interval interv(0, nFlux-1); fluxInterpolant.exchange(interv); ibox = 0; //check the answer over grown set Real tolerance = 0.001; for (DataIterator dit = a_dbl.dataIterator(); dit.ok(); ++dit) { const BaseIFFAB<Real>& srcFab = fluxInterpolant[dit()]; const IntVectSet& ivsGrown = irregSetsGrown[dit()]; for (FaceIterator faceit(ivsGrown, a_ebisl[dit()].getEBGraph(), faceDir, FaceStop::SurroundingWithBoundary); faceit.ok(); ++faceit) { Real correct = rightAns(faceit()); Real fabAns = srcFab(faceit(), 0); if (Abs(correct - fabAns) > tolerance) { pout() << "iffab test failed at face " << faceit().gridIndex(Side::Lo) << faceit().gridIndex(Side::Hi) << endl; pout() << " right ans = " << correct << endl; pout() << " data holds= " << fabAns << endl; int eekflag = -3; return eekflag; } } ibox++; } return 0; }
int fluxRegTest() { int nref = 2; int eekflag = 0; ParmParse pp; Box domainCoar, domainFine; eekflag = makeGeometry(domainFine); if (eekflag != 0) return eekflag; domainCoar = coarsen(domainFine, nref); DisjointBoxLayout dblFine,dblCoar; eekflag = makeLayouts(dblCoar, dblFine, domainCoar, domainFine); Interval interv(0,0); EBISLayout ebislFine, ebislCoar; int nghost = 3; makeEBISL(ebislFine, dblFine, domainFine, nghost); makeEBISL(ebislCoar, dblCoar, domainCoar, nghost); EBCellFactory factFine(ebislFine); EBCellFactory factCoar(ebislCoar); IntVect ivghost = IntVect::Unit; LevelData<EBCellFAB> fineData(dblFine, 1,ivghost, factFine); LevelData<EBCellFAB> coarData(dblCoar, 1,ivghost, factCoar); LevelData<EBCellFAB> extraDense(dblCoar, 1,ivghost, factCoar); //set data and flux registers to zero for (DataIterator coarIt = coarData.dataIterator(); coarIt.ok(); ++coarIt) coarData[coarIt()].setVal(0.); for (DataIterator fineIt = fineData.dataIterator(); fineIt.ok(); ++fineIt) fineData[fineIt()].setVal(0.); { // pout() << "before constructor" << endl; EBFluxRegister fluxReg(dblFine, dblCoar, ebislFine, ebislCoar, domainCoar, nref, 1, Chombo_EBIS::instance()); // pout() << "after constructor" << endl; fluxReg.setToZero(); // pout() << "after settozero" << endl; //loop through directions Real scale = 1.0; Real fluxVal = 4.77; for (int idir = 0; idir < SpaceDim; idir++) { // pout() << "idir = " << idir << endl; // MPI_Barrier(Chombo_MPI::comm); //increment and decrement //flux registers with equal size fluxes for (DataIterator coarIt = coarData.dataIterator(); coarIt.ok(); ++coarIt) { const Box& boxCoar = dblCoar.get(coarIt()); const EBISBox& ebisBox = ebislCoar[coarIt()]; IntVectSet ivsBC(boxCoar); EBFaceFAB edgeFluxReg(ebisBox, boxCoar, idir, 1); BaseIFFAB<Real> edgeFluxIrr(ivsBC, ebisBox.getEBGraph(), idir, 1); edgeFluxReg.setVal(fluxVal); edgeFluxIrr.setVal(fluxVal); fluxReg.incrementCoarseRegular(edgeFluxReg, scale, coarIt(), interv, idir); // pout() << "after increment coar regular"<< endl; fluxReg.incrementCoarseIrregular(edgeFluxIrr, scale, coarIt(), interv, idir); // pout() << "after increment coar irregular"<< endl; } // pout() << "after increment coar"<< endl; // MPI_Barrier(Chombo_MPI::comm); for (DataIterator fineIt = fineData.dataIterator(); fineIt.ok(); ++fineIt) { const Box& boxFine = dblFine.get(fineIt()); const EBISBox& ebisBox = ebislFine[fineIt()]; IntVectSet ivsBF(boxFine); EBFaceFAB edgeFluxReg(ebisBox, boxFine, idir, 1); BaseIFFAB<Real> edgeFluxIrr(ivsBF, ebisBox.getEBGraph(), idir, 1); edgeFluxReg.setVal(fluxVal); edgeFluxIrr.setVal(fluxVal); for (SideIterator sit; sit.ok(); ++sit) { fluxReg.incrementFineRegular(edgeFluxReg, scale, fineIt(), interv, idir, sit()); fluxReg.incrementFineIrregular(edgeFluxIrr, scale, fineIt(), interv, idir, sit()); } } // pout() << "after increment fine"<< endl; // MPI_Barrier(Chombo_MPI::comm); } //reflux what ought to be zero into zero and the result should be zero //except where the coarse-fine boundary gets crossed by the embedded //boundary. That should get fixed by the extramass thing. fluxReg.reflux(coarData, interv, scale); // pout() << "after reflux"<< endl; for (DataIterator coarIt = coarData.dataIterator(); coarIt.ok(); ++coarIt) extraDense[coarIt()].setVal(0.); // now add extra density to soltuion //in the end the solution should return to zero fluxReg.incrementDensityArray(extraDense, interv, scale); } // pout() << "after fluxreg destruction" << endl; // pout() << "after incementDensityArray"<< endl; for (DataIterator coarIt = coarData.dataIterator(); coarIt.ok(); ++coarIt) coarData[coarIt()] += extraDense[coarIt()]; // MPI_Barrier(Chombo_MPI::comm); // pout() << "after += operation "<< endl; DataIterator datIt = coarData.dataIterator(); for (datIt.reset(); datIt.ok(); ++datIt) { const EBCellFAB& data = coarData[datIt()]; IntVectSet ivsBox(dblCoar.get(datIt())); const EBISBox& ebisBox = ebislCoar[datIt()]; Real rmax = 0.; Real rmin = 0.; for (VoFIterator vofit(ivsBox, ebisBox.getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); rmax = Max(rmax, Abs(data(vof, 0))); rmin = Min(rmax, Abs(data(vof, 0))); #ifdef CH_USE_FLOAT Real tolerance = 1.0e-6; #else Real tolerance = 1.0e-10; #endif if ((rmax > tolerance)||(rmin > tolerance)) { pout() << "EBFluxRegister failed the test at " << " vof = " << vof << endl; pout() << " rmax: " << rmax << ", or" << " rmin: " << rmin << " >" << " tolerance: " << tolerance << ")" << endl; eekflag = 42; return eekflag; } } } // pout() << "about to return "<< endl; return eekflag; }
int fluxRegTest() { #ifdef CH_USE_HDF5 writeLevel(NULL); #endif int retflag = 0; int nref; Vector<Box> fineboxes; Vector<Box> coarboxes; Box domf, domc; //set coarse and fine grid boxes setDefaults(nref, coarboxes, fineboxes, domc, domf); { // first do nonperiodic test Interval interv(0,0); //set up coarse and fine grids DisjointBoxLayout dblFineCell,dblCoarCell; Vector<int> procAssignCoar(coarboxes.size(), 0); Vector<int> procAssignFine(fineboxes.size(), 0); LoadBalance(procAssignCoar, coarboxes); LoadBalance(procAssignFine, fineboxes); dblCoarCell.define(coarboxes, procAssignCoar); dblFineCell.define(fineboxes, procAssignFine); dblCoarCell.close(); dblFineCell.close(); LevelData<FArrayBox> coarData(dblCoarCell, 1); LevelData<FArrayBox> fineData(dblFineCell, 1); DataIterator coarIt = coarData.dataIterator(); DataIterator fineIt = fineData.dataIterator(); LevelFluxRegister fluxReg(dblFineCell, dblCoarCell, domf, nref, 1); //set data and flux registers to zero for (coarIt.reset(); coarIt.ok(); ++coarIt) coarData[coarIt()].setVal(0.); fluxReg.setToZero(); //increment and decrement //flux registers with equal size fluxes Real scale = 1.0; Real fluxVal = 4.77; for (coarIt.reset(); coarIt.ok(); ++coarIt) { const Box& cellBoxCoar = dblCoarCell.get(coarIt()); for (int idir = 0; idir < SpaceDim; idir++) { Box edgeBoxCoar = surroundingNodes(cellBoxCoar, idir); FArrayBox edgeFlux(edgeBoxCoar,1); edgeFlux.setVal(fluxVal); DataIndex dataIndGlo = coarIt(); fluxReg.incrementCoarse(edgeFlux, scale, dataIndGlo, interv, interv, idir); } } for (fineIt.reset(); fineIt.ok(); ++fineIt) { const Box& cellBoxFine = dblFineCell.get(fineIt()); for (int idir = 0; idir < SpaceDim; idir++) { Box edgeBoxFine = surroundingNodes(cellBoxFine, idir); FArrayBox edgeFlux(edgeBoxFine,1); edgeFlux.setVal(fluxVal); SideIterator sit; DataIndex dataIndGlo = fineIt(); for (sit.reset(); sit.ok(); ++sit) { fluxReg.incrementFine(edgeFlux, scale, dataIndGlo, interv, interv, idir, sit()); } } } //reflux what ought to be zero into zero and the result should be zero fluxReg.reflux(coarData, scale); DataIterator datIt = coarData.dataIterator(); for (datIt.reset(); datIt.ok(); ++datIt) { const FArrayBox& data = coarData[datIt()]; Real rmax = Abs(data.max()); Real rmin = Abs(data.min()); if ((rmax > 1.0e-10)||(rmin > 1.0e-10)) { pout() << indent << pgmname << ": fluxRegister failed the nonperiodic conservation test = " << endl; retflag = 1; } } } // end non-periodic test // now do the same thing all over again, this time with a periodic domain { ProblemDomain coarseDomain(domc); ProblemDomain fineDomain(domf); for (int dir=0; dir<SpaceDim; dir++) { coarseDomain.setPeriodic(dir, true); fineDomain.setPeriodic(dir, true); } Interval interv(0,0); //set up coarse and fine grids DisjointBoxLayout dblFineCell,dblCoarCell; Vector<int> procAssignCoar(coarboxes.size(), 0); Vector<int> procAssignFine(fineboxes.size(), 0); LoadBalance(procAssignCoar, coarboxes); LoadBalance(procAssignFine, fineboxes); dblCoarCell.define(coarboxes, procAssignCoar, coarseDomain); dblFineCell.define(fineboxes, procAssignFine, fineDomain); dblCoarCell.close(); dblFineCell.close(); LevelData<FArrayBox> coarData(dblCoarCell, 1); LevelData<FArrayBox> fineData(dblFineCell, 1); DataIterator coarIt = coarData.dataIterator(); DataIterator fineIt = fineData.dataIterator(); LevelFluxRegister fluxReg(dblFineCell, dblCoarCell, fineDomain, nref, 1); //set data and flux registers to zero for (coarIt.reset(); coarIt.ok(); ++coarIt) coarData[coarIt()].setVal(0.); fluxReg.setToZero(); //increment and decrement //flux registers with equal size fluxes Real scale = 1.0; Real fluxVal = 4.77; for (coarIt.reset(); coarIt.ok(); ++coarIt) { const Box& cellBoxCoar = dblCoarCell.get(coarIt()); for (int idir = 0; idir < SpaceDim; idir++) { Box edgeBoxCoar = surroundingNodes(cellBoxCoar, idir); FArrayBox edgeFlux(edgeBoxCoar,1); edgeFlux.setVal(fluxVal); DataIndex dataIndGlo = coarIt(); fluxReg.incrementCoarse(edgeFlux, scale, dataIndGlo, interv, interv, idir); } } for (fineIt.reset(); fineIt.ok(); ++fineIt) { const Box& cellBoxFine = dblFineCell.get(fineIt()); for (int idir = 0; idir < SpaceDim; idir++) { Box edgeBoxFine = surroundingNodes(cellBoxFine, idir); FArrayBox edgeFlux(edgeBoxFine,1); edgeFlux.setVal(fluxVal); SideIterator sit; DataIndex dataIndGlo = fineIt(); for (sit.reset(); sit.ok(); ++sit) { fluxReg.incrementFine(edgeFlux, scale, dataIndGlo, interv, interv, idir, sit()); } } } //reflux what ought to be zero into zero and the result should be zero fluxReg.reflux(coarData, scale); DataIterator datIt = coarData.dataIterator(); for (datIt.reset(); datIt.ok(); ++datIt) { const FArrayBox& data = coarData[datIt()]; Real rmax = Abs(data.max()); Real rmin = Abs(data.min()); if ((rmax > 1.0e-10)||(rmin > 1.0e-10)) { pout() << indent << pgmname << ": fluxRegister failed the periodic conservation test " << endl; retflag += 2; } } } // end periodic test return retflag; }
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); }
// // 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 drawline(int i, int cl, int cr, int lintype, int noheight, int shortl) { const char *exhr, *exhl, *lnch; int lcount, ln, linpos, oldpos, nodata; lcount=0; exhr=exhl= ""; switch(lintype) { case '-': lcount=1;break; case '=': lcount = nflm ? 1 : 2; break; case SHORTLINE: lcount=1; break; } if (lcount<=0) return; nodata = cr-cl>=ncol || noheight || allh(i); if (!nflm) { if (!nodata) fprintf(tabout, "\\v'-.5m'"); if (graphics) fprintf(tabout, "\\v'\\n(#Du'"); } for(ln=oldpos=0; ln<lcount; ln++) { linpos = 2*ln - lcount +1; if (linpos != oldpos) fprintf(tabout, "\\v'%dp'", linpos-oldpos); oldpos=linpos; if (shortl==0) { tohcol(cl); if (lcount>1) { switch(interv(i,cl)) { case TOP: exhl = ln==0 ? "1p" : "-1p"; break; case BOT: exhl = ln==1 ? "1p" : "-1p"; break; case THRU: exhl = "1p"; break; } if (exhl[0]) fprintf(tabout, "\\h'%s'", exhl); } else if (lcount==1) { switch(interv(i,cl)) { case TOP: case BOT: exhl = "-1p"; break; case THRU: exhl = "1p"; break; } if (exhl[0]) fprintf(tabout, "\\h'%s'", exhl); } if (lcount>1) { switch(interv(i,cr+1)) { case TOP: exhr = ln==0 ? "-1p" : "+1p"; break; case BOT: exhr = ln==1 ? "-1p" : "+1p"; break; case THRU: exhr = "-1p"; break; } } else if (lcount==1) { switch(interv(i,cr+1)) { case TOP: case BOT: exhr = "+1p"; break; case THRU: exhr = "-1p"; break; } } } else fprintf(tabout, "\\h'|\\n(%du'", cl+CLEFT); if (!graphics) fprintf(tabout, "\\s\\n(%d",LSIZE); if (linsize) fprintf(tabout, "\\v'-\\n(%dp/6u'", LSIZE); if (shortl) { if (graphics) fprintf(tabout, "\\D'l |\\n(%du 0'", cr+CRIGHT); else fprintf(tabout, "\\l'|\\n(%du%s'", cr+CRIGHT, utf8 ? "\\U'2500'" : /* ─ */ tlp ? "\\-" : ""); } else if (graphics) { if (cr+1>=ncol) fprintf(tabout, "\\D'l |\\n(TWu%s 0'", exhr); else fprintf(tabout, "\\D'l (|\\n(%du+|\\n(%du)/2u%s 0'", cr+CRIGHT, cr+1+CLEFT, exhr); } else { lnch = "\\(ul"; if (utf8) lnch = lintype == '=' ? "\\U'2550'" : /* ═ */ "\\U'2500'" ; /* ─ */ else if (tlp) lnch = lintype == '=' ? "\\&=" : "\\-"; else if (pr1403) lnch = lintype == '=' ? "\\&=" : "\\(ru"; if (cr+1>=ncol) fprintf(tabout, "\\l'|\\n(TWu%s%s'", exhr,lnch); else fprintf(tabout, "\\l'(|\\n(%du+|\\n(%du)/2u%s%s'", cr+CRIGHT, cr+1+CLEFT, exhr, lnch); } if (linsize) fprintf(tabout, "\\v'\\n(%dp/6u'", LSIZE); if (!graphics) fprintf(tabout, "\\s0"); } if (oldpos!=0) fprintf(tabout, "\\v'%dp'", -oldpos); if (graphics) fprintf(tabout, "\\v'-\\n(#Du'"); if (!nodata) fprintf(tabout, "\\v'+.5m'"); if (!shortl && (utf8 || tlp)) { int corred, c, ccr, licr; const char *s; ccr = cr; if (ccr == cl) ccr++; corred = 0; if (ccr == ncol && (boxflg || allflg || dboxflg) && (s = grbe(i, lintype))) { fprintf(tabout, "\n.sp -1\n"); corred = 1; fprintf(tabout, "\\h'|\\n(TWu'"); fprintf(tabout, "%s", s); } licr = ccr; if (licr == ncol) { licr--; if (!(boxflg || allflg || dboxflg)) ccr--; } for(c = cl; c <= licr; c++) { if ((s = glibe(i, c, cl, ccr, lintype))) { if (!corred) { fprintf(tabout, "\n.sp -1\n"); corred = 1; } tohcol(c); fprintf(tabout, "%s", s); } } } }
int getError(LevelData<EBCellFAB>& a_errorFine, const EBISLayout& a_ebislFine, const DisjointBoxLayout& a_gridsFine, const Box& a_domainFine, const RealVect& a_dxFine) { ParmParse pp; int eekflag = 0; int nvar = 1; int nghost = 1; int nref = 2; pp.get("ref_ratio",nref); int maxsize; pp.get("maxboxsize",maxsize); //generate coarse dx, domain Box domainCoar = coarsen(a_domainFine, nref); RealVect dxCoar = nref*a_dxFine; //make the coarse grids completely cover the domain Vector<Box> vbox; domainSplit(domainCoar, vbox, maxsize); Vector<int> procAssign; eekflag = LoadBalance(procAssign,vbox); DisjointBoxLayout gridsCoar(vbox, procAssign); //make coarse ebisl EBISLayout ebislCoar; eekflag = makeEBISL(ebislCoar, gridsCoar, domainCoar, nghost); if (eekflag != 0) return eekflag; // pout() << "getError dom coar = " << domainCoar << endl;; // pout() << "getError grids coar = " << gridsCoar << endl;; // pout() << "getError dom fine = " << a_domainFine << endl;; // pout() << "getError grids fine = " << a_gridsFine << endl;; //create data at both refinemenets EBCellFactory ebcellfactFine(a_ebislFine); EBCellFactory ebcellfactCoar(ebislCoar); LevelData<EBCellFAB> phiFine(a_gridsFine, nvar, IntVect::Unit,ebcellfactFine); LevelData<EBCellFAB> phiCoar(gridsCoar, nvar, IntVect::Unit,ebcellfactCoar); //fill phi fine and phiCExact //put phiFexact into a_errorFine and phiFine //this should make the error at the interior = 0 for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit) { Box grownBox = grow(a_gridsFine.get(dit()), 1); grownBox &= a_domainFine; IntVectSet ivsBox(grownBox); phiFine[dit()].setVal(0.0); a_errorFine[dit()].setVal(0.0); EBCellFAB& phiFineFAB = phiFine[dit()]; EBCellFAB& errFineFAB = a_errorFine[dit()]; phiFineFAB.setCoveredCellVal(0.0,0); for (VoFIterator vofit(ivsBox, a_ebislFine[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real rightAns = exactFunc(vof.gridIndex(), a_dxFine); phiFineFAB(vof, 0) = rightAns; errFineFAB(vof, 0) = rightAns; } } for (DataIterator dit = gridsCoar.dataIterator(); dit.ok(); ++dit) { Box grownBox = grow(gridsCoar.get(dit()), 1); grownBox &= domainCoar; IntVectSet ivsBox(grownBox); EBCellFAB& phiCoarFAB = phiCoar[dit()]; phiCoarFAB.setCoveredCellVal(0.0,0); for (VoFIterator vofit(ivsBox, ebislCoar[dit()].getEBGraph()); vofit.ok(); ++vofit) { const VolIndex& vof = vofit(); Real rightAns = exactFunc(vof.gridIndex(), dxCoar); phiCoarFAB(vof, 0) = rightAns; } } LayoutData<IntVectSet> cfivs; EBArith::defineCFIVS(cfivs, a_gridsFine, a_domainFine); EBQuadCFInterp interpOp(a_gridsFine, gridsCoar, a_ebislFine, ebislCoar, domainCoar, nref, nvar, cfivs, Chombo_EBIS::instance(), true); Interval interv(0,0); interpOp.interpolate(phiFine, phiCoar, interv); //error = phiF - phiFExact for (DataIterator dit = a_gridsFine.dataIterator(); dit.ok(); ++dit) { EBCellFAB& errorFAB = a_errorFine[dit()]; EBCellFAB& phiFineFAB = phiFine[dit()]; errorFAB -= phiFineFAB; } return eekflag; }