diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.C index 9e0439c578f5db795e24cef96acc522d776cd6ee..b2f968aaf696d3057d4648ea5cff7e3c56223dcb 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.C @@ -98,37 +98,77 @@ bool Foam::manualGAMGProcAgglomeration::agglomerate() continue; } - if (agglom_.hasMeshLevel(fineLevelIndex)) { - const labelList& procAgglomMap = procAgglomMaps_[i].second(); // Get the fine mesh const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex); + // My processor id + const label myProcID = Pstream::myProcNo(levelMesh.comm()); + + const List<clusterAndMaster>& clusters = + procAgglomMaps_[i].second(); + + // Coarse to fine master processor + labelList coarseToMaster(clusters.size()); + + // Fine to coarse map + labelList procAgglomMap(Pstream::nProcs(levelMesh.comm()), -1); + + // Cluster for my processor (with master index first) + labelList agglomProcIDs; + + + + forAll(clusters, coarseI) + { + const labelList& cluster = clusters[coarseI].first(); + coarseToMaster[coarseI] = clusters[coarseI].second(); + + forAll(cluster, i) + { + procAgglomMap[cluster[i]] = coarseI; + } - if (procAgglomMap.size() != Pstream::nProcs(levelMesh.comm())) + label masterIndex = findIndex + ( + cluster, + coarseToMaster[coarseI] + ); + + if (masterIndex == -1) + { + FatalErrorIn + ( + "manualGAMGProcAgglomeration::agglomerate()" + ) << "At level " << fineLevelIndex + << " the master processor " + << coarseToMaster[coarseI] + << " is not in the cluster " + << cluster + << exit(FatalError); + } + + if (findIndex(cluster, myProcID) != -1) + { + // This is my cluster. Make sure master index is first + agglomProcIDs = cluster; + Swap(agglomProcIDs[0], agglomProcIDs[masterIndex]); + } + } + + + // Check that we've done all processors + if (findIndex(procAgglomMap, -1) != -1) { FatalErrorIn("manualGAMGProcAgglomeration::agglomerate()") << "At level " << fineLevelIndex - << "The fine-to-coarse agglomeration map size " - << procAgglomMap.size() << " differs from the" - << " number of processors " - << Pstream::nProcs(levelMesh.comm()) + << " processor " + << findIndex(procAgglomMap, -1) + << " is not in any cluster" << exit(FatalError); } - // Master processor - labelList masterProcs; - // Local processors that agglomerate. agglomProcIDs[0] is in - // masterProc. - List<int> agglomProcIDs; - GAMGAgglomeration::calculateRegionMaster - ( - levelMesh.comm(), - procAgglomMap, - masterProcs, - agglomProcIDs - ); // Allocate a communicator for the processor-agglomerated matrix comms_.append @@ -136,7 +176,7 @@ bool Foam::manualGAMGProcAgglomeration::agglomerate() UPstream::allocateCommunicator ( levelMesh.comm(), - masterProcs + coarseToMaster ) ); @@ -147,7 +187,7 @@ bool Foam::manualGAMGProcAgglomeration::agglomerate() ( fineLevelIndex, procAgglomMap, - masterProcs, + coarseToMaster, agglomProcIDs, comms_.last() ); diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.H index 70679070918e1fbe17c696bd35a5bedd4137b3fa..c7efec92f0ff9733526de56953684c79430ed445 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.H +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.H @@ -27,23 +27,26 @@ Class Description Manual processor agglomeration of GAMGAgglomerations. - In the GAMG defintion: + In the GAMG control dictionary: processorAgglomerator manual; processorAgglomeration ( - (3 (0 0 1 1)) - (6 (0 0)) + ( + 3 //at level 3 + ( + ((0 1) 0) //coarse 0 from 0,1 (and moved onto 0) + ((2 3) 3) //coarse 1 from 2,3 (and moved onto 3) + ) + ) + ( + 6 //at level6 + ( + ((0 1) 0) //coarse 0 from 0,1 (and moved onto 0) + ) + ) ); - which says that - - at level 3 of the agglomeration processors 0 and 1 will combine - into coarse processor 0 (located on processor0) and 2,3 - will combine into coarse processor 1 (located on 2) - (currently the master is always the minimum of the set) - - at level 6 of the agglomeration coarse processors 0 and 1 will combine - into coarse processor 0 (located on the minimum, processor 0) - SourceFiles manualGAMGProcAgglomeration.C @@ -73,8 +76,10 @@ class manualGAMGProcAgglomeration { // Private data + typedef Tuple2<labelList, label> clusterAndMaster; + //- Per level the agglomeration map - const List<Tuple2<label, labelList> > procAgglomMaps_; + const List<Tuple2<label, List<clusterAndMaster> > > procAgglomMaps_; //- Any allocated communicators DynamicList<label> comms_;