poisson::poisson(const REGION& input_domain, const P_DOMAIN& input_patches, double input_h, int input_nref, int debug) { // Set up some defaults first. // In my experience, I have never seen a need for a correction // radius greater than 0. I'm leaving it in the code in case it // needs to be turned on later, at which point I will make another // constructor and add a method to set the value. // Also, in my experience, id_border of 10 works just fine. I'll // add hooks later to change it, if necessary. // Both these changes could be a bit painful: you can't change // them after instantiation without completely changing the // grids. Obviously, that's not something you want to do. Hm. c = 0; int id_border = 10; // The value of d is stencil-dependent, and shouldn't be changed // unless the stencil is changed. There shouldn't be a user // option to change this. Change c instead: it will have the same // effect. int d = 2; fine_domain = input_domain; fine_interior = input_patches; fine_h = input_h; nref = input_nref; // Consider choosing a default for this somehow? debug_level = debug; coarse_h = input_h*nref; int border = MAX((c+d)*nref, id_border*(MAX(MAX(fine_domain.extents(0), fine_domain.extents(1)), fine_domain.extents(2))) / (input_patches.size()*100)); int lcm_ref = ((nref - 1)/4 + 1)*4; P_DOMAIN all_fine_domains = nrefine(ncoarsen(grow(fine_interior, border), lcm_ref), lcm_ref); REGION phi_region; POINT low_h, high_h; POINT e1(1, 1, 1); POINT e2(2, 2, 2); for_1(i, input_patches) { phi_region = all_fine_domains(i); low_h = coarsen((phi_region.lower() + input_patches(i).lower()), 2); high_h = (phi_region.upper() + input_patches(i).upper())/e2; low_h = (coarsen(low_h, 2))*2; high_h = (coarsen(high_h - e1, 2) + e1)*2; if (!(grow(phi_region, -1).inside(low_h) && grow(phi_region, -1).inside(high_h))) { all_fine_domains.grow(i, lcm_ref); } } end_for;
void VolumetricProgressiveMesh<PFP>::gotoLevel(unsigned int l) { if(l == m_cur || l > m_splits.size() || l < 0) return ; if(l > m_cur) while(m_cur != l) coarsen() ; else while(m_cur != l) refine() ; // unsigned int i=0; // if(l == m_level || l > m_nodes->size() || l < 0) // return ; // // if(l > m_level) // for(i=m_level ; i<l ; i++) // m_nodes->coarsen(positionsTable); // else // for(i=l ; i<m_level ; i++) // m_nodes->refine(positionsTable); // // m_level = i; }
/** Initializes the DisjointBoxLayouts, each step. */ void EBRestart::makeHierarchy(Vector<DisjointBoxLayout>& a_dbl, const ProblemDomain& a_baseDomain, const IntVectSet& a_baseTags, const Vector<int>& a_refRatios, const InputParams& a_inputs) { a_dbl.resize(a_inputs.nlevs); Real fillRatio = 0.85; BRMeshRefine regridder(a_baseDomain, a_refRatios, fillRatio, a_inputs.blocking_factor, a_inputs.buffer_size, a_inputs.max_size); Vector<Vector<Box> > oldGrids(a_inputs.nlevs,1), newGrids(a_inputs.nlevs); oldGrids[0][0]=a_baseDomain.domainBox(); for ( int l=1; l<a_inputs.nlevs; ++l ) { oldGrids[l][0]=coarsen(oldGrids[l-1][0], a_refRatios[l-1]); // FIXME: is a_refRatios[l-1] correct?? } regridder.regrid(newGrids, a_baseTags, 0, 1, oldGrids); // 0 is baselevel, 1 is toplevel. Vector<int> procs; for (int l=0; l<a_inputs.nlevs; l++) { newGrids[l].sort(); LoadBalance(procs, newGrids[l]); a_dbl[l] = DisjointBoxLayout(newGrids[l], procs); } }
Graph coarsen_heavy_edge(Graph graph) { boost::graph_traits<Graph>::vertices_size_type n_vertices = num_vertices(graph); std::vector<boost::graph_traits<Graph>::vertex_descriptor> match(n_vertices, boost::graph_traits<Graph>::null_vertex()); // TODO: Should not have to initialize vector to null_vertex // TODO: May be able to use iterator_property_map for speedup std::vector<Graph> graphs; graphs.push_back(graph); heavy_edge_matching(graph, &match[0]); /* boost::graph_traits<Graph>::vertex_iterator vi, vi_end; for(boost::tie(vi,vi_end) = vertices(graph); vi != vi_end; ++vi) { if (match[*vi] != 0 && *vi < match[*vi]) { std::cout << "{" << *vi << ", " << match[*vi] << "}" << std::endl; } } */ //std::cout << "TEST!" << std::endl; // Matching done, need to coarsen graphs.push_back(coarsen(graphs[0], match)); //std::cout << "TEST END!" << std::endl; return graph; }
// --------------------------------------------------------- void NodeMGInterp::define(const DisjointBoxLayout& a_grids, int a_numcomps, int a_refRatio, const ProblemDomain& a_domain) { m_refRatio = a_refRatio; m_domain = a_domain; m_grids = a_grids; m_boxRef = Box(IntVect::Zero, (m_refRatio-1)*IntVect::Unit); Box corners(IntVect::Zero, IntVect::Unit); m_weights.define(corners, m_boxRef.numPts()); FORT_NODEINTERPMG_GETWEIGHTS(CHF_CONST_INT(m_refRatio), CHF_BOX(m_boxRef), CHF_FRA(m_weights)); // create the work array DisjointBoxLayout coarsenedGrids; coarsen(coarsenedGrids, a_grids, m_refRatio); m_coarsenedFine.define(coarsenedGrids, a_numcomps); is_defined = true; }
void divergenceTest() { int maxsize; ParmParse pp; pp.get("max_grid_size", maxsize); //make layouts == domain Box domainBoxFine, domainBoxCoar; Real dxFine, dxCoar; sphereGeometry(domainBoxFine, dxFine); domainBoxCoar = coarsen(domainBoxFine, 2); //debug dxFine = 1.0; dxCoar = 2.*dxFine; Vector<Box> boxFine; domainSplit(domainBoxFine, boxFine, maxsize); Vector<int> proc(boxFine.size(), 0); DisjointBoxLayout dblFine(boxFine, proc); DisjointBoxLayout dblCoar; coarsen(dblCoar, dblFine, 2); LevelData<EBCellFAB> errorFine, errorCoar; EBISLayout ebislFine, ebislCoar; const EBIndexSpace* const ebisPtr = Chombo_EBIS::instance(); ebisPtr->fillEBISLayout(ebislFine, dblFine, domainBoxFine, 2); ebisPtr->fillEBISLayout(ebislCoar, dblCoar, domainBoxCoar, 2); getError(errorFine, ebislFine, dblFine, dxFine); getError(errorCoar, ebislCoar, dblCoar, dxCoar); for (DataIterator dit= dblFine.dataIterator(); dit.ok(); ++dit) { const EBCellFAB& errorFineFAB = errorFine[dit()]; const EBCellFAB& errorCoarFAB = errorCoar[dit()]; int i1 = errorFineFAB.getMultiCells().numPts(); int i2 = errorCoarFAB.getMultiCells().numPts(); pout() << i1 << i2 << endl; } compareError(errorFine, ebislFine, dblFine, domainBoxFine, errorCoar, ebislCoar, dblCoar, domainBoxCoar); }
int makeLayout(DisjointBoxLayout& a_dbl, const Box& a_domainFine) { //set up mesh refine object ParmParse pp; int eekflag= 0; int maxsize; pp.get("maxboxsize",maxsize); int bufferSize = 1; int blockFactor = 2; Real fillrat = 0.75; Box domainCoar = coarsen(a_domainFine, 2); Vector<int> refRat(2,2); BRMeshRefine meshRefObj(domainCoar, refRat, fillrat, blockFactor, bufferSize, maxsize); Vector<Vector<Box> > oldMeshes(2); oldMeshes[0] = Vector<Box>(1, domainCoar); oldMeshes[1] = Vector<Box>(1, a_domainFine); //set up coarse tags int nc = domainCoar.size(0); int nmi = nc/2;//16 int nqu = nc/4;//8 int ntf = (nc*3)/4; //24 int nte = (nc*3)/8; //12 int nfe = (nc*5)/8; //20 #if (CH_SPACEDIM ==2) Box boxf1(IntVect(0, nqu), IntVect(nmi-1,ntf-1)); Box boxf2(IntVect(nmi,nte), IntVect(ntf-1,nfe-1)); Box boxf3(IntVect(nqu,0 ), IntVect(nfe-1,nqu-1)); Box boxf4(IntVect(nfe,nqu), IntVect(nc -1,nte-1)); #else Box boxf1(IntVect(0, nqu,nqu), IntVect(nmi-1,ntf-1,ntf-1)); Box boxf2(IntVect(nmi,nte,nte), IntVect(ntf-1,nfe-1,nfe-1)); Box boxf3(IntVect(nqu,0,0 ), IntVect(nfe-1,nqu-1,nqu-1)); Box boxf4(IntVect(nfe,nqu,nqu), IntVect(nc -1,nte-1,nte-1)); #endif IntVectSet tags; tags |= boxf1; tags |= boxf2; tags |= boxf3; tags |= boxf4; int baseLevel = 0; int topLevel = 0; Vector<Vector<Box> > newMeshes; meshRefObj.regrid(newMeshes, tags, baseLevel, topLevel, oldMeshes); const Vector<Box>& vbox = newMeshes[1]; Vector<int> procAssign; eekflag = LoadBalance(procAssign,vbox); if (eekflag != 0) return eekflag; a_dbl.define(vbox, procAssign); return eekflag; }
void NewPoissonOp:: createCoarsened(FArrayBox& a_lhs, const FArrayBox& a_rhs, const int & a_refRat) { int ncomp = a_rhs.nComp(); //fill ebislayout Box coarsenedBox = coarsen(a_rhs.box(), a_refRat); a_lhs.define(coarsenedBox, ncomp); }
EBCFData:: EBCFData(const DisjointBoxLayout& a_gridsFine, const DisjointBoxLayout& a_gridsCoar, const EBISLayout& a_ebislFine, const EBISLayout& a_ebislCoar, const ProblemDomain& a_domainCoar, const int& a_nref, const LayoutData<IntVectSet>& a_cfivs, const EBIndexSpace* const a_ebisPtr, bool a_doEBCFCrossing, bool a_doCornerEdgeIterators) { m_refRat = a_nref; m_gridsFine = a_gridsFine; m_gridsCoar = a_gridsCoar; m_ebislFine = a_ebislFine; m_ebislCoar = a_ebislCoar; m_domainCoar = a_domainCoar; m_domainFine = refine(m_domainCoar, m_refRat); if (m_ebislFine.getMaxCoarseningRatio() < m_refRat) { m_ebislFine.setMaxCoarseningRatio(m_refRat,a_ebisPtr); } //do EB-Crossing-CF interface tricks int nghostEBISL = 4; m_doEBCFCrossing = a_doEBCFCrossing; //might need this stuff for corners m_gridsCoarsenedFine = DisjointBoxLayout(); coarsen(m_gridsCoarsenedFine, m_gridsFine, m_refRat); a_ebisPtr->fillEBISLayout(m_ebislCoarsenedFine, m_gridsCoarsenedFine, m_domainCoar, nghostEBISL); if (m_doEBCFCrossing) { //figure out where we need to do our EB-crossing-tricks (and if we need them at all) m_doEBCFCrossing = getEBCFIVS(a_cfivs); if (m_doEBCFCrossing) { defineLoHiIterators(a_cfivs); } } if (a_doCornerEdgeIterators) { defineEdCoIterators(a_cfivs); } }
// ---------------------------------------------------------- void CoarseAverageEdge::define(const DisjointBoxLayout& a_fineGrids, int a_nComp, int a_nRef) { m_nRef = a_nRef; DisjointBoxLayout coarsened_fine_domain; coarsen(coarsened_fine_domain, a_fineGrids, m_nRef); m_coarsenedFineData.define(coarsened_fine_domain, a_nComp); m_isDefined = true; }
void coarsen(EBLevelGrid& a_eblgCoar, const EBLevelGrid& a_eblgFine, const int& a_ref) { CH_assert(a_eblgFine.coarsenable(a_ref)); DisjointBoxLayout coarsenedFineGrids; coarsen(coarsenedFineGrids, a_eblgFine.getDBL(), a_ref); ProblemDomain domainCoar(a_eblgFine.getDomain()); domainCoar.coarsen(a_ref); a_eblgCoar.define(coarsenedFineGrids,domainCoar,a_eblgFine.getGhost(),a_eblgFine.getEBIS()); }
int MxGeoMultigridPrec::ApplyInverse(const Epetra_MultiVector & b, Epetra_MultiVector & x) const { numApplyInverse++; time_t start, end; time(&start); // Allocate workspace for multigrid cycles int nvec = b.NumVectors(); std::vector<Epetra_MultiVector *> bvecs, xvecs; //std::cout << *(ops_[levels_-1]); //std::cout << x; // x will be modified, so put it in workspace xvecs.push_back(&x); //xvecs.push_back(new Epetra_MultiVector(x)); // always copy b bvecs.push_back(new Epetra_MultiVector(b)); //RemoveConstField(*bvecs[0]); // now allocate the coarse grid stuff, coarsening b all the way down to // initialize the start of a full multigrid cycle for (int i = 1; i < levels; ++i) { bvecs.push_back(new Epetra_MultiVector(ops[i]->RangeMap(), nvec)); //coarseners[i - 1]->Apply(*bvecs[i - 1], *bvecs[i]); //coarsen b coarsen(i, *bvecs[i - 1], *bvecs[i]); //SmoothInterpolation(i, *bvecs[i]); xvecs.push_back(new Epetra_MultiVector(ops[i]->DomainMap(), nvec, true)); //zero-out } // do it! fullVCycle(bvecs, xvecs); // delete coarsegrids' workspace for (int i = 1; i < levels; ++i) { delete bvecs[i]; delete xvecs[i]; } // delete copied b delete bvecs[0]; //x = *xvecs[0]; //delete xvecs[0]; //throw 1; time(&end); totalTime += difftime(end, start); return 0; }
////////////////////////////////////////////////////////////////////////////// // Define the object so that time stepping can begin void TimeInterpolatorRK4::define(/// layout at this level const DisjointBoxLayout& a_thisDisjointBoxLayout, /// layout at next coarser level const DisjointBoxLayout& a_coarserDisjointBoxLayout, /// problem domain on this level const ProblemDomain& a_domain, /// refinement ratio between this level and next coarser level const int& a_refineCoarse, /// number of variables const int& a_numStates, /// layers of ghost cells to be filled in on the coarsened layout at this level const int& a_ghosts) { // Cache data m_refineCoarse = a_refineCoarse; m_coarseDomain = coarsen(a_domain, m_refineCoarse); m_numStates = a_numStates; m_ghosts = a_ghosts; m_ghostVect = m_ghosts * IntVect::Unit; m_numCoeffs = 4; m_coarseLayout = a_coarserDisjointBoxLayout; // petermc, 19 Dec 2008: prevents crash in case of calling define again m_thisCoarsenedLayout = DisjointBoxLayout(); coarsen(m_thisCoarsenedLayout, a_thisDisjointBoxLayout, m_refineCoarse); m_rhsCopy.define(m_thisCoarsenedLayout, m_numStates, m_ghostVect); m_taylorCoeffs.define(m_thisCoarsenedLayout, m_numCoeffs * m_numStates, m_ghostVect); m_diff12.define(m_thisCoarsenedLayout, m_numStates, m_ghostVect); m_copier.define(m_coarseLayout, m_thisCoarsenedLayout, m_coarseDomain, m_ghostVect); // Everything is defined now. m_defined = true; }
////////////////////////////////////////////////////////////////////////////// // Define the object so that time stepping can begin void FourthOrderPatchInterp::define( /// problem domain on this level const ProblemDomain& a_domain, /// refinement ratio between this level and next coarser level const int& a_refineCoarse, /// maximum distance of stencil from domain boundary const int& a_maxStencilDist, /// dimensions that are fixed, not interpolated Interval a_fixedDims) { if (m_defined) { const Box& stencilBox = m_stencils.box(); for (BoxIterator bit(stencilBox); bit.ok(); ++bit) { IntVect offset = bit(); delete m_stencils(offset, 0); } m_defined = false; } m_domain = a_domain; m_refineCoarse = a_refineCoarse; m_maxStencilDist = a_maxStencilDist; m_fixedDims = a_fixedDims; IntVect interpUnit = IntVect::Unit; m_refineVect = m_refineCoarse * IntVect::Unit; for (int dirf = m_fixedDims.begin(); dirf <= m_fixedDims.end(); dirf++) { interpUnit[dirf] = 0; m_refineVect[dirf] = 1; } m_coarseDomain = coarsen(m_domain, m_refineVect); m_degree = 3; Box stencilBox(-m_maxStencilDist*interpUnit, m_maxStencilDist*interpUnit); m_stencils.define(stencilBox, 1); for (BoxIterator bit(stencilBox); bit.ok(); ++bit) { IntVect offset = bit(); m_stencils(offset, 0) = new FourthOrderInterpStencil(offset, m_refineCoarse, m_degree, m_fixedDims); } // Everything is defined now. m_defined = true; }
int checkCoarseAssortment(const Box& a_domain) { int retval = 0; const EBIndexSpace* const ebisPtr = Chombo_EBIS::instance(); CH_assert(ebisPtr->isDefined()); Box fineDomain = a_domain; int numLevels = ebisPtr->numLevels(); for (int ilev = 1; ilev < numLevels; ilev++) { CH_assert(!fineDomain.isEmpty()); Vector<Box> vbox(1, fineDomain); Vector<int> proc(1, 0); DisjointBoxLayout fineDBL(vbox, proc); EBISLayout fineEBISL; int nghost = 4; ebisPtr->fillEBISLayout(fineEBISL, fineDBL, fineDomain, nghost); Box coarDomain = coarsen(fineDomain, 2); DisjointBoxLayout coarDBL; coarsen(coarDBL, fineDBL, 2); EBISLayout coarEBISL; ebisPtr->fillEBISLayout(coarEBISL, coarDBL, coarDomain, nghost); for (DataIterator dit = fineDBL.dataIterator(); dit.ok(); ++dit) { retval = checkEBISBox(coarDBL.get(dit()), coarEBISL[dit()], fineEBISL[dit()]); if (retval != 0) { pout() << "problem in coarsening " << fineDomain << " to " << coarDomain << endl; return retval; } } fineDomain.coarsen(2); } return retval; }
// --------------------------------------------------------- // interpolate from coarse level to fine level void NodeMGInterp::interpToFine(LevelData<NodeFArrayBox>& a_fine, const LevelData<NodeFArrayBox>& a_coarse, bool a_sameGrids) // a_sameGrids default false { CH_assert(is_defined); const int nComp = a_fine.nComp(); CH_assert(a_coarse.nComp() == nComp); // Copy a_coarse to m_coarsenedFine on grids of m_coarsenedFine. // petermc, 15 Nov 2002: // You don't need a Copier for this copyTo, because // the grid layout of the destination, m_coarsenedFine, // will be contained in that of the source, a_coarse. if (! a_sameGrids) { a_coarse.copyTo(a_coarse.interval(), m_coarsenedFine, m_coarsenedFine.interval() ); } for (DataIterator dit = m_grids.dataIterator(); dit.ok(); ++dit) { Box fineBox = m_grids.get(dit()); Box crseBox = coarsen(fineBox, m_refRatio); const FArrayBox& crseFab = (a_sameGrids) ? a_coarse[dit()].getFab() : m_coarsenedFine[dit()].getFab(); FArrayBox& fineFab = a_fine[dit()].getFab(); FORT_NODEINTERPMG(CHF_FRA(fineFab), CHF_CONST_FRA(crseFab), CHF_BOX(crseBox), CHF_CONST_INT(m_refRatio), CHF_BOX(m_boxRef), CHF_FRA(m_weights)); // dummy statement in order to get around gdb bug int dummy_unused = 0; dummy_unused = 0; } }
void EBPoissonOp:: createCoarser(LevelData<EBCellFAB>& a_coar, const LevelData<EBCellFAB>& a_fine, bool a_ghosted) { CH_assert(a_fine.nComp() == 1); const DisjointBoxLayout& dbl = m_eblgCoarMG.getDBL(); ProblemDomain coarDom = coarsen(m_eblg.getDomain(), 2); int nghost = a_fine.ghostVect()[0]; EBISLayout coarEBISL; const EBIndexSpace* const ebisPtr = Chombo_EBIS::instance(); ebisPtr->fillEBISLayout(coarEBISL, dbl, coarDom, nghost); EBCellFactory ebcellfact(coarEBISL); a_coar.define(dbl, 1,a_fine.ghostVect(),ebcellfact); }
void NewPoissonOp::prolongIncrement(FArrayBox& a_phiThisLevel, const FArrayBox& a_correctCoarse) { FArrayBox& phi = a_phiThisLevel; const FArrayBox& coarse = a_correctCoarse; //FArrayBox& c = (FArrayBox&)coarse; Box region = a_phiThisLevel.box(); region.grow(-1); Box cBox = a_correctCoarse.box(); cBox.grow(-1); CH_assert(cBox == coarsen(region, 2)); int r = 2; FORT_PROLONG(CHF_FRA(phi), CHF_CONST_FRA(coarse), CHF_BOX(region), CHF_CONST_INT(r)); }
int makeLayout(DisjointBoxLayout& a_dbl, const Box& a_domainFine) { //set up mesh refine object ParmParse pp; int eekflag= 0; int maxsize; pp.get("maxboxsize",maxsize); int bufferSize = 2; int blockFactor = 8; Real fillrat = 0.7; Box domainCoar = coarsen(a_domainFine, 2); Vector<int> refRat(2,2); BRMeshRefine meshRefObj(domainCoar, refRat, fillrat, blockFactor, bufferSize, maxsize); Vector<Vector<Box> > oldMeshes(2); oldMeshes[0] = Vector<Box>(1, domainCoar); oldMeshes[1] = Vector<Box>(1, a_domainFine); //set up coarse tags int nc = domainCoar.size(0); Box halfBox = domainCoar; halfBox.growHi(0, -nc/2); IntVectSet tags(halfBox); int baseLevel = 0; int topLevel = 0; Vector<Vector<Box> > newMeshes; meshRefObj.regrid(newMeshes, tags, baseLevel, topLevel, oldMeshes); const Vector<Box>& vbox = newMeshes[1]; Vector<int> procAssign; eekflag = LoadBalance(procAssign,vbox); if (eekflag != 0) return eekflag; a_dbl.define(vbox, procAssign); return eekflag; }
void EBCoarsen::define(const EBLevelGrid& a_eblgFine, const EBLevelGrid& a_eblgCoar, const int& a_nref, const int& a_nvar) { CH_TIME("EBCoarsen:define"); CH_assert(a_nref > 0); CH_assert(a_nvar > 0); CH_assert(a_eblgFine.getDBL().coarsenable(a_nref)); CH_assert(a_eblgFine.getEBIS()->isDefined()); CH_assert(a_eblgCoar.getEBIS()->isDefined()); m_cfivsPtr = a_eblgFine.getCFIVS(); m_isDefined = true; m_refRat = a_nref; m_nComp = a_nvar; m_gridsCoar = a_eblgCoar.getDBL(); m_gridsFine = a_eblgFine.getDBL(); m_ebislCoar = a_eblgCoar.getEBISL(); m_ebislFine = a_eblgFine.getEBISL(); m_domainCoar = a_eblgCoar.getDomain(); m_domainFine = a_eblgFine.getDomain(); IntVect ghost = 4*IntVect::Unit; int nghost = 4; m_coarsenedFineGrids = DisjointBoxLayout(); coarsen(m_coarsenedFineGrids, m_gridsFine, m_refRat); a_eblgFine.getEBIS()->fillEBISLayout(m_coarsenedFineEBISL, m_coarsenedFineGrids, m_domainCoar, nghost); m_coarsenedFineEBISL.setMaxRefinementRatio(m_refRat, a_eblgFine.getEBIS()); EBCellFactory ebcellfact(m_coarsenedFineEBISL); m_coarsenedFineData.define(m_coarsenedFineGrids, m_nComp, ghost, ebcellfact); //define the coarsening stencil for irreg vofs and // for coarse vofs next to the cf interface if refRat<4 defineStencil(*a_eblgFine.getCFIVS()); }
// ----------------------------------------------------------------------------- // Adds coarse cell values directly to all overlying fine cells. // ----------------------------------------------------------------------------- void ConstInterpPS::prolongIncrement (LevelData<FArrayBox>& a_phiThisLevel, const LevelData<FArrayBox>& a_correctCoarse) { CH_TIME("ConstInterpPS::prolongIncrement"); // Gather grids, domains, refinement ratios... const DisjointBoxLayout& fineGrids = a_phiThisLevel.getBoxes(); const DisjointBoxLayout& crseGrids = a_correctCoarse.getBoxes(); CH_assert(fineGrids.compatible(crseGrids)); const ProblemDomain& fineDomain = fineGrids.physDomain(); const ProblemDomain& crseDomain = crseGrids.physDomain(); const IntVect mgRefRatio = fineDomain.size() / crseDomain.size(); CH_assert(mgRefRatio.product() > 1); DataIterator dit = fineGrids.dataIterator(); for (dit.reset(); dit.ok(); ++dit) { // Create references for convenience FArrayBox& fineFAB = a_phiThisLevel[dit]; const FArrayBox& crseFAB = a_correctCoarse[dit]; const Box& fineValid = fineGrids[dit]; // To make things easier, we will offset the // coarse and fine data boxes to zero. const IntVect& fiv = fineValid.smallEnd(); const IntVect civ = coarsen(fiv, mgRefRatio); // Correct the fine data FORT_CONSTINTERPPS ( CHF_FRA_SHIFT(fineFAB, fiv), CHF_CONST_FRA_SHIFT(crseFAB, civ), CHF_BOX_SHIFT(fineValid, fiv), CHF_CONST_INTVECT(mgRefRatio)); } }
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; }
static U_CHAR adapt_mesh(MESH *mesh, ADAPT_STAT *adapt) { FUNCNAME("adapt_mesh"); U_CHAR flag = 0; U_CHAR mark_flag; int n_elements, iadmin; clock_t first = clock(); TEST_EXIT(adapt, "no ADAPT_STAT\n"); if (adapt->marking) mark_flag = adapt->marking(mesh, adapt); else mark_flag = marking(mesh, adapt); if ((!adapt->coarsen_allowed)) mark_flag &= MESH_REFINED; /* use refine mark only */ if (adapt->build_before_refine) adapt->build_before_refine(mesh, mark_flag); n_elements = mesh->n_elements; if (mark_flag & MESH_REFINED) flag = refine(mesh); if (flag & MESH_REFINED) { n_elements = mesh->n_elements - n_elements; INFO(adapt->info,8, "%d element%s refined, giving %d element%s\n", n_elements, n_elements > 1 ? "s" : "", mesh->n_elements, mesh->n_elements > 1 ? "s" : ""); for (iadmin = 0; iadmin < mesh->n_dof_admin; iadmin++) INFO(adapt->info,7,"%d DOFs of admin <%s>\n", mesh->dof_admin[iadmin]->used_count, NAME(mesh->dof_admin[iadmin])); } else INFO(adapt->info,8,"no element refined\n"); if (adapt->build_before_coarsen) adapt->build_before_coarsen(mesh, mark_flag); n_elements = mesh->n_elements; if (mark_flag & MESH_COARSENED) flag |= coarsen(mesh); if (flag & MESH_COARSENED) { n_elements -= mesh->n_elements; INFO(adapt->info,8, "%d element%s coarsened, giving %d element%s\n", n_elements, n_elements > 1 ? "s" : "", mesh->n_elements, mesh->n_elements > 1 ? "s" : ""); for (iadmin = 0; iadmin < mesh->n_dof_admin; iadmin++) INFO(adapt->info,7,"%d DOFs of dof_admin <%s>\n", mesh->dof_admin[iadmin]->used_count, NAME(mesh->dof_admin[iadmin])); } else INFO(adapt->info,8,"no element coarsened\n"); if (adapt->build_after_coarsen) adapt->build_after_coarsen(mesh, flag); INFO(adapt->info,6,"adapting mesh and build needed %.5lg seconds\n", TIME_USED(first,clock())); return(flag); }
void coarsen ( /* Coarsen until nvtxs <= vmax, compute and uncoarsen. */ struct vtx_data **graph, /* array of vtx data for graph */ int nvtxs, /* number of vertices in graph */ int nedges, /* number of edges in graph */ int using_vwgts, /* are vertices weights being used? */ int using_ewgts, /* are edge weights being used? */ float *term_wgts[], /* terminal weights */ int igeom, /* dimension for geometric information */ float **coords, /* coordinates for vertices */ double **yvecs, /* eigenvectors returned */ int ndims, /* number of eigenvectors to calculate */ int solver_flag, /* which eigensolver to use */ int vmax, /* largest subgraph to stop coarsening */ double eigtol, /* tolerence in eigen calculation */ int nstep, /* number of coarsenings between RQI steps */ int step, /* current step number */ int give_up /* has coarsening bogged down? */ ) { extern FILE *Output_File; /* output file or null */ extern int DEBUG_COARSEN; /* debug flag for coarsening */ extern int PERTURB; /* was matrix perturbed in Lanczos? */ extern double COARSEN_RATIO_MIN; /* min vtx reduction for coarsening */ extern int COARSEN_VWGTS; /* use vertex weights while coarsening? */ extern int COARSEN_EWGTS; /* use edge weights while coarsening? */ extern double refine_time; /* time for RQI/Symmlq iterative refinement */ struct vtx_data **cgraph; /* array of vtx data for coarsened graph */ struct orthlink *orthlist; /* list of lower evecs to suppress */ struct orthlink *newlink; /* lower evec to suppress */ double *cyvecs[MAXDIMS + 1]; /* eigenvectors for subgraph */ double evals[MAXDIMS + 1]; /* eigenvalues returned */ double goal[MAXSETS]; /* needed for convergence mode = 1 */ double *r1, *r2, *work; /* space needed by symmlq/RQI */ double *v, *w, *x, *y; /* space needed by symmlq/RQI */ double *gvec; /* rhs vector in extended eigenproblem */ double evalest; /* eigenvalue estimate returned by RQI */ double maxdeg; /* maximum weighted degree of a vertex */ float **ccoords; /* coordinates for coarsened graph */ float *cterm_wgts[MAXSETS]; /* coarse graph terminal weights */ float *new_term_wgts[MAXSETS]; /* terminal weights for Bui's method*/ float **real_term_wgts; /* one of the above */ float *twptr; /* loops through term_wgts */ float *twptr_save; /* copy of twptr */ float *ctwptr; /* loops through cterm_wgts */ double *vwsqrt = NULL; /* square root of vertex weights */ double norm, alpha; /* values used for orthogonalization */ double initshift; /* initial shift for RQI */ double total_vwgt; /* sum of all the vertex weights */ double w1, w2; /* weights of two sets */ double sigma; /* norm of rhs in extended eigenproblem */ double term_tot; /* sum of all terminal weights */ int *space; /* room for assignment in Lanczos */ int *morespace; /* room for assignment in Lanczos */ int *v2cv; /* mapping from vertices to coarse vtxs */ int vwgt_max; /* largest vertex weight */ int oldperturb; /* saves PERTURB value */ int cnvtxs; /* number of vertices in coarsened graph */ int cnedges; /* number of edges in coarsened graph */ int nextstep; /* next step in RQI test */ int nsets; /* number of sets being created */ int i, j; /* loop counters */ double time; /* time marker */ double dot(), ch_normalize(), find_maxdeg(), seconds(); struct orthlink *makeorthlnk(); void makevwsqrt(), eigensolve(), coarsen1(), orthogvec(), rqi_ext(); void ch_interpolate(), orthog1(), rqi(), scadd(), free_graph(); if (DEBUG_COARSEN > 0) { printf("<Entering coarsen, step=%d, nvtxs=%d, nedges=%d, vmax=%d>\n", step, nvtxs, nedges, vmax); } nsets = 1 << ndims; /* Is problem small enough to solve? */ if (nvtxs <= vmax || give_up) { if (using_vwgts) { vwsqrt = smalloc((nvtxs + 1) * sizeof(double)); makevwsqrt(vwsqrt, graph, nvtxs); } else vwsqrt = NULL; maxdeg = find_maxdeg(graph, nvtxs, using_ewgts, (float *) NULL); if (using_vwgts) { vwgt_max = 0; total_vwgt = 0; for (i = 1; i <= nvtxs; i++) { if (graph[i]->vwgt > vwgt_max) vwgt_max = graph[i]->vwgt; total_vwgt += graph[i]->vwgt; } } else { vwgt_max = 1; total_vwgt = nvtxs; } for (i = 0; i < nsets; i++) goal[i] = total_vwgt / nsets; space = smalloc((nvtxs + 1) * sizeof(int)); /* If not coarsening ewgts, then need care with term_wgts. */ if (!using_ewgts && term_wgts[1] != NULL && step != 0) { twptr = smalloc((nvtxs + 1) * (nsets - 1) * sizeof(float)); twptr_save = twptr; for (j = 1; j < nsets; j++) { new_term_wgts[j] = twptr; twptr += nvtxs + 1; } for (j = 1; j < nsets; j++) { twptr = term_wgts[j]; ctwptr = new_term_wgts[j]; for (i = 1; i <= nvtxs; i++) { if (twptr[i] > .5) ctwptr[i] = 1; else if (twptr[i] < -.5) ctwptr[i] = -1; else ctwptr[i] = 0; } } real_term_wgts = new_term_wgts; } else { real_term_wgts = term_wgts; new_term_wgts[1] = NULL; } eigensolve(graph, nvtxs, nedges, maxdeg, vwgt_max, vwsqrt, using_vwgts, using_ewgts, real_term_wgts, igeom, coords, yvecs, evals, 0, space, goal, solver_flag, FALSE, 0, ndims, 3, eigtol); if (real_term_wgts != term_wgts && new_term_wgts[1] != NULL) { sfree(real_term_wgts[1]); } sfree(space); if (vwsqrt != NULL) sfree(vwsqrt); return; } /* Otherwise I have to coarsen. */ if (coords != NULL) { ccoords = smalloc(igeom * sizeof(float *)); } else { ccoords = NULL; } coarsen1(graph, nvtxs, nedges, &cgraph, &cnvtxs, &cnedges, &v2cv, igeom, coords, ccoords, using_ewgts); /* If coarsening isn't working very well, give up and partition. */ give_up = FALSE; if (nvtxs * COARSEN_RATIO_MIN < cnvtxs && cnvtxs > vmax ) { printf("WARNING: Coarsening not making enough progress, nvtxs = %d, cnvtxs = %d.\n", nvtxs, cnvtxs); printf(" Recursive coarsening being stopped prematurely.\n"); if (Output_File != NULL) { fprintf(Output_File, "WARNING: Coarsening not making enough progress, nvtxs = %d, cnvtxs = %d.\n", nvtxs, cnvtxs); fprintf(Output_File, " Recursive coarsening being stopped prematurely.\n"); } give_up = TRUE; } /* Create space for subgraph yvecs. */ for (i = 1; i <= ndims; i++) { cyvecs[i] = smalloc((cnvtxs + 1) * sizeof(double)); } /* Make coarse version of terminal weights. */ if (term_wgts[1] != NULL) { twptr = smalloc((cnvtxs + 1) * (nsets - 1) * sizeof(float)); twptr_save = twptr; for (i = (cnvtxs + 1) * (nsets - 1); i ; i--) { *twptr++ = 0; } twptr = twptr_save; for (j = 1; j < nsets; j++) { cterm_wgts[j] = twptr; twptr += cnvtxs + 1; } for (j = 1; j < nsets; j++) { ctwptr = cterm_wgts[j]; twptr = term_wgts[j]; for (i = 1; i < nvtxs; i++){ ctwptr[v2cv[i]] += twptr[i]; } } } else { cterm_wgts[1] = NULL; } /* Now recurse on coarse subgraph. */ nextstep = step + 1; coarsen(cgraph, cnvtxs, cnedges, COARSEN_VWGTS, COARSEN_EWGTS, cterm_wgts, igeom, ccoords, cyvecs, ndims, solver_flag, vmax, eigtol, nstep, nextstep, give_up); ch_interpolate(yvecs, cyvecs, ndims, graph, nvtxs, v2cv, using_ewgts); sfree(cterm_wgts[1]); sfree(v2cv); /* I need to do Rayleigh Quotient Iteration each nstep stages. */ time = seconds(); if (!(step % nstep)) { oldperturb = PERTURB; PERTURB = FALSE; /* Should I do some orthogonalization here against vwsqrt? */ if (using_vwgts) { vwsqrt = smalloc((nvtxs + 1) * sizeof(double)); makevwsqrt(vwsqrt, graph, nvtxs); for (i = 1; i <= ndims; i++) orthogvec(yvecs[i], 1, nvtxs, vwsqrt); } else for (i = 1; i <= ndims; i++) orthog1(yvecs[i], 1, nvtxs); /* Allocate space that will be needed in RQI. */ r1 = smalloc(7 * (nvtxs + 1) * sizeof(double)); r2 = &r1[nvtxs + 1]; v = &r1[2 * (nvtxs + 1)]; w = &r1[3 * (nvtxs + 1)]; x = &r1[4 * (nvtxs + 1)]; y = &r1[5 * (nvtxs + 1)]; work = &r1[6 * (nvtxs + 1)]; if (using_vwgts) { vwgt_max = 0; total_vwgt = 0; for (i = 1; i <= nvtxs; i++) { if (graph[i]->vwgt > vwgt_max) vwgt_max = graph[i]->vwgt; total_vwgt += graph[i]->vwgt; } } else { vwgt_max = 1; total_vwgt = nvtxs; } for (i = 0; i < nsets; i++) goal[i] = total_vwgt / nsets; space = smalloc((nvtxs + 1) * sizeof(int)); morespace = smalloc((nvtxs) * sizeof(int)); initshift = 0; orthlist = NULL; for (i = 1; i < ndims; i++) { ch_normalize(yvecs[i], 1, nvtxs); rqi(graph, yvecs, i, nvtxs, r1, r2, v, w, x, y, work, eigtol, initshift, &evalest, vwsqrt, orthlist, 0, nsets, space, morespace, 3, goal, vwgt_max, ndims); /* Now orthogonalize higher yvecs against this one. */ norm = dot(yvecs[i], 1, nvtxs, yvecs[i]); for (j = i + 1; j <= ndims; j++) { alpha = -dot(yvecs[j], 1, nvtxs, yvecs[i]) / norm; scadd(yvecs[j], 1, nvtxs, alpha, yvecs[i]); } /* Now prepare for next pass through loop. */ initshift = evalest; newlink = makeorthlnk(); newlink->vec = yvecs[i]; newlink->pntr = orthlist; orthlist = newlink; } ch_normalize(yvecs[ndims], 1, nvtxs); if (term_wgts[1] != NULL && ndims == 1) { /* Solve extended eigen problem */ /* If not coarsening ewgts, then need care with term_wgts. */ if (!using_ewgts && term_wgts[1] != NULL && step != 0) { twptr = smalloc((nvtxs + 1) * (nsets - 1) * sizeof(float)); twptr_save = twptr; for (j = 1; j < nsets; j++) { new_term_wgts[j] = twptr; twptr += nvtxs + 1; } for (j = 1; j < nsets; j++) { twptr = term_wgts[j]; ctwptr = new_term_wgts[j]; for (i = 1; i <= nvtxs; i++) { if (twptr[i] > .5) ctwptr[i] = 1; else if (twptr[i] < -.5) ctwptr[i] = -1; else ctwptr[i] = 0; } } real_term_wgts = new_term_wgts; } else { real_term_wgts = term_wgts; new_term_wgts[1] = NULL; } /* Following only works for bisection. */ w1 = goal[0]; w2 = goal[1]; sigma = sqrt(4*w1*w2/(w1+w2)); gvec = smalloc((nvtxs+1)*sizeof(double)); term_tot = sigma; /* Avoids lint warning for now. */ term_tot = 0; for (j=1; j<=nvtxs; j++) term_tot += (real_term_wgts[1])[j]; term_tot /= (w1+w2); if (using_vwgts) { for (j=1; j<=nvtxs; j++) { gvec[j] = (real_term_wgts[1])[j]/graph[j]->vwgt - term_tot; } } else { for (j=1; j<=nvtxs; j++) { gvec[j] = (real_term_wgts[1])[j] - term_tot; } } rqi_ext(); sfree(gvec); if (real_term_wgts != term_wgts && new_term_wgts[1] != NULL) { sfree(new_term_wgts[1]); } } else { rqi(graph, yvecs, ndims, nvtxs, r1, r2, v, w, x, y, work, eigtol, initshift, &evalest, vwsqrt, orthlist, 0, nsets, space, morespace, 3, goal, vwgt_max, ndims); } refine_time += seconds() - time; /* Free the space allocated for RQI. */ sfree(morespace); sfree(space); while (orthlist != NULL) { newlink = orthlist->pntr; sfree(orthlist); orthlist = newlink; } sfree(r1); if (vwsqrt != NULL) sfree(vwsqrt); PERTURB = oldperturb; } if (DEBUG_COARSEN > 0) { printf(" Leaving coarsen, step=%d\n", step); } /* Free the space that was allocated. */ if (ccoords != NULL) { for (i = 0; i < igeom; i++) sfree(ccoords[i]); sfree(ccoords); } for (i = ndims; i > 0; i--) sfree(cyvecs[i]); free_graph(cgraph); }
void CFStencil::define( const ProblemDomain& a_fineDomain, const Box& a_grid, const Vector<Box>& a_periodicVector, int a_refRatio, int a_direction, Side::LoHiSide a_hiorlo) { m_isDefined = true; CH_assert(a_refRatio >= 1); CH_assert(a_direction >= 0); CH_assert(a_direction < SpaceDim); CH_assert((a_hiorlo == Side::Lo) || (a_hiorlo == Side::Hi)); CH_assert(!a_fineDomain.isEmpty()); //set internal vars. most of these are kept around //just to keep the class from having an identity crisis. m_direction = a_direction; m_hiorlo = a_hiorlo; Box finebox = a_grid; //compute intvectset of all points on fine grid that //need to be interpolated //shift direction int hilo = sign(a_hiorlo); //create fine stencil Box edgebox; CH_assert((hilo ==1) || (hilo == -1)); if (hilo == -1) { edgebox = adjCellLo(finebox,m_direction,1); } else { edgebox = adjCellHi(finebox,m_direction,1); } edgebox = a_fineDomain & edgebox; if (edgebox.isEmpty()) return; int w1 = edgebox.smallEnd()[0]; int w2 = edgebox.bigEnd()[0]; m_fineIVS.define(edgebox); // moving window loop in i-direction (bvs) for (int i=0; i<a_periodicVector.size(); ++i) { const Box& b = a_periodicVector[i]; if (b.bigEnd()[0] >= w1) { m_fineIVS -= b; if (b.smallEnd()[0] > w2) { i=a_periodicVector.size(); } } } //ivs where all coarse slopes are defined //== coarsened fine ivs m_coarIVS.define(m_fineIVS); m_coarIVS.coarsen(a_refRatio); // this is a trick to get around the lack of a IntVectSet intersection // operator which works with a ProblemDomain ProblemDomain coardom= coarsen(a_fineDomain, a_refRatio); Box domainIntersectBox = m_coarIVS.minBox(); domainIntersectBox = coardom & domainIntersectBox; m_coarIVS &= domainIntersectBox; m_packedBox = m_fineIVS.minBox(); if (m_fineIVS.numPts() == m_packedBox.numPts()) { m_isPacked = true; } else { m_isPacked = false; m_packedBox = Box(); } }
void CFStencil::define( const ProblemDomain& a_fineDomain, const Box& a_grid, const DisjointBoxLayout& a_fineBoxes, const DisjointBoxLayout& a_coarBoxes, int a_refRatio, int a_direction, Side::LoHiSide a_hiorlo) { m_isDefined = true; CH_assert(a_refRatio >= 1); CH_assert(a_direction >= 0); CH_assert(a_direction < SpaceDim); CH_assert((a_hiorlo == Side::Lo) || (a_hiorlo == Side::Hi)); CH_assert(!a_fineDomain.isEmpty()); //set internal vars. most of these are kept around //just to keep the class from having an identity crisis. m_direction = a_direction; m_hiorlo = a_hiorlo; Box finebox = a_grid; //compute intvectset of all points on fine grid that //need to be interpolated //shift direction int hilo = sign(a_hiorlo); //create fine stencil Box edgebox; CH_assert((hilo ==1) || (hilo == -1)); if (hilo == -1) { edgebox = adjCellLo(finebox,m_direction,1); } else { edgebox = adjCellHi(finebox,m_direction,1); } edgebox = a_fineDomain & edgebox; if (!edgebox.isEmpty()) { Box periodicTestBox(a_fineDomain.domainBox()); if (a_fineDomain.isPeriodic()) { for (int idir=0; idir<SpaceDim; idir++) { if (a_fineDomain.isPeriodic(idir)) { periodicTestBox.grow(idir,-1); } } } m_fineIVS.define(edgebox); LayoutIterator lit = a_fineBoxes.layoutIterator(); for (lit.reset(); lit.ok(); ++lit) { m_fineIVS -= a_fineBoxes[lit()]; // if periodic, also need to subtract periodic images // only do this IF we're periodic _and_ both boxes // adjoin the domain box boundary somewhere if (a_fineDomain.isPeriodic() && !periodicTestBox.contains(edgebox) && !periodicTestBox.contains(a_fineBoxes[lit()])) { ShiftIterator shiftIt = a_fineDomain.shiftIterator(); IntVect shiftMult(a_fineDomain.domainBox().size()); Box shiftedBox(a_fineBoxes[lit()]); for (shiftIt.begin(); shiftIt.ok(); ++shiftIt) { IntVect shiftVect = shiftMult*shiftIt(); shiftedBox.shift(shiftVect); m_fineIVS -= shiftedBox; shiftedBox.shift(-shiftVect); } // end loop over periodic shift directions } // end if periodic } } //ivs where all coarse slopes are defined //== coarsened fine ivs m_coarIVS.define(m_fineIVS); m_coarIVS.coarsen(a_refRatio); // this is a trick to get around the lack of a IntVectSet intersection // operator which works with a ProblemDomain ProblemDomain coardom= coarsen(a_fineDomain, a_refRatio); Box domainIntersectBox = m_coarIVS.minBox(); domainIntersectBox = coardom & domainIntersectBox; m_coarIVS &= domainIntersectBox; m_packedBox = m_fineIVS.minBox(); if (m_fineIVS.numPts() == m_packedBox.numPts()) { m_isPacked = true; } else { m_isPacked = false; m_packedBox = Box(); } }
int main( int argc, char *argv[] ) { unsigned iter; FILE *infile, *resfile; char *resfilename; // algorithmic parameters algoparam_t param; int np; double runtime, flop; double residual=0.0; // check arguments if( argc < 2 ) { usage( argv[0] ); return 1; } // check input file if( !(infile=fopen(argv[1], "r")) ) { fprintf(stderr, "\nError: Cannot open \"%s\" for reading.\n\n", argv[1]); usage(argv[0]); return 1; } // check result file resfilename= (argc>=3) ? argv[2]:"heat.ppm"; if( !(resfile=fopen(resfilename, "w")) ) { fprintf(stderr, "\nError: Cannot open \"%s\" for writing.\n\n", resfilename); usage(argv[0]); return 1; } // check input if( !read_input(infile, ¶m) ) { fprintf(stderr, "\nError: Error parsing input file.\n\n"); usage(argv[0]); return 1; } print_params(¶m); if( !initialize(¶m) ) { fprintf(stderr, "Error in Solver initialization.\n\n"); usage(argv[0]); return 1; } // full size (param.resolution are only the inner points) np = param.resolution + 2; #if _EXTRAE_ Extrae_init(); #endif // starting time runtime = wtime(); iter = 0; while(1) { switch( param.algorithm ) { case 0: // JACOBI residual = relax_jacobi(param.u, param.uhelp, np, np); // Copy uhelp into u copy_mat(param.uhelp, param.u, np, np); break; case 1: // GAUSS residual = relax_gauss(param.u, np, np); break; } iter++; // solution good enough ? if (residual < 0.00005) break; // max. iteration reached ? (no limit with maxiter=0) if (param.maxiter>0 && iter>=param.maxiter) break; } // Flop count after iter iterations flop = iter * 11.0 * param.resolution * param.resolution; // stopping time runtime = wtime() - runtime; #if _EXTRAE_ Extrae_fini(); #endif fprintf(stdout, "Time: %04.3f \n", runtime); fprintf(stdout, "Flops and Flops per second: (%3.3f GFlop => %6.2f MFlop/s)\n", flop/1000000000.0, flop/runtime/1000000); fprintf(stdout, "Convergence to residual=%f: %d iterations\n", residual, iter); // for plot... coarsen( param.u, np, np, param.uvis, param.visres+2, param.visres+2 ); write_image( resfile, param.uvis, param.visres+2, param.visres+2 ); finalize( ¶m ); return 0; }
EBPoissonOp* EBPoissonOpFactory:: MGnewOp(const ProblemDomain& a_domainFine, int a_depth, bool a_homoOnly) { //find out if there is a real starting point here. if (a_domainFine != m_eblg.getDomain()) { MayDay::Error("No corresponding AMRLevel to starting point of MGnewOp"); } //multigrid operator. coarn by two from depth no //coarse or finer to worry about. EBLevelGrid eblgMGLevel; EBLevelGrid eblgCoarMG; RealVect dxMGLevel; RefCountedPtr<EBQuadCFInterp> quadCFIMGLevel; //only defined if on an amr level bool hasCoarMGObjects = false; int icoar = 1; for (int idep = 0; idep < a_depth; idep++) { icoar *= 2; } const ProblemDomain domainFine = m_eblg.getDomain(); ProblemDomain domainBoxMGLevel = coarsen(domainFine, icoar); bool foundMGLevel = false; int numMGLevels = m_eblgVecMG.size(); for (int img = 0; img < numMGLevels; img++) { if (m_eblgVecMG[img].getDomain() == domainBoxMGLevel) { eblgMGLevel = m_eblgVecMG[img]; foundMGLevel = true; hasCoarMGObjects = ((img+1) < (numMGLevels)); if (hasCoarMGObjects) { eblgCoarMG = m_eblgVecMG[img+1]; } break; } } bool coarsenable = foundMGLevel; dxMGLevel = m_dx; dxMGLevel *= Real(icoar); if (!coarsenable) { //not coarsenable. //return null return NULL; } //creates coarse and finer info and bcs and all that EBPoissonOp* op = createOperator(eblgMGLevel, eblgCoarMG, hasCoarMGObjects, dxMGLevel); return op; }
void EBLevelAdvect:: define(const DisjointBoxLayout& a_thisDBL, const DisjointBoxLayout& a_coarDBL, const EBISLayout& a_thisEBISL, const EBISLayout& a_coarEBISL, const ProblemDomain& a_domain, const int& a_nRefine, const RealVect& a_dx, const bool& a_hasCoarser, const bool& a_hasFiner, const EBPatchGodunovFactory* const a_patchGodunov, const EBIndexSpace* const a_eb) { CH_TIME("EBLevelAdvect::define"); CH_assert(a_dx[0] > 0.0); CH_assert(a_nRefine > 0); if (m_isDefined) { for (DataIterator dit = m_ebPatchAdvect.dataIterator(); dit.ok(); ++dit) { if (m_ebPatchAdvect[dit()] != NULL) { delete m_ebPatchAdvect[dit()]; m_ebPatchAdvect[dit()] = NULL; } } } m_isDefined = true; m_thisGrids = a_thisDBL; m_thisEBISL = a_thisEBISL; m_refRatCrse = a_nRefine; m_dx = a_dx; m_domain = a_domain; m_hasCoarser = a_hasCoarser; m_hasFiner = a_hasFiner; if (m_hasCoarser) { m_coarGrids = a_coarDBL; m_coarEBISL = a_coarEBISL; } m_ebPatchAdvect.define(m_thisGrids); m_nVar = 1; for (DataIterator dit = m_ebPatchAdvect.dataIterator(); dit.ok(); ++dit) { EBPatchGodunov* ebPatchGodunov = a_patchGodunov->create(); m_ebPatchAdvect[dit()] = dynamic_cast<EBPatchAdvect*>(ebPatchGodunov); if (m_ebPatchAdvect[dit()] == NULL) { MayDay::Error("problem in casting to patch advection class"); } m_ebPatchAdvect[dit()]->define(m_domain, m_dx); IntVectSet cfivs; //not used here. only used in flux interpolation Real time = 0; //needs to get reset later Real dt = 0; //needs to get reset later m_ebPatchAdvect[dit()]->setValidBox(m_thisGrids[dit()], m_thisEBISL[dit()], cfivs, time, dt); } m_nGhost = 4; if (m_hasCoarser) { CH_TIME("EBLevelAdvect::define::fillPatchDefine"); ProblemDomain domainCrse = coarsen(m_domain, m_refRatCrse); //patcher is defined with the number of conserved vars. m_fillPatch.define(m_thisGrids, m_coarGrids, m_thisEBISL, m_coarEBISL, domainCrse, m_refRatCrse, m_nVar, m_nGhost, a_eb); m_fillPatchVel.define(m_thisGrids, m_coarGrids, m_thisEBISL, m_coarEBISL, domainCrse, m_refRatCrse, SpaceDim, m_nGhost, a_eb); } }
void viewLevelNoFine() { DisjointBoxLayout layoutFineCoarsened; coarsen(layoutFineCoarsened); }