Foam::label Foam::checkMeshQuality ( const polyMesh& mesh, const dictionary& dict ) { label noFailedChecks = 0; { faceSet faces(mesh, "meshQualityFaces", mesh.nFaces()/100+1); motionSmoother::checkMesh(false, mesh, dict, faces); label nFaces = returnReduce(faces.size(), sumOp<label>()); if (nFaces > 0) { noFailedChecks++; Info<< " <<Writing " << nFaces << " faces in error to set " << faces.name() << endl; faces.instance() = mesh.pointsInstance(); faces.write(); } } return noFailedChecks; }
//- (optionally destructively) construct from components Foam::mapDistributePolyMesh::mapDistributePolyMesh ( const polyMesh& mesh, const label nOldPoints, const label nOldFaces, const label nOldCells, labelList& oldPatchStarts, labelList& oldPatchNMeshPoints, labelListList& subPointMap, labelListList& subFaceMap, labelListList& subCellMap, labelListList& subPatchMap, labelListList& constructPointMap, labelListList& constructFaceMap, labelListList& constructCellMap, labelListList& constructPatchMap, const bool reUse // clone or reuse ) : mesh_(mesh), nOldPoints_(nOldPoints), nOldFaces_(nOldFaces), nOldCells_(nOldCells), oldPatchSizes_(oldPatchStarts.size()), oldPatchStarts_(oldPatchStarts, reUse), oldPatchNMeshPoints_(oldPatchNMeshPoints, reUse), pointMap_(mesh.nPoints(), subPointMap, constructPointMap, reUse), faceMap_(mesh.nFaces(), subFaceMap, constructFaceMap, reUse), cellMap_(mesh.nCells(), subCellMap, constructCellMap, reUse), patchMap_(mesh.boundaryMesh().size(), subPatchMap, constructPatchMap, reUse) { calcPatchSizes(); }
void Foam::syncTools::swapBoundaryCellPositions ( const polyMesh& mesh, const UList<point>& cellData, List<point>& neighbourCellData ) { if (cellData.size() != mesh.nCells()) { FatalErrorInFunction << "Number of cell values " << cellData.size() << " is not equal to the number of cells in the mesh " << mesh.nCells() << abort(FatalError); } const polyBoundaryMesh& patches = mesh.boundaryMesh(); label nBnd = mesh.nFaces()-mesh.nInternalFaces(); neighbourCellData.setSize(nBnd); forAll(patches, patchI) { const polyPatch& pp = patches[patchI]; const labelUList& faceCells = pp.faceCells(); forAll(faceCells, i) { label bFaceI = pp.start()+i-mesh.nInternalFaces(); neighbourCellData[bFaceI] = cellData[faceCells[i]]; } }
// Construct from mesh. No morphing data: the mesh has not changed // HJ, 27/Nov/2009 Foam::mapPolyMesh::mapPolyMesh(const polyMesh& mesh) : mesh_(mesh), morphing_(false), nOldPoints_(mesh.nPoints()), nOldFaces_(mesh.nFaces()), nOldCells_(mesh.nCells()) {}
void Foam::decompositionMethod::calcCellCells ( const polyMesh& mesh, const labelList& agglom, const label nLocalCoarse, const bool parallel, CompactListList<label>& cellCells ) { const labelList& faceOwner = mesh.faceOwner(); const labelList& faceNeighbour = mesh.faceNeighbour(); const polyBoundaryMesh& patches = mesh.boundaryMesh(); // Create global cell numbers // ~~~~~~~~~~~~~~~~~~~~~~~~~~ globalIndex globalAgglom ( nLocalCoarse, Pstream::msgType(), Pstream::worldComm, parallel ); // Get agglomerate owner on other side of coupled faces // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ labelList globalNeighbour(mesh.nFaces()-mesh.nInternalFaces()); forAll(patches, patchI) { const polyPatch& pp = patches[patchI]; if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp))) { label faceI = pp.start(); label bFaceI = pp.start() - mesh.nInternalFaces(); forAll(pp, i) { globalNeighbour[bFaceI] = globalAgglom.toGlobal ( agglom[faceOwner[faceI]] ); bFaceI++; faceI++; } }
// Adds empty patch if not yet there. Returns patchID. label addPatch(polyMesh& mesh, const word& patchName) { label patchi = mesh.boundaryMesh().findPatchID(patchName); if (patchi == -1) { const polyBoundaryMesh& patches = mesh.boundaryMesh(); List<polyPatch*> newPatches(patches.size() + 1); patchi = 0; // Copy all old patches forAll(patches, i) { const polyPatch& pp = patches[i]; newPatches[patchi] = pp.clone ( patches, patchi, pp.size(), pp.start() ).ptr(); patchi++; } // Add zero-sized patch newPatches[patchi] = new polyPatch ( patchName, 0, mesh.nFaces(), patchi, patches, polyPatch::typeName ); mesh.removeBoundary(); mesh.addPatches(newPatches); Pout<< "Created patch " << patchName << " at " << patchi << endl; } else {
bool Foam::motionSmootherAlgo::checkMesh ( const bool report, const polyMesh& mesh, const dictionary& dict, labelHashSet& wrongFaces ) { return checkMesh ( report, mesh, dict, identity(mesh.nFaces()), wrongFaces ); }
// Determines face blocking void Foam::channelIndex::walkOppositeFaces ( const polyMesh& mesh, const labelList& startFaces, boolList& blockedFace ) { const cellList& cells = mesh.cells(); const faceList& faces = mesh.faces(); label nBnd = mesh.nFaces() - mesh.nInternalFaces(); DynamicList<label> frontFaces(startFaces); forAll(frontFaces, i) { label facei = frontFaces[i]; blockedFace[facei] = true; }
Foam::MeshWave<Type>::MeshWave ( const polyMesh& mesh, const labelList& changedFaces, const List<Type>& changedFacesInfo, const label maxIter ) : allFaceInfo_(mesh.nFaces()), allCellInfo_(mesh.nCells()), calc_ ( mesh, changedFaces, changedFacesInfo, allFaceInfo_, allCellInfo_, maxIter ) {}
//- Construct from components Foam::mapDistributePolyMesh::mapDistributePolyMesh ( const polyMesh& mesh, // mesh before changes const label nOldPoints, const label nOldFaces, const label nOldCells, const labelList& oldPatchStarts, const labelList& oldPatchNMeshPoints, // how to subset pieces of mesh to send across const labelListList& subPointMap, const labelListList& subFaceMap, const labelListList& subCellMap, const labelListList& subPatchMap, // how to reconstruct received mesh const labelListList& constructPointMap, const labelListList& constructFaceMap, const labelListList& constructCellMap, const labelListList& constructPatchMap ) : mesh_(mesh), nOldPoints_(nOldPoints), nOldFaces_(nOldFaces), nOldCells_(nOldCells), oldPatchSizes_(oldPatchStarts.size()), oldPatchStarts_(oldPatchStarts), oldPatchNMeshPoints_(oldPatchNMeshPoints), pointMap_(mesh.nPoints(), subPointMap, constructPointMap), faceMap_(mesh.nFaces(), subFaceMap, constructFaceMap), cellMap_(mesh.nCells(), subCellMap, constructCellMap), patchMap_(mesh.boundaryMesh().size(), subPatchMap, constructPatchMap) { calcPatchSizes(); }
// Naive feature detection. All boundary edges with angle > featureAngle become // feature edges. All points on feature edges become feature points. All // boundary faces become feature faces. void simpleMarkFeatures ( const polyMesh& mesh, const PackedBoolList& isBoundaryEdge, const scalar featureAngle, const bool concaveMultiCells, const bool doNotPreserveFaceZones, labelList& featureFaces, labelList& featureEdges, labelList& singleCellFeaturePoints, labelList& multiCellFeaturePoints ) { scalar minCos = Foam::cos(featureAngle * mathematicalConstant::pi/180.0); const polyBoundaryMesh& patches = mesh.boundaryMesh(); // Working sets labelHashSet featureEdgeSet; labelHashSet singleCellFeaturePointSet; labelHashSet multiCellFeaturePointSet; // 1. Mark all edges between patches // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ forAll(patches, patchI) { const polyPatch& pp = patches[patchI]; const labelList& meshEdges = pp.meshEdges(); // All patch corner edges. These need to be feature points & edges! for (label edgeI = pp.nInternalEdges(); edgeI < pp.nEdges(); edgeI++) { label meshEdgeI = meshEdges[edgeI]; featureEdgeSet.insert(meshEdgeI); singleCellFeaturePointSet.insert(mesh.edges()[meshEdgeI][0]); singleCellFeaturePointSet.insert(mesh.edges()[meshEdgeI][1]); } } // 2. Mark all geometric feature edges // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Make distinction between convex features where the boundary point becomes // a single cell and concave features where the boundary point becomes // multiple 'half' cells. // Addressing for all outside faces primitivePatch allBoundary ( SubList<face> ( mesh.faces(), mesh.nFaces()-mesh.nInternalFaces(), mesh.nInternalFaces() ), mesh.points() ); // Check for non-manifold points (surface pinched at point) allBoundary.checkPointManifold(false, &singleCellFeaturePointSet); // Check for non-manifold edges (surface pinched at edge) const labelListList& edgeFaces = allBoundary.edgeFaces(); const labelList& meshPoints = allBoundary.meshPoints(); forAll(edgeFaces, edgeI) { const labelList& eFaces = edgeFaces[edgeI]; if (eFaces.size() > 2) { const edge& e = allBoundary.edges()[edgeI]; //Info<< "Detected non-manifold boundary edge:" << edgeI // << " coords:" // << allBoundary.points()[meshPoints[e[0]]] // << allBoundary.points()[meshPoints[e[1]]] << endl; singleCellFeaturePointSet.insert(meshPoints[e[0]]); singleCellFeaturePointSet.insert(meshPoints[e[1]]); } } // Check for features. forAll(edgeFaces, edgeI) { const labelList& eFaces = edgeFaces[edgeI]; if (eFaces.size() == 2) { label f0 = eFaces[0]; label f1 = eFaces[1]; // check angle const vector& n0 = allBoundary.faceNormals()[f0]; const vector& n1 = allBoundary.faceNormals()[f1]; if ((n0 & n1) < minCos) { const edge& e = allBoundary.edges()[edgeI]; label v0 = meshPoints[e[0]]; label v1 = meshPoints[e[1]]; label meshEdgeI = meshTools::findEdge(mesh, v0, v1); featureEdgeSet.insert(meshEdgeI); // Check if convex or concave by looking at angle // between face centres and normal vector c1c0 ( allBoundary[f1].centre(allBoundary.points()) - allBoundary[f0].centre(allBoundary.points()) ); if (concaveMultiCells && (c1c0 & n0) > SMALL) { // Found concave edge. Make into multiCell features Info<< "Detected concave feature edge:" << edgeI << " cos:" << (c1c0 & n0) << " coords:" << allBoundary.points()[v0] << allBoundary.points()[v1] << endl; singleCellFeaturePointSet.erase(v0); multiCellFeaturePointSet.insert(v0); singleCellFeaturePointSet.erase(v1); multiCellFeaturePointSet.insert(v1); } else { // Convex. singleCell feature. if (!multiCellFeaturePointSet.found(v0)) { singleCellFeaturePointSet.insert(v0); } if (!multiCellFeaturePointSet.found(v1)) { singleCellFeaturePointSet.insert(v1); } } } } } // 3. Mark all feature faces // ~~~~~~~~~~~~~~~~~~~~~~~~~ // Face centres that need inclusion in the dual mesh labelHashSet featureFaceSet(mesh.nFaces()-mesh.nInternalFaces()); // A. boundary faces. for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) { featureFaceSet.insert(faceI); } // B. face zones. const faceZoneMesh& faceZones = mesh.faceZones(); if (doNotPreserveFaceZones) { if (faceZones.size() > 0) { WarningIn("simpleMarkFeatures(..)") << "Detected " << faceZones.size() << " faceZones. These will not be preserved." << endl; } } else { if (faceZones.size() > 0) { Info<< "Detected " << faceZones.size() << " faceZones. Preserving these by marking their" << " points, edges and faces as features." << endl; } forAll(faceZones, zoneI) { const faceZone& fz = faceZones[zoneI]; Info<< "Inserting all faces in faceZone " << fz.name() << " as features." << endl; forAll(fz, i) { label faceI = fz[i]; const face& f = mesh.faces()[faceI]; const labelList& fEdges = mesh.faceEdges()[faceI]; featureFaceSet.insert(faceI); forAll(f, fp) { // Mark point as multi cell point (since both sides of // face should have different cells) singleCellFeaturePointSet.erase(f[fp]); multiCellFeaturePointSet.insert(f[fp]); // Make sure there are points on the edges. featureEdgeSet.insert(fEdges[fp]); } } }
void Foam::decompositionConstraints::singleProcessorFaceSetsConstraint::add ( const polyMesh& mesh, boolList& blockedFace, PtrList<labelList>& specifiedProcessorFaces, labelList& specifiedProcessor, List<labelPair>& explicitConnections ) const { blockedFace.setSize(mesh.nFaces(), true); // Mark faces already in set labelList faceToSet(mesh.nFaces(), -1); forAll(specifiedProcessorFaces, setI) { const labelList& faceLabels = specifiedProcessorFaces[setI]; forAll(faceLabels, i) { faceToSet[faceLabels[i]] = setI; } } forAll(setNameAndProcs_, setI) { //Info<< "Keeping all cells connected to faceSet " // << setNameAndProcs_[setI].first() // << " on processor " << setNameAndProcs_[setI].second() << endl; const label destProcI = setNameAndProcs_[setI].second(); // Read faceSet const faceSet fz(mesh, setNameAndProcs_[setI].first()); // Check that it does not overlap with existing specifiedProcessorFaces labelList nMatch(specifiedProcessorFaces.size(), 0); forAllConstIter(faceSet, fz, iter) { label setI = faceToSet[iter.key()]; if (setI != -1) { nMatch[setI]++; } } // Only store if all faces are not yet in specifiedProcessorFaces // (on all processors) bool store = true; forAll(nMatch, setI) { if (nMatch[setI] == fz.size()) { // full match store = false; break; } else if (nMatch[setI] > 0) { // partial match store = false; break; } } reduce(store, andOp<bool>()); if (store) { specifiedProcessorFaces.append(new labelList(fz.sortedToc())); specifiedProcessor.append(destProcI); } }