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