示例#1
0
int
GameBoard::NumNeighbours(const Cell& cell) {
  BoundingBox searchBox;
  if (cell.x == 0) {
    searchBox._x = 0;
    searchBox._width = 1;
  } else {
    searchBox._x = cell.x - 1;
    searchBox._width = 2;
  }

  if (cell.y == 0) {
    searchBox._y = 0;
    searchBox._height = 1;
  } else {
    searchBox._y = cell.y - 1;
    searchBox._height = 2;
  }

  CellSet neighbours;
  _quadTree.FindPoints(searchBox, neighbours);
  // The original cell is in the search box, so should
  // be at least one. If a dead cell, we only look at
  // dead cells next to alive ones so there should be at least one.
  assert(neighbours.size() > 0);
  return cell.isAlive ? neighbours.size() - 1 : neighbours.size();
}
示例#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);
}
示例#3
0
void
GameBoard::MarkAlive(const CellSet& cells,
                     QuadTree& tree) {
  tree.Clear();
  for (CellSet::iterator it = cells.begin();
       it != cells.end(); ++it) {
    tree.Insert(*it);
  } 
}
示例#4
0
文件: cell.cpp 项目: xenia-cjen/atpg
//{{{ CellSet Cell::getNetCells()
CellSet Cell::getNetCells(const size_t &i) const {
    CellSet cells;
    if (i >= nets_.size())
        return cells;
    NetSet eqv = getEqvNets(i);
    for (NetSet::iterator it = eqv.begin(); it != eqv.end(); ++it)
        for (size_t i = 0; i < (*it)->getNPort(); ++i)
            if ((*it)->getPort(i)->top_ != this)
                cells.insert((*it)->getPort(i)->top_);
    return cells;
} //}}}
示例#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);
  } 
}
示例#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;
}
示例#7
0
CellSet KeyFace::spatialBoundary() const
{
    CellSet res;

    for(int i=0; i<cycles_.size(); ++i)
    {
        CellSet cells = cycles_[i].cells();
        res.unite(cells);
    }

    return res;
}
示例#8
0
CellSet EdgeCell::spatialBoundary() const
{
    if(isClosed())
    {
        return CellSet();
    }
    else
    {
        CellSet left = startVertices();
        CellSet right = endVertices();
        left.unite(right);
        return left;
    }
}
示例#9
0
void
GameBoard::Update() {
  CellSet nextLiveCells;
  CellQueue processQueue(_liveCells);

  while (!processQueue.Empty()) {
    Cell& cell = processQueue.Front();
    if (nextLiveCells.count(cell) == 0) {
      // Add neighbours if necessary
      if (cell.isAlive) {
        // TODO: Check for dupes? Worth it?
        if (cell.x < ULONG_MAX) {
          processQueue.Push(Cell(cell.x+1, cell.y, false));
          if (cell.y < ULONG_MAX) {
            processQueue.Push(Cell(cell.x+1, cell.y+1, false));
          }
          if (cell.y > 0) {
            processQueue.Push(Cell(cell.x+1, cell.y-1, false));
          }
        }
        if (cell.y < ULONG_MAX) {
          processQueue.Push(Cell(cell.x, cell.y+1, false));
        }
        if (cell.x > 0) {
          processQueue.Push(Cell(cell.x-1, cell.y, false));
          if (cell.y < ULONG_MAX) {
            processQueue.Push(Cell(cell.x-1, cell.y+1, false));
          }
          if (cell.y > 0) {
            processQueue.Push(Cell(cell.x-1, cell.y-1, false));
          }
        }
        if (cell.y > 0) {
          processQueue.Push(Cell(cell.x, cell.y-1, false));
        }
      }
      int numNeighbours = NumNeighbours(cell);
      if (numNeighbours == 3 || (cell.isAlive && numNeighbours == 2)) {
        cell.isAlive = true;
        nextLiveCells.insert(cell);
      }
      processQueue.Pop();
    }
  }

  _liveCells = nextLiveCells;
  MarkAlive(_liveCells, _quadTree);
}
示例#10
0
文件: cell.cpp 项目: xenia-cjen/atpg
//{{{ CellSet Cell::getNetCells()
CellSet Cell::getNetCells(const size_t &i, const bool &input) const {
    CellSet cells;
    if (i >= nets_.size())
        return cells;
    NetSet eqv = getEqvNets(i);
    for (NetSet::iterator it = eqv.begin(); it != eqv.end(); ++it) {
        for (size_t i = 0; i < (*it)->getNPort(); ++i) {
            Port *p = (*it)->getPort(i);
            if (p->top_ != this && input && p->type_ == Port::INPUT)
                cells.insert(p->top_);
            else if (p->top_ != this && !input && p->type_ == Port::OUTPUT)
                cells.insert(p->top_);
        }
    }
    return cells;
} //}}}
示例#11
0
ZOrderedCells::Iterator ZOrderedCells::findFirst(const CellSet & cells)
{
    Iterator it = begin();
    for(; it != end(); ++it)
        if(cells.contains(*it))
            break;
    return it;
}
示例#12
0
ZOrderedCells::ReverseIterator ZOrderedCells::findLast(const CellSet & cells)
{
    ReverseIterator it = rbegin();
    for(; it != rend(); ++it)
        if(cells.contains(*it))
            break;
    return it;
}
示例#13
0
文件: cell.cpp 项目: xenia-cjen/atpg
//{{{ CellSet Cell::getPortCells()
CellSet Cell::getPortCells(const size_t &i) const {
    CellSet cells;
    if (i >= ports_.size())
        return cells;
    Net *n = ports_[i]->inNet_;
    if (!n)
        return cells;
    NetSet eqv = getEqvNets(n->id_);
    for (NetSet::iterator it = eqv.begin() ; it != eqv.end(); ++it) {
        Net *n = *it;
        for (size_t i = 0; i < n->getNPort(); ++i) {
            Port *p = n->getPort(i);
            if (p->top_ != this)
                cells.insert(p->top_);
        }
    }
    return cells;
} //}}}
示例#14
0
void CalculateNeighbourCells(        Complex2D&  G, 
			       const CellSet  &  cell_set,
			             FacetMap &  facet_map)
{

  typedef typename CellSet::CellIterator  SetCellIt;

  typedef typename FacetMap::iterator     MapIt;
  typedef grid_types<Complex2D>           gt;
  typedef typename gt::Cell               Cell;
  typedef typename gt::FacetOnCellIterator FacetOnCellIt;
  //  typedef typename gt::CellOnCellIterator CellNeighbourIt;
  
  friend_for_input gg(G); // gg == G + access to private routines
  
  typedef vtuple_2d<Complex2D> vtuple;
  SetCellIt c = cell_set.FirstCell();
  for(c= cell_set.FirstCell(); !c.IsDone(); ++c){
    Cell C(*c);
    FacetOnCellIt f(C.FirstFacet());
    for(; !f.IsDone();++f) {
      vtuple  facet(get_vertices(f));
      MapIt nb;
      if((nb = facet_map.find(facet)) != facet_map.end()){ 
        // facet found: nb has already been visited
        // do appropriate entries in the neighbourlists
        //  & remove facet from the map.
        FacetOnCellIt NbIt((*nb).second);
        gg.set_neighbour(f,    NbIt.TheCell());
        gg.set_neighbour(NbIt, f.   TheCell());
        //(int&)(*f._nb)      = G.handle(NbIt.TheCell()); // replace with call to
        //(int&)(*(NbIt._nb)) = G.handle(f.TheCell());    // internal fct of Complex2D
        facet_map.erase(nb);
      }
      else // 1st time this facet is encountered: add it to map
        facet_map[facet] = f ;
    } // for(f=C.FirstNeighbour();...
  } // for(c=FirstCell();...

  // all remaining map entries are on the boundary of cell_set
  // because they have been encountered exactly once.

}
示例#15
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);
    }
  }

}
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;
    }
}
示例#17
0
// Insert the new cell just below the lowest boundary cell
void ZOrderedCells::insertCell(Cell * cell)
{
    // Get boundary cells
    CellSet boundary = cell->boundary();

    // Insert at appropriate position
    if(boundary.size() == 0)
    {
        // Insert last
        insertLast(cell);
    }
    else
    {
        // Insert before boundary
        Iterator it = begin();
        while(it!=end() && !boundary.contains(*it))
            ++it;
        list_.insert(it,cell);
    }
}
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());
  }
}
示例#19
0
文件: cell.cpp 项目: xenia-cjen/atpg
//{{{ CellSet Cell::getFanin()
CellSet Cell::getFanin(const size_t &i) const {
    CellSet fi;
    if (i >= cells_.size())
        return fi;
    Cell *c = cells_[i];
    NetSet eqvs;
    for (size_t i = 0; i < c->getNPort(); ++i) {
        if (c->getPort(i)->type_ != Port::INPUT || !c->getPort(i)->exNet_)
            continue;
        NetSet eqv = getEqvNets(c->getPort(i)->exNet_->id_);
        eqvs.insert(eqv.begin(), eqv.end());
    }
    NetSet::iterator it = eqvs.begin();
    for ( ; it != eqvs.end(); ++it) {
        Net *n = *it;
        for (size_t j = 0; j < n->getNPort(); ++j) {
            Port *p = n->getPort(j);
            if (p->top_ != this && p->type_ == Port::OUTPUT)
                fi.insert(p->top_);
        }
    }
    return fi;
} //}}}
示例#20
0
void
GameBoard::ApplyPattern(const CellSet& pattern,
                        const Cell& refCell) {
  UndoPattern();
  // By convention - first cell will be centre
  CellSet::const_iterator it = pattern.cbegin();
  bool xOffsetNeg;
  bool yOffsetNeg;
  unsigned long xOffset = CalculateOffset(it->x, refCell.x, &xOffsetNeg);
  unsigned long yOffset = CalculateOffset(it->y, refCell.y, &yOffsetNeg);

  for (;it != pattern.cend(); ++it) {
    try {
      unsigned long newX = ApplyOffset(it->x, xOffset, xOffsetNeg);
      unsigned long newY = ApplyOffset(it->y, yOffset, yOffsetNeg);
      _pattern.insert(Cell(newX, newY));
    } catch (const out_of_range& err) {
      // Can't apply pattern
      _pattern.clear();
      break;
    }
  }
  MarkAlive(_pattern, _patternQuadTree);
}
示例#21
0
void
QuadTree::FindPoints(const BoundingBox& bound,
                     CellSet& out) const {
  if (_boundary.Intersects(bound)) {
    if (_upperLeft == NULL) {
      // This is a leaf node. Check it!
      for (vector<Cell>::const_iterator it = _cells.begin();
           it != _cells.end(); ++it) {
        if (bound.ContainsGreedy(it->x, it->y)) {
          out.insert(*it);
        }
      }
    } else {
      // This is a parent node.
      assert(_cells.empty());
      _upperLeft->FindPoints(bound, out);
      _upperRight->FindPoints(bound, out);
      _lowerLeft->FindPoints(bound, out);
      _lowerRight->FindPoints(bound, out);
    }
  }
}
示例#22
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 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]; 
            }
        }
    }

}
示例#25
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");

}
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()));
}
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");
}