Esempio n. 1
0
void
GameBoard::Draw(const ViewInfo& view,
                sf::RenderTarget& texture,
                bool running) const {

  if (!running) {
    for (int x = 0; x < view.GetHorizontalCells(); ++x) {
      for (int y = 0; y < view.GetVerticalCells(); ++y) {
        sf::RectangleShape shape(sf::Vector2f(view.cellSize, view.cellSize));
        shape.setFillColor(BACKGROUND_COLOUR);
        shape.setOutlineThickness(1);
        shape.setOutlineColor(GRID_COLOUR);
        shape.setPosition(x * view.cellSize, y * view.cellSize);
        texture.draw(shape);
      }
    }
  }

  CellSet liveCells;
  _quadTree.FindPoints(view.viewBox, liveCells);
  for (CellSet::iterator it = liveCells.begin();
       it != liveCells.end(); ++it) {
    // If stopped, don't draw cells that are deleted
    if (!running) {
      CellSet::iterator changesIt = _changedCells.find(*it);
      if (changesIt != _changedCells.end() && !changesIt->isAlive) {
      continue;
      }
    }
    it->Draw(view, texture, CELL_COLOUR);
  }
  if (!running) {
    CellSet changedCells;
    _changeQuadTree.FindPoints(view.viewBox, changedCells);
    for (CellSet::iterator it = changedCells.begin();
         it != changedCells.end(); ++it) {
      it->Draw(view, texture, GRID_COLOUR);
    }

    CellSet patternCells;
    _patternQuadTree.FindPoints(view.viewBox, patternCells);
    for (CellSet::iterator it = patternCells.begin();
         it != patternCells.end(); ++it) {
      it->Draw(view, texture, GRID_COLOUR);
    }
  }

}
Esempio n. 2
0
CellSet connectedNodeSet(const CellFilter& f, const Mesh& mesh)
{
  CellSet cells = f.getCells(mesh);
  int dim = cells.dimension();
  if (dim==0) return cells;


  Array<int> cellLID;

  for (CellIterator i=cells.begin(); i!=cells.end(); i++)
  {
    cellLID.append(*i);
  }

  Array<int> nodes;
  Array<int> fo;

  mesh.getFacetLIDs(dim, cellLID, 0, nodes, fo);

  Set<int> nodeSet;

  for (int i=0; i<nodes.size(); i++)
  {
    nodeSet.put(nodes[i]);
  }
  
  return CellSet(mesh, 0, PointCell, nodeSet);
}
bool CellFilter::isSubsetOf(const CellFilter& other,
  const Mesh& mesh) const
{
  if (isKnownSubsetOf(other)) 
  {
    return true;
  }
  else
  {
    CellSet myCells = getCells(mesh);
    CellSet yourCells = other.getCells(mesh);
    CellSet inter = myCells.setIntersection(yourCells);
    if (inter.begin() == inter.end()) return false;
    CellSet diff = myCells.setDifference(inter);
    return (diff.begin() == diff.end());
  }
}
Esempio n. 4
0
void
GameBoard::MarkAlive(const CellSet& cells,
                     QuadTree& tree) {
  tree.Clear();
  for (CellSet::iterator it = cells.begin();
       it != cells.end(); ++it) {
    tree.Insert(*it);
  } 
}
Esempio n. 5
0
GameBoard::GameBoard(const CellSet& points)
  : _initialCells(points), _liveCells(points),
    _quadTree(BoundingBox(0, 0, ULONG_MAX, ULONG_MAX)),
    _changeQuadTree(BoundingBox(0, 0, ULONG_MAX, ULONG_MAX)),
    _patternQuadTree(BoundingBox(0, 0, ULONG_MAX, ULONG_MAX))
{
  for (CellSet::const_iterator it = points.begin();
       it != points.end(); ++it) {
    _quadTree.Insert(*it);
  } 
}
Esempio n. 6
0
RCP<Array<int> > cellSetToLIDArray(const CellSet& cs)
{
  RCP<Array<int> > cellLID = rcp(new Array<int>());

  for (CellIterator i=cs.begin(); i!=cs.end(); i++)
  {
    cellLID->append(*i);
  }
  
  return cellLID;
}
void AToCDensitySampler::init()
{
  const CellFilter& domain = discSpace_.cellFilters(0);

  elemWeightVec_ = DiscreteFunction::discFunc(elemWeights_)->getVector();

  elemToVecIndexMap_ = rcp(new Array<int>(mesh_.numCells(dim_), -1));

  Array<int>& a = *elemToVecIndexMap_;

  CellSet cells = domain.getCells(mesh_);

  Array<int> cellLID;
  cellLID.reserve(mesh_.numCells(dim_));

  for (CellIterator i=cells.begin(); i!=cells.end(); i++)
    {
      cellLID.append(*i);
    }

  const RCP<DOFMapBase>& dofMap = discSpace_.map();

  Set<int> funcs = makeSet(0);
  Array<Array<int> > dofs;
  Array<int> nNodes;
  dofMap->getDOFsForCellBatch(dim_, cellLID, funcs, dofs, nNodes,0);
  
  const Array<int>& dofs0 = dofs[0];
  for (int c=0; c<cellLID.size(); c++)
    {
      int vecIndex = dofs0[c];
      int lid = cellLID[c];
      a[lid] = vecIndex;
      double vol = volume(mesh_, dim_, lid);
      if (isAxisymmetric_)
        {
          Point xCell = mesh_.centroid(dim_, lid) - origin_;
          double dPerp = ::sqrt(xCell*xCell - (xCell*axis_)*(xCell*axis_));
          vol = vol * dPerp;
        }
      elemWeightVec_[vecIndex] = vol;
    }
}
Esempio n. 8
0
Cell
GameBoard::FindNearest(const Cell& cell) const {
  if (_liveCells.count(cell)) {
    return cell;
  }
  // Select random cell, find all cells in the minimal bounding
  // box such that the random cell is on the edge.
  // Repeat until there is only one cell in the bounding box.
  CellSet candidateSet = _liveCells;
  srand(time(0));
  while (candidateSet.size() > 1) {
    int index = rand() % candidateSet.size();
    CellSet::iterator it = candidateSet.begin();
    for (int i = 0; i < index; ++i) {
      ++it;
      assert(it != candidateSet.end());
    }
    Cell nextCandidate = *it;
    unsigned long boxWidth = (nextCandidate.x > cell.x) ?
                             nextCandidate.x - cell.x :
                             cell.x - nextCandidate.x;
    unsigned long boxHeight = (nextCandidate.y > cell.y) ?
                              nextCandidate.y - cell.y :
                              cell.y - nextCandidate.y;
    unsigned long boxX = cell.x >= (0 + boxWidth) ? cell.x - boxWidth : 0;
    unsigned long boxY = cell.y >= (0 + boxHeight) ? cell.y - boxHeight : 0;

    candidateSet.clear();
    _quadTree.FindPoints(BoundingBox(boxX, boxY,
                                     boxWidth * 2, boxHeight * 2),
                         candidateSet);
  }
  assert(candidateSet.size() == 1);
  return *candidateSet.begin();
  
}
AToCPointLocator::AToCPointLocator(const Mesh& mesh, 
                                   const CellFilter& subdomain,
                                   const std::vector<int>& nx)
  : dim_(mesh.spatialDim()),
    mesh_(mesh),
    nFacets_(mesh.numFacets(dim_, 0, 0)),
    nx_(nx),
    low_(nx.size(), 1.0/ScalarTraits<double>::sfmin()),
    high_(nx.size(), -1.0/ScalarTraits<double>::sfmin()),
    dx_(nx.size()),
    table_(),
    subdomain_(subdomain),
    neighborSet_()
{
  TimeMonitor timer(pointLocatorCtorTimer());
  
  /* allocate the neighbor set table */
  neighborSet_.resize(mesh.numCells(dim_));

  /* first pass to find bounding box */
  CellSet cells = subdomain.getCells(mesh);
  
  for (CellIterator i = cells.begin(); i!= cells.end(); i++)
    {
      int cellLID = *i;
      Array<int> facetLIDs;
      Array<int> facetOri;
      mesh.getFacetArray(dim_, cellLID, 0, facetLIDs, facetOri);
      for (int f=0; f<facetLIDs.size(); f++)
        {
          Point x = mesh.nodePosition(facetLIDs[f]);
          for (int d=0; d<dim_; d++)
            {
              if (x[d] < low_[d]) low_[d] = x[d];
              if (x[d] > high_[d]) high_[d] = x[d];
            }
        }
    }

  /* fudge the bounding box */
  for (int d=0; d<dim_; d++)
    {
      low_[d] -= 0.01 * (high_[d] - low_[d]);
      high_[d] += 0.01 * (high_[d] - low_[d]);
    }

  /* second pass to put cells in lookup table */

  int s = 1;
  for (int d=0; d<dim_; d++) 
    {
      dx_[d] = (high_[d] - low_[d])/nx_[d];
      s *= nx_[d];
    }


  table_ = rcp(new Array<int>(s, -1));


  Array<int> lowIndex;
  Array<int> highIndex;
  for (CellIterator i = cells.begin(); i!= cells.end(); i++)
    {
      int cellLID = *i;
      getGridRange(mesh, dim_, cellLID, lowIndex, highIndex);
      if (dim_==2)
        {
          for (int ix=lowIndex[0]; ix<=highIndex[0]; ix++)
            {
              for (int iy=lowIndex[1]; iy<=highIndex[1]; iy++)
                {
                  int index = nx_[1]*ix + iy;
                  (*table_)[index] = cellLID;
                }
            }
        }
      else
        {
          TEST_FOR_EXCEPT(true);
        }
    }
}
void HomogeneousDOFMap::initMap()
{
  Tabs tab;
  SUNDANCE_MSG1(setupVerb(), tab << "initializing DOF map");
  /* start the DOF count at zero. */
  int nextDOF = 0;

  /* Space in which to keep a list of remote cells needed by each processor
   * for each dimension. The first index is dimension, the second proc, the
   * third cell number. */
  Array<Array<Array<int> > > remoteCells(mesh().spatialDim()+1,
                                         mesh().comm().getNProc());
  
  for (int r=0; r<numCellSets(); r++)
    {
      /* Loop over maximal cells in the order specified by the cell iterator.
       * This might be reordered relative to the mesh. 
       *
       * At each maximal cell, we'll run through the facets and 
       * assign DOFs. That will take somewhat more work, but gives much 
       * better cache locality for the matrix because all the DOFs for
       * each maximal element and its facets are grouped together. */

      CellSet cells = cellSet(r);
      CellIterator iter;
      for (iter=cells.begin(); iter != cells.end(); iter++)
        {
          /* first assign any DOFs associated with the maximal cell */
          int cellLID = *iter;
          int owner;
      
          if (nNodesPerCell_[dim_] > 0)
            {
              /* if the maximal cell is owned by another processor,
               * put it in the list of cells for which we need to request 
               * DOF information from another processor */
              if (isRemote(dim_, cellLID, owner))
                {
                  int dummy=0;
                  int cellGID = mesh().mapLIDToGID(dim_, cellLID);
                  remoteCells[dim_][owner].append(cellGID); 
                  setDOFs(dim_, cellLID, dummy);
                }
              else /* the cell is locally owned, so we can 
                    * set its DOF numbers now */
                {
                  setDOFs(dim_, cellLID, nextDOF);
                }
            }

          /* Now assign any DOFs associated with the facets. */
          /* We can skip this step if the basis is discontinuous at element
           * boundaries, because the facets will own no nodes */
          if (basisIsContinuous_)
            {
              for (int d=0; d<dim_; d++)
                {
                  if (nNodesPerCell_[d] > 0)
                    {
                      int nf = numFacets_[dim_][d];
                      Array<int> facetLID(nf);
                      Array<int> facetOrientations(nf);
                      /* look up the LIDs of the facets */
                      mesh().getFacetArray(dim_, cellLID, d, 
                                           facetLID, facetOrientations);
                      /* for each facet, process its DOFs */
                      for (int f=0; f<nf; f++)
                        {
                          /* if the facet's DOFs have been assigned already,
                           * we're done */
                          if (!hasBeenAssigned(d, facetLID[f]))
                            {
                              /* the facet may be owned by another processor */
                              if (isRemote(d, facetLID[f], owner))
                                {
                                  int dummy=0;
                                  int facetGID = mesh().mapLIDToGID(d, facetLID[f]);
                                  remoteCells[d][owner].append(facetGID);
                                  setDOFs(d, facetLID[f], dummy);
                                }
                              else /* we can assign a DOF locally */
                                {
                                  /* assign DOF */
                                  setDOFs(d, facetLID[f], nextDOF);
                                  /* record the orientation wrt the maximal cell */
                                  if (d > 0) 
                                    {
                                      originalFacetOrientation_[d-1][facetLID[f]] 
                                        = facetOrientations[f];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
  /* Done with first pass, in which we have assigned DOFs for all
   * local processors. We now have to share DOF information between
   * processors */

  if (mesh().comm().getNProc() > 1)
    {
      for (int d=0; d<=dim_; d++)
        {
          if (nNodesPerCell_[d] > 0)
            {
              computeOffsets(d, nextDOF);
              shareDOFs(d, remoteCells[d]);
            }
        }
    }
  else
    {
      setLowestLocalDOF(0);
      setNumLocalDOFs(nextDOF);
      setTotalNumDOFs(nextDOF);
    }
  SUNDANCE_MSG1(setupVerb(), tab << "done initializing DOF map");
}
SubmaximalNodalDOFMap
::SubmaximalNodalDOFMap(const Mesh& mesh, 
  const CellFilter& cf,
  int nFuncs,
  int setupVerb)
  : DOFMapBase(mesh, setupVerb),
    dim_(0),
    nTotalFuncs_(nFuncs),
    domain_(cf),
    domains_(tuple(cf)),
    nodeLIDs_(),
    nodeDOFs_(),
    lidToPtrMap_(),
    mapStructure_()
{
  Tabs tab0(0);
  SUNDANCE_MSG1(setupVerb, tab0 << "in SubmaximalNodalDOFMap ctor");
  Tabs tab1;
  SUNDANCE_MSG2(setupVerb, tab1 << "domain " << domain_);
  SUNDANCE_MSG2(setupVerb, tab1 << "N funcs " << nFuncs);

  const MPIComm& comm = mesh.comm();
  int rank = comm.getRank();
  int nProc = comm.getNProc();
  
  dim_ = cf.dimension(mesh);  
  TEUCHOS_TEST_FOR_EXCEPT(dim_ != 0);

  CellSet nodes = cf.getCells(mesh);
  int nc = nodes.numCells();
  nodeLIDs_.reserve(nc);
  nodeDOFs_.reserve(nc);

  Array<Array<int> > remoteNodes(nProc);
  
  int nextDOF = 0;
  int k=0; 
  for (CellIterator c=nodes.begin(); c!=nodes.end(); c++, k++)
  {
    int nodeLID = *c;
    lidToPtrMap_.put(nodeLID, k);
    nodeLIDs_.append(nodeLID);
    int remoteOwner = rank;
    if (isRemote(0, nodeLID, remoteOwner))
    {
      int GID = mesh.mapLIDToGID(0, nodeLID);
      remoteNodes[remoteOwner].append(GID);
      for (int f=0; f<nFuncs; f++) nodeDOFs_.append(-1);
    }
    else
    {
      for (int f=0; f<nFuncs; f++) nodeDOFs_.append(nextDOF++);
    }
  }

  /* Compute offsets for each processor */
  int localCount = nextDOF;
  computeOffsets(localCount);
  
  /* Resolve remote DOF numbers */
  shareRemoteDOFs(remoteNodes);

  BasisFamily basis = new Lagrange(1);
  mapStructure_ = rcp(new MapStructure(nTotalFuncs_, basis.ptr()));
}
Esempio n. 12
0
void NodalDOFMapHN::init()
{ 
  Tabs tab;

  SUNDANCE_MSG2(setupVerb(), tab << "NodalDOFMapHN initializing nodal DOF map nrFunc:"
		  << nFuncs_ << "  nNodes_:" << nNodes_ << " nElems_:" <<nElems_);

  Array<Array<int> > remoteNodes(mesh().comm().getNProc());
  Array<int> hasProcessedCell(nNodes_, 0);

  /* start the DOF count at zero. */
  int nextDOF = 0;
  int owner;

  nFacets_ = mesh().numFacets(dim_, 0, 0);
  Array<int> elemLID(nElems_);
  Array<int> facetOrientations(nFacets_*nElems_);

  /* Assign node DOFs for locally owned 0-cells */
  CellSet maxCells = maxCellFilter_.getCells(mesh());

  int cc = 0;
  for (CellIterator iter=maxCells.begin(); iter != maxCells.end(); iter++, cc++)
    {
      int c = *iter;
      elemLID[cc] = c;
    }
  /* look up the LIDs of the facets (points)*/
  /* This is important so that we have locality in the DOF numbering */
  mesh().getFacetLIDs(dim_, elemLID, 0, facetLID_, facetOrientations);
  
  for (int c=0; c<nElems_; c++) {
	  hasCellHanging_[c] = false;
      /* for each facet, process its DOFs */
      for (int f=0; f<nFacets_; f++) {
          /* if the facet's DOFs have been assigned already,
           * we're done */
          int fLID = facetLID_[c*nFacets_+f];
          SUNDANCE_MSG2(setupVerb(), "NodalDOFMapHN::init() CellLID:"<< c <<"Try point LID:" << fLID << " facet:" << f);
          if (hasProcessedCell[fLID] == 0) {
              /* the facet may be owned by another processor */
        	  /* Do this only when that node is not HANGING! */
              if ( isRemote(0, fLID, owner) && (!mesh().isElementHangingNode(0,fLID)) ) {
                  int facetGID 
                    = mesh().mapLIDToGID(0, fLID);
                  remoteNodes[owner].append(facetGID);
                }
              else {/* we can assign a DOF locally */
            	    SUNDANCE_MSG2(setupVerb(), "NodalDOFMapHN::init() Doing point LID:" << fLID << " facet:" << f);
                    // test if the node is not a hanging node
                    if ( mesh().isElementHangingNode(0,fLID) == false ){
                       /* assign DOFs , (for each function space) */
                       for (int i=0; i<nFuncs_; i++){
                          nodeDofs_[fLID*nFuncs_ + i] = nextDOF;
                          nextDOF++;
                       }
                    } else {
                       SUNDANCE_MSG2(setupVerb(), "NodalDOFMapHN::init() Hanging node found LID:" << fLID);
                  	   hasCellHanging_[c] = true;
                       for (int i=0; i<nFuncs_; i++){
                	       nodeDofs_[fLID*nFuncs_ + i] = -1; // this means that this is not golbal DoF
                       }
                       Array<int> pointsLIDs;
                       Array<int> facetIndex;
                       Array<double> coefs;
                       // get the global DoFs which contribute (what if that is not yet numbered?, then only the "fLIDs")
                       getPointLIDsForHN( fLID, f, c , pointsLIDs, coefs , facetIndex);

                	   // also store the corresponding coefficients
                       hangingNodeLID_to_NodesLIDs_.put( fLID , pointsLIDs );
                       hangindNodeLID_to_Coefs_.put(fLID,coefs);
                    }
                }
              hasProcessedCell[fLID] = 1;
            }
            // if this node is hanging then mark the cell as hanging
            if (mesh().isElementHangingNode(0,fLID) == true) {
        	          hasCellHanging_[c] = true;
            }
       }
  }
  
  //SUNDANCE_MSG2(setupVerb(), "Before Communication: " << nodeDofs_);

  /* Compute offsets for each processor */
  int localCount = nextDOF;
  computeOffsets(localCount);
  
  /* Resolve remote DOF numbers */
  shareRemoteDOFs(remoteNodes);

  //SUNDANCE_MSG2(setupVerb(), "After Communication: " << nodeDofs_);

  /* Assign DOFs for elements */
  for (int c=0; c<nElems_; c++)
    {
	    if (hasCellHanging_[c]){
	    	Array<int> HNDoFs(nFacets_);
	    	Array<double> transMatrix;
	    	Array<double> coefs;

	    	transMatrix.resize(nFacets_*nFacets_);
	    	for (int ii = 0 ; ii < nFacets_*nFacets_ ; ii++) transMatrix[ii] = 0.0;

	    	for (int f=0; f<nFacets_; f++)
	    	{
	  		  int fLID = facetLID_[c*nFacets_+f];
	  		SUNDANCE_MSG2(setupVerb(), tab << "NodalDOFMapHN cell:" << c << " facetLID:" << fLID
	  				  << " hanging:"<< nodeDofs_[fLID*nFuncs_] << "  array:" << HNDoFs);
              if (nodeDofs_[fLID*nFuncs_] < 0)
              {
                  Array<int> pointsLIDs;
                  Array<int> facetIndex;
                  Array<double> coefs;
                  // get the composing points
                  getPointLIDsForHN( fLID, f, c , pointsLIDs, coefs , facetIndex);

                  for (int j=0 ; j < pointsLIDs.size() ; j++){
                	  // look for tmpArray[j] in the existing set, put there coefs[j]
                	  HNDoFs[facetIndex[j]] = pointsLIDs[j];
                	  transMatrix[f*nFacets_  + facetIndex[j]] = coefs[j];
                  }
              }
              else
              {
            	  // look for fLID in the actual set and put there 1.0, if not found then size+1
            	  HNDoFs[f] = fLID;
            	  transMatrix[f*nFacets_  + f] = 1.0;
              }
	    	}
	    	// store the matrix corresponding to this cell
	    	int matrixIndex = matrixStore_.addMatrix(0,transMatrix);
	    	maxCellLIDwithHN_to_TrafoMatrix_.put( c , matrixIndex );

	    	// store the point LID's which contribute to this cell
	    	cellsWithHangingDoF_globalDoFs_.put( c , HNDoFs );

	    	SUNDANCE_MSG2(setupVerb(), tab << "NodalDOFMapHN initializing cellLID:" << c << " array:" << HNDoFs);
	    	SUNDANCE_MSG2(setupVerb(), tab << "NodalDOFMapHN initializing cellLID:" << c << " Trafo array:" << transMatrix);

	    	// add the global DOFs to the array
	    	for (int f=0; f<nFacets_; f++)
	    	{
	    	   int fLID = HNDoFs[f];
    		   for (int i=0; i<nFuncs_; i++) {
    			  elemDofs_[(c*nFuncs_+i)*nFacets_ + f] = nodeDofs_[fLID*nFuncs_ + i];
    		   }

	    	}
	    	SUNDANCE_MSG2(setupVerb(),tab << "NodalDOFMapHN HN initializing cellLID:" << c << " elemDofs_:" << elemDofs_);
	    }
	    else {
		/* set the element DOFs given the dofs of the facets */
	    	for (int f=0; f<nFacets_; f++)
	    	{
	    		int fLID = facetLID_[c*nFacets_+f];
	    		for (int i=0; i<nFuncs_; i++)
	    		{
	    			elemDofs_[(c*nFuncs_+i)*nFacets_ + f] = nodeDofs_[fLID*nFuncs_ + i];
	    		}
	    	}
	    	  SUNDANCE_MSG2(setupVerb(),tab << "NodalDOFMapHN initializing cellLID:" << c << " elemDofs_:" << elemDofs_);
	    }
    }
  SUNDANCE_MSG2(setupVerb(),tab << "NodalDOFMapHN initializing DONE");

}
void NodalDOFMap::init() 
{ 
  Tabs tab;

  SUNDANCE_MSG1(setupVerb(), tab << "initializing nodal DOF map");

  Array<Array<int> > remoteNodes(mesh().comm().getNProc());
  Array<int> hasProcessedCell(nNodes_, 0);

  /* start the DOF count at zero. */
  int nextDOF = 0;
  int owner;

  int nFacets = mesh().numFacets(dim_, 0, 0);
  Array<int> elemLID(nElems_);
  Array<int> facetLID(nFacets*nElems_);
  Array<int> facetOrientations(nFacets*nElems_);

  /* Assign node DOFs for locally owned 0-cells */
  CellSet maxCells = maxCellFilter_.getCells(mesh());

  int cc = 0;
  for (CellIterator iter=maxCells.begin(); iter != maxCells.end(); iter++, cc++)
    {
      int c = *iter;
      elemLID[cc] = c;
    }
  /* look up the LIDs of the facets */
  mesh().getFacetLIDs(dim_, elemLID, 0, facetLID, facetOrientations);
  
  for (int c=0; c<nElems_; c++)
    {
      /* for each facet, process its DOFs */
      for (int f=0; f<nFacets; f++)
        {
          /* if the facet's DOFs have been assigned already,
           * we're done */
          int fLID = facetLID[c*nFacets+f];
          if (hasProcessedCell[fLID] == 0)
            {
              /* the facet may be owned by another processor */
              if (isRemote(0, fLID, owner))
                {
                  int facetGID 
                    = mesh().mapLIDToGID(0, fLID);
                  remoteNodes[owner].append(facetGID);
                  
                }
              else /* we can assign a DOF locally */
                {
                  /* assign DOFs */
                  for (int i=0; i<nFuncs_; i++)
                    {
                      nodeDofs_[fLID*nFuncs_ + i] = nextDOF;
                      nextDOF++;
                    }
                }
              hasProcessedCell[fLID] = 1;
            }
        }
    }

  
  /* Compute offsets for each processor */
  int localCount = nextDOF;
  computeOffsets(localCount);
  
  /* Resolve remote DOF numbers */
  shareRemoteDOFs(remoteNodes);


  /* Assign DOFs for elements */
  for (int c=0; c<nElems_; c++)
    {
      /* set the element DOFs given the dofs of the facets */
      for (int f=0; f<nFacets; f++)
        {
          int fLID = facetLID[c*nFacets+f];
          for (int i=0; i<nFuncs_; i++)
            {
              elemDofs_[(c*nFuncs_+i)*nFacets + f] = nodeDofs_[fLID*nFuncs_ + i]; 
            }
        }
    }

}