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(); }
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); }
void GameBoard::MarkAlive(const CellSet& cells, QuadTree& tree) { tree.Clear(); for (CellSet::iterator it = cells.begin(); it != cells.end(); ++it) { tree.Insert(*it); } }
//{{{ 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; } //}}}
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); } }
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; }
CellSet KeyFace::spatialBoundary() const { CellSet res; for(int i=0; i<cycles_.size(); ++i) { CellSet cells = cycles_[i].cells(); res.unite(cells); } return res; }
CellSet EdgeCell::spatialBoundary() const { if(isClosed()) { return CellSet(); } else { CellSet left = startVertices(); CellSet right = endVertices(); left.unite(right); return left; } }
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); }
//{{{ 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; } //}}}
ZOrderedCells::Iterator ZOrderedCells::findFirst(const CellSet & cells) { Iterator it = begin(); for(; it != end(); ++it) if(cells.contains(*it)) break; return it; }
ZOrderedCells::ReverseIterator ZOrderedCells::findLast(const CellSet & cells) { ReverseIterator it = rbegin(); for(; it != rend(); ++it) if(cells.contains(*it)) break; return it; }
//{{{ 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; } //}}}
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. }
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; } }
// 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()); } }
//{{{ 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; } //}}}
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); }
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); } } }
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]; } } } }
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"); }