示例#1
0
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;
示例#2
0
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;
}
示例#3
0
/** 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);
  }
}
示例#4
0
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;
}
示例#5
0
// ---------------------------------------------------------
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;
}
示例#6
0
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);

}
示例#7
0
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;
}
示例#8
0
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);
}
示例#9
0
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);
    }

}
示例#10
0
// ----------------------------------------------------------
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;
}
示例#11
0
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());
}
示例#12
0
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;
}
示例#13
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;
}
示例#14
0
//////////////////////////////////////////////////////////////////////////////
// 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;
}
示例#15
0
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;
}
示例#16
0
// ---------------------------------------------------------
// 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;
    }
}
示例#17
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);
}
示例#18
0
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));
}
示例#19
0
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;
}
示例#20
0
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());
}
示例#21
0
// -----------------------------------------------------------------------------
// 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));
    }
}
示例#22
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;
}
示例#23
0
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);
}
示例#24
0
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);
}
示例#25
0
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();
    }
}
示例#26
0
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();
    }
}
示例#27
0
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, &param) )
    {
	fprintf(stderr, "\nError: Error parsing input file.\n\n");
	usage(argv[0]);
	return 1;
    }
    print_params(&param);

    if( !initialize(&param) )
	{
	    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( &param );

    return 0;
}
示例#28
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;
}
示例#29
0
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);

    }

}
示例#30
0
void viewLevelNoFine()
   {
     DisjointBoxLayout layoutFineCoarsened;
     coarsen(layoutFineCoarsened);
   }