ENH: GAMGProcAgglomeration: check for parallel running

This commit is contained in:
mattijs
2013-04-20 20:59:24 +01:00
parent 7c022605e7
commit c983a581d4
6 changed files with 402 additions and 103 deletions

View File

@ -328,6 +328,8 @@ masterCoarsestGAMGProcAgglomeration = $(GAMGProcAgglomerations)/masterCoarsestGA
$(masterCoarsestGAMGProcAgglomeration)/masterCoarsestGAMGProcAgglomeration.C $(masterCoarsestGAMGProcAgglomeration)/masterCoarsestGAMGProcAgglomeration.C
manualGAMGProcAgglomeration = $(GAMGProcAgglomerations)/manualGAMGProcAgglomeration manualGAMGProcAgglomeration = $(GAMGProcAgglomerations)/manualGAMGProcAgglomeration
$(manualGAMGProcAgglomeration)/manualGAMGProcAgglomeration.C $(manualGAMGProcAgglomeration)/manualGAMGProcAgglomeration.C
eagerGAMGProcAgglomeration = $(GAMGProcAgglomerations)/eagerGAMGProcAgglomeration
$(eagerGAMGProcAgglomeration)/eagerGAMGProcAgglomeration.C
/* /*
cellFaceRatioGAMGProcAgglomeration = $(GAMGProcAgglomerations)/cellFaceRatioGAMGProcAgglomeration cellFaceRatioGAMGProcAgglomeration = $(GAMGProcAgglomerations)/cellFaceRatioGAMGProcAgglomeration
$(cellFaceRatioGAMGProcAgglomeration)/cellFaceRatioGAMGProcAgglomeration.C $(cellFaceRatioGAMGProcAgglomeration)/cellFaceRatioGAMGProcAgglomeration.C

View File

@ -121,7 +121,10 @@ Foam::GAMGAgglomeration::GAMGAgglomeration
), ),
procAgglomeratorPtr_ procAgglomeratorPtr_
( (
controlDict.found("processorAgglomerator") (
(UPstream::nProcs(mesh.comm()) > 1)
&& controlDict.found("processorAgglomerator")
)
? GAMGProcAgglomeration::New ? GAMGProcAgglomeration::New
( (
controlDict.lookup("processorAgglomerator"), controlDict.lookup("processorAgglomerator"),

View File

@ -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;
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -102,95 +102,104 @@ bool Foam::manualGAMGProcAgglomeration::agglomerate()
{ {
// Get the fine mesh // Get the fine mesh
const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex); const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex);
label nProcs = UPstream::nProcs(levelMesh.comm());
// My processor id if (nProcs > 1)
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(); // My processor id
coarseToMaster[coarseI] = clusters[coarseI].second(); const label myProcID = Pstream::myProcNo(levelMesh.comm());
forAll(cluster, i) const List<clusterAndMaster>& clusters =
procAgglomMaps_[i].second();
// Coarse to fine master processor
labelList coarseToMaster(clusters.size());
// Fine to coarse map
labelList procAgglomMap(nProcs, -1);
// Cluster for my processor (with master index first)
labelList agglomProcIDs;
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 FatalErrorIn
( (
"manualGAMGProcAgglomeration::agglomerate()" "manualGAMGProcAgglomeration::agglomerate()"
) << "At level " << fineLevelIndex ) << "At level " << fineLevelIndex
<< " the master processor " << " processor "
<< coarseToMaster[coarseI] << findIndex(procAgglomMap, -1)
<< " is not in the cluster " << " is not in any cluster"
<< cluster
<< exit(FatalError); << exit(FatalError);
} }
if (findIndex(cluster, myProcID) != -1)
{
// This is my cluster. Make sure master index is first
agglomProcIDs = cluster;
Swap(agglomProcIDs[0], agglomProcIDs[masterIndex]);
}
}
// Allocate a communicator for the processor-agglomerated
// Check that we've done all processors // matrix
if (findIndex(procAgglomMap, -1) != -1) comms_.append
{
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(), UPstream::allocateCommunicator
coarseToMaster (
) 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()
); );
// Use procesor agglomeration maps to do the actual
// collecting
if (Pstream::myProcNo(levelMesh.comm()) != -1)
{
GAMGProcAgglomeration::agglomerate
(
fineLevelIndex,
procAgglomMap,
coarseToMaster,
agglomProcIDs,
comms_.last()
);
}
} }
} }
} }

View File

@ -93,44 +93,48 @@ bool Foam::masterCoarsestGAMGProcAgglomeration::agglomerate()
// Get the fine mesh // Get the fine mesh
const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex); const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex);
label levelComm = levelMesh.comm(); label levelComm = levelMesh.comm();
label nProcs = UPstream::nProcs(levelComm);
// Processor restriction map: per processor the coarse processor if (nProcs > 1)
labelList procAgglomMap(UPstream::nProcs(levelComm), 0); {
// Processor restriction map: per processor the coarse processor
labelList procAgglomMap(nProcs, 0);
// Master processor // Master processor
labelList masterProcs; labelList masterProcs;
// Local processors that agglomerate. agglomProcIDs[0] is in // Local processors that agglomerate. agglomProcIDs[0] is in
// masterProc. // masterProc.
List<int> agglomProcIDs; List<int> agglomProcIDs;
GAMGAgglomeration::calculateRegionMaster GAMGAgglomeration::calculateRegionMaster
(
levelComm,
procAgglomMap,
masterProcs,
agglomProcIDs
);
// Allocate a communicator for the processor-agglomerated matrix
comms_.append
(
UPstream::allocateCommunicator
( (
levelComm, levelComm,
masterProcs
)
);
// Use procesor agglomeration maps to do the actual collecting.
if (Pstream::myProcNo(levelComm) != -1)
{
GAMGProcAgglomeration::agglomerate
(
fineLevelIndex,
procAgglomMap, procAgglomMap,
masterProcs, masterProcs,
agglomProcIDs, agglomProcIDs
comms_.last()
); );
// 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()
);
}
} }
} }
} }