From c6d4035ced915c4e95587a25201920d93e1acaa3 Mon Sep 17 00:00:00 2001 From: mattijs <mattijs> Date: Mon, 4 Jan 2010 13:25:30 +0000 Subject: [PATCH] Added master-slave addressing for coupled points. - Rewrote globalPoints to use globalIndex class so now only transfers single label instead of labelPair - Added addressing in globalMeshData - from coupled master points to slave points - ,, edges ,, edges - from coupled points (master or slave) to uncoupled boundary faces - ,, ,, cells - See test/globalMeshData for simple test --- applications/test/globalMeshData/Make/files | 3 + applications/test/globalMeshData/Make/options | 3 + .../test/globalMeshData/globalMeshDataTest.C | 221 +++++ .../polyMesh/globalMeshData/globalMeshData.C | 821 +++++++++++++++++- .../polyMesh/globalMeshData/globalMeshData.H | 104 ++- .../polyMesh/globalMeshData/globalPoints.C | 694 +++++++++------ .../polyMesh/globalMeshData/globalPoints.H | 146 +++- 7 files changed, 1627 insertions(+), 365 deletions(-) create mode 100644 applications/test/globalMeshData/Make/files create mode 100644 applications/test/globalMeshData/Make/options create mode 100644 applications/test/globalMeshData/globalMeshDataTest.C diff --git a/applications/test/globalMeshData/Make/files b/applications/test/globalMeshData/Make/files new file mode 100644 index 00000000000..dc5877e3835 --- /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 00000000000..4c3dd783cb4 --- /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 00000000000..75f98b1b9ce --- /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/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C index 147b370d1a2..1b3bb264a21 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 7c4893126d7..a6e03baf957 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 bd94a301420..6dfc702fdd6 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 c2361da2baa..41d010ec9f2 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_; -- GitLab