diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H index 2e71d97579..e113365e52 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinement.H @@ -507,7 +507,6 @@ private: void getIntersections ( const labelList& surfacesToTest, - const labelList& neiLevel, const pointField& neiCc, const labelList& testFaces, @@ -515,6 +514,18 @@ private: labelList& globalRegion2 ) const; + //- Calculate intersections on zoned faces. Return per face -1 + // or the index of the surface and the orientation w.r.t. surface + void getIntersections + ( + const labelList& surfacesToTest, + const pointField& neiCc, + const labelList& testFaces, + + labelList& namedSurfaceIndex, + PackedBoolList& posOrientation + ) const; + //- Determine patches for baffles void getBafflePatches ( @@ -635,13 +646,13 @@ private: labelList& cellToZone ) const; - //- Finds zone per cell for cells inside named surfaces that have - // an inside point specified. + //- Finds zone per cell for cells inside region for which name + // is specified. void findCellZoneInsideWalk ( - const labelList& locationSurfaces, - const labelList& namedSurfaceIndex, - const labelList& surfaceToCellZone, + const pointField& locationsInMesh, + const labelList& zonesInMesh, + const labelList& blockedFace, // per face -1 or some index >= 0 labelList& cellToZone ) const; @@ -650,8 +661,8 @@ private: void findCellZoneInsideWalk ( const pointField& locationsInMesh, - const wordList& regionsInMesh, - const labelList& blockedFace, // per face -1 or some index >= 0 + const wordList& zoneNamesInMesh, + const labelList& faceToZone, // per face -1 or some index >= 0 labelList& cellToZone ) const; @@ -670,6 +681,7 @@ private: void findCellZoneTopo ( const pointField& locationsInMesh, + const labelList& allSurfaceIndex, const labelList& namedSurfaceIndex, const labelList& surfaceToCellZone, labelList& cellToZone @@ -677,10 +689,23 @@ private: void makeConsistentFaceIndex ( + const labelList& zoneToNamedSurface, const labelList& cellToZone, labelList& namedSurfaceIndex ) const; + //- Calculate cellZone allocation + void zonify + ( + const bool allowFreeStandingZoneFaces, + const pointField& locationsInMesh, + const wordList& zonesInMesh, + + labelList& cellToZone, + labelList& namedSurfaceIndex, + PackedBoolList& posOrientation + ) const; + //- Put cells into cellZone, faces into faceZone void zonify ( diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C index 302882a3fb..05f5ad917c 100644 --- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C +++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementBaffles.C @@ -51,6 +51,9 @@ License #include "IOmanip.H" #include "refinementParameters.H" +#include "zeroGradientFvPatchFields.H" +#include "volFields.H" + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // Repatches external face or creates baffle for internal face @@ -175,7 +178,6 @@ Foam::label Foam::meshRefinement::createBaffle void Foam::meshRefinement::getIntersections ( const labelList& surfacesToTest, - const labelList& neiLevel, const pointField& neiCc, const labelList& testFaces, @@ -217,7 +219,7 @@ void Foam::meshRefinement::getIntersections calcCellCellRays ( neiCc, - neiLevel, + labelList(neiCc.size(), -1), testFaces, start, end, @@ -228,6 +230,7 @@ void Foam::meshRefinement::getIntersections // Do test for intersections // ~~~~~~~~~~~~~~~~~~~~~~~~~ + labelList surface1; List hit1; labelList region1; @@ -296,30 +299,79 @@ void Foam::meshRefinement::getBafflePatches labelList& neiPatch ) const { - // Check all unnamed surfaces + // 1. Determine cell zones + // ~~~~~~~~~~~~~~~~~~~~~~~ + // Note that this does not determine the surface that was intersected + // so that is done in step 2 below. + labelList cellToZone; { - const labelList testFaces(intersectedFaces()); - - labelList globalRegion1; - labelList globalRegion2; - getIntersections + labelList namedSurfaceIndex; + PackedBoolList posOrientation; + zonify ( - surfaceZonesInfo::getUnnamedSurfaces(surfaces_.surfZones()), - neiLevel, - neiCc, - testFaces, - globalRegion1, - globalRegion2 - ); + true, // allowFreeStandingZoneFaces + locationsInMesh, + zonesInMesh, - ownPatch.setSize(mesh_.nFaces()); - ownPatch = -1; - neiPatch.setSize(mesh_.nFaces()); - neiPatch = -1; - forAll(testFaces, i) + cellToZone, + namedSurfaceIndex, + posOrientation + ); + } + + + // 2. Check intersections of all unnamed surfaces + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + const labelList testFaces(intersectedFaces()); + + labelList globalRegion1; + labelList globalRegion2; + getIntersections + ( + surfaceZonesInfo::getUnnamedSurfaces(surfaces_.surfZones()), + neiCc, + testFaces, + globalRegion1, + globalRegion2 + ); + + + labelList neiCellZone; + syncTools::swapBoundaryCellList(mesh_, cellToZone, neiCellZone); + + + // 3. Baffle all faces on outside of unvisited cells (cellToZone = -2) + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Use patch according to globalRegion1,2 + + ownPatch.setSize(mesh_.nFaces()); + ownPatch = -1; + neiPatch.setSize(mesh_.nFaces()); + neiPatch = -1; + forAll(testFaces, i) + { + label faceI = testFaces[i]; + label ownZone = cellToZone[mesh_.faceOwner()[faceI]]; + label neiZone = -1; + + if (mesh_.isInternalFace(faceI)) + { + neiZone = cellToZone[mesh_.faceNeighbour()[faceI]]; + } + else + { + neiZone = neiCellZone[faceI-mesh_.nInternalFaces()]; + } + + + if + ( + (ownZone == -2 && neiZone != -2) + || (ownZone != -2 && neiZone == -2) + ) { - label faceI = testFaces[i]; if (globalRegion1[faceI] != -1) { ownPatch[faceI] = globalToMasterPatch[globalRegion1[faceI]]; @@ -332,100 +384,6 @@ void Foam::meshRefinement::getBafflePatches } - if (locationsInMesh.size() > 1) - { - // Now we need to filter out any possible intersections between - // multiple regions. Only the faces on the outside of all - // regions are candidates for baffling. - // For this we need to go to per-cell information - - labelList cellToZone(mesh_.nCells(), -2); - - - // Closed surfaces with cellZone specified. - const labelList closedNamedSurfaces - ( - surfaceZonesInfo::getClosedNamedSurfaces - ( - surfaces_.surfZones(), - surfaces_.geometry(), - surfaces_.surfaces() - ) - ); - - if (closedNamedSurfaces.size()) - { - Info<< "Found " << closedNamedSurfaces.size() - << " closed, named surfaces. Assigning cells in/outside" - << " these surfaces to the corresponding cellZone." - << nl << endl; - - findCellZoneGeometric - ( - neiCc, - closedNamedSurfaces, // indices of closed surfaces - ownPatch, // per face patch - labelList(mesh_.boundaryMesh().size(), 0),// cellZone per patch - - cellToZone - ); - } - - // Locations in mesh - walk - findCellZoneInsideWalk - ( - locationsInMesh, - zonesInMesh, - ownPatch, // per face -1 or some index >= 0 - cellToZone - ); - - - // Now we will still have some -2 in cellToZone on parts that - // are unreachable from the locationsInMesh or named surfaces. We only - // want to keep the interfaces to these cellZones. - - - labelList neiCellZone; - syncTools::swapBoundaryCellList(mesh_, cellToZone, neiCellZone); - - // Only keep baffles where one of the sides has an unset cellToZone (-2) - for (label faceI=0; faceI < mesh_.nInternalFaces(); faceI++) - { - if (ownPatch[faceI] != -1 || neiPatch[faceI] != -1) - { - label ownZone = cellToZone[mesh_.faceOwner()[faceI]]; - label neiZone = cellToZone[mesh_.faceNeighbour()[faceI]]; - - if (ownZone != -2 && neiZone != -2) - { - ownPatch[faceI] = -1; - neiPatch[faceI] = -1; - } - } - } - for - ( - label faceI = mesh_.nInternalFaces(); - faceI < mesh_.nFaces(); - faceI++ - ) - { - if (ownPatch[faceI] != -1 || neiPatch[faceI] != -1) - { - label ownZone = cellToZone[mesh_.faceOwner()[faceI]]; - label neiZone = neiCellZone[faceI-mesh_.nInternalFaces()]; - - if (ownZone != -2 && neiZone != -2) - { - ownPatch[faceI] = -1; - neiPatch[faceI] = -1; - } - } - } - } - - // No need to parallel sync since intersection data (surfaceIndex_ etc.) // already guaranteed to be synced... // However: @@ -1563,7 +1521,9 @@ void Foam::meshRefinement::findCellZoneGeometric if (namedSurfaceIndex[faceI] == -1 && (ownZone != neiZone)) { - // Give face the zone of min cell zone + // Give face the zone of min cell zone (but only if the + // cellZone originated from a closed, named surface) + label minZone; if (ownZone == -1) { @@ -1578,7 +1538,13 @@ void Foam::meshRefinement::findCellZoneGeometric minZone = min(ownZone, neiZone); } - namedSurfaceIndex[faceI] = findIndex(surfaceToCellZone, minZone); + // Make sure the cellZone originated from a closed surface + label geomSurfI = findIndex(surfaceToCellZone, minZone); + + if (geomSurfI != -1) + { + namedSurfaceIndex[faceI] = geomSurfI; + } } } @@ -1616,11 +1582,13 @@ void Foam::meshRefinement::findCellZoneGeometric minZone = min(ownZone, neiZone); } - namedSurfaceIndex[faceI] = findIndex - ( - surfaceToCellZone, - minZone - ); + // Make sure the cellZone originated from a closed surface + label geomSurfI = findIndex(surfaceToCellZone, minZone); + + if (geomSurfI != -1) + { + namedSurfaceIndex[faceI] = geomSurfI; + } } } } @@ -1631,111 +1599,10 @@ void Foam::meshRefinement::findCellZoneGeometric } -void Foam::meshRefinement::findCellZoneInsideWalk -( - const labelList& locationSurfaces, // indices of surfaces with inside point - const labelList& namedSurfaceIndex, // per face index of named surface - const labelList& surfaceToCellZone, // cell zone index per surface - - labelList& cellToZone -) const -{ - // Analyse regions. Reuse regionsplit - boolList blockedFace(mesh_.nFaces()); - //selectSeparatedCoupledFaces(blockedFace); - - forAll(namedSurfaceIndex, faceI) - { - if (namedSurfaceIndex[faceI] == -1) - { - blockedFace[faceI] = false; - } - else - { - blockedFace[faceI] = true; - } - } - // No need to sync since namedSurfaceIndex already is synced - - // Set region per cell based on walking - regionSplit cellRegion(mesh_, blockedFace); - blockedFace.clear(); - - - // Force calculation of face decomposition (used in findCell) - (void)mesh_.tetBasePtIs(); - - const PtrList& surfZones = surfaces_.surfZones(); - - // For all locationSurface find the cell - forAll(locationSurfaces, i) - { - label surfI = locationSurfaces[i]; - - const point& insidePoint = surfZones[surfI].zoneInsidePoint(); - - // Find the region containing the insidePoint - label keepRegionI = findRegion - ( - mesh_, - cellRegion, - mergeDistance_*vector(1,1,1), - insidePoint - ); - - Info<< "For surface " << surfaces_.names()[surfI] - << " found point " << insidePoint - << " in global region " << keepRegionI - << " out of " << cellRegion.nRegions() << " regions." << endl; - - if (keepRegionI == -1) - { - FatalErrorIn - ( - "meshRefinement::findCellZoneInsideWalk" - "(const labelList&, const labelList&" - ", const labelList&, const labelList&)" - ) << "Point " << insidePoint - << " is not inside the mesh." << nl - << "Bounding box of the mesh:" << mesh_.bounds() - << exit(FatalError); - } - - // Set all cells with this region - forAll(cellRegion, cellI) - { - if (cellRegion[cellI] == keepRegionI) - { - if (cellToZone[cellI] == -2) - { - cellToZone[cellI] = surfaceToCellZone[surfI]; - } - else if (cellToZone[cellI] != surfaceToCellZone[surfI]) - { - WarningIn - ( - "meshRefinement::findCellZoneInsideWalk" - "(const labelList&, const labelList&" - ", const labelList&, const labelList&)" - ) << "Cell " << cellI - << " at " << mesh_.cellCentres()[cellI] - << " is inside surface " << surfaces_.names()[surfI] - << " but already marked as being in zone " - << cellToZone[cellI] << endl - << "This can happen if your surfaces are not" - << " (sufficiently) closed." - << endl; - } - } - } - } -} - - void Foam::meshRefinement::findCellZoneInsideWalk ( const pointField& locationsInMesh, - const wordList& zonesInMesh, + const labelList& zonesInMesh, const labelList& faceToZone, // per face -1 or some index >= 0 labelList& cellToZone @@ -1756,7 +1623,7 @@ void Foam::meshRefinement::findCellZoneInsideWalk blockedFace[faceI] = true; } } - // No need to sync since blockedFace already is synced + // No need to sync since faceToZone already is synced // Set region per cell based on walking regionSplit cellRegion(mesh_, blockedFace); @@ -1775,7 +1642,7 @@ void Foam::meshRefinement::findCellZoneInsideWalk { // Get location and index of zone ("none" for cellZone -1) const point& insidePoint = locationsInMesh[i]; - label zoneID = mesh_.cellZones().findZoneID(zonesInMesh[i]); + label zoneID = zonesInMesh[i]; // Find the region containing the insidePoint label keepRegionI = findRegion @@ -1786,7 +1653,12 @@ void Foam::meshRefinement::findCellZoneInsideWalk insidePoint ); - Info<< "For cellZone " << zonesInMesh[i] + Info<< "For cellZone " + << ( + zoneID == -1 + ? "none" + : mesh_.cellZones()[zoneID].name() + ) << " found point " << insidePoint << " in global region " << keepRegionI << " out of " << cellRegion.nRegions() << " regions." << endl; @@ -1834,7 +1706,12 @@ void Foam::meshRefinement::findCellZoneInsideWalk ", const labelList&, const labelList&)" ) << "Cell " << cellI << " at " << mesh_.cellCentres()[cellI] - << " is inside cellZone " << zonesInMesh[i] + << " is inside cellZone " + << ( + zoneID == -1 + ? "none" + : mesh_.cellZones()[zoneID].name() + ) << " from locationInMesh " << insidePoint << " but already marked as being in zone " << mesh_.cellZones()[cellToZone[cellI]].name() @@ -1848,54 +1725,32 @@ void Foam::meshRefinement::findCellZoneInsideWalk } } } +} - // Check if any unassigned regions - label nUnzoned = 0; - forAll(regionToZone, regionI) +void Foam::meshRefinement::findCellZoneInsideWalk +( + const pointField& locationsInMesh, + const wordList& zoneNamesInMesh, + const labelList& faceToZone, // per face -1 or some index >= 0 + + labelList& cellToZone +) const +{ + const cellZoneMesh& czs = mesh_.cellZones(); + + labelList zoneIDs(zoneNamesInMesh.size()); + forAll(zoneNamesInMesh, i) { - if (regionToZone[regionI] == -2) - { - // region that has not been assigned a cellZone - nUnzoned++; - } - } - - if (nUnzoned > 0) - { - Info<< "Detected " << nUnzoned << " regions in the mesh that do" - << " not have a locationInMesh." << nl - << "Per unzoned region displaying a single cell centre:" << endl; - - // Determine single location per unzoned region - pointField regionToLocation - ( - regionToZone.size(), - point(GREAT, GREAT, GREAT) - ); - forAll(cellRegion, cellI) - { - label regionI = cellRegion[cellI]; - if (regionToZone[regionI] == -2) - { - const point& cc = mesh_.cellCentres()[cellI]; - minMagSqrEqOp()(regionToLocation[regionI], cc); - } - } - - Pstream::listCombineGather(regionToLocation, minMagSqrEqOp()); - Pstream::listCombineScatter(regionToLocation); - - forAll(regionToZone, regionI) - { - if (regionToZone[regionI] == -2) - { - Info<< '\t' << regionI - << '\t' << regionToLocation[regionI] << endl; - } - } - Info<< endl; + zoneIDs[i] = czs.findZoneID(zoneNamesInMesh[i]); } + findCellZoneInsideWalk + ( + locationsInMesh, + zoneIDs, + faceToZone, + cellToZone + ); } @@ -1964,6 +1819,7 @@ bool Foam::meshRefinement::calcRegionToZone void Foam::meshRefinement::findCellZoneTopo ( const pointField& locationsInMesh, + const labelList& allSurfaceIndex, const labelList& namedSurfaceIndex, const labelList& surfaceToCellZone, labelList& cellToZone @@ -1972,9 +1828,9 @@ void Foam::meshRefinement::findCellZoneTopo // Analyse regions. Reuse regionsplit boolList blockedFace(mesh_.nFaces()); - forAll(namedSurfaceIndex, faceI) + forAll(allSurfaceIndex, faceI) { - if (namedSurfaceIndex[faceI] == -1) + if (allSurfaceIndex[faceI] == -1) { blockedFace[faceI] = false; } @@ -2000,12 +1856,21 @@ void Foam::meshRefinement::findCellZoneTopo // Note: could be improved to count number of cells per region. forAll(cellToZone, cellI) { - if (cellToZone[cellI] != -2) + label regionI = cellRegion[cellI]; + if (cellToZone[cellI] != -2 && regionToCellZone[regionI] == -2) { - regionToCellZone[cellRegion[cellI]] = cellToZone[cellI]; + regionToCellZone[regionI] = cellToZone[cellI]; } } + // Synchronise regionToCellZone. + // Note: + // - region numbers are identical on all processors + // - keepRegion is identical ,, + // - cellZones are identical ,, + Pstream::listCombineGather(regionToCellZone, maxEqOp