1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "simpleGeomDecomp.H"
28 #include "addToRunTimeSelectionTable.H"
29 #include "SortableList.H"
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 defineTypeNameAndDebug(simpleGeomDecomp, 0);
37 addToRunTimeSelectionTable
44 addToRunTimeSelectionTable
52 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54 // assignToProcessorGroup : given nCells cells and nProcGroup processor
55 // groups to share them, how do we share them out? Answer : each group
56 // gets nCells/nProcGroup cells, and the first few get one
57 // extra to make up the numbers. This should produce almost
58 // perfect load balancing
60 void Foam::simpleGeomDecomp::assignToProcessorGroup
62 labelList& processorGroup,
63 const label nProcGroup
66 label jump = processorGroup.size()/nProcGroup;
67 label jumpb = jump + 1;
68 label fstProcessorGroup = processorGroup.size() - jump*nProcGroup;
73 // assign cells to the first few processor groups (those with
74 // one extra cell each
75 for (j=0; j<fstProcessorGroup; j++)
77 for (register label k=0; k<jumpb; k++)
79 processorGroup[ind++] = j;
83 // and now to the `normal' processor groups
84 for (; j<nProcGroup; j++)
86 for (register label k=0; k<jump; k++)
88 processorGroup[ind++] = j;
94 void Foam::simpleGeomDecomp::assignToProcessorGroup
96 labelList& processorGroup,
97 const label nProcGroup,
98 const labelList& indices,
99 const scalarField& weights,
100 const scalar summedWeights
103 // This routine gets the sorted points.
104 // Easiest to explain with an example.
105 // E.g. 400 points, sum of weights : 513.
106 // Now with number of divisions in this direction (nProcGroup) : 4
107 // gives the split at 513/4 = 128
108 // So summed weight from 0..128 goes into bin 0,
109 // ,, 128..256 goes into bin 1
111 // Finally any remaining ones go into the last bin (3).
113 const scalar jump = summedWeights/nProcGroup;
114 const label nProcGroupM1 = nProcGroup - 1;
115 scalar sumWeights = 0;
119 // assign cells to all except last group.
120 for (j=0; j<nProcGroupM1; j++)
122 const scalar limit = jump*scalar(j + 1);
123 while (sumWeights < limit)
125 sumWeights += weights[indices[ind]];
126 processorGroup[ind++] = j;
129 // Ensure last included.
130 while (ind < processorGroup.size())
132 processorGroup[ind++] = nProcGroupM1;
137 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
139 Foam::simpleGeomDecomp::simpleGeomDecomp(const dictionary& decompositionDict)
141 geomDecomp(decompositionDict, typeName)
145 Foam::simpleGeomDecomp::simpleGeomDecomp
147 const dictionary& decompositionDict,
151 geomDecomp(decompositionDict, typeName)
155 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
157 Foam::labelList Foam::simpleGeomDecomp::decompose(const pointField& points)
159 // construct a list for the final result
160 labelList finalDecomp(points.size());
162 labelList processorGroups(points.size());
164 labelList pointIndices(points.size());
165 forAll(pointIndices, i)
170 pointField rotatedPoints = rotDelta_ & points;
172 // and one to take the processor group id's. For each direction.
173 // we assign the processors to groups of processors labelled
174 // 0..nX to give a banded structure on the mesh. Then we
175 // construct the actual processor number by treating this as
176 // the units part of the processor number.
180 UList<scalar>::less(rotatedPoints.component(vector::X))
183 assignToProcessorGroup(processorGroups, n_.x());
187 finalDecomp[pointIndices[i]] = processorGroups[i];
191 // now do the same thing in the Y direction. These processor group
192 // numbers add multiples of nX to the proc. number (columns)
196 UList<scalar>::less(rotatedPoints.component(vector::Y))
199 assignToProcessorGroup(processorGroups, n_.y());
203 finalDecomp[pointIndices[i]] += n_.x()*processorGroups[i];
207 // finally in the Z direction. Now we add multiples of nX*nY to give
212 UList<scalar>::less(rotatedPoints.component(vector::Z))
215 assignToProcessorGroup(processorGroups, n_.z());
219 finalDecomp[pointIndices[i]] += n_.x()*n_.y()*processorGroups[i];
226 Foam::labelList Foam::simpleGeomDecomp::decompose
228 const pointField& points,
229 const scalarField& weights
232 // construct a list for the final result
233 labelList finalDecomp(points.size());
235 labelList processorGroups(points.size());
237 labelList pointIndices(points.size());
238 forAll(pointIndices, i)
243 pointField rotatedPoints = rotDelta_ & points;
245 // and one to take the processor group id's. For each direction.
246 // we assign the processors to groups of processors labelled
247 // 0..nX to give a banded structure on the mesh. Then we
248 // construct the actual processor number by treating this as
249 // the units part of the processor number.
253 UList<scalar>::less(rotatedPoints.component(vector::X))
256 const scalar summedWeights = sum(weights);
257 assignToProcessorGroup
268 finalDecomp[pointIndices[i]] = processorGroups[i];
272 // now do the same thing in the Y direction. These processor group
273 // numbers add multiples of nX to the proc. number (columns)
277 UList<scalar>::less(rotatedPoints.component(vector::Y))
280 assignToProcessorGroup
291 finalDecomp[pointIndices[i]] += n_.x()*processorGroups[i];
295 // finally in the Z direction. Now we add multiples of nX*nY to give
300 UList<scalar>::less(rotatedPoints.component(vector::Z))
303 assignToProcessorGroup
314 finalDecomp[pointIndices[i]] += n_.x()*n_.y()*processorGroups[i];
319 // ************************************************************************* //