void referredCell::locallyMapEdgeList ( const labelList& points, const edgeList& sourceCellEdges ) { edges_.setSize(sourceCellEdges.size()); forAll(sourceCellEdges, sCE) { const edge& e(sourceCellEdges[sCE]); edges_[sCE].start() = findIndex(points, e.start()); edges_[sCE].end() = findIndex(points, e.end()); if ( edges_[sCE].start() == -1 || edges_[sCE].end() == -1 ) { FatalErrorIn("Foam::referredCell::locallyMapEdgeList") << "edgeList and points labelList for " << "referred cell do not match: " << nl << "points: " << points << nl << "egdes: " << sourceCellEdges << abort(FatalError); } } }
bool Foam::polyMeshZipUpCells(polyMesh& mesh) { if (polyMesh::debug) { Info<< "bool polyMeshZipUpCells(polyMesh& mesh) const: " << "zipping up topologically open cells" << endl; } // Algorithm: // Take the original mesh and visit all cells. For every cell // calculate the edges of all faces on the cells. A cell is // correctly topologically closed when all the edges are referenced // by exactly two faces. If the edges are referenced only by a // single face, additional vertices need to be inserted into some // of the faces (topological closedness). If an edge is // referenced by more that two faces, there is an error in // topological closedness. // Point insertion into the faces is done by attempting to create // closed loops and inserting the intermediate points into the // defining edge // Note: // The algorithm is recursive and changes the mesh faces in each // pass. It is therefore essential to discard the addressing // after every pass. The algorithm is completed when the mesh // stops changing. label nChangedFacesInMesh = 0; label nCycles = 0; labelHashSet problemCells; do { nChangedFacesInMesh = 0; const cellList& Cells = mesh.cells(); const pointField& Points = mesh.points(); faceList newFaces = mesh.faces(); const faceList& oldFaces = mesh.faces(); const labelListList& pFaces = mesh.pointFaces(); forAll(Cells, cellI) { const labelList& curFaces = Cells[cellI]; const edgeList cellEdges = Cells[cellI].edges(oldFaces); const labelList cellPoints = Cells[cellI].labels(oldFaces); // Find the edges used only once in the cell labelList edgeUsage(cellEdges.size(), 0); forAll(curFaces, faceI) { edgeList curFaceEdges = oldFaces[curFaces[faceI]].edges(); forAll(curFaceEdges, faceEdgeI) { const edge& curEdge = curFaceEdges[faceEdgeI]; forAll(cellEdges, cellEdgeI) { if (cellEdges[cellEdgeI] == curEdge) { edgeUsage[cellEdgeI]++; break; } } } } edgeList singleEdges(cellEdges.size()); label nSingleEdges = 0; forAll(edgeUsage, edgeI) { if (edgeUsage[edgeI] == 1) { singleEdges[nSingleEdges] = cellEdges[edgeI]; nSingleEdges++; } else if (edgeUsage[edgeI] != 2) { WarningIn("void polyMeshZipUpCells(polyMesh& mesh)") << "edge " << cellEdges[edgeI] << " in cell " << cellI << " used " << edgeUsage[edgeI] << " times. " << nl << "Should be 1 or 2 - serious error " << "in mesh structure. " << endl; # ifdef DEBUG_ZIPUP forAll(curFaces, faceI) { Info<< "face: " << oldFaces[curFaces[faceI]] << endl; } Info<< "Cell edges: " << cellEdges << nl << "Edge usage: " << edgeUsage << nl << "Cell points: " << cellPoints << endl; forAll(cellPoints, cpI) { Info<< "vertex create \"" << cellPoints[cpI] << "\" coordinates " << Points[cellPoints[cpI]] << endl; } # endif // Gather the problem cell problemCells.insert(cellI); } } // Check if the cell is already zipped up if (nSingleEdges == 0) continue; singleEdges.setSize(nSingleEdges); # ifdef DEBUG_ZIPUP Info<< "Cell " << cellI << endl; forAll(curFaces, faceI) { Info<< "face: " << oldFaces[curFaces[faceI]] << endl; } Info<< "Cell edges: " << cellEdges << nl << "Edge usage: " << edgeUsage << nl << "Single edges: " << singleEdges << nl << "Cell points: " << cellPoints << endl; forAll(cellPoints, cpI) { Info<< "vertex create \"" << cellPoints[cpI] << "\" coordinates " << points()[cellPoints[cpI]] << endl; } # endif // Loop through all single edges and mark the points they use // points marked twice are internal to edge; those marked more than // twice are corners labelList pointUsage(cellPoints.size(), 0); forAll(singleEdges, edgeI) { const edge& curEdge = singleEdges[edgeI]; forAll(cellPoints, pointI) { if ( cellPoints[pointI] == curEdge.start() || cellPoints[pointI] == curEdge.end() ) { pointUsage[pointI]++; } } } boolList singleEdgeUsage(singleEdges.size(), false); // loop through all edges and eliminate the ones that are // blocked out forAll(singleEdges, edgeI) { bool blockedHead = false; bool blockedTail = false; label newEdgeStart = singleEdges[edgeI].start(); label newEdgeEnd = singleEdges[edgeI].end(); // check that the edge has not got all ends blocked forAll(cellPoints, pointI) { if (cellPoints[pointI] == newEdgeStart) { if (pointUsage[pointI] > 2) { blockedHead = true; } } else if (cellPoints[pointI] == newEdgeEnd) { if (pointUsage[pointI] > 2) { blockedTail = true; } } } if (blockedHead && blockedTail) { // Eliminating edge singleEdges[edgeI] as blocked singleEdgeUsage[edgeI] = true; } }