diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 321855de69a28a53a8a1dde8ee3da614ff8cc626..554e890db9de49de806fb5e9bfe4d419b37c0aaf 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -328,6 +328,8 @@ masterCoarsestGAMGProcAgglomeration = $(GAMGProcAgglomerations)/masterCoarsestGA $(masterCoarsestGAMGProcAgglomeration)/masterCoarsestGAMGProcAgglomeration.C manualGAMGProcAgglomeration = $(GAMGProcAgglomerations)/manualGAMGProcAgglomeration $(manualGAMGProcAgglomeration)/manualGAMGProcAgglomeration.C +eagerGAMGProcAgglomeration = $(GAMGProcAgglomerations)/eagerGAMGProcAgglomeration +$(eagerGAMGProcAgglomeration)/eagerGAMGProcAgglomeration.C /* cellFaceRatioGAMGProcAgglomeration = $(GAMGProcAgglomerations)/cellFaceRatioGAMGProcAgglomeration $(cellFaceRatioGAMGProcAgglomeration)/cellFaceRatioGAMGProcAgglomeration.C diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C index 324ace4c917d77939f31ab4b84c10d5e6b82ae44..a572f5ff43b23c5fc293d3364e130eed7b54f63b 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C @@ -121,7 +121,10 @@ Foam::GAMGAgglomeration::GAMGAgglomeration ), procAgglomeratorPtr_ ( - controlDict.found("processorAgglomerator") + ( + (UPstream::nProcs(mesh.comm()) > 1) + && controlDict.found("processorAgglomerator") + ) ? GAMGProcAgglomeration::New ( controlDict.lookup("processorAgglomerator"), diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/eagerGAMGProcAgglomeration/eagerGAMGProcAgglomeration.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/eagerGAMGProcAgglomeration/eagerGAMGProcAgglomeration.C new file mode 100644 index 0000000000000000000000000000000000000000..c1f166d1ec3a4c1f1376bea067c572302779bb18 --- /dev/null +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/eagerGAMGProcAgglomeration/eagerGAMGProcAgglomeration.C @@ -0,0 +1,168 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ 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 3 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, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "eagerGAMGProcAgglomeration.H" +#include "addToRunTimeSelectionTable.H" +#include "GAMGAgglomeration.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(eagerGAMGProcAgglomeration, 0); + + addToRunTimeSelectionTable + ( + GAMGProcAgglomeration, + eagerGAMGProcAgglomeration, + GAMGAgglomeration + ); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::eagerGAMGProcAgglomeration::eagerGAMGProcAgglomeration +( + GAMGAgglomeration& agglom, + const dictionary& controlDict +) +: + GAMGProcAgglomeration(agglom, controlDict), + mergeLevels_(controlDict.lookupOrDefault<label>("mergeLevels", 1)) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::eagerGAMGProcAgglomeration:: +~eagerGAMGProcAgglomeration() +{ + forAllReverse(comms_, i) + { + if (comms_[i] != -1) + { + UPstream::freeCommunicator(comms_[i]); + } + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::eagerGAMGProcAgglomeration::agglomerate() +{ + if (debug) + { + Pout<< nl << "Starting mesh overview" << endl; + printStats(Pout, agglom_); + } + + if (agglom_.size() >= 1) + { + // Agglomerate one but last level (since also agglomerating + // restrictAddressing) + for + ( + label fineLevelIndex = 2; + fineLevelIndex < agglom_.size(); + fineLevelIndex++ + ) + { + if (agglom_.hasMeshLevel(fineLevelIndex)) + { + // Get the fine mesh + const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex); + label levelComm = levelMesh.comm(); + label nProcs = UPstream::nProcs(levelComm); + + if (nProcs > 1) + { + // Processor restriction map: per processor the coarse + // processor + labelList procAgglomMap(nProcs); + + forAll(procAgglomMap, procI) + { + procAgglomMap[procI] = procI/(1<<mergeLevels_); + } + + // Master processor + labelList masterProcs; + // Local processors that agglomerate. agglomProcIDs[0] + // is in masterProc. + List<int> agglomProcIDs; + GAMGAgglomeration::calculateRegionMaster + ( + levelComm, + procAgglomMap, + masterProcs, + agglomProcIDs + ); + + // Allocate a communicator for the processor-agglomerated + // matrix + comms_.append + ( + UPstream::allocateCommunicator + ( + levelComm, + masterProcs + ) + ); + + // Use procesor agglomeration maps to do the actual + // collecting. + if (Pstream::myProcNo(levelComm) != -1) + { + GAMGProcAgglomeration::agglomerate + ( + fineLevelIndex, + procAgglomMap, + masterProcs, + agglomProcIDs, + comms_.last() + ); + } + } + } + } + } + + // Print a bit + if (debug) + { + Pout<< nl << "Agglomerated mesh overview" << endl; + printStats(Pout, agglom_); + } + + return true; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/eagerGAMGProcAgglomeration/eagerGAMGProcAgglomeration.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/eagerGAMGProcAgglomeration/eagerGAMGProcAgglomeration.H new file mode 100644 index 0000000000000000000000000000000000000000..99bc37941c005f6ea55fedc7014ce4620108e582 --- /dev/null +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/eagerGAMGProcAgglomeration/eagerGAMGProcAgglomeration.H @@ -0,0 +1,113 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ 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 3 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, see <http://www.gnu.org/licenses/>. + +Class + Foam::eagerGAMGProcAgglomeration + +Description + 'Eager' processor agglomeration of GAMGAgglomerations: at every + level agglomerates 'mergeLevels' number of processors onto the + minimum processor number. + +SourceFiles + eagerGAMGProcAgglomeration.C + +\*---------------------------------------------------------------------------*/ + +#ifndef eagerGAMGProcAgglomeration_H +#define eagerGAMGProcAgglomeration_H + +#include "GAMGProcAgglomeration.H" +#include "DynamicList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class GAMGAgglomeration; + +/*---------------------------------------------------------------------------*\ + Class eagerGAMGProcAgglomeration Declaration +\*---------------------------------------------------------------------------*/ + +class eagerGAMGProcAgglomeration +: + public GAMGProcAgglomeration +{ + // Private data + + //- Agglpmeration level + const label mergeLevels_; + + DynamicList<label> comms_; + + // Private Member Functions + + //- Disallow default bitwise copy construct + eagerGAMGProcAgglomeration + ( + const eagerGAMGProcAgglomeration& + ); + + //- Disallow default bitwise assignment + void operator=(const eagerGAMGProcAgglomeration&); + + +public: + + //- Runtime type information + TypeName("eager"); + + + // Constructors + + //- Construct given agglomerator and controls + eagerGAMGProcAgglomeration + ( + GAMGAgglomeration& agglom, + const dictionary& controlDict + ); + + + //- Destructor + virtual ~eagerGAMGProcAgglomeration(); + + + // Member Functions + + //- Modify agglomeration. Return true if modified + virtual bool agglomerate(); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // 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 b2f968aaf696d3057d4648ea5cff7e3c56223dcb..1fea00057c63073558ae62e3ebca33fd170ce6c6 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.C @@ -102,95 +102,104 @@ bool Foam::manualGAMGProcAgglomeration::agglomerate() { // Get the fine mesh const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex); + label nProcs = UPstream::nProcs(levelMesh.comm()); - // My processor id - const label myProcID = Pstream::myProcNo(levelMesh.comm()); - - const List<clusterAndMaster>& clusters = - procAgglomMaps_[i].second(); + if (nProcs > 1) + { + // My processor id + const label myProcID = Pstream::myProcNo(levelMesh.comm()); - // Coarse to fine master processor - labelList coarseToMaster(clusters.size()); + const List<clusterAndMaster>& clusters = + procAgglomMaps_[i].second(); - // Fine to coarse map - labelList procAgglomMap(Pstream::nProcs(levelMesh.comm()), -1); + // Coarse to fine master processor + labelList coarseToMaster(clusters.size()); - // Cluster for my processor (with master index first) - labelList agglomProcIDs; + // Fine to coarse map + labelList procAgglomMap(nProcs, -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) + forAll(clusters, coarseI) { - procAgglomMap[cluster[i]] = coarseI; + const labelList& cluster = clusters[coarseI].first(); + coarseToMaster[coarseI] = clusters[coarseI].second(); + + forAll(cluster, i) + { + procAgglomMap[cluster[i]] = coarseI; + } + + 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]); + } } - label masterIndex = findIndex - ( - cluster, - coarseToMaster[coarseI] - ); - if (masterIndex == -1) + // Check that we've done all processors + if (findIndex(procAgglomMap, -1) != -1) { FatalErrorIn ( "manualGAMGProcAgglomeration::agglomerate()" ) << "At level " << fineLevelIndex - << " the master processor " - << coarseToMaster[coarseI] - << " is not in the cluster " - << cluster + << " processor " + << findIndex(procAgglomMap, -1) + << " is not in any 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 - << " processor " - << findIndex(procAgglomMap, -1) - << " is not in any cluster" - << exit(FatalError); - } - - - // Allocate a communicator for the processor-agglomerated matrix - comms_.append - ( - UPstream::allocateCommunicator - ( - levelMesh.comm(), - coarseToMaster - ) - ); - - // Use procesor agglomeration maps to do the actual collecting. - if (Pstream::myProcNo(levelMesh.comm()) != -1) - { - GAMGProcAgglomeration::agglomerate + // Allocate a communicator for the processor-agglomerated + // matrix + comms_.append ( - fineLevelIndex, - procAgglomMap, - coarseToMaster, - agglomProcIDs, - comms_.last() + UPstream::allocateCommunicator + ( + levelMesh.comm(), + coarseToMaster + ) ); + + // Use procesor agglomeration maps to do the actual + // collecting + if (Pstream::myProcNo(levelMesh.comm()) != -1) + { + GAMGProcAgglomeration::agglomerate + ( + fineLevelIndex, + procAgglomMap, + coarseToMaster, + agglomProcIDs, + comms_.last() + ); + } } } } diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.C index 8f3552c9ff12ce82200a1510005441febb0fdfd7..480795fb558b0b0da85fed8218006ecec9624ce9 100644 --- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.C +++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.C @@ -93,44 +93,48 @@ bool Foam::masterCoarsestGAMGProcAgglomeration::agglomerate() // Get the fine mesh const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex); label levelComm = levelMesh.comm(); + label nProcs = UPstream::nProcs(levelComm); - // Processor restriction map: per processor the coarse processor - labelList procAgglomMap(UPstream::nProcs(levelComm), 0); - - // Master processor - labelList masterProcs; - // Local processors that agglomerate. agglomProcIDs[0] is in - // masterProc. - List<int> agglomProcIDs; - GAMGAgglomeration::calculateRegionMaster - ( - levelComm, - procAgglomMap, - masterProcs, - agglomProcIDs - ); - - // Allocate a communicator for the processor-agglomerated matrix - comms_.append - ( - UPstream::allocateCommunicator - ( - levelComm, - masterProcs - ) - ); - - // Use procesor agglomeration maps to do the actual collecting. - if (Pstream::myProcNo(levelComm) != -1) + if (nProcs > 1) { - GAMGProcAgglomeration::agglomerate + // Processor restriction map: per processor the coarse processor + labelList procAgglomMap(nProcs, 0); + + // Master processor + labelList masterProcs; + // Local processors that agglomerate. agglomProcIDs[0] is in + // masterProc. + List<int> agglomProcIDs; + GAMGAgglomeration::calculateRegionMaster ( - fineLevelIndex, + levelComm, procAgglomMap, masterProcs, - agglomProcIDs, - comms_.last() + agglomProcIDs ); + + // Allocate a communicator for the processor-agglomerated matrix + comms_.append + ( + UPstream::allocateCommunicator + ( + levelComm, + masterProcs + ) + ); + + // Use procesor agglomeration maps to do the actual collecting. + if (Pstream::myProcNo(levelComm) != -1) + { + GAMGProcAgglomeration::agglomerate + ( + fineLevelIndex, + procAgglomMap, + masterProcs, + agglomProcIDs, + comms_.last() + ); + } } } }