diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C index c02f9bf68e..4ba6d43b4e 100644 --- a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C +++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C @@ -22,7 +22,8 @@ License along with OpenFOAM. If not, see . Description - Extrude faceZones into separate mesh (as a different region). + Extrude faceZones (internal or boundary faces) or faceSets (boundary faces + only) into a separate mesh (as a different region). - used to e.g. extrude baffles (extrude internal faces) or create liquid film regions. @@ -101,22 +102,6 @@ becomes BBB=mapped between original mesh and new extrusion CCC=polypatch - - - -Usage - - - extrudeToRegionMesh \ \ \ - - \param \ \n - Name of mesh to create. - - \param \ \n - List of faceZones to extrude - - \param \ \n - Thickness of extruded mesh. - \*---------------------------------------------------------------------------*/ #include "argList.H" @@ -132,7 +117,7 @@ Usage #include "nonuniformTransformCyclicPolyPatch.H" #include "extrudeModel.H" #include "globalIndex.H" -#include "addPatchCellLayer.H" +#include "faceSet.H" #include "volFields.H" #include "surfaceFields.H" @@ -782,18 +767,6 @@ void deleteEmptyPatches(fvMesh& mesh) label usedI = 0; label notUsedI = patches.size(); - //Pout<< "deleteEmptyPatches:" << endl; - //forAll(patches, patchI) - //{ - // Pout<< " patch:" << patchI << " name:" << patches[patchI].name() - // << " start:" << patches[patchI].start() - // << " nFaces:" << patches[patchI].size() - // << " index:" << patches[patchI].index() - // << endl; - //} - //Pout<< endl; - - // Add all the non-empty, non-processor patches forAll(masterNames, masterI) { @@ -912,6 +885,117 @@ void createDummyFvMeshFiles(const polyMesh& mesh, const word& regionName) } +// Check zone either all internal or all external faces +void checkZoneInside +( + const polyMesh& mesh, + const wordList& zoneNames, + const labelList& zoneID, + const labelList& extrudeMeshFaces, + const boolList& isInternal +) +{ + forAll(zoneNames, i) + { + if (isInternal[i]) + { + Info<< "Zone " << zoneNames[i] << " has internal faces" << endl; + } + else + { + Info<< "Zone " << zoneNames[i] << " has boundary faces" << endl; + } + } + + forAll(extrudeMeshFaces, i) + { + label faceI = extrudeMeshFaces[i]; + label zoneI = zoneID[i]; + if (isInternal[zoneI] != mesh.isInternalFace(faceI)) + { + FatalErrorIn("checkZoneInside(..)") + << "Zone " << zoneNames[zoneI] + << " is not consistently all internal or all boundary faces." + << " Face " << faceI << " at " << mesh.faceCentres()[faceI] + << " is the first occurrence." + << exit(FatalError); + } + } +} + + +// To combineReduce a labelList. Filters out duplicates. +class uniqueEqOp +{ + +public: + + void operator()(labelList& x, const labelList& y) const + { + if (x.empty()) + { + if (y.size()) + { + x = y; + } + } + else + { + forAll(y, yi) + { + if (findIndex(x, y[yi]) == -1) + { + label sz = x.size(); + x.setSize(sz+1); + x[sz] = y[yi]; + } + } + } + } +}; + + +// Calculate global pp faces per pp edge. +labelListList globalEdgeFaces +( + const polyMesh& mesh, + const globalIndex& globalFaces, + const primitiveFacePatch& pp, + const labelList& ppMeshEdges +) +{ + // From mesh edge to global pp face labels. + labelListList globalEdgeFaces(ppMeshEdges.size()); + + const labelListList& edgeFaces = pp.edgeFaces(); + + forAll(edgeFaces, edgeI) + { + const labelList& eFaces = edgeFaces[edgeI]; + + // Store pp face and processor as unique tag. + labelList& globalEFaces = globalEdgeFaces[edgeI]; + globalEFaces.setSize(eFaces.size()); + forAll(eFaces, i) + { + globalEFaces[i] = globalFaces.toGlobal(eFaces[i]); + } + } + + // Synchronise across coupled edges. + syncTools::syncEdgeList + ( + mesh, + ppMeshEdges, + globalEdgeFaces, + uniqueEqOp(), + labelList() // null value + ); + + return globalEdgeFaces; +} + + // Find a patch face that is not extruded. Return -1 if not found. label findUncoveredPatchFace ( @@ -927,11 +1011,19 @@ label findUncoveredPatchFace extrudeFaceSet.insert(extrudeMeshFaces[i]); } + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); const labelList& eFaces = mesh.edgeFaces()[meshEdgeI]; forAll(eFaces, i) { label faceI = eFaces[i]; - if (!mesh.isInternalFace(faceI) && !extrudeFaceSet.found(faceI)) + label patchI = pbm.whichPatch(faceI); + + if + ( + patchI != -1 + && !pbm[patchI].coupled() + && !extrudeFaceSet.found(faceI) + ) { return faceI; } @@ -940,6 +1032,60 @@ label findUncoveredPatchFace } +// Calculate per edge min and max zone +void calcEdgeMinMaxZone +( + const fvMesh& mesh, + const primitiveFacePatch& extrudePatch, + const labelList& extrudeMeshEdges, + const labelList& zoneID, + const mapDistribute& extrudeEdgeFacesMap, + const labelListList& extrudeEdgeGlobalFaces, + + labelList& minZoneID, + labelList& maxZoneID +) +{ + // Get zoneIDs in extrudeEdgeGlobalFaces order + labelList mappedZoneID(zoneID); + extrudeEdgeFacesMap.distribute(mappedZoneID); + + // Get min and max zone per edge + minZoneID.setSize(extrudeEdgeGlobalFaces.size(), labelMax); + maxZoneID.setSize(extrudeEdgeGlobalFaces.size(), labelMin); + + forAll(extrudeEdgeGlobalFaces, edgeI) + { + const labelList& eFaces = extrudeEdgeGlobalFaces[edgeI]; + if (eFaces.size()) + { + forAll(eFaces, i) + { + label zoneI = mappedZoneID[eFaces[i]]; + minZoneID[edgeI] = min(minZoneID[edgeI], zoneI); + maxZoneID[edgeI] = max(maxZoneID[edgeI], zoneI); + } + } + } + syncTools::syncEdgeList + ( + mesh, + extrudeMeshEdges, + minZoneID, + minOp