bool Foam::meshTriangulation::isInternalFace ( const primitiveMesh& mesh, const boolList& includedCell, const label faceI ) { if (mesh.isInternalFace(faceI)) { label own = mesh.faceOwner()[faceI]; label nei = mesh.faceNeighbour()[faceI]; if (includedCell[own] && includedCell[nei]) { // Neighbouring cell will get included in subset // as well so face is internal. return true; } else { return false; } } else { return false; } }
Foam::cellShape Foam::degenerateMatcher::match ( const primitiveMesh& mesh, const label cellI ) { return match ( mesh.faces(), mesh.faceOwner(), cellI, mesh.cells()[cellI] ); }
// Step from faceI (on side cellI) to connected face & cell without crossing // fenceEdges. void Foam::regionSide::visitConnectedFaces ( const primitiveMesh& mesh, const labelHashSet& region, const labelHashSet& fenceEdges, const label cellI, const label faceI, labelHashSet& visitedFace ) { if (!visitedFace.found(faceI)) { if (debug) { Info<< "visitConnectedFaces : cellI:" << cellI << " faceI:" << faceI << " isOwner:" << (cellI == mesh.faceOwner()[faceI]) << endl; } // Mark as visited visitedFace.insert(faceI); // Mark which side of face was visited. if (cellI == mesh.faceOwner()[faceI]) { sideOwner_.insert(faceI); } // Visit all neighbouring faces on faceSet. Stay on this 'side' of // face by doing edge-face-cell walk. const labelList& fEdges = mesh.faceEdges()[faceI]; forAll(fEdges, fEdgeI) { label edgeI = fEdges[fEdgeI]; if (!fenceEdges.found(edgeI)) { // Step along faces on edge from cell to cell until // we hit face on faceSet. // Find face reachable from edge label otherFaceI = otherFace(mesh, cellI, faceI, edgeI); if (mesh.isInternalFace(otherFaceI)) { label otherCellI = cellI; // Keep on crossing faces/cells until back on face on // surface while (!region.found(otherFaceI)) { visitedFace.insert(otherFaceI); if (debug) { Info<< "visitConnectedFaces : cellI:" << cellI << " found insideEdgeFace:" << otherFaceI << endl; } // Cross otherFaceI into neighbouring cell otherCellI = meshTools::otherCell ( mesh, otherCellI, otherFaceI ); otherFaceI = otherFace ( mesh, otherCellI, otherFaceI, edgeI ); } visitConnectedFaces ( mesh, region, fenceEdges, otherCellI, otherFaceI, visitedFace ); } } } }
// Given sin and cos of max angle between normals calculate whether f0 and f1 // on celli make larger angle. Uses sinAngle only for quadrant detection. bool largerAngle ( const primitiveMesh& mesh, const scalar cosAngle, const scalar sinAngle, const label celli, const label f0, // face label const label f1, const vector& n0, // normal at f0 const vector& n1 ) { const labelList& own = mesh.faceOwner(); bool sameFaceOrder = !((own[f0] == celli) ^ (own[f1] == celli)); // Get cos between faceArea vectors. Correct so flat angle (180 degrees) // gives -1. scalar normalCosAngle = n0 & n1; if (sameFaceOrder) { normalCosAngle = -normalCosAngle; } // Get cos between faceCentre and normal vector to determine in // which quadrant angle is. (Is correct for unwarped faces only!) // Correct for non-outwards pointing normal. vector c1c0(mesh.faceCentres()[f1] - mesh.faceCentres()[f0]); c1c0 /= mag(c1c0) + VSMALL; scalar fcCosAngle = n0 & c1c0; if (own[f0] != celli) { fcCosAngle = -fcCosAngle; } if (sinAngle < 0.0) { // Looking for concave angles (quadrant 3 or 4) if (fcCosAngle <= 0) { // Angle is convex so smaller. return false; } else { if (normalCosAngle < cosAngle) { return false; } else { return true; } } } else { // Looking for convex angles (quadrant 1 or 2) if (fcCosAngle > 0) { // Concave angle return true; } else { // Convex. Check cos of normal vectors. if (normalCosAngle > cosAngle) { return false; } else { return true; } } } }