diff --git a/applications/test/globalMeshData/Make/files b/applications/test/globalMeshData/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..dc5877e38355722c4836cf2f346bc877c33d04d4 --- /dev/null +++ b/applications/test/globalMeshData/Make/files @@ -0,0 +1,3 @@ +globalMeshDataTest.C + +EXE = $(FOAM_USER_APPBIN)/globalMeshDataTest diff --git a/applications/test/globalMeshData/Make/options b/applications/test/globalMeshData/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..4c3dd783cb4170feefb3f5385510a83257b43b18 --- /dev/null +++ b/applications/test/globalMeshData/Make/options @@ -0,0 +1,3 @@ +EXE_INC = + +EXE_LIBS = diff --git a/applications/test/globalMeshData/globalMeshDataTest.C b/applications/test/globalMeshData/globalMeshDataTest.C new file mode 100644 index 0000000000000000000000000000000000000000..75f98b1b9cef2f068417955fbb50d992c3289bf0 --- /dev/null +++ b/applications/test/globalMeshData/globalMeshDataTest.C @@ -0,0 +1,221 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Application + globalMeshDataTest + +Description + Test global point communication + +\*---------------------------------------------------------------------------*/ + +#include "globalMeshData.H" +#include "argList.H" +#include "polyMesh.H" +#include "Time.H" +#include "mapDistribute.H" + +using namespace Foam; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Main program: + +int main(int argc, char *argv[]) +{ +# include "setRootCase.H" +# include "createTime.H" +# include "createPolyMesh.H" + + const globalMeshData& globalData = mesh.globalData(); + const indirectPrimitivePatch& coupledPatch = globalData.coupledPatch(); + + + // Test:print shared points + { + const labelListList& globalPointSlaves = + globalData.globalPointSlaves(); + const mapDistribute& globalPointSlavesMap = + globalData.globalPointSlavesMap(); + + pointField coords(globalPointSlavesMap.constructSize()); + SubList<point>(coords, coupledPatch.nPoints()).assign + ( + coupledPatch.localPoints() + ); + + // Exchange data + globalPointSlavesMap.distribute(coords); + + // Print + forAll(globalPointSlaves, pointI) + { + const labelList& slavePoints = globalPointSlaves[pointI]; + + if (slavePoints.size() > 0) + { + Pout<< "Master point:" << pointI + << " coord:" << coords[pointI] + << " connected to slave points:" << endl; + + forAll(slavePoints, i) + { + Pout<< " " << coords[slavePoints[i]] << endl; + } + } + } + } + + + + // Test: point to faces addressing + { + const labelListList& globalPointBoundaryFaces = + globalData.globalPointBoundaryFaces(); + const mapDistribute& globalPointBoundaryFacesMap = + globalData.globalPointBoundaryFacesMap(); + + label nBnd = mesh.nFaces()-mesh.nInternalFaces(); + + pointField fc(globalPointBoundaryFacesMap.constructSize()); + SubList<point>(fc, nBnd).assign + ( + primitivePatch + ( + SubList<face> + ( + mesh.faces(), + nBnd, + mesh.nInternalFaces() + ), + mesh.points() + ).faceCentres() + ); + + // Exchange data + globalPointBoundaryFacesMap.distribute(fc); + + // Print + forAll(globalPointBoundaryFaces, pointI) + { + const labelList& bFaces = globalPointBoundaryFaces[pointI]; + + Pout<< "Point:" << pointI + << " at:" << coupledPatch.localPoints()[pointI] + << " connected to faces:" << endl; + + forAll(bFaces, i) + { + Pout<< " " << fc[bFaces[i]] << endl; + } + } + } + + + + + + // Test:point to cells addressing + { + const labelList& boundaryCells = globalData.boundaryCells(); + const labelListList& globalPointBoundaryCells = + globalData.globalPointBoundaryCells(); + const mapDistribute& globalPointBoundaryCellsMap = + globalData.globalPointBoundaryCellsMap(); + + pointField cc(globalPointBoundaryCellsMap.constructSize()); + forAll(boundaryCells, i) + { + cc[i] = mesh.cellCentres()[boundaryCells[i]]; + } + + // Exchange data + globalPointBoundaryCellsMap.distribute(cc); + + // Print + forAll(globalPointBoundaryCells, pointI) + { + const labelList& bCells = globalPointBoundaryCells[pointI]; + + Pout<< "Point:" << pointI + << " at:" << coupledPatch.localPoints()[pointI] + << " connected to cells:" << endl; + + forAll(bCells, i) + { + Pout<< " " << cc[bCells[i]] << endl; + } + } + } + + + + // Test:print shared edges + { + const labelListList& globalEdgeSlaves = + globalData.globalEdgeSlaves(); + const mapDistribute& globalEdgeSlavesMap = + globalData.globalEdgeSlavesMap(); + + // Test: distribute edge centres + pointField ec(globalEdgeSlavesMap.constructSize()); + forAll(coupledPatch.edges(), edgeI) + { + ec[edgeI] = coupledPatch.edges()[edgeI].centre + ( + coupledPatch.localPoints() + ); + } + + // Exchange data + globalEdgeSlavesMap.distribute(ec); + + // Print + forAll(globalEdgeSlaves, edgeI) + { + const labelList& slaveEdges = globalEdgeSlaves[edgeI]; + + if (slaveEdges.size() > 0) + { + Pout<< "Master edge:" << edgeI + << " centre:" << ec[edgeI] + << " connected to slave edges:" << endl; + + forAll(slaveEdges, i) + { + Pout<< " " << ec[slaveEdges[i]] << endl; + } + } + } + } + + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/syncTools/Make/files b/applications/test/syncTools/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..6a186ca84a47161b8b78d18cb54dd97ce62be951 --- /dev/null +++ b/applications/test/syncTools/Make/files @@ -0,0 +1,3 @@ +syncToolsTest.C + +EXE = $(FOAM_USER_APPBIN)/syncToolsTest diff --git a/applications/test/syncTools/Make/options b/applications/test/syncTools/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..41306609f208806f0c6f42a2426867d3e10d4897 --- /dev/null +++ b/applications/test/syncTools/Make/options @@ -0,0 +1 @@ +EXE_INC = diff --git a/applications/test/syncTools/syncToolsTest.C b/applications/test/syncTools/syncToolsTest.C new file mode 100644 index 0000000000000000000000000000000000000000..320b4e6f6129e3e5a503b502f4e4343efa953d27 --- /dev/null +++ b/applications/test/syncTools/syncToolsTest.C @@ -0,0 +1,629 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Application + syncToolsTest + +Description + Test some functionality in syncTools. + +\*---------------------------------------------------------------------------*/ + + +#include "argList.H" +#include "polyMesh.H" +#include "Time.H" +#include "Random.H" +#include "PackedList.H" +#include "syncTools.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +void testPackedList(const polyMesh& mesh, Random& rndGen) +{ + Info<< nl << "Testing PackedList synchronisation." << endl; + + { + PackedList<3> bits(mesh.nEdges()); + forAll(bits, i) + { + bits.set(i, rndGen.integer(0,3)); + } + + labelList edgeValues(mesh.nEdges()); + forAll(bits, i) + { + edgeValues[i] = bits.get(i); + } + + PackedList<3> maxBits(bits); + labelList maxEdgeValues(edgeValues); + + syncTools::syncEdgeList(mesh, bits, minEqOp<unsigned int>(), 0); + syncTools::syncEdgeList(mesh, edgeValues, minEqOp<label>(), 0, false); + + syncTools::syncEdgeList(mesh, maxBits, maxEqOp<unsigned int>(), 0); + syncTools::syncEdgeList(mesh, maxEdgeValues, maxEqOp<label>(), 0, false); + + forAll(bits, i) + { + if + ( + edgeValues[i] != label(bits.get(i)) + || maxEdgeValues[i] != label(maxBits.get(i)) + ) + { + FatalErrorIn("testPackedList()") + << "edge:" << i + << " minlabel:" << edgeValues[i] + << " minbits:" << bits.get(i) + << " maxLabel:" << maxEdgeValues[i] + << " maxBits:" << maxBits.get(i) + << exit(FatalError); + } + } + } + + { + PackedList<3> bits(mesh.nPoints()); + forAll(bits, i) + { + bits.set(i, rndGen.integer(0,3)); + } + + labelList pointValues(mesh.nPoints()); + forAll(bits, i) + { + pointValues[i] = bits.get(i); + } + + PackedList<3> maxBits(bits); + labelList maxPointValues(pointValues); + + syncTools::syncPointList(mesh, bits, minEqOp<unsigned int>(), 0); + syncTools::syncPointList(mesh, pointValues, minEqOp<label>(), 0, false); + + syncTools::syncPointList(mesh, maxBits, maxEqOp<unsigned int>(), 0); + syncTools::syncPointList(mesh, maxPointValues, maxEqOp<label>(), 0, false); + + forAll(bits, i) + { + if + ( + pointValues[i] != label(bits.get(i)) + || maxPointValues[i] != label(maxBits.get(i)) + ) + { + FatalErrorIn("testPackedList()") + << "point:" << i + << " minlabel:" << pointValues[i] + << " minbits:" << bits.get(i) + << " maxLabel:" << maxPointValues[i] + << " maxBits:" << maxBits.get(i) + << exit(FatalError); + } + } + } + + { + PackedList<3> bits(mesh.nFaces()); + forAll(bits, faceI) + { + bits.set(faceI, rndGen.integer(0,3)); + } + + labelList faceValues(mesh.nFaces()); + forAll(bits, faceI) + { + faceValues[faceI] = bits.get(faceI); + } + + PackedList<3> maxBits(bits); + labelList maxFaceValues(faceValues); + + syncTools::syncFaceList(mesh, bits, minEqOp<unsigned int>()); + syncTools::syncFaceList(mesh, faceValues, minEqOp<label>(), false); + + syncTools::syncFaceList(mesh, maxBits, maxEqOp<unsigned int>()); + syncTools::syncFaceList(mesh, maxFaceValues, maxEqOp<label>(), false); + + forAll(bits, faceI) + { + if + ( + faceValues[faceI] != label(bits.get(faceI)) + || maxFaceValues[faceI] != label(maxBits.get(faceI)) + ) + { + FatalErrorIn("testPackedList()") + << "face:" << faceI + << " minlabel:" << faceValues[faceI] + << " minbits:" << bits.get(faceI) + << " maxLabel:" << maxFaceValues[faceI] + << " maxBits:" << maxBits.get(faceI) + << exit(FatalError); + } + } + } +} + + +void testSparseData(const polyMesh& mesh, Random& rndGen) +{ + Info<< nl << "Testing Map synchronisation." << endl; + + primitivePatch allBoundary + ( + SubList<face> + ( + mesh.faces(), + mesh.nFaces()-mesh.nInternalFaces(), + mesh.nInternalFaces() + ), + mesh.points() + ); + const pointField& localPoints = allBoundary.localPoints(); + + const point greatPoint(GREAT, GREAT, GREAT); + + + // Point data + // ~~~~~~~~~~ + + { + // Create some data. Use slightly perturbed positions. + Map<vector> sparseData; + pointField fullData(mesh.nPoints(), greatPoint); + + forAll(localPoints, i) + { + const point pt = localPoints[i] + 1E-4*rndGen.vector01(); + + label meshPointI = allBoundary.meshPoints()[i]; + + sparseData.insert(meshPointI, pt); + fullData[meshPointI] = pt; + } + + //Pout<< "sparseData:" << sparseData << endl; + + syncTools::syncPointMap + ( + mesh, + sparseData, + minEqOp<vector>(), + true // apply separation + ); + syncTools::syncPointList + ( + mesh, + fullData, + minEqOp<vector>(), + greatPoint, + true // apply separation + ); + + // Compare. + // 1. Is all fullData also present in sparseData and same value + forAll(fullData, meshPointI) + { + const point& fullPt = fullData[meshPointI]; + + if (fullPt != greatPoint) + { + const point& sparsePt = sparseData[meshPointI]; + + if (fullPt != sparsePt) + { + FatalErrorIn("testSparseData()") + << "point:" << meshPointI + << " full:" << fullPt + << " sparse:" << sparsePt + << exit(FatalError); + } + } + } + + // 2. Does sparseData contain more? + forAllConstIter(Map<vector>, sparseData, iter) + { + const point& sparsePt = iter(); + label meshPointI = iter.key(); + const point& fullPt = fullData[meshPointI]; + + if (fullPt != sparsePt) + { + FatalErrorIn("testSparseData()") + << "point:" << meshPointI + << " full:" << fullPt + << " sparse:" << sparsePt + << exit(FatalError); + } + } + } + + + // Edge data + // ~~~~~~~~~ + + { + // Create some data. Use slightly perturbed positions. + EdgeMap<vector> sparseData; + pointField fullData(mesh.nEdges(), greatPoint); + + const edgeList& edges = allBoundary.edges(); + const labelList meshEdges = allBoundary.meshEdges + ( + mesh.edges(), + mesh.pointEdges() + ); + + forAll(edges, i) + { + const edge& e = edges[i]; + + const point pt = e.centre(localPoints) + 1E-4*rndGen.vector01(); + + label meshEdgeI = meshEdges[i]; + + sparseData.insert(mesh.edges()[meshEdgeI], pt); + fullData[meshEdgeI] = pt; + } + + //Pout<< "sparseData:" << sparseData << endl; + + syncTools::syncEdgeMap + ( + mesh, + sparseData, + minEqOp<vector>(), + true + ); + syncTools::syncEdgeList + ( + mesh, + fullData, + minEqOp<vector>(), + greatPoint, + true + ); + + // Compare. + // 1. Is all fullData also present in sparseData and same value + forAll(fullData, meshEdgeI) + { + const point& fullPt = fullData[meshEdgeI]; + + if (fullPt != greatPoint) + { + const point& sparsePt = sparseData[mesh.edges()[meshEdgeI]]; + + if (fullPt != sparsePt) + { + FatalErrorIn("testSparseData()") + << "edge:" << meshEdgeI + << " points:" << mesh.edges()[meshEdgeI] + << " full:" << fullPt + << " sparse:" << sparsePt + << exit(FatalError); + } + } + } + + // 2. Does sparseData contain more? + forAll(fullData, meshEdgeI) + { + const edge& e = mesh.edges()[meshEdgeI]; + + EdgeMap<vector>::const_iterator iter = sparseData.find(e); + + if (iter != sparseData.end()) + { + const point& sparsePt = iter(); + const point& fullPt = fullData[meshEdgeI]; + + if (fullPt != sparsePt) + { + FatalErrorIn("testSparseData()") + << "Extra edge:" << meshEdgeI + << " points:" << mesh.edges()[meshEdgeI] + << " full:" << fullPt + << " sparse:" << sparsePt + << exit(FatalError); + } + } + } + } +} + + +void testPointSync(const polyMesh& mesh, Random& rndGen) +{ + Info<< nl << "Testing point-wise data synchronisation." << endl; + + const point greatPoint(GREAT, GREAT, GREAT); + + // Test position. + + { + WarningIn("testPointSync()") + << "Position test only correct for cases without cyclics" + << " with shared points." << endl; + + pointField syncedPoints(mesh.points()); + syncTools::syncPointList + ( + mesh, + syncedPoints, + minEqOp<point>(), + greatPoint, + true + ); + + forAll(syncedPoints, pointI) + { + if (mag(syncedPoints[pointI] - mesh.points()[pointI]) > SMALL) + { + FatalErrorIn("testPointSync()") + << "Point " << pointI + << " original location " << mesh.points()[pointI] + << " synced location " << syncedPoints[pointI] + << exit(FatalError); + } + } + } + + // Test masterPoints + + { + labelList nMasters(mesh.nPoints(), 0); + + PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh)); + + forAll(isMasterPoint, pointI) + { + if (isMasterPoint[pointI]) + { + nMasters[pointI] = 1; + } + } + + syncTools::syncPointList + ( + mesh, + nMasters, + plusEqOp<label>(), + 0, + false + ); + + forAll(nMasters, pointI) + { + if (nMasters[pointI] != 1) + { + //FatalErrorIn("testPointSync()") + WarningIn("testPointSync()") + << "Point " << pointI + << " original location " << mesh.points()[pointI] + << " has " << nMasters[pointI] + << " masters." + //<< exit(FatalError); + << endl; + } + } + } +} + + +void testEdgeSync(const polyMesh& mesh, Random& rndGen) +{ + Info<< nl << "Testing edge-wise data synchronisation." << endl; + + const edgeList& edges = mesh.edges(); + + const point greatPoint(GREAT, GREAT, GREAT); + + // Test position. + + { + WarningIn("testEdgeSync()") + << "Position test only correct for cases without cyclics" + << " with shared edges." << endl; + + pointField syncedMids(edges.size()); + forAll(syncedMids, edgeI) + { + syncedMids[edgeI] = edges[edgeI].centre(mesh.points()); + } + syncTools::syncEdgeList + ( + mesh, + syncedMids, + minEqOp<point>(), + greatPoint, + true + ); + + forAll(syncedMids, edgeI) + { + point eMid = edges[edgeI].centre(mesh.points()); + + if (mag(syncedMids[edgeI] - eMid) > SMALL) + { + FatalErrorIn("testEdgeSync()") + << "Edge " << edgeI + << " original midpoint " << eMid + << " synced location " << syncedMids[edgeI] + << exit(FatalError); + } + } + } + + // Test masterEdges + + { + labelList nMasters(edges.size(), 0); + + PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh)); + + forAll(isMasterEdge, edgeI) + { + if (isMasterEdge[edgeI]) + { + nMasters[edgeI] = 1; + } + } + + syncTools::syncEdgeList + ( + mesh, + nMasters, + plusEqOp<label>(), + 0, + false + ); + + forAll(nMasters, edgeI) + { + if (nMasters[edgeI] != 1) + { + //FatalErrorIn("testEdgeSync()") + WarningIn("testEdgeSync()") + << "Edge " << edgeI + << " midpoint " << edges[edgeI].centre(mesh.points()) + << " has " << nMasters[edgeI] + << " masters." + //<< exit(FatalError); + << endl; + } + } + } +} + + +void testFaceSync(const polyMesh& mesh, Random& rndGen) +{ + Info<< nl << "Testing face-wise data synchronisation." << endl; + + // Test position. + + { + pointField syncedFc(mesh.faceCentres()); + + syncTools::syncFaceList + ( + mesh, + syncedFc, + maxEqOp<point>(), + true + ); + + forAll(syncedFc, faceI) + { + if (mag(syncedFc[faceI] - mesh.faceCentres()[faceI]) > SMALL) + { + FatalErrorIn("testFaceSync()") + << "Face " << faceI + << " original centre " << mesh.faceCentres()[faceI] + << " synced centre " << syncedFc[faceI] + << exit(FatalError); + } + } + } + + // Test masterFaces + + { + labelList nMasters(mesh.nFaces(), 0); + + PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh)); + + forAll(isMasterFace, faceI) + { + if (isMasterFace[faceI]) + { + nMasters[faceI] = 1; + } + } + + syncTools::syncFaceList + ( + mesh, + nMasters, + plusEqOp<label>(), + false + ); + + forAll(nMasters, faceI) + { + if (nMasters[faceI] != 1) + { + FatalErrorIn("testFaceSync()") + << "Face " << faceI + << " centre " << mesh.faceCentres()[faceI] + << " has " << nMasters[faceI] + << " masters." + << exit(FatalError); + } + } + } +} + + +// Main program: + +int main(int argc, char *argv[]) +{ +# include "setRootCase.H" +# include "createTime.H" +# include "createPolyMesh.H" + + + Random rndGen(5341*(Pstream::myProcNo()+1)); + + + // Face sync + testFaceSync(mesh, rndGen); + + // Edge sync + testEdgeSync(mesh, rndGen); + + // Point sync + testPointSync(mesh, rndGen); + + // PackedList synchronisation + testPackedList(mesh, rndGen); + + // Sparse synchronisation + testSparseData(mesh, rndGen); + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict index ab8adca478e8fc7235c1949081d1d213f150f569..c7f2d5b6f3ca297dda04026929420315ac798cb4 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict @@ -180,6 +180,12 @@ castellatedMeshControls // NOTE: This point should never be on a face, always inside a cell, even // after refinement. locationInMesh (5 0.28 0.43); + + + // Whether any faceZones (as specified in the refinementSurfaces) + // are only on the boundary of corresponding cellZones or also allow + // free-standing zone faces. Not used if there are no faceZones. + allowFreeStandingZoneFaces true; } @@ -274,6 +280,7 @@ addLayersControls maxThicknessToMedialRatio 0.3; // Angle used to pick up medial axis points + // Note: changed(corrected) w.r.t 16x! 90 degrees corresponds to 130 in 16x. minMedianAxisAngle 90; // Create buffer region for new layer terminations diff --git a/src/Allwmake b/src/Allwmake index 969687eb83e7844c23dcca19f5ec2d462f65b739..a91f131e55a3c559d30749c4bca7ac4bf2e55a87 100755 --- a/src/Allwmake +++ b/src/Allwmake @@ -28,6 +28,7 @@ wmake libso triSurface # Decomposition methods needed by meshTools wmake libso parallel/decompositionMethods +wmake libso parallel/metisDecomp wmake libso meshTools wmake libso finiteVolume diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C index 147b370d1a2aed21c8584dff457290d7481520dd..1b3bb264a2147086193552f52551eac30fd5e575 100644 --- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C +++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C @@ -32,6 +32,8 @@ License #include "demandDrivenData.H" #include "globalPoints.H" //#include "geomGlobalPoints.H" +#include "polyMesh.H" +#include "mapDistribute.H" #include "labelIOList.H" #include "PackedList.H" #include "mergePoints.H" @@ -115,24 +117,17 @@ void Foam::globalMeshData::initProcAddr() // Given information about locally used edges allocate global shared edges. void Foam::globalMeshData::countSharedEdges ( - const HashTable<labelList, edge, Hash<edge> >& procSharedEdges, - HashTable<label, edge, Hash<edge> >& globalShared, + const EdgeMap<labelList>& procSharedEdges, + EdgeMap<label>& globalShared, label& sharedEdgeI ) { // Count occurrences of procSharedEdges in global shared edges table. - for - ( - HashTable<labelList, edge, Hash<edge> >::const_iterator iter = - procSharedEdges.begin(); - iter != procSharedEdges.end(); - ++iter - ) + forAllConstIter(EdgeMap<labelList>, procSharedEdges, iter) { const edge& e = iter.key(); - HashTable<label, edge, Hash<edge> >::iterator globalFnd = - globalShared.find(e); + EdgeMap<label>::iterator globalFnd = globalShared.find(e); if (globalFnd == globalShared.end()) { @@ -189,10 +184,7 @@ void Foam::globalMeshData::calcSharedEdges() const // Find edges using shared points. Store correspondence to local edge // numbering. Note that multiple local edges can have the same shared // points! (for cyclics or separated processor patches) - HashTable<labelList, edge, Hash<edge> > localShared - ( - 2*sharedPtAddr.size() - ); + EdgeMap<labelList> localShared(2*sharedPtAddr.size()); const edgeList& edges = mesh_.edges(); @@ -218,7 +210,7 @@ void Foam::globalMeshData::calcSharedEdges() const sharedPtAddr[e1Fnd()] ); - HashTable<labelList, edge, Hash<edge> >::iterator iter = + EdgeMap<labelList>::iterator iter = localShared.find(sharedEdge); if (iter == localShared.end()) @@ -249,7 +241,7 @@ void Foam::globalMeshData::calcSharedEdges() const // used). But then this only gets done once so not too bothered about the // extra global communication. - HashTable<label, edge, Hash<edge> > globalShared(nGlobalPoints()); + EdgeMap<label> globalShared(nGlobalPoints()); if (Pstream::master()) { @@ -275,10 +267,7 @@ void Foam::globalMeshData::calcSharedEdges() const { // Receive the edges using shared points from the slave. IPstream fromSlave(Pstream::blocking, slave); - HashTable<labelList, edge, Hash<edge> > procSharedEdges - ( - fromSlave - ); + EdgeMap<labelList> procSharedEdges(fromSlave); if (debug) { @@ -295,17 +284,11 @@ void Foam::globalMeshData::calcSharedEdges() const // These were only used once so are not proper shared edges. // Remove them. { - HashTable<label, edge, Hash<edge> > oldSharedEdges(globalShared); + EdgeMap<label> oldSharedEdges(globalShared); globalShared.clear(); - for - ( - HashTable<label, edge, Hash<edge> >::const_iterator iter = - oldSharedEdges.begin(); - iter != oldSharedEdges.end(); - ++iter - ) + forAllConstIter(EdgeMap<label>, oldSharedEdges, iter) { if (iter() != -1) { @@ -361,18 +344,11 @@ void Foam::globalMeshData::calcSharedEdges() const DynamicList<label> dynSharedEdgeLabels(globalShared.size()); DynamicList<label> dynSharedEdgeAddr(globalShared.size()); - for - ( - HashTable<labelList, edge, Hash<edge> >::const_iterator iter = - localShared.begin(); - iter != localShared.end(); - ++iter - ) + forAllConstIter(EdgeMap<labelList>, localShared, iter) { const edge& e = iter.key(); - HashTable<label, edge, Hash<edge> >::const_iterator edgeFnd = - globalShared.find(e); + EdgeMap<label>::const_iterator edgeFnd = globalShared.find(e); if (edgeFnd != globalShared.end()) { @@ -434,6 +410,557 @@ Foam::label Foam::globalMeshData::countCoincidentFaces } +void Foam::globalMeshData::calcGlobalPointSlaves() const +{ + if (debug) + { + Pout<< "globalMeshData::calcGlobalPointSlaves() :" + << " calculating coupled master to slave point addressing." + << endl; + } + + // Calculate connected points for master points + globalPoints globalData(mesh_, coupledPatch(), true); + + const Map<label>& meshToProcPoint = globalData.meshToProcPoint(); + + // Create global numbering for coupled points + globalPointNumberingPtr_.reset + ( + new globalIndex(globalData.globalIndices()) + ); + const globalIndex& globalIndices = globalPointNumberingPtr_(); + + // Create master to slave addressing. Empty for slave points. + globalPointSlavesPtr_.reset + ( + new labelListList(coupledPatch().nPoints()) + ); + labelListList& globalPointSlaves = globalPointSlavesPtr_(); + + forAllConstIter(Map<label>, meshToProcPoint, iter) + { + label localPointI = iter.key(); + const labelList& pPoints = globalData.procPoints()[iter()]; + + // Am I master? + if + ( + globalIndices.isLocal(pPoints[0]) + && globalIndices.toLocal(pPoints[0]) == localPointI + ) + { + labelList& slaves = globalPointSlaves[localPointI]; + slaves.setSize(pPoints.size()-1); + for (label i = 1; i < pPoints.size(); i++) + { + slaves[i-1] = pPoints[i]; + } + } + } + + // Create schedule to get information from slaves onto master + + // Construct compact numbering and distribution map. + // Changes globalPointSlaves to be indices into compact data + + List<Map<label> > compactMap(Pstream::nProcs()); + globalPointSlavesMapPtr_.reset + ( + new mapDistribute + ( + globalIndices, + globalPointSlaves, + compactMap + ) + ); + + if (debug) + { + Pout<< "globalMeshData::calcGlobalPointSlaves() :" + << " coupled points:" << coupledPatch().nPoints() + << " additional remote points:" + << globalPointSlavesMapPtr_().constructSize() + - coupledPatch().nPoints() + << endl; + } +} + + +void Foam::globalMeshData::calcGlobalEdgeSlaves() const +{ + if (debug) + { + Pout<< "globalMeshData::calcGlobalEdgeSlaves() :" + << " calculating coupled master to slave edge addressing." + << endl; + } + + const labelListList& globalPointSlaves = this->globalPointSlaves(); + const mapDistribute& globalPointSlavesMap = this->globalPointSlavesMap(); + + // - Send across connected edges (in global edge addressing) + // - Check on receiving side whether edge has same slave edge + // on both endpoints. + + // Create global numbering for coupled edges + globalEdgeNumberingPtr_.reset + ( + new globalIndex(coupledPatch().nEdges()) + ); + const globalIndex& globalIndices = globalEdgeNumberingPtr_(); + + // Coupled point to global coupled edges. + labelListList globalPointEdges(globalPointSlavesMap.constructSize()); + + // Create local version + const labelListList& pointEdges = coupledPatch().pointEdges(); + forAll(pointEdges, pointI) + { + const labelList& pEdges = pointEdges[pointI]; + labelList& globalPEdges = globalPointEdges[pointI]; + globalPEdges.setSize(pEdges.size()); + forAll(pEdges, i) + { + globalPEdges[i] = globalIndices.toGlobal(pEdges[i]); + } + } + + // Pull slave data to master + globalPointSlavesMap.distribute(globalPointEdges); + + // Now check on master if any of my edges are also on slave. + // This assumes that if slaves have a coupled edge it is also on + // the master (otherwise the mesh would be illegal anyway) + + labelHashSet pointEdgeSet; + + const edgeList& edges = coupledPatch().edges(); + + // Create master to slave addressing. Empty for slave edges. + globalEdgeSlavesPtr_.reset(new labelListList(edges.size())); + labelListList& globalEdgeSlaves = globalEdgeSlavesPtr_(); + + forAll(edges, edgeI) + { + const edge& e = edges[edgeI]; + const labelList& slaves0 = globalPointSlaves[e[0]]; + const labelList& slaves1 = globalPointSlaves[e[1]]; + + // Check for edges that are in both slaves0 and slaves1. + pointEdgeSet.clear(); + forAll(slaves0, i) + { + const labelList& connectedEdges = globalPointEdges[slaves0[i]]; + pointEdgeSet.insert(connectedEdges); + } + forAll(slaves1, i) + { + const labelList& connectedEdges = globalPointEdges[slaves1[i]]; + + forAll(connectedEdges, j) + { + label globalEdgeI = connectedEdges[j]; + + if (pointEdgeSet.found(globalEdgeI)) + { + // Found slave edge. + label sz = globalEdgeSlaves[edgeI].size(); + globalEdgeSlaves[edgeI].setSize(sz+1); + globalEdgeSlaves[edgeI][sz] = globalEdgeI; + } + } + } + } + + + // Construct map + List<Map<label> > compactMap(Pstream::nProcs()); + globalEdgeSlavesMapPtr_.reset + ( + new mapDistribute + ( + globalIndices, + globalEdgeSlaves, + compactMap + ) + ); + + if (debug) + { + Pout<< "globalMeshData::calcGlobalEdgeSlaves() :" + << " coupled edge:" << edges.size() + << " additional remote edges:" + << globalEdgeSlavesMapPtr_().constructSize() - edges.size() + << endl; + } +} + + +// Calculate uncoupled boundary faces (without calculating +// primitiveMesh::pointFaces()) +void Foam::globalMeshData::calcPointBoundaryFaces +( + labelListList& pointBoundaryFaces +) const +{ + const polyBoundaryMesh& bMesh = mesh_.boundaryMesh(); + const Map<label>& meshPointMap = coupledPatch().meshPointMap(); + + // 1. Count + + labelList nPointFaces(coupledPatch().nPoints(), 0); + + forAll(bMesh, patchI) + { + const polyPatch& pp = bMesh[patchI]; + + if (!pp.coupled()) + { + forAll(pp, i) + { + const face& f = pp[i]; + + forAll(f, fp) + { + Map<label>::const_iterator iter = meshPointMap.find(f[fp]); + if (iter != meshPointMap.end()) + { + nPointFaces[iter()]++; + } + } + } + } + } + + + // 2. Size + + pointBoundaryFaces.setSize(coupledPatch().nPoints()); + forAll(nPointFaces, pointI) + { + pointBoundaryFaces[pointI].setSize(nPointFaces[pointI]); + } + nPointFaces = 0; + + + // 3. Fill + + forAll(bMesh, patchI) + { + const polyPatch& pp = bMesh[patchI]; + + if (!pp.coupled()) + { + forAll(pp, i) + { + const face& f = pp[i]; + forAll(f, fp) + { + Map<label>::const_iterator iter = meshPointMap.find(f[fp]); + if (iter != meshPointMap.end()) + { + label bFaceI = pp.start() + i - mesh_.nInternalFaces(); + pointBoundaryFaces[iter()][nPointFaces[iter()]++] = + bFaceI; + } + } + } + } + } +} + +void Foam::globalMeshData::calcGlobalPointBoundaryFaces() const +{ + if (debug) + { + Pout<< "globalMeshData::calcGlobalPointBoundaryFaces() :" + << " calculating coupled point to boundary face addressing." + << endl; + } + + // Construct local point to (uncoupled)boundaryfaces. + labelListList pointBoundaryFaces; + calcPointBoundaryFaces(pointBoundaryFaces); + + + // Global indices for boundary faces + globalBoundaryFaceNumberingPtr_.reset + ( + new globalIndex(mesh_.nFaces()-mesh_.nInternalFaces()) + ); + globalIndex& globalIndices = globalBoundaryFaceNumberingPtr_(); + + + // Convert local boundary faces to global numbering + globalPointBoundaryFacesPtr_.reset + ( + new labelListList(globalPointSlavesMap().constructSize()) + ); + labelListList& globalPointBoundaryFaces = globalPointBoundaryFacesPtr_(); + + forAll(pointBoundaryFaces, pointI) + { + const labelList& bFaces = pointBoundaryFaces[pointI]; + labelList& globalFaces = globalPointBoundaryFaces[pointI]; + globalFaces.setSize(bFaces.size()); + forAll(bFaces, i) + { + globalFaces[i] = globalIndices.toGlobal(bFaces[i]); + } + } + + + // Pull slave pointBoundaryFaces to master + globalPointSlavesMap().distribute(globalPointBoundaryFaces); + + + // Merge slave labels into master globalPointBoundaryFaces + const labelListList& pointSlaves = globalPointSlaves(); + + forAll(pointSlaves, pointI) + { + const labelList& slaves = pointSlaves[pointI]; + + if (slaves.size() > 0) + { + labelList& myBFaces = globalPointBoundaryFaces[pointI]; + + forAll(slaves, i) + { + const labelList& slaveBFaces = + globalPointBoundaryFaces[slaves[i]]; + + // Add all slaveBFaces. Note that need to check for + // uniqueness only in case of cyclics. + + label sz = myBFaces.size(); + myBFaces.setSize(sz+slaveBFaces.size()); + forAll(slaveBFaces, j) + { + label slave = slaveBFaces[j]; + if (findIndex(SubList<label>(myBFaces, sz), slave) == -1) + { + myBFaces[sz++] = slave; + } + } + myBFaces.setSize(sz); + } + } + } + + + // Copy merged boundaryFaces back from master into slave slot + forAll(pointSlaves, pointI) + { + const labelList& bFaces = globalPointBoundaryFaces[pointI]; + const labelList& slaves = pointSlaves[pointI]; + + forAll(slaves, i) + { + globalPointBoundaryFaces[slaves[i]] = bFaces; + } + } + + + // Sync back to slaves. + globalPointSlavesMap().reverseDistribute + ( + coupledPatch().nPoints(), + globalPointBoundaryFaces + ); + + + // Construct a map to get the face data directly + List<Map<label> > compactMap(Pstream::nProcs()); + globalPointBoundaryFacesMapPtr_.reset + ( + new mapDistribute + ( + globalIndices, + globalPointBoundaryFaces, + compactMap + ) + ); + + if (debug) + { + Pout<< "globalMeshData::calcGlobalPointBoundaryFaces() :" + << " coupled points:" << coupledPatch().nPoints() + << " local boundary faces:" << globalIndices.localSize() + << " additional remote faces:" + << globalPointBoundaryFacesMapPtr_().constructSize() + - globalIndices.localSize() + << endl; + } +} + + +void Foam::globalMeshData::calcGlobalPointBoundaryCells() const +{ + if (debug) + { + Pout<< "globalMeshData::calcGlobalPointBoundaryCells() :" + << " calculating coupled point to boundary cell addressing." + << endl; + } + + // Create map of boundary cells and point-cell addressing + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + label bCellI = 0; + Map<label> meshCellMap(4*coupledPatch().nPoints()); + DynamicList<label> cellMap(meshCellMap.size()); + + // Create addressing for point to boundary cells (local) + labelListList pointBoundaryCells(coupledPatch().nPoints()); + + forAll(coupledPatch().meshPoints(), pointI) + { + label meshPointI = coupledPatch().meshPoints()[pointI]; + const labelList& pCells = mesh_.pointCells(meshPointI); + + labelList& bCells = pointBoundaryCells[pointI]; + bCells.setSize(pCells.size()); + + forAll(pCells, i) + { + label cellI = pCells[i]; + Map<label>::iterator fnd = meshCellMap.find(cellI); + + if (fnd != meshCellMap.end()) + { + bCells[i] = fnd(); + } + else + { + meshCellMap.insert(cellI, bCellI); + cellMap.append(cellI); + bCells[i] = bCellI; + bCellI++; + } + } + } + + + boundaryCellsPtr_.reset(new labelList()); + labelList& boundaryCells = boundaryCellsPtr_(); + boundaryCells.transfer(cellMap.shrink()); + + + // Convert point-cells to global point numbers + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + globalBoundaryCellNumberingPtr_.reset + ( + new globalIndex(boundaryCells.size()) + ); + globalIndex& globalIndices = globalBoundaryCellNumberingPtr_(); + + + globalPointBoundaryCellsPtr_.reset + ( + new labelListList(globalPointSlavesMap().constructSize()) + ); + labelListList& globalPointBoundaryCells = globalPointBoundaryCellsPtr_(); + + forAll(pointBoundaryCells, pointI) + { + const labelList& pCells = pointBoundaryCells[pointI]; + labelList& globalCells = globalPointBoundaryCells[pointI]; + globalCells.setSize(pCells.size()); + forAll(pCells, i) + { + globalCells[i] = globalIndices.toGlobal(pCells[i]); + } + } + + + // Pull slave pointBoundaryCells to master + globalPointSlavesMap().distribute(globalPointBoundaryCells); + + + // Merge slave labels into master globalPointBoundaryCells + const labelListList& pointSlaves = globalPointSlaves(); + + forAll(pointSlaves, pointI) + { + const labelList& slaves = pointSlaves[pointI]; + + if (slaves.size() > 0) + { + labelList& myBCells = globalPointBoundaryCells[pointI]; + + forAll(slaves, i) + { + const labelList& slaveBCells = + globalPointBoundaryCells[slaves[i]]; + + // Add all slaveBCells. Note that need to check for + // uniqueness only in case of cyclics. + + label sz = myBCells.size(); + myBCells.setSize(sz+slaveBCells.size()); + forAll(slaveBCells, j) + { + label slave = slaveBCells[j]; + if (findIndex(SubList<label>(myBCells, sz), slave) == -1) + { + myBCells[sz++] = slave; + } + } + myBCells.setSize(sz); + } + } + } + + + // Copy merged boundaryCells back from master into slave slot + forAll(pointSlaves, pointI) + { + const labelList& bCells = globalPointBoundaryCells[pointI]; + const labelList& slaves = pointSlaves[pointI]; + + forAll(slaves, i) + { + globalPointBoundaryCells[slaves[i]] = bCells; + } + } + + + // Sync back to slaves. + globalPointSlavesMap().reverseDistribute + ( + coupledPatch().nPoints(), + globalPointBoundaryCells + ); + + + // Construct a map to get the cell data directly + List<Map<label> > compactMap(Pstream::nProcs()); + globalPointBoundaryCellsMapPtr_.reset + ( + new mapDistribute + ( + globalIndices, + globalPointBoundaryCells, + compactMap + ) + ); + + if (debug) + { + Pout<< "globalMeshData::calcGlobalPointBoundaryCells() :" + << " coupled points:" << coupledPatch().nPoints() + << " local boundary cells:" << globalIndices.localSize() + << " additional remote cells:" + << globalPointBoundaryCellsMapPtr_().constructSize() + - globalIndices.localSize() + << endl; + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from polyMesh @@ -511,6 +1038,25 @@ void Foam::globalMeshData::clearOut() nGlobalPoints_ = -1; deleteDemandDrivenData(sharedEdgeLabelsPtr_); deleteDemandDrivenData(sharedEdgeAddrPtr_); + + coupledPatchPtr_.clear(); + // Point + globalPointNumberingPtr_.clear(); + globalPointSlavesPtr_.clear(); + globalPointSlavesMapPtr_.clear(); + // Edge + globalEdgeNumberingPtr_.clear(); + globalEdgeSlavesPtr_.clear(); + globalEdgeSlavesMapPtr_.clear(); + // Face + globalBoundaryFaceNumberingPtr_.clear(); + globalPointBoundaryFacesPtr_.clear(); + globalPointBoundaryFacesMapPtr_.clear(); + // Cell + boundaryCellsPtr_.clear(); + globalBoundaryCellNumberingPtr_.clear(); + globalPointBoundaryCellsPtr_.clear(); + globalPointBoundaryCellsMapPtr_.clear(); } @@ -709,6 +1255,203 @@ const Foam::labelList& Foam::globalMeshData::sharedEdgeAddr() const } +const Foam::indirectPrimitivePatch& Foam::globalMeshData::coupledPatch() const +{ + if (!coupledPatchPtr_.valid()) + { + const polyBoundaryMesh& bMesh = mesh_.boundaryMesh(); + + label nCoupled = 0; + + forAll(bMesh, patchI) + { + const polyPatch& pp = bMesh[patchI]; + + if (pp.coupled()) + { + nCoupled += pp.size(); + } + } + labelList coupledFaces(nCoupled); + nCoupled = 0; + + forAll(bMesh, patchI) + { + const polyPatch& pp = bMesh[patchI]; + + if (pp.coupled()) + { + label faceI = pp.start(); + + forAll(pp, i) + { + coupledFaces[nCoupled++] = faceI++; + } + } + } + + coupledPatchPtr_.reset + ( + new indirectPrimitivePatch + ( + IndirectList<face> + ( + mesh_.faces(), + coupledFaces + ), + mesh_.points() + ) + ); + + if (debug) + { + Pout<< "globalMeshData::coupledPatch() :" + << " constructed coupled faces patch:" + << " faces:" << coupledPatchPtr_().size() + << " points:" << coupledPatchPtr_().nPoints() + << endl; + } + } + return coupledPatchPtr_(); +} + + +const Foam::globalIndex& Foam::globalMeshData::globalPointNumbering() const +{ + if (!globalPointNumberingPtr_.valid()) + { + calcGlobalPointSlaves(); + } + return globalPointNumberingPtr_(); +} + + +const Foam::labelListList& Foam::globalMeshData::globalPointSlaves() const +{ + if (!globalPointSlavesPtr_.valid()) + { + calcGlobalPointSlaves(); + } + return globalPointSlavesPtr_(); +} + + +const Foam::mapDistribute& Foam::globalMeshData::globalPointSlavesMap() const +{ + if (!globalPointSlavesMapPtr_.valid()) + { + calcGlobalPointSlaves(); + } + return globalPointSlavesMapPtr_(); +} + + +const Foam::globalIndex& Foam::globalMeshData::globalEdgeNumbering() const +{ + if (!globalEdgeNumberingPtr_.valid()) + { + calcGlobalEdgeSlaves(); + } + return globalEdgeNumberingPtr_(); +} + + +const Foam::labelListList& Foam::globalMeshData::globalEdgeSlaves() const +{ + if (!globalEdgeSlavesPtr_.valid()) + { + calcGlobalEdgeSlaves(); + } + return globalEdgeSlavesPtr_(); +} + + +const Foam::mapDistribute& Foam::globalMeshData::globalEdgeSlavesMap() const +{ + if (!globalEdgeSlavesMapPtr_.valid()) + { + calcGlobalEdgeSlaves(); + } + return globalEdgeSlavesMapPtr_(); +} + + +const Foam::globalIndex& Foam::globalMeshData::globalBoundaryFaceNumbering() +const +{ + if (!globalBoundaryFaceNumberingPtr_.valid()) + { + calcGlobalPointBoundaryFaces(); + } + return globalBoundaryFaceNumberingPtr_(); +} + + +const Foam::labelListList& Foam::globalMeshData::globalPointBoundaryFaces() +const +{ + if (!globalPointBoundaryFacesPtr_.valid()) + { + calcGlobalPointBoundaryFaces(); + } + return globalPointBoundaryFacesPtr_(); +} + + +const Foam::mapDistribute& Foam::globalMeshData::globalPointBoundaryFacesMap() +const +{ + if (!globalPointBoundaryFacesMapPtr_.valid()) + { + calcGlobalPointBoundaryFaces(); + } + return globalPointBoundaryFacesMapPtr_(); +} + + +const Foam::labelList& Foam::globalMeshData::boundaryCells() const +{ + if (!boundaryCellsPtr_.valid()) + { + calcGlobalPointBoundaryCells(); + } + return boundaryCellsPtr_(); +} + + +const Foam::globalIndex& Foam::globalMeshData::globalBoundaryCellNumbering() +const +{ + if (!globalBoundaryCellNumberingPtr_.valid()) + { + calcGlobalPointBoundaryCells(); + } + return globalBoundaryCellNumberingPtr_(); +} + + +const Foam::labelListList& Foam::globalMeshData::globalPointBoundaryCells() +const +{ + if (!globalPointBoundaryCellsPtr_.valid()) + { + calcGlobalPointBoundaryCells(); + } + return globalPointBoundaryCellsPtr_(); +} + + +const Foam::mapDistribute& Foam::globalMeshData::globalPointBoundaryCellsMap() +const +{ + if (!globalPointBoundaryCellsMapPtr_.valid()) + { + calcGlobalPointBoundaryCells(); + } + return globalPointBoundaryCellsMapPtr_(); +} + + void Foam::globalMeshData::movePoints(const pointField& newPoints) { // Topology does not change and we don't store any geometry so nothing @@ -740,7 +1483,7 @@ void Foam::globalMeshData::updateMesh() // Option 1. Topological { // Calculate all shared points. This does all the hard work. - globalPoints parallelPoints(mesh_); + globalPoints parallelPoints(mesh_, false); // Copy data out. nGlobalPoints_ = parallelPoints.nGlobalPoints(); diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H index 7c4893126d716d04bb11d5a56fcc860f263b01d6..a6e03baf95795b53173654092f94108da189c7d0 100644 --- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H +++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H @@ -74,10 +74,13 @@ SourceFiles #ifndef globalMeshData_H #define globalMeshData_H -#include "polyMesh.H" +//#include "polyMesh.H" #include "Switch.H" #include "processorTopology.H" #include "labelPair.H" +#include "indirectPrimitivePatch.H" +#include "boundBox.H" +#include "IOobject.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -88,7 +91,10 @@ namespace Foam class globalMeshData; Ostream& operator<<(Ostream&, const globalMeshData&); - +class globalIndex; +class polyMesh; +class mapDistribute; +template<class T> class EdgeMap; /*---------------------------------------------------------------------------*\ Class globalMeshData Declaration @@ -194,6 +200,39 @@ class globalMeshData mutable labelList* sharedEdgeAddrPtr_; + // Coupled point addressing + // This is addressing from coupled point to coupled points,faces,cells + // This is a full schedule so includes points only used by two + // coupled patches. + + mutable autoPtr<indirectPrimitivePatch> coupledPatchPtr_; + + // Coupled point to coupled points + + mutable autoPtr<globalIndex> globalPointNumberingPtr_; + mutable autoPtr<labelListList> globalPointSlavesPtr_; + mutable autoPtr<mapDistribute> globalPointSlavesMapPtr_; + + // Coupled edge to coupled edges + + mutable autoPtr<globalIndex> globalEdgeNumberingPtr_; + mutable autoPtr<labelListList> globalEdgeSlavesPtr_; + mutable autoPtr<mapDistribute> globalEdgeSlavesMapPtr_; + + // Coupled point to boundary faces + + mutable autoPtr<globalIndex> globalBoundaryFaceNumberingPtr_; + mutable autoPtr<labelListList> globalPointBoundaryFacesPtr_; + mutable autoPtr<mapDistribute> globalPointBoundaryFacesMapPtr_; + + // Coupled point to boundary cells + + mutable autoPtr<labelList> boundaryCellsPtr_; + mutable autoPtr<globalIndex> globalBoundaryCellNumberingPtr_; + mutable autoPtr<labelListList> globalPointBoundaryCellsPtr_; + mutable autoPtr<mapDistribute> globalPointBoundaryCellsMapPtr_; + + // Private Member Functions //- Set up processor patch addressing @@ -202,8 +241,8 @@ class globalMeshData //- Helper function for shared edge addressing static void countSharedEdges ( - const HashTable<labelList, edge, Hash<edge> >& procSharedEdges, - HashTable<label, edge, Hash<edge> >&, + const EdgeMap<labelList>&, + EdgeMap<label>&, label& ); @@ -217,6 +256,22 @@ class globalMeshData const vectorField& separationDist ); + //- Calculate global point addressing. + void calcGlobalPointSlaves() const; + + //- Calculate global edge addressing. + void calcGlobalEdgeSlaves() const; + + //- Calculate coupled point to uncoupled boundary faces. Local only. + void calcPointBoundaryFaces(labelListList& pointBoundaryFaces) const; + + //- Calculate global point to global boundary face addressing. + void calcGlobalPointBoundaryFaces() const; + + //- Calculate global point to global boundary cell addressing. + void calcGlobalPointBoundaryCells() const; + + //- Disallow default bitwise copy construct globalMeshData(const globalMeshData&); @@ -388,6 +443,47 @@ public: const labelList& sharedEdgeAddr() const; + + // Global master - slave point communication + + //- Return patch of all coupled faces + const indirectPrimitivePatch& coupledPatch() const; + + // Coupled point to coupled points. Coupled points are points on + // any coupled patch. + + //- Numbering of coupled points is according to coupledPatch. + const globalIndex& globalPointNumbering() const; + //- For every coupled point the indices into the field + // distributed by below map. + const labelListList& globalPointSlaves() const; + const mapDistribute& globalPointSlavesMap() const; + + // Coupled edge to coupled edges. + + const globalIndex& globalEdgeNumbering() const; + const labelListList& globalEdgeSlaves() const; + const mapDistribute& globalEdgeSlavesMap() const; + + // Coupled point to boundary faces. These are uncoupled boundary + // faces only but include empty patches. + + //- Numbering of boundary faces is face-mesh.nInternalFaces() + const globalIndex& globalBoundaryFaceNumbering() const; + const labelListList& globalPointBoundaryFaces() const; + const mapDistribute& globalPointBoundaryFacesMap() const; + + // Coupled point to boundary cell + + //- From boundary cell to mesh cell + const labelList& boundaryCells() const; + + //- Numbering of boundary cells is according to boundaryCells() + const globalIndex& globalBoundaryCellNumbering() const; + const labelListList& globalPointBoundaryCells() const; + const mapDistribute& globalPointBoundaryCellsMap() const; + + // Edit //- Update for moving points. diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.C index bd94a3014200615cd558dfd26b946050872bb429..6dfc702fdd65213b894dd5d6ac0d67a1017fe5b8 100644 --- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.C +++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.C @@ -70,11 +70,11 @@ void Foam::globalPoints::addToSend ( const primitivePatch& pp, const label patchPointI, - const procPointList& knownInfo, + const labelList& knownInfo, DynamicList<label>& patchFaces, DynamicList<label>& indexInFace, - DynamicList<procPointList>& allInfo + DynamicList<labelList>& allInfo ) { label meshPointI = pp.meshPoints()[patchPointI]; @@ -97,58 +97,65 @@ void Foam::globalPoints::addToSend // Add nbrInfo to myInfo. Return true if anything changed. -// nbrInfo is for a point a list of all the processors using it (and the -// meshPoint label on that processor) +// nbrInfo is for a point a list of all the global points using it bool Foam::globalPoints::mergeInfo ( - const procPointList& nbrInfo, - procPointList& myInfo + const labelList& nbrInfo, + labelList& myInfo ) { - // Indices of entries in nbrInfo not yet in myInfo. - DynamicList<label> newInfo(nbrInfo.size()); + labelList newInfo(myInfo); + label newI = newInfo.size(); + newInfo.setSize(newI + nbrInfo.size()); forAll(nbrInfo, i) { - const procPoint& info = nbrInfo[i]; - - // Check if info already in myInfo. - label index = -1; - - forAll(myInfo, j) - { - if (myInfo[j] == info) - { - // Already have information for processor/point combination - // in my list so skip. - index = j; - - break; - } - } + label index = findIndex(myInfo, nbrInfo[i]); if (index == -1) { - // Mark this information as being not yet in myInfo - newInfo.append(i); + newInfo[newI++] = nbrInfo[i]; } } - newInfo.shrink(); + newInfo.setSize(newI); - // Append all nbrInfos referenced in newInfo to myInfo. + // Did anything change? + bool anyChanged = (newI > myInfo.size()); - label index = myInfo.size(); + myInfo.transfer(newInfo); - myInfo.setSize(index + newInfo.size()); + return anyChanged; +} - forAll(newInfo, i) - { - myInfo[index++] = nbrInfo[newInfo[i]]; - } - // Did anything change? - return newInfo.size() > 0; +Foam::label Foam::globalPoints::meshToLocalPoint +( + const Map<label>& meshToPatchPoint, // from mesh point to local numbering + const label meshPointI +) +{ + return + ( + meshToPatchPoint.size() == 0 + ? meshPointI + : meshToPatchPoint[meshPointI] + ); +} + + +Foam::label Foam::globalPoints::localToMeshPoint +( + const labelList& patchToMeshPoint, + const label localPointI +) +{ + return + ( + patchToMeshPoint.size() == 0 + ? localPointI + : patchToMeshPoint[localPointI] + ); } @@ -156,34 +163,30 @@ bool Foam::globalPoints::mergeInfo // Uses mergeInfo above. Returns true if data kept for meshPointI changed. bool Foam::globalPoints::storeInfo ( - const procPointList& nbrInfo, - const label meshPointI + const labelList& nbrInfo, + const label localPointI ) { label infoChanged = false; // Get the index into the procPoints list. - Map<label>::iterator iter = meshToProcPoint_.find(meshPointI); + Map<label>::iterator iter = meshToProcPoint_.find(localPointI); if (iter != meshToProcPoint_.end()) { - procPointList& knownInfo = procPoints_[iter()]; - - if (mergeInfo(nbrInfo, knownInfo)) + if (mergeInfo(nbrInfo, procPoints_[iter()])) { infoChanged = true; } } else { - procPointList knownInfo(1); - knownInfo[0][0] = Pstream::myProcNo(); - knownInfo[0][1] = meshPointI; + labelList knownInfo(1, globalIndices_.toGlobal(localPointI)); if (mergeInfo(nbrInfo, knownInfo)) { // Update addressing from into procPoints - meshToProcPoint_.insert(meshPointI, procPoints_.size()); + meshToProcPoint_.insert(localPointI, procPoints_.size()); // Insert into list of equivalences. procPoints_.append(knownInfo); @@ -197,6 +200,7 @@ bool Foam::globalPoints::storeInfo // Insert my own points into structure and mark as changed. void Foam::globalPoints::initOwnPoints ( + const Map<label>& meshToPatchPoint, const bool allPoints, labelHashSet& changedPoints ) @@ -221,18 +225,24 @@ void Foam::globalPoints::initOwnPoints forAll(meshPoints, i) { label meshPointI = meshPoints[i]; + label localPointI = meshToLocalPoint + ( + meshToPatchPoint, + meshPointI + ); + labelList knownInfo + ( + 1, + globalIndices_.toGlobal(localPointI) + ); - procPointList knownInfo(1); - knownInfo[0][0] = Pstream::myProcNo(); - knownInfo[0][1] = meshPointI; - - // Update addressing from meshpoint to index in procPoints - meshToProcPoint_.insert(meshPointI, procPoints_.size()); + // Update addressing from point to index in procPoints + meshToProcPoint_.insert(localPointI, procPoints_.size()); // Insert into list of equivalences. procPoints_.append(knownInfo); // Update changedpoints info. - changedPoints.insert(meshPointI); + changedPoints.insert(localPointI); } } else @@ -243,18 +253,25 @@ void Foam::globalPoints::initOwnPoints forAll(boundaryPoints, i) { label meshPointI = meshPoints[boundaryPoints[i]]; + label localPointI = meshToLocalPoint + ( + meshToPatchPoint, + meshPointI + ); - procPointList knownInfo(1); - knownInfo[0][0] = Pstream::myProcNo(); - knownInfo[0][1] = meshPointI; + labelList knownInfo + ( + 1, + globalIndices_.toGlobal(localPointI) + ); - // Update addressing from meshpoint to index in procPoints - meshToProcPoint_.insert(meshPointI, procPoints_.size()); + // Update addressing from point to index in procPoints + meshToProcPoint_.insert(localPointI, procPoints_.size()); // Insert into list of equivalences. procPoints_.append(knownInfo); // Update changedpoints info. - changedPoints.insert(meshPointI); + changedPoints.insert(localPointI); } } } @@ -263,8 +280,12 @@ void Foam::globalPoints::initOwnPoints // Send all my info on changedPoints_ to my neighbours. -void Foam::globalPoints::sendPatchPoints(const labelHashSet& changedPoints) - const +void Foam::globalPoints::sendPatchPoints +( + const Map<label>& meshToPatchPoint, + PstreamBuffers& pBufs, + const labelHashSet& changedPoints +) const { const polyBoundaryMesh& patches = mesh_.boundaryMesh(); @@ -280,10 +301,10 @@ void Foam::globalPoints::sendPatchPoints(const labelHashSet& changedPoints) // index in patch face DynamicList<label> indexInFace(pp.nPoints()); // all information I currently hold about this patchPoint - DynamicList<procPointList> allInfo(pp.nPoints()); + DynamicList<labelList> allInfo(pp.nPoints()); - // Now collect information on all mesh points mentioned in + // Now collect information on all points mentioned in // changedPoints. Note that these points only should occur on // processorPatches (or rather this is a limitation!). @@ -292,14 +313,19 @@ void Foam::globalPoints::sendPatchPoints(const labelHashSet& changedPoints) forAll(meshPoints, patchPointI) { label meshPointI = meshPoints[patchPointI]; + label localPointI = meshToLocalPoint + ( + meshToPatchPoint, + meshPointI + ); - if (changedPoints.found(meshPointI)) + if (changedPoints.found(localPointI)) { - label index = meshToProcPoint_[meshPointI]; + label index = meshToProcPoint_[localPointI]; - const procPointList& knownInfo = procPoints_[index]; + const labelList& knownInfo = procPoints_[index]; - // Add my information about meshPointI to the send buffers + // Add my information about localPointI to the send buffers addToSend ( pp, @@ -312,9 +338,6 @@ void Foam::globalPoints::sendPatchPoints(const labelHashSet& changedPoints) ); } } - patchFaces.shrink(); - indexInFace.shrink(); - allInfo.shrink(); // Send to neighbour { @@ -328,12 +351,7 @@ void Foam::globalPoints::sendPatchPoints(const labelHashSet& changedPoints) << patchFaces.size() << endl; } - OPstream toNeighbour - ( - Pstream::blocking, - procPatch.neighbProcNo() - ); - + UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs); toNeighbour << patchFaces << indexInFace << allInfo; } } @@ -345,8 +363,13 @@ void Foam::globalPoints::sendPatchPoints(const labelHashSet& changedPoints) // After finishing will have updated // - procPoints_ : all neighbour information merged in. // - meshToProcPoint_ -// - changedPoints: all meshPoints for which something changed. -void Foam::globalPoints::receivePatchPoints(labelHashSet& changedPoints) +// - changedPoints: all points for which something changed. +void Foam::globalPoints::receivePatchPoints +( + const Map<label>& meshToPatchPoint, + PstreamBuffers& pBufs, + labelHashSet& changedPoints +) { const polyBoundaryMesh& patches = mesh_.boundaryMesh(); @@ -364,14 +387,10 @@ void Foam::globalPoints::receivePatchPoints(labelHashSet& changedPoints) labelList patchFaces; labelList indexInFace; - List<procPointList> nbrInfo; + List<labelList> nbrInfo; { - IPstream fromNeighbour - ( - Pstream::blocking, - procPatch.neighbProcNo() - ); + UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs); fromNeighbour >> patchFaces >> indexInFace >> nbrInfo; } @@ -392,19 +411,15 @@ void Foam::globalPoints::receivePatchPoints(labelHashSet& changedPoints) // Get the meshpoint on my side label meshPointI = f[index]; - //const procPointList& info = nbrInfo[i]; - //Pout << "Received for my coord " - // << mesh_.points()[meshPointI]; - // - //forAll(info, j) - //{ - // Pout<< ' ' <<info[j]; - //} - //Pout<< endl; - - if (storeInfo(nbrInfo[i], meshPointI)) + label localPointI = meshToLocalPoint + ( + meshToPatchPoint, + meshPointI + ); + + if (storeInfo(nbrInfo[i], localPointI)) { - changedPoints.insert(meshPointI); + changedPoints.insert(localPointI); } } } @@ -428,29 +443,41 @@ void Foam::globalPoints::receivePatchPoints(labelHashSet& changedPoints) label meshPointA = meshPoints[e[0]]; label meshPointB = meshPoints[e[1]]; - // Do we have information on meshPointA? + label localA = meshToLocalPoint + ( + meshToPatchPoint, + meshPointA + ); + label localB = meshToLocalPoint + ( + meshToPatchPoint, + meshPointB + ); + + + // Do we have information on pointA? Map<label>::iterator procPointA = - meshToProcPoint_.find(meshPointA); + meshToProcPoint_.find(localA); if (procPointA != meshToProcPoint_.end()) { // Store A info onto pointB - if (storeInfo(procPoints_[procPointA()], meshPointB)) + if (storeInfo(procPoints_[procPointA()], localB)) { - changedPoints.insert(meshPointB); + changedPoints.insert(localB); } } // Same for info on pointB Map<label>::iterator procPointB = - meshToProcPoint_.find(meshPointB); + meshToProcPoint_.find(localB); if (procPointB != meshToProcPoint_.end()) { // Store B info onto pointA - if (storeInfo(procPoints_[procPointB()], meshPointA)) + if (storeInfo(procPoints_[procPointB()], localA)) { - changedPoints.insert(meshPointA); + changedPoints.insert(localA); } } } @@ -461,25 +488,24 @@ void Foam::globalPoints::receivePatchPoints(labelHashSet& changedPoints) // Remove entries which are handled by normal face-face communication. I.e. // those points where the equivalence list is only me and my (face)neighbour -void Foam::globalPoints::remove(const Map<label>& directNeighbours) +void Foam::globalPoints::remove +( + const labelList& patchToMeshPoint, + const Map<label>& directNeighbours +) { // Save old ones. Map<label> oldMeshToProcPoint(meshToProcPoint_); meshToProcPoint_.clear(); - List<procPointList> oldProcPoints; + List<labelList> oldProcPoints; oldProcPoints.transfer(procPoints_); // Go through all equivalences - for - ( - Map<label>::const_iterator iter = oldMeshToProcPoint.begin(); - iter != oldMeshToProcPoint.end(); - ++iter - ) + forAllConstIter(Map<label>, oldMeshToProcPoint, iter) { - label meshPointI = iter.key(); - const procPointList& pointInfo = oldProcPoints[iter()]; + label localPointI = iter.key(); + const labelList& pointInfo = oldProcPoints[iter()]; if (pointInfo.size() == 2) { @@ -488,23 +514,29 @@ void Foam::globalPoints::remove(const Map<label>& directNeighbours) // is in it. This would be an ordinary connection and can be // handled by normal face-face connectivity. - const procPoint& a = pointInfo[0]; - const procPoint& b = pointInfo[1]; + const label a = pointInfo[0]; + const label b = pointInfo[1]; if ( - (a[0] == Pstream::myProcNo() && directNeighbours.found(a[1])) - || (b[0] == Pstream::myProcNo() && directNeighbours.found(b[1])) + ( + globalIndices_.isLocal(a) + && directNeighbours.found(globalIndices_.toLocal(a)) + ) + || ( + globalIndices_.isLocal(b) + && directNeighbours.found(globalIndices_.toLocal(b)) + ) ) { // Normal faceNeighbours - if (a[0] == Pstream::myProcNo()) + if (globalIndices_.isLocal(a)) { //Pout<< "Removing direct neighbour:" // << mesh_.points()[a[1]] // << endl; } - else if (b[0] == Pstream::myProcNo()) + else if (globalIndices_.isLocal(b)) { //Pout<< "Removing direct neighbour:" // << mesh_.points()[b[1]] @@ -525,7 +557,7 @@ void Foam::globalPoints::remove(const Map<label>& directNeighbours) // be found if the two domains are face connected at all // (not shown in the picture) - meshToProcPoint_.insert(meshPointI, procPoints_.size()); + meshToProcPoint_.insert(localPointI, procPoints_.size()); procPoints_.append(pointInfo); } } @@ -536,17 +568,17 @@ void Foam::globalPoints::remove(const Map<label>& directNeighbours) // So this meshPoint will have info of size one only. if ( - pointInfo[0][0] != Pstream::myProcNo() - || !directNeighbours.found(pointInfo[0][1]) + !globalIndices_.isLocal(pointInfo[0]) + || !directNeighbours.found(globalIndices_.toLocal(pointInfo[0])) ) { - meshToProcPoint_.insert(meshPointI, procPoints_.size()); + meshToProcPoint_.insert(localPointI, procPoints_.size()); procPoints_.append(pointInfo); } } else { - meshToProcPoint_.insert(meshPointI, procPoints_.size()); + meshToProcPoint_.insert(localPointI, procPoints_.size()); procPoints_.append(pointInfo); } } @@ -555,35 +587,67 @@ void Foam::globalPoints::remove(const Map<label>& directNeighbours) } +// Compact indices +void Foam::globalPoints::compact() +{ + // TBD: find same procPoints entries. Or rather check if + // in a procPoints there are points with indices < my index. + // This will just merge identical entries so lower storage, but will + // not affect anything else. Note: only relevant with cyclics. + + labelList oldToNew(procPoints_.size(), -1); + labelList newToOld(meshToProcPoint_.size()); + + label newIndex = 0; + forAllIter(Map<label>, meshToProcPoint_, iter) + { + label oldIndex = iter(); + + if (oldToNew[oldIndex] == -1) + { + iter() = newIndex; + oldToNew[oldIndex] = newIndex; + newToOld[newIndex] = oldIndex; + newIndex++; + } + } + List<labelList> oldProcPoints; + oldProcPoints.transfer(procPoints_); + + procPoints_.setSize(meshToProcPoint_.size()); + forAll(procPoints_, i) + { + // Transfer + procPoints_[i].transfer(oldProcPoints[newToOld[i]]); + } +} + + // Get (indices of) points for which I am master (= lowest numbered point on // lowest numbered processor). // (equivalence lists should be complete by now) -Foam::labelList Foam::globalPoints::getMasterPoints() const +Foam::labelList Foam::globalPoints::getMasterPoints +( + const labelList& patchToMeshPoint +) const { labelList masterPoints(nPatchPoints_); label nMaster = 0; - // Go through all equivalences and determine meshPoints where I am master. - for - ( - Map<label>::const_iterator iter = meshToProcPoint_.begin(); - iter != meshToProcPoint_.end(); - ++iter - ) + // Go through all equivalences and determine points where I am master. + forAllConstIter(Map<label>, meshToProcPoint_, iter) { - label meshPointI = iter.key(); - const procPointList& pointInfo = procPoints_[iter()]; + label localPointI = iter.key(); + const labelList& pointInfo = procPoints_[iter()]; if (pointInfo.size() < 2) { // Points should have an equivalence list >= 2 since otherwise // they would be direct neighbours and have been removed in the // call to 'remove'. - Pout<< "MeshPoint:" << meshPointI - << " coord:" << mesh_.points()[meshPointI] - << " has no corresponding point on a neighbouring processor" - << endl; - FatalErrorIn("globalPoints::getMasterPoints()") + label meshPointI = localToMeshPoint(patchToMeshPoint, localPointI); + + FatalErrorIn("globalPoints::getMasterPoints(..)") << '[' << Pstream::myProcNo() << ']' << " MeshPoint:" << meshPointI << " coord:" << mesh_.points()[meshPointI] @@ -592,33 +656,17 @@ Foam::labelList Foam::globalPoints::getMasterPoints() const } else { - // Find lowest processor and lowest mesh point on this processor. - label lowestProcI = labelMax; - label lowestPointI = labelMax; - - forAll(pointInfo, i) - { - label proc = pointInfo[i][0]; - - if (proc < lowestProcI) - { - lowestProcI = proc; - lowestPointI = pointInfo[i][1]; - } - else if (proc == lowestProcI) - { - lowestPointI = min(lowestPointI, pointInfo[i][1]); - } - } + // Check if lowest numbered processor and point is + // on this processor. Since already sorted is first element. if ( - lowestProcI == Pstream::myProcNo() - && lowestPointI == meshPointI + globalIndices_.isLocal(pointInfo[0]) + && globalIndices_.toLocal(pointInfo[0]) == localPointI ) { // I am lowest numbered processor and point. Add to my list. - masterPoints[nMaster++] = meshPointI; + masterPoints[nMaster++] = localPointI; } } } @@ -630,7 +678,11 @@ Foam::labelList Foam::globalPoints::getMasterPoints() const // Send subset of lists -void Foam::globalPoints::sendSharedPoints(const labelList& changedIndices) const +void Foam::globalPoints::sendSharedPoints +( + PstreamBuffers& pBufs, + const labelList& changedIndices +) const { const polyBoundaryMesh& patches = mesh_.boundaryMesh(); @@ -643,7 +695,7 @@ void Foam::globalPoints::sendSharedPoints(const labelList& changedIndices) const const processorPolyPatch& procPatch = refCast<const processorPolyPatch>(pp); - OPstream toNeighbour(Pstream::blocking, procPatch.neighbProcNo()); + UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs); if (debug) { @@ -652,6 +704,7 @@ void Foam::globalPoints::sendSharedPoints(const labelList& changedIndices) const << changedIndices.size() << endl; } + // Send over changed elements toNeighbour << UIndirectList<label>(sharedPointAddr_, changedIndices)() << UIndirectList<label>(sharedPointLabels_, changedIndices)(); @@ -661,10 +714,15 @@ void Foam::globalPoints::sendSharedPoints(const labelList& changedIndices) const // Receive shared point indices for all my shared points. Note that since -// there are only a few here we can build a reverse map using the meshpoint +// there are only a few here we can build a reverse map using the point label // instead of doing all this relative point indexing (patch face + index in // face) as in send/receivePatchPoints -void Foam::globalPoints::receiveSharedPoints(labelList& changedIndices) +void Foam::globalPoints::receiveSharedPoints +( + const Map<label>& meshToPatchPoint, + PstreamBuffers& pBufs, + labelList& changedIndices +) { changedIndices.setSize(sharedPointAddr_.size()); label nChanged = 0; @@ -681,22 +739,18 @@ void Foam::globalPoints::receiveSharedPoints(labelList& changedIndices) const processorPolyPatch& procPatch = refCast<const processorPolyPatch>(pp); - // Map from neighbouring meshPoint to sharedPoint) + // Map from neighbouring mesh or patch point to sharedPoint) Map<label> nbrSharedPoints(sharedPointAddr_.size()); { - // Receive meshPoints on neighbour and sharedPoints and build + // Receive points on neighbour and sharedPoints and build // map from it. Note that we could have built the map on the // neighbour and sent it over. labelList nbrSharedPointAddr; labelList nbrSharedPointLabels; { - IPstream fromNeighbour - ( - Pstream::blocking, - procPatch.neighbProcNo() - ); + UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs); fromNeighbour >> nbrSharedPointAddr >> nbrSharedPointLabels; } @@ -705,7 +759,7 @@ void Foam::globalPoints::receiveSharedPoints(labelList& changedIndices) { nbrSharedPoints.insert ( - nbrSharedPointLabels[i], // meshpoint on neighbour + nbrSharedPointLabels[i], // mesh/patchpoint on neighbour nbrSharedPointAddr[i] // sharedPoint label ); } @@ -713,39 +767,36 @@ void Foam::globalPoints::receiveSharedPoints(labelList& changedIndices) // Merge into whatever information I hold. - for - ( - Map<label>::const_iterator iter = meshToProcPoint_.begin(); - iter != meshToProcPoint_.end(); - ++iter - ) + forAllConstIter(Map<label>, meshToProcPoint_, iter) { - label meshPointI = iter.key(); + label localPointI = iter.key(); label index = iter(); if (sharedPointAddr_[index] == -1) { - // No shared point known yet for this meshPoint. + // No shared point known yet for this point. // See if was received from neighbour. - const procPointList& knownInfo = procPoints_[index]; + const labelList& knownInfo = procPoints_[index]; // Check through the whole equivalence list for any // point from the neighbour. forAll(knownInfo, j) { - const procPoint& info = knownInfo[j]; + const label info = knownInfo[j]; + label procI = globalIndices_.whichProcID(info); + label pointI = globalIndices_.toLocal(procI, info); if ( - (info[0] == procPatch.neighbProcNo()) - && nbrSharedPoints.found(info[1]) + procI == procPatch.neighbProcNo() + && nbrSharedPoints.found(pointI) ) { // So this knownInfo contains the neighbour point - label sharedPointI = nbrSharedPoints[info[1]]; + label sharedPointI = nbrSharedPoints[pointI]; sharedPointAddr_[index] = sharedPointI; - sharedPointLabels_[index] = meshPointI; + sharedPointLabels_[index] = localPointI; changedIndices[nChanged++] = index; break; @@ -759,13 +810,15 @@ void Foam::globalPoints::receiveSharedPoints(labelList& changedIndices) const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch>(pp); - // Build map from meshPoint to sharedPoint - Map<label> meshToSharedPoint(sharedPointAddr_.size()); + // Build map from mesh or patch point to sharedPoint + Map<label> localToSharedPoint(sharedPointAddr_.size()); forAll(sharedPointLabels_, i) { - label meshPointI = sharedPointLabels_[i]; - - meshToSharedPoint.insert(meshPointI, sharedPointAddr_[i]); + localToSharedPoint.insert + ( + sharedPointLabels_[i], + sharedPointAddr_[i] + ); } // Sync all info. @@ -775,17 +828,27 @@ void Foam::globalPoints::receiveSharedPoints(labelList& changedIndices) forAll(connections, i) { const edge& e = connections[i]; - label meshPointA = pp.meshPoints()[e[0]]; label meshPointB = pp.meshPoints()[e[1]]; - // Do we already have shared point for meshPointA? - Map<label>::iterator fndA = meshToSharedPoint.find(meshPointA); - Map<label>::iterator fndB = meshToSharedPoint.find(meshPointB); + label localA = meshToLocalPoint + ( + meshToPatchPoint, + meshPointA + ); + label localB = meshToLocalPoint + ( + meshToPatchPoint, + meshPointB + ); + + // Do we already have shared point for pointA? + Map<label>::iterator fndA = localToSharedPoint.find(localA); + Map<label>::iterator fndB = localToSharedPoint.find(localB); - if (fndA != meshToSharedPoint.end()) + if (fndA != localToSharedPoint.end()) { - if (fndB != meshToSharedPoint.end()) + if (fndB != localToSharedPoint.end()) { if (fndA() != fndB()) { @@ -808,26 +871,26 @@ void Foam::globalPoints::receiveSharedPoints(labelList& changedIndices) // No shared point yet for B. label sharedPointI = fndA(); - // Store shared point for meshPointB - label index = meshToProcPoint_[meshPointB]; + // Store shared point for pointB + label index = meshToProcPoint_[localB]; sharedPointAddr_[index] = sharedPointI; - sharedPointLabels_[index] = meshPointB; + sharedPointLabels_[index] = localB; changedIndices[nChanged++] = index; } } else { // No shared point yet for A. - if (fndB != meshToSharedPoint.end()) + if (fndB != localToSharedPoint.end()) { label sharedPointI = fndB(); - // Store shared point for meshPointA - label index = meshToProcPoint_[meshPointA]; + // Store shared point for pointA + label index = meshToProcPoint_[localA]; sharedPointAddr_[index] = sharedPointI; - sharedPointLabels_[index] = meshPointA; + sharedPointLabels_[index] = localA; changedIndices[nChanged++] = index; } } @@ -887,18 +950,12 @@ Foam::edgeList Foam::globalPoints::coupledPoints(const cyclicPolyPatch& pp) } -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -// Construct from components -Foam::globalPoints::globalPoints(const polyMesh& mesh) -: - mesh_(mesh), - nPatchPoints_(countPatchPoints(mesh.boundaryMesh())), - procPoints_(nPatchPoints_), - meshToProcPoint_(nPatchPoints_), - sharedPointAddr_(0), - sharedPointLabels_(0), - nGlobalPoints_(0) +void Foam::globalPoints::calculateSharedPoints +( + const Map<label>& meshToPatchPoint, // from mesh point to local numbering + const labelList& patchToMeshPoint, // from local numbering to mesh point + const bool keepAllPoints +) { if (debug) { @@ -921,24 +978,33 @@ Foam::globalPoints::globalPoints(const polyMesh& mesh) // shared point is not on the boundary of any processor patches using it. // This would happen if a domain was pinched such that two patches share // a point or edge. - initOwnPoints(true, changedPoints); + initOwnPoints(meshToPatchPoint, true, changedPoints); // Do one exchange iteration to get neighbour points. - sendPatchPoints(changedPoints); - receivePatchPoints(changedPoints); + { + PstreamBuffers pBufs(Pstream::defaultCommsType); + sendPatchPoints(meshToPatchPoint, pBufs, changedPoints); + pBufs.finishedSends(); + receivePatchPoints(meshToPatchPoint, pBufs, changedPoints); + } // Save neighbours reachable through face-face communication. - Map<label> neighbourList(meshToProcPoint_); - + Map<label> neighbourList; + if (!keepAllPoints) + { + neighbourList = meshToProcPoint_; + } // Exchange until nothing changes on all processors. bool changed = false; do { - sendPatchPoints(changedPoints); - receivePatchPoints(changedPoints); + PstreamBuffers pBufs(Pstream::defaultCommsType); + sendPatchPoints(meshToPatchPoint, pBufs, changedPoints); + pBufs.finishedSends(); + receivePatchPoints(meshToPatchPoint, pBufs, changedPoints); changed = changedPoints.size() > 0; reduce(changed, orOp<bool>()); @@ -947,29 +1013,57 @@ Foam::globalPoints::globalPoints(const polyMesh& mesh) // Remove direct neighbours from point equivalences. - remove(neighbourList); - - - //Pout<< "After removing locally connected points:" << endl; - //for - //( - // Map<label>::const_iterator iter = meshToProcPoint_.begin(); - // iter != meshToProcPoint_.end(); - // ++iter - //) - //{ - // label meshPointI = iter.key(); - // const procPointList& pointInfo = procPoints_[iter()]; - // - // forAll(pointInfo, i) - // { - // Pout<< " pointI:" << meshPointI << ' ' - // << mesh.points()[meshPointI] - // << " connected to proc " << pointInfo[i][0] - // << " point:" << pointInfo[i][1] - // << endl; - // } - //} + if (!keepAllPoints) + { + remove(patchToMeshPoint, neighbourList); + } + else + { + // Compact out unused elements + compact(); + } + + procPoints_.shrink(); + + // Sort procPoints in incremental order. This will make the master the + // first element. + forAllIter(Map<label>, meshToProcPoint_, iter) + { + sort(procPoints_[iter()]); + } + + + // Pout<< "Now connected points:" << endl; + // forAllConstIter(Map<label>, meshToProcPoint_, iter) + // { + // label localI = iter.key(); + // const labelList& pointInfo = procPoints_[iter()]; + // + // Pout<< "pointI:" << localI << " index:" << iter() + // << " coord:" + // << mesh_.points()[localToMeshPoint(patchToMeshPoint, localI)] + // << endl; + // + // forAll(pointInfo, i) + // { + // label procI = globalIndices_.whichProcID(pointInfo[i]); + // Pout<< " connected to proc " << procI + // << " localpoint:" + // << globalIndices_.toLocal(procI, pointInfo[i]); + // + // if (globalIndices_.isLocal(pointInfo[i])) + // { + // label meshPointI = localToMeshPoint + // ( + // patchToMeshPoint, + // globalIndices_.toLocal(pointInfo[i]) + // ); + // Pout<< " at:" << mesh_.points()[meshPointI]; + // } + // + // Pout<< endl; + // } + // } // We now have - in procPoints_ - a list of points which are shared between @@ -988,49 +1082,21 @@ Foam::globalPoints::globalPoints(const polyMesh& mesh) sharedPointLabels_ = -1; - // Get points for which I am master (lowest numbered proc) - labelList masterPoints(getMasterPoints()); - + // Get point labels of points for which I am master (lowest + // numbered proc) + labelList masterPoints(getMasterPoints(patchToMeshPoint)); - // Determine number of master points on all processors. - labelList sharedPointSizes(Pstream::nProcs()); - sharedPointSizes[Pstream::myProcNo()] = masterPoints.size(); - - Pstream::gatherList(sharedPointSizes); - Pstream::scatterList(sharedPointSizes); - - if (debug) - { - Pout<< "sharedPointSizes:" << sharedPointSizes << endl; - } - - // Get total number of shared points - nGlobalPoints_ = 0; - forAll(sharedPointSizes, procI) - { - nGlobalPoints_ += sharedPointSizes[procI]; - } - - // Assign sharedPoint labels. Every processor gets assigned consecutive - // numbers for its master points. - // These are assigned in processor order so processor0 gets - // 0..masterPoints.size()-1 etc. - - // My point labels start after those of lower numbered processors - label sharedPointI = 0; - for (label procI = 0; procI < Pstream::myProcNo(); procI++) - { - sharedPointI += sharedPointSizes[procI]; - } + // Get global numbering for master points + globalIndex globalMasterPoints(masterPoints.size()); + nGlobalPoints_ = globalMasterPoints.size(); forAll(masterPoints, i) { - label meshPointI = masterPoints[i]; - - label index = meshToProcPoint_[meshPointI]; + label localPointI = masterPoints[i]; + label index = meshToProcPoint_[localPointI]; - sharedPointLabels_[index] = meshPointI; - sharedPointAddr_[index] = sharedPointI++; + sharedPointLabels_[index] = localPointI; + sharedPointAddr_[index] = globalMasterPoints.toGlobal(i); } @@ -1060,8 +1126,10 @@ Foam::globalPoints::globalPoints(const polyMesh& mesh) Pout<< "Determined " << changedIndices.size() << " shared points." << " Exchanging them" << endl; } - sendSharedPoints(changedIndices); - receiveSharedPoints(changedIndices); + PstreamBuffers pBufs(Pstream::defaultCommsType); + sendSharedPoints(pBufs, changedIndices); + pBufs.finishedSends(); + receiveSharedPoints(meshToPatchPoint, pBufs, changedIndices); changed = changedIndices.size() > 0; reduce(changed, orOp<bool>()); @@ -1073,7 +1141,7 @@ Foam::globalPoints::globalPoints(const polyMesh& mesh) { if (sharedPointLabels_[i] == -1) { - FatalErrorIn("globalPoints::globalPoints(const polyMesh& mesh)") + FatalErrorIn("globalPoints::globalPoints(const polyMesh&)") << "Problem: shared point on processor " << Pstream::myProcNo() << " not set at index " << sharedPointLabels_[i] << endl << "This might mean the individual processor domains are not" @@ -1091,4 +1159,56 @@ Foam::globalPoints::globalPoints(const polyMesh& mesh) } +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +// Construct from mesh +Foam::globalPoints::globalPoints +( + const polyMesh& mesh, + const bool keepAllPoints +) +: + mesh_(mesh), + globalIndices_(mesh_.nPoints()), + nPatchPoints_(countPatchPoints(mesh.boundaryMesh())), + procPoints_(nPatchPoints_), + meshToProcPoint_(nPatchPoints_), + sharedPointAddr_(0), + sharedPointLabels_(0), + nGlobalPoints_(0) +{ + // Empty patch maps to signal storing mesh point labels + Map<label> meshToPatchPoint(0); + labelList patchToMeshPoint(0); + + calculateSharedPoints(meshToPatchPoint, patchToMeshPoint, keepAllPoints); +} + + +// Construct from mesh and patch of coupled faces +Foam::globalPoints::globalPoints +( + const polyMesh& mesh, + const indirectPrimitivePatch& coupledPatch, + const bool keepAllPoints +) +: + mesh_(mesh), + globalIndices_(coupledPatch.nPoints()), + nPatchPoints_(coupledPatch.nPoints()), + procPoints_(nPatchPoints_), + meshToProcPoint_(nPatchPoints_), + sharedPointAddr_(0), + sharedPointLabels_(0), + nGlobalPoints_(0) +{ + calculateSharedPoints + ( + coupledPatch.meshPointMap(), + coupledPatch.meshPoints(), + keepAllPoints + ); +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.H index c2361da2baa179208b0cf0ac2d1f9b4d8f2fc7c7..41d010ec9f2c2e91a4c5ff987ce7dbae4760d8ac 100644 --- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.H +++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalPoints.H @@ -29,9 +29,8 @@ Description Calculates points shared by more than two processor patches or cyclic patches. - Is used in globalMeshData. (this info is needed for point-edge - communication where you do all but these shared points with patch to - patch communication but need to do a reduce on these shared points) + Is used in globalMeshData. (this info is needed for point/edge + communication where processor swaps are not enough to exchange data) Works purely topological and using local communication only. Needs: @@ -41,8 +40,8 @@ Description - f[0] ordering on patch faces to be ok. Works by constructing equivalence lists for all the points on processor - patches. These list are procPointList and give processor and meshPoint - label on that processor. + patches. These list are in globalIndex numbering (so consecutively numbered + per processor) E.g. @verbatim ((7 93)(4 731)(3 114)) @@ -85,6 +84,9 @@ Description endloop until nothing changes. + Note: the data held is either mesh point labels (construct from mesh only) + or patch point labels (construct from mesh and patch). + SourceFiles globalPoints.C @@ -95,11 +97,11 @@ SourceFiles #include "DynamicList.H" #include "Map.H" -#include "labelList.H" -#include "FixedList.H" #include "primitivePatch.H" #include "className.H" #include "edgeList.H" +#include "globalIndex.H" +#include "indirectPrimitivePatch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -119,30 +121,29 @@ class globalPoints { // Private classes - //- Define procPointList as holding a list of meshPoint/processor labels - typedef FixedList<label, 2> procPoint; - typedef List<procPoint> procPointList; - // Private data //- Mesh reference const polyMesh& mesh_; + //- Global numbering of points + globalIndex globalIndices_; + //- Sum of points on processor patches (unfiltered, point on 2 patches // counts as 2) const label nPatchPoints_; //- All points on boundaries and their corresponding connected points // on other processors. - DynamicList<procPointList> procPoints_; + DynamicList<labelList> procPoints_; - //- Map from mesh point to index in procPoints + //- Map from mesh (or patch) point to index in procPoints Map<label> meshToProcPoint_; //- Shared points used by this processor (= global point number) labelList sharedPointAddr_; - //- My meshpoints corresponding to the shared points + //- My mesh(or patch) points corresponding to the shared points labelList sharedPointLabels_; //- Total number of shared points. @@ -155,56 +156,108 @@ class globalPoints // information is collected. static label countPatchPoints(const polyBoundaryMesh&); + ////- Get all faces on coupled patches + //static labelListl coupledFaces(const polyBoundaryMesh&); + //- Add information about patchPointI in relative indices to send // buffers (patchFaces, indexInFace etc.) static void addToSend ( const primitivePatch&, const label patchPointI, - const procPointList&, + const labelList&, DynamicList<label>& patchFaces, DynamicList<label>& indexInFace, - DynamicList<procPointList>& allInfo + DynamicList<labelList>& allInfo ); //- Merge info from neighbour into my data static bool mergeInfo ( - const procPointList& nbrInfo, - procPointList& myInfo + const labelList& nbrInfo, + labelList& myInfo + ); + + //- From mesh point to 'local point'. Is the mesh point itself + // if meshToPatchPoint is empty. + static label meshToLocalPoint + ( + const Map<label>& meshToPatchPoint, + const label meshPointI + ); + + //- Opposite of meshToLocalPoint. + static label localToMeshPoint + ( + const labelList& patchToMeshPoint, + const label localPointI ); //- Store (and merge) info for meshPointI - bool storeInfo(const procPointList& nbrInfo, const label meshPointI); + bool storeInfo + ( + const labelList& nbrInfo, + const label localPointI + ); //- Initialize procPoints_ to my patch points. allPoints = true: // seed with all patch points, = false: only boundaryPoints(). - void initOwnPoints(const bool allPoints, labelHashSet& changedPoints); + void initOwnPoints + ( + const Map<label>& meshToPatchPoint, + const bool allPoints, + labelHashSet& changedPoints + ); //- Send subset of procPoints to neighbours - void sendPatchPoints(const labelHashSet& changedPoints) const; + void sendPatchPoints + ( + const Map<label>&, + PstreamBuffers&, + const labelHashSet& + ) const; //- Receive neighbour points and merge into my procPoints. - void receivePatchPoints(labelHashSet& changedPoints); + void receivePatchPoints + ( + const Map<label>&, + PstreamBuffers&, + labelHashSet& + ); //- Remove entries of size 2 where meshPoint is in provided Map. // Used to remove normal face-face connected points. - void remove(const Map<label>&); + void remove(const labelList& patchToMeshPoint, const Map<label>&); + + //- Compact out unused elements of procPoints. + void compact(); //- Get indices of point for which I am master (lowest numbered proc) - labelList getMasterPoints() const; + labelList getMasterPoints(const labelList& patchToMeshPoint) const; //- Send subset of shared points to neighbours - void sendSharedPoints(const labelList& changedIndices) const; + void sendSharedPoints(PstreamBuffers&, const labelList&) const; //- Receive shared points and update subset. - void receiveSharedPoints(labelList& changedIndices); - + void receiveSharedPoints + ( + const Map<label>&, + PstreamBuffers&, + labelList& + ); - //- Should move into cyclicPolyPatch but some ordering problem + //- Should move into cyclicPolyPatch ordering problem // keeps on giving problems. static edgeList coupledPoints(const cyclicPolyPatch&); + //- Do all calculations. + void calculateSharedPoints + ( + const Map<label>&, + const labelList&, + const bool keepAllPoints + ); + //- Disallow default bitwise copy construct globalPoints(const globalPoints&); @@ -220,22 +273,44 @@ public: // Constructors - //- Construct from mesh - globalPoints(const polyMesh& mesh); + //- Construct from mesh. + // keepAllPoints = false : filter out points that are on two + // neighbouring coupled patches (so can be swapped) + globalPoints(const polyMesh& mesh, const bool keepAllPoints); + + //- Construct from mesh and patch of coupled faces. Difference with + // construct from mesh only is that this stores the meshToProcPoint, + // procPoints and sharedPointLabels as patch local point labels + // instead of mesh point labels. + globalPoints + ( + const polyMesh& mesh, + const indirectPrimitivePatch& coupledPatch, + const bool keepAllPoints + ); // Member Functions // Access - label nPatchPoints() const + //- From (mesh or patch) point to index in procPoints + const Map<label>& meshToProcPoint() const { - return nPatchPoints_; + return meshToProcPoint_; } - const Map<label>& meshToProcPoint() const + //- procPoints is per point the connected points (in global + // point numbers) + const DynamicList<labelList>& procPoints() const { - return meshToProcPoint_; + return procPoints_; + } + + //- Global numbering of (mesh or patch) points + const globalIndex& globalIndices() const + { + return globalIndices_; } //- shared points used by this processor (= global point number) @@ -244,12 +319,13 @@ public: return sharedPointAddr_; } - //- my meshpoints corresponding to the shared points + //- my (mesh or patch)points corresponding to the shared points const labelList& sharedPointLabels() const { return sharedPointLabels_; } + //- total number of shared points label nGlobalPoints() const { return nGlobalPoints_; diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C index 47620111b8244b2b105dba09ec725442935fc2ce..f9b4a37e465d416e78f6a6d3fb0c3cc5b39ca681 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C @@ -288,6 +288,7 @@ Foam::mapDistribute::mapDistribute forAll(compactMap, procI) { + compactMap[procI].clear(); if (procI != Pstream::myProcNo()) { compactMap[procI].resize(2*nNonLocal[procI]); @@ -433,6 +434,7 @@ Foam::mapDistribute::mapDistribute forAll(compactMap, procI) { + compactMap[procI].clear(); if (procI != Pstream::myProcNo()) { compactMap[procI].resize(2*nNonLocal[procI]); diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H index e0af4d6a0c5c63c423f5b0af4363ceb3f1497081..b1f78236dec9af16024d7b002e6fdda549a22d31 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H @@ -276,6 +276,49 @@ public: } } + //- Reverse distribute data using default commsType. + template<class T> + void reverseDistribute(const label constructSize, List<T>& fld) + const + { + if (Pstream::defaultCommsType == Pstream::nonBlocking) + { + distribute + ( + Pstream::nonBlocking, + List<labelPair>(), + constructSize, + constructMap_, + subMap_, + fld + ); + } + else if (Pstream::defaultCommsType == Pstream::scheduled) + { + distribute + ( + Pstream::scheduled, + schedule(), + constructSize, + constructMap_, + subMap_, + fld + ); + } + else + { + distribute + ( + Pstream::blocking, + List<labelPair>(), + constructSize, + constructMap_, + subMap_, + fld + ); + } + } + //- Correct for topo change. void updateMesh(const mapPolyMesh&) { diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C index 09ce0cb1b7dd500c60feb435916fc4396568060e..29d9fc5c96911ab930447c72592ceae76f69603f 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C @@ -552,7 +552,6 @@ void Foam::mapDistribute::distribute { if (!contiguous<T>()) { -//XXXXXX PstreamBuffers pBuffs(Pstream::nonBlocking); // Stream data into buffer diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H index 754eaf907c3c4ff4cf1e2dcaf3ed793204fd5743..ddd0b18cb20b7812505733e3a0f13c854716c3c7 100644 --- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H +++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H @@ -26,7 +26,7 @@ Class Foam::syncTools Description - Various tools to aid synchronizing lists across coupled patches. + Various tools to aid synchronizing lists across coupled patches. WIP. Require - combineOperator (e.g. sumEqOp - not sumOp!) that is defined for the @@ -34,8 +34,11 @@ Description - null value which gets overridden by any valid value. - transform function - Can apply coordinate rotation/separation on cyclics but only for faces + note:Can apply coordinate rotation/separation on cyclics but only for faces or if there is a single rotation/separation tensor. + note:syncPointList or syncEdgeList will visit shared points/edges + multiple times (once through patch exchange, once through shared + points reduce). Should be replaced by pointMesh functionality. SourceFiles syncTools.C diff --git a/src/finiteVolume/fields/fvPatchFields/basic/sliced/slicedFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/basic/sliced/slicedFvPatchField.C index 8643dba429d74f319baaed5b7920d4359127b142..ef24cbf2aad8f37cd79d1ab6a047b446947d4a52 100644 --- a/src/finiteVolume/fields/fvPatchFields/basic/sliced/slicedFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/basic/sliced/slicedFvPatchField.C @@ -55,7 +55,7 @@ slicedFvPatchField<Type>::slicedFvPatchField const DimensionedField<Type, volMesh>& iF ) : - fvPatchField<Type>(p, iF) + fvPatchField<Type>(p, iF, Field<Type>()) {} diff --git a/src/mesh/autoMesh/Make/options b/src/mesh/autoMesh/Make/options index 573d0007c1d9445f4cee37c8f74341922bbc4940..28c3d5fdf00a980939ba9d8569ce07ec91135de1 100644 --- a/src/mesh/autoMesh/Make/options +++ b/src/mesh/autoMesh/Make/options @@ -8,7 +8,6 @@ EXE_INC = \ -I$(LIB_SRC)/triSurface/lnInclude LIB_LIBS = \ - -ldecompositionMethods \ -ldynamicMesh \ -lfiniteVolume \ -llagrangian \ diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C index 83852a1affc276672917046bc881242da0366846..5bfa725225bd3110a0c6e744016711a83508d69f 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.C @@ -1506,8 +1506,12 @@ void Foam::autoSnapDriver::doSnap // meshMover. calcNearestSurface(snapDist, meshMover); - // Get smoothly varying internal displacement field. - smoothDisplacement(snapParams, meshMover); + //// Get smoothly varying internal displacement field. + //- 2009-12-16 : was not found to be beneficial. Keeping internal + // fields fixed slightly increases skewness (on boundary) + // but lowers non-orthogonality quite a bit (e.g. 65->59 degrees). + // Maybe if better smoother? + //smoothDisplacement(snapParams, meshMover); // Apply internal displacement to mesh. scaleMesh(snapParams, nInitErrors, baffles, meshMover); diff --git a/src/meshTools/Make/options b/src/meshTools/Make/options index 0ff22029260fd949e08c06a762e8352bcadf6d7c..6bf989d4f51e698d2a50738a0f0b0ef0720fbead 100644 --- a/src/meshTools/Make/options +++ b/src/meshTools/Make/options @@ -6,4 +6,5 @@ EXE_INC = \ LIB_LIBS = \ -ltriSurface \ -ldecompositionMethods \ + -lmetisDecompositionMethod \ -llagrangian diff --git a/src/parallel/Allwmake b/src/parallel/Allwmake index 34d323251aadcde80683ac1b8609faba82fc936d..48c7d4162420750e74df2092668b90005a95fffd 100755 --- a/src/parallel/Allwmake +++ b/src/parallel/Allwmake @@ -3,6 +3,7 @@ cd ${0%/*} || exit 1 # run from this directory set -x wmake libso decompositionMethods +wmake libso metisDecomp wmake libso reconstruct if [ -d "$FOAM_MPI_LIBBIN" ] diff --git a/src/parallel/decompositionMethods/Make/files b/src/parallel/decompositionMethods/Make/files index 2acbfd56060aa85ed912373d83bb9e58a00b675e..751ebe90f2e99876ac1b34743f59cc9d4054bfef 100644 --- a/src/parallel/decompositionMethods/Make/files +++ b/src/parallel/decompositionMethods/Make/files @@ -6,6 +6,4 @@ manualDecomp/manualDecomp.C scotchDecomp/scotchDecomp.C -metisDecomp/metisDecomp.C - LIB = $(FOAM_LIBBIN)/libdecompositionMethods diff --git a/src/parallel/decompositionMethods/Make/options b/src/parallel/decompositionMethods/Make/options index 97569aa663f2a4ab623cf3c5f30ec77cdbebd3c8..fe6e8b6a05f74c33087c951fcfe5b3f5b4d579b5 100644 --- a/src/parallel/decompositionMethods/Make/options +++ b/src/parallel/decompositionMethods/Make/options @@ -1,8 +1,6 @@ EXE_INC = \ - -I$(WM_THIRD_PARTY_DIR)/scotch_5.1/src/libscotch/lnInclude \ - -I$(WM_THIRD_PARTY_DIR)/metis-5.0pre2/include + -I$(WM_THIRD_PARTY_DIR)/scotch_5.1/include \ + -I../metisDecomp/lnInclude LIB_LIBS = \ - -lscotch \ - -lmetis \ - -lGKlib + -lscotch -lscotcherrexit diff --git a/src/parallel/decompositionMethods/scotchDecomp/scotchDecomp.C b/src/parallel/decompositionMethods/scotchDecomp/scotchDecomp.C index 61a9483837daef150a8aabfe8da01acfddb142b4..5375fb529bf870cc74b1bc0ad8311c6d51d0a3a2 100644 --- a/src/parallel/decompositionMethods/scotchDecomp/scotchDecomp.C +++ b/src/parallel/decompositionMethods/scotchDecomp/scotchDecomp.C @@ -61,17 +61,12 @@ License #include "scotchDecomp.H" #include "addToRunTimeSelectionTable.H" #include "floatScalar.H" -#include "IFstream.H" #include "Time.H" #include "cyclicPolyPatch.H" #include "OFstream.H" -#include "metisDecomp.H" extern "C" { -#define OMPI_SKIP_MPICXX -#include "module.h" -#include "common.h" #include "scotch.h" } @@ -115,13 +110,13 @@ void Foam::scotchDecomp::check(const int retVal, const char* str) if (retVal) { FatalErrorIn("scotchDecomp::decompose(..)") - << "Called to scotch routine " << str << " failed." + << "Call to scotch routine " << str << " failed." << exit(FatalError); } } -// Call Metis with options from dictionary. +// Call scotch with options from dictionary. Foam::label Foam::scotchDecomp::decompose ( const List<int>& adjncy, @@ -173,7 +168,7 @@ Foam::label Foam::scotchDecomp::decompose { FatalErrorIn ( - "parMetisDecomp::decompose" + "scotchDecomp::decompose" "(const pointField&, const scalarField&)" ) << "Number of cell weights " << cWeights.size() << " does not equal number of cells " << xadj.size()-1 @@ -377,7 +372,10 @@ Foam::labelList Foam::scotchDecomp::decompose { if (points.size() != mesh_.nCells()) { - FatalErrorIn("scotchDecomp::decompose(const pointField&)") + FatalErrorIn + ( + "scotchDecomp::decompose(const pointField&, const scalarField&)" + ) << "Can use this decomposition method only for the whole mesh" << endl << "and supply one coordinate (cellCentre) for every cell." << endl @@ -391,12 +389,7 @@ Foam::labelList Foam::scotchDecomp::decompose // xadj(celli) : start of information in adjncy for celli List<int> adjncy; List<int> xadj; - metisDecomp::calcMetisCSR - ( - mesh_, - adjncy, - xadj - ); + calcCSR(mesh_, adjncy, xadj); // Decompose using default weights List<int> finalDecomp; @@ -445,7 +438,7 @@ Foam::labelList Foam::scotchDecomp::decompose cellCells ); - metisDecomp::calcMetisCSR(cellCells, adjncy, xadj); + calcCSR(cellCells, adjncy, xadj); } // Decompose using weights @@ -475,7 +468,8 @@ Foam::labelList Foam::scotchDecomp::decompose { FatalErrorIn ( - "scotchDecomp::decompose(const pointField&, const labelListList&)" + "scotchDecomp::decompose" + "(const labelListList&, const pointField&, const scalarField&)" ) << "Inconsistent number of cells (" << globalCellCells.size() << ") and number of cell centres (" << cellCentres.size() << ")." << exit(FatalError); @@ -488,7 +482,7 @@ Foam::labelList Foam::scotchDecomp::decompose List<int> adjncy; List<int> xadj; - metisDecomp::calcMetisCSR(globalCellCells, adjncy, xadj); + calcCSR(globalCellCells, adjncy, xadj); // Decompose using weights List<int> finalDecomp; @@ -504,4 +498,144 @@ Foam::labelList Foam::scotchDecomp::decompose } +void Foam::scotchDecomp::calcCSR +( + const polyMesh& mesh, + List<int>& adjncy, + List<int>& xadj +) +{ + // Make Metis CSR (Compressed Storage Format) storage + // adjncy : contains neighbours (= edges in graph) + // xadj(celli) : start of information in adjncy for celli + + xadj.setSize(mesh.nCells()+1); + + // Initialise the number of internal faces of the cells to twice the + // number of internal faces + label nInternalFaces = 2*mesh.nInternalFaces(); + + // Check the boundary for coupled patches and add to the number of + // internal faces + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + + forAll(pbm, patchi) + { + if (isA<cyclicPolyPatch>(pbm[patchi])) + { + nInternalFaces += pbm[patchi].size(); + } + } + + // Create the adjncy array the size of the total number of internal and + // coupled faces + adjncy.setSize(nInternalFaces); + + // Fill in xadj + // ~~~~~~~~~~~~ + label freeAdj = 0; + + for (label cellI = 0; cellI < mesh.nCells(); cellI++) + { + xadj[cellI] = freeAdj; + + const labelList& cFaces = mesh.cells()[cellI]; + + forAll(cFaces, i) + { + label faceI = cFaces[i]; + + if + ( + mesh.isInternalFace(faceI) + || isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)]) + ) + { + freeAdj++; + } + } + } + xadj[mesh.nCells()] = freeAdj; + + + // Fill in adjncy + // ~~~~~~~~~~~~~~ + + labelList nFacesPerCell(mesh.nCells(), 0); + + // Internal faces + for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) + { + label own = mesh.faceOwner()[faceI]; + label nei = mesh.faceNeighbour()[faceI]; + + adjncy[xadj[own] + nFacesPerCell[own]++] = nei; + adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; + } + + // Coupled faces. Only cyclics done. + forAll(pbm, patchi) + { + if (isA<cyclicPolyPatch>(pbm[patchi])) + { + const unallocLabelList& faceCells = pbm[patchi].faceCells(); + + label sizeby2 = faceCells.size()/2; + + for (label facei=0; facei<sizeby2; facei++) + { + label own = faceCells[facei]; + label nei = faceCells[facei + sizeby2]; + + adjncy[xadj[own] + nFacesPerCell[own]++] = nei; + adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; + } + } + } +} + + +// From cell-cell connections to Metis format (like CompactListList) +void Foam::scotchDecomp::calcCSR +( + const labelListList& cellCells, + List<int>& adjncy, + List<int>& xadj +) +{ + // Count number of internal faces + label nConnections = 0; + + forAll(cellCells, coarseI) + { + nConnections += cellCells[coarseI].size(); + } + + // Create the adjncy array as twice the size of the total number of + // internal faces + adjncy.setSize(nConnections); + + xadj.setSize(cellCells.size()+1); + + + // Fill in xadj + // ~~~~~~~~~~~~ + label freeAdj = 0; + + forAll(cellCells, coarseI) + { + xadj[coarseI] = freeAdj; + + const labelList& cCells = cellCells[coarseI]; + + forAll(cCells, i) + { + adjncy[freeAdj++] = cCells[i]; + } + } + xadj[cellCells.size()] = freeAdj; +} + + + // ************************************************************************* // diff --git a/src/parallel/decompositionMethods/scotchDecomp/scotchDecomp.H b/src/parallel/decompositionMethods/scotchDecomp/scotchDecomp.H index 54efb1bafa283d3aa9cb1ad84c87670b2894d74e..93bcc7b9a46538d00dc2a20dcf5dd3884bdb4301 100644 --- a/src/parallel/decompositionMethods/scotchDecomp/scotchDecomp.H +++ b/src/parallel/decompositionMethods/scotchDecomp/scotchDecomp.H @@ -135,6 +135,25 @@ public: const scalarField& cWeights ); + + //- Helper to convert local connectivity (supplied as owner,neighbour) + // into CSR (Metis,scotch) storage. Does cyclics but not processor + // patches + static void calcCSR + ( + const polyMesh& mesh, + List<int>& adjncy, + List<int>& xadj + ); + + //- Helper to convert connectivity (supplied as cellcells) into + // CSR (Metis,scotch) storage + static void calcCSR + ( + const labelListList& globalCellCells, + List<int>& adjncy, + List<int>& xadj + ); }; diff --git a/src/parallel/metisDecomp/Make/files b/src/parallel/metisDecomp/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..eb1e633e18bc833a024b0e47171344f09fd4fc11 --- /dev/null +++ b/src/parallel/metisDecomp/Make/files @@ -0,0 +1,3 @@ +metisDecomp.C + +LIB = $(FOAM_LIBBIN)/libmetisDecompositionMethod diff --git a/src/parallel/metisDecomp/Make/options b/src/parallel/metisDecomp/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..a7d5398f0307436460a48f02107914159c18a1ec --- /dev/null +++ b/src/parallel/metisDecomp/Make/options @@ -0,0 +1,7 @@ +EXE_INC = \ + -I$(WM_THIRD_PARTY_DIR)/metis-5.0pre2/include \ + -I../decompositionMethods/lnInclude + +LIB_LIBS = \ + -lmetis \ + -lGKlib diff --git a/src/parallel/decompositionMethods/metisDecomp/metisDecomp.C b/src/parallel/metisDecomp/metisDecomp.C similarity index 78% rename from src/parallel/decompositionMethods/metisDecomp/metisDecomp.C rename to src/parallel/metisDecomp/metisDecomp.C index 3b2c5fb58cedddaa6fe57f771dd0ebbf15b282e8..9066e922489ea2e2dafbea3cf9cc2a86c9af7612 100644 --- a/src/parallel/decompositionMethods/metisDecomp/metisDecomp.C +++ b/src/parallel/metisDecomp/metisDecomp.C @@ -27,9 +27,8 @@ License #include "metisDecomp.H" #include "addToRunTimeSelectionTable.H" #include "floatScalar.H" -#include "IFstream.H" #include "Time.H" -#include "cyclicPolyPatch.H" +#include "scotchDecomp.H" extern "C" { @@ -331,12 +330,7 @@ Foam::labelList Foam::metisDecomp::decompose List<int> adjncy; List<int> xadj; - calcMetisCSR - ( - mesh_, - adjncy, - xadj - ); + scotchDecomp::calcCSR(mesh_, adjncy, xadj); // Decompose using default weights List<int> finalDecomp; @@ -352,145 +346,6 @@ Foam::labelList Foam::metisDecomp::decompose } -void Foam::metisDecomp::calcMetisCSR -( - const polyMesh& mesh, - List<int>& adjncy, - List<int>& xadj -) -{ - // Make Metis CSR (Compressed Storage Format) storage - // adjncy : contains neighbours (= edges in graph) - // xadj(celli) : start of information in adjncy for celli - - xadj.setSize(mesh.nCells()+1); - - // Initialise the number of internal faces of the cells to twice the - // number of internal faces - label nInternalFaces = 2*mesh.nInternalFaces(); - - // Check the boundary for coupled patches and add to the number of - // internal faces - const polyBoundaryMesh& pbm = mesh.boundaryMesh(); - - forAll(pbm, patchi) - { - if (isA<cyclicPolyPatch>(pbm[patchi])) - { - nInternalFaces += pbm[patchi].size(); - } - } - - // Create the adjncy array the size of the total number of internal and - // coupled faces - adjncy.setSize(nInternalFaces); - - // Fill in xadj - // ~~~~~~~~~~~~ - label freeAdj = 0; - - for (label cellI = 0; cellI < mesh.nCells(); cellI++) - { - xadj[cellI] = freeAdj; - - const labelList& cFaces = mesh.cells()[cellI]; - - forAll(cFaces, i) - { - label faceI = cFaces[i]; - - if - ( - mesh.isInternalFace(faceI) - || isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)]) - ) - { - freeAdj++; - } - } - } - xadj[mesh.nCells()] = freeAdj; - - - // Fill in adjncy - // ~~~~~~~~~~~~~~ - - labelList nFacesPerCell(mesh.nCells(), 0); - - // Internal faces - for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) - { - label own = mesh.faceOwner()[faceI]; - label nei = mesh.faceNeighbour()[faceI]; - - adjncy[xadj[own] + nFacesPerCell[own]++] = nei; - adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; - } - - // Coupled faces. Only cyclics done. - forAll(pbm, patchi) - { - if (isA<cyclicPolyPatch>(pbm[patchi])) - { - const unallocLabelList& faceCells = pbm[patchi].faceCells(); - - label sizeby2 = faceCells.size()/2; - - for (label facei=0; facei<sizeby2; facei++) - { - label own = faceCells[facei]; - label nei = faceCells[facei + sizeby2]; - - adjncy[xadj[own] + nFacesPerCell[own]++] = nei; - adjncy[xadj[nei] + nFacesPerCell[nei]++] = own; - } - } - } -} - - -// From cell-cell connections to Metis format (like CompactListList) -void Foam::metisDecomp::calcMetisCSR -( - const labelListList& cellCells, - List<int>& adjncy, - List<int>& xadj -) -{ - // Count number of internal faces - label nConnections = 0; - - forAll(cellCells, coarseI) - { - nConnections += cellCells[coarseI].size(); - } - - // Create the adjncy array as twice the size of the total number of - // internal faces - adjncy.setSize(nConnections); - - xadj.setSize(cellCells.size()+1); - - - // Fill in xadj - // ~~~~~~~~~~~~ - label freeAdj = 0; - - forAll(cellCells, coarseI) - { - xadj[coarseI] = freeAdj; - - const labelList& cCells = cellCells[coarseI]; - - forAll(cCells, i) - { - adjncy[freeAdj++] = cCells[i]; - } - } - xadj[cellCells.size()] = freeAdj; -} - - Foam::labelList Foam::metisDecomp::decompose ( const labelList& agglom, @@ -525,7 +380,7 @@ Foam::labelList Foam::metisDecomp::decompose cellCells ); - calcMetisCSR(cellCells, adjncy, xadj); + scotchDecomp::calcCSR(cellCells, adjncy, xadj); } // Decompose using default weights @@ -570,7 +425,7 @@ Foam::labelList Foam::metisDecomp::decompose List<int> adjncy; List<int> xadj; - calcMetisCSR(globalCellCells, adjncy, xadj); + scotchDecomp::calcCSR(globalCellCells, adjncy, xadj); // Decompose using default weights diff --git a/src/parallel/decompositionMethods/metisDecomp/metisDecomp.H b/src/parallel/metisDecomp/metisDecomp.H similarity index 89% rename from src/parallel/decompositionMethods/metisDecomp/metisDecomp.H rename to src/parallel/metisDecomp/metisDecomp.H index 6a38e25c8a83bd0fd12285f1bb1608dec5829df3..c585686f60e9e96d87ef706907bfe37940176bfd 100644 --- a/src/parallel/decompositionMethods/metisDecomp/metisDecomp.H +++ b/src/parallel/metisDecomp/metisDecomp.H @@ -132,24 +132,6 @@ public: const scalarField& cWeights ); - //- Helper to convert connectivity (supplied as owner,neighbour) into - // Metis storage - static void calcMetisCSR - ( - const polyMesh& mesh, - List<int>& adjncy, - List<int>& xadj - ); - - //- Helper to convert connectivity (supplied as cellcells) into - // Metis storage - static void calcMetisCSR - ( - const labelListList& globalCellCells, - List<int>& adjncy, - List<int>& xadj - ); - }; diff --git a/src/parallel/parMetisDecomp/Make/options b/src/parallel/parMetisDecomp/Make/options index 475bf5dbb17c41f753c8fe86906486f089ca956f..79beb369af56c61636ac24c0c015c455629f2e2f 100644 --- a/src/parallel/parMetisDecomp/Make/options +++ b/src/parallel/parMetisDecomp/Make/options @@ -4,7 +4,8 @@ EXE_INC = \ $(PFLAGS) $(PINC) \ -I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1/ParMETISLib \ -I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1 \ - -I../decompositionMethods/lnInclude + -I../decompositionMethods/lnInclude \ + -I../metisDecomp/lnInclude LIB_LIBS = \ -L$(FOAM_MPI_LIBBIN) \ diff --git a/src/parallel/parMetisDecomp/parMetisDecomp.C b/src/parallel/parMetisDecomp/parMetisDecomp.C index c4dde21d65799a895d1fd5f2d913acfc08d6c5d7..cf7434b5c9ee7846f5599598251f0c065b0488bb 100644 --- a/src/parallel/parMetisDecomp/parMetisDecomp.C +++ b/src/parallel/parMetisDecomp/parMetisDecomp.C @@ -26,6 +26,7 @@ License #include "parMetisDecomp.H" #include "metisDecomp.H" +#include "scotchDecomp.H" #include "syncTools.H" #include "addToRunTimeSelectionTable.H" #include "floatScalar.H" @@ -434,7 +435,7 @@ Foam::labelList Foam::parMetisDecomp::decompose { FatalErrorIn ( - "metisDecomp::decompose" + "parMetisDecomp::decompose" "(const pointField&, const scalarField&)" ) << "Number of cell weights " << cWeights.size() << " does not equal number of cells " << mesh_.nCells() @@ -762,7 +763,7 @@ Foam::labelList Foam::parMetisDecomp::decompose Field<int> adjncy; // Offsets into adjncy Field<int> xadj; - metisDecomp::calcMetisCSR(globalCellCells, adjncy, xadj); + scotchDecomp::calcCSR(globalCellCells, adjncy, xadj); // decomposition options. 0 = use defaults List<int> options(3, 0); diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentTemperatureCoupledBaffle/turbulentTemperatureCoupledBaffleFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentTemperatureCoupledBaffle/turbulentTemperatureCoupledBaffleFvPatchScalarField.H index 3438b6025610a4f48733820b7ed5e2d79b4eb408..8c7014a9003b9ca2b85073c9b790f6ec2e496b50 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentTemperatureCoupledBaffle/turbulentTemperatureCoupledBaffleFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentTemperatureCoupledBaffle/turbulentTemperatureCoupledBaffleFvPatchScalarField.H @@ -36,7 +36,7 @@ Description Example usage: myInterfacePatchName { - type turbulentTemperatureCoupledBaffle; + type compressible::turbulentTemperatureCoupledBaffle; neighbourFieldName T; K K; // or none value uniform 300; diff --git a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentTemperatureCoupledBaffleMixed/turbulentTemperatureCoupledBaffleMixedFvPatchScalarField.H b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentTemperatureCoupledBaffleMixed/turbulentTemperatureCoupledBaffleMixedFvPatchScalarField.H index 22df0cad0aec5f9bc0240a099c1ad5b2f1240d5d..c4a6a7a7634bbbe289165a3222753e5b235d2a34 100644 --- a/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentTemperatureCoupledBaffleMixed/turbulentTemperatureCoupledBaffleMixedFvPatchScalarField.H +++ b/src/turbulenceModels/compressible/RAS/derivedFvPatchFields/turbulentTemperatureCoupledBaffleMixed/turbulentTemperatureCoupledBaffleMixedFvPatchScalarField.H @@ -37,7 +37,7 @@ Description Example usage: myInterfacePatchName { - type turbulentTemperatureCoupledBaffleMixed; + type compressible::turbulentTemperatureCoupledBaffleMixed; neighbourFieldName T; K K; // or none value uniform 300; diff --git a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict index 714a95ebbfeecf3e1e137885890666da75641e4e..94282655bb34b04acb2492324cff2ab8a7e4e168 100644 --- a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict +++ b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict @@ -220,6 +220,12 @@ castellatedMeshControls // NOTE: This point should never be on a face, always inside a cell, even // after refinement. locationInMesh (3 0.28 0.43); + + + // Whether any faceZones (as specified in the refinementSurfaces) + // are only on the boundary of corresponding cellZones or also allow + // free-standing zone faces. Not used if there are no faceZones. + allowFreeStandingZoneFaces true; } @@ -311,7 +317,8 @@ addLayersControls maxThicknessToMedialRatio 0.3; // Angle used to pick up medial axis points - minMedianAxisAngle 130; + // Note: changed(corrected) w.r.t 16x! 90 degrees corresponds to 130 in 16x. + minMedianAxisAngle 90; // Create buffer region for new layer terminations nBufferCellsNoExtrude 0; diff --git a/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict b/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict index 70593293f560d1e861fea6ad5774bb2024ccc415..948273e71d41956bf05892b5659c6703f1178947 100644 --- a/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict +++ b/tutorials/incompressible/simpleFoam/motorBike/system/snappyHexMeshDict @@ -145,6 +145,12 @@ castellatedMeshControls // NOTE: This point should never be on a face, always inside a cell, even // after refinement. locationInMesh (3 3 0.43); + + + // Whether any faceZones (as specified in the refinementSurfaces) + // are only on the boundary of corresponding cellZones or also allow + // free-standing zone faces. Not used if there are no faceZones. + allowFreeStandingZoneFaces true; } @@ -500,7 +506,9 @@ addLayersControls maxThicknessToMedialRatio 0.3; // Angle used to pick up medial axis points - minMedianAxisAngle 130; + // Note: changed(corrected) w.r.t 16x! 90 degrees corresponds to 130 in 16x. + minMedianAxisAngle 90; + // Create buffer region for new layer terminations nBufferCellsNoExtrude 0;