Newer
Older
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
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 "masterCoarsestGAMGProcAgglomeration.H"
#include "addToRunTimeSelectionTable.H"
#include "GAMGAgglomeration.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(masterCoarsestGAMGProcAgglomeration, 0);
addToRunTimeSelectionTable
(
GAMGProcAgglomeration,
GAMGAgglomeration
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::masterCoarsestGAMGProcAgglomeration::masterCoarsestGAMGProcAgglomeration
(
GAMGAgglomeration& agglom,
const dictionary& controlDict
)
:
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
GAMGProcAgglomeration(agglom, controlDict),
nProcessorsPerMaster_
(
controlDict.getOrDefault<label>
(
"nProcessorsPerMaster",
0,
keyType::LITERAL
)
)
{
const auto* ePtr = controlDict.findEntry("nMasters", keyType::LITERAL);
if (ePtr)
{
if (nProcessorsPerMaster_ > 0)
{
FatalIOErrorInFunction(controlDict)
<< "Cannot specify both \"nMasters\" and"
<< " \"nProcessorsPerMaster\"" << exit(FatalIOError);
}
const label nMasters(readLabel(ePtr->stream()));
if (nMasters <= 0)
{
FatalIOErrorInFunction(controlDict)
<< "Illegal value \"nMasters\" "
<< nMasters << exit(FatalIOError);
}
nProcessorsPerMaster_ =
(Pstream::nProcs(agglom.mesh().comm())+nMasters-1)
/ nMasters;
}
if (nProcessorsPerMaster_ < 0)
{
FatalIOErrorInFunction(controlDict)
<< "Illegal value \"nProcessorsPerMaster\" "
<< nProcessorsPerMaster_ << exit(FatalIOError);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::masterCoarsestGAMGProcAgglomeration::
~masterCoarsestGAMGProcAgglomeration()
{
forAllReverse(comms_, i)
{
if (comms_[i] != -1)
{
UPstream::freeCommunicator(comms_[i]);
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::masterCoarsestGAMGProcAgglomeration::agglomerate()
{
Pout<< nl << "Starting mesh overview" << endl;
printStats(Pout, agglom_);
}
if (agglom_.size() >= 1)
{
// Agglomerate one but last level (since also agglomerating
// restrictAddressing)
label fineLevelIndex = agglom_.size()-1;
// 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(nProcs);
if (nProcessorsPerMaster_ > 0)
{
forAll(procAgglomMap, fineProci)
{
procAgglomMap[fineProci] =
(
fineProci
/ nProcessorsPerMaster_
);
}
}
else
{
procAgglomMap = Zero;
}
// Master processor
labelList masterProcs;
// Local processors that agglomerate. agglomProcIDs[0] is in
// masterProc.
GAMGAgglomeration::calculateRegionMaster
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
if (debug)
{
if (masterProcs.size())
{
labelListList masterToProcs
(
invertOneToMany
(
masterProcs.size(),
procAgglomMap
)
);
Info<< typeName << " : agglomerating" << nl
<< "\tmaster\tnProcs\tprocIDs" << endl;
for (const auto& p : masterToProcs)
{
Info<< '\t' << p[0]
<< '\t' << p.size()
<< '\t'
<< flatOutput(SubList<label>(p, p.size()-1, 1))
<< endl;
}
}
}
// Allocate a communicator for the processor-agglomerated matrix
comms_.append
(
UPstream::allocateCommunicator
(
levelComm,
masterProcs
)
);
// Use processor agglomeration maps to do the actual collecting.
if (Pstream::myProcNo(levelComm) != -1)
{
GAMGProcAgglomeration::agglomerate
(
fineLevelIndex,
procAgglomMap,
masterProcs,
agglomProcIDs,
comms_.last()
);
}