1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "domainDecomposition.H"
27 #include "decompositionMethod.H"
30 #include "regionSplit.H"
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 void Foam::domainDecomposition::distributeCells()
36 Info<< "\nCalculating distribution of cells" << endl;
38 cpuTime decompositionTime;
41 // See if any faces need to have owner and neighbour on same processor
42 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44 labelHashSet sameProcFaces;
46 if (decompositionDict_.found("preservePatches"))
48 wordList pNames(decompositionDict_.lookup("preservePatches"));
50 Info<< "Keeping owner of faces in patches " << pNames
51 << " on same processor. This only makes sense for cyclics." << endl;
53 const polyBoundaryMesh& patches = boundaryMesh();
57 const label patchI = patches.findPatchID(pNames[i]);
61 FatalErrorIn("domainDecomposition::distributeCells()")
62 << "Unknown preservePatch " << pNames[i]
63 << endl << "Valid patches are " << patches.names()
67 const polyPatch& pp = patches[patchI];
71 sameProcFaces.insert(pp.start() + i);
75 if (decompositionDict_.found("preserveFaceZones"))
77 wordList zNames(decompositionDict_.lookup("preserveFaceZones"));
79 Info<< "Keeping owner and neighbour of faces in zones " << zNames
80 << " on same processor" << endl;
82 const faceZoneMesh& fZones = faceZones();
86 label zoneI = fZones.findZoneID(zNames[i]);
90 FatalErrorIn("domainDecomposition::distributeCells()")
91 << "Unknown preserveFaceZone " << zNames[i]
92 << endl << "Valid faceZones are " << fZones.names()
96 const faceZone& fz = fZones[zoneI];
100 sameProcFaces.insert(fz[i]);
106 // Construct decomposition method and either do decomposition on
107 // cell centres or on agglomeration
110 autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
115 if (sameProcFaces.empty())
117 if (decompositionDict_.found("weightField"))
119 word weightName = decompositionDict_.lookup("weightField");
121 volScalarField weights
134 cellToProc_ = decomposePtr().decompose
138 weights.internalField()
143 cellToProc_ = decomposePtr().decompose(*this, cellCentres());
149 Info<< "Selected " << sameProcFaces.size()
150 << " faces whose owner and neighbour cell should be kept on the"
151 << " same processor" << endl;
153 // Faces where owner and neighbour are not 'connected' (= all except
155 boolList blockedFace(nFaces(), true);
157 forAllConstIter(labelHashSet, sameProcFaces, iter)
159 blockedFace[iter.key()] = false;
162 // Connect coupled boundary faces
163 const polyBoundaryMesh& patches = boundaryMesh();
165 forAll(patches, patchI)
167 const polyPatch& pp = patches[patchI];
173 blockedFace[pp.start()+i] = false;
178 // Determine global regions, separated by blockedFaces
179 regionSplit globalRegion(*this, blockedFace);
182 // Determine region cell centres
183 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185 // This just takes the first cell in the region. Otherwise the problem
186 // is with cyclics - if we'd average the region centre might be
187 // somewhere in the middle of the domain which might not be anywhere
188 // near any of the cells.
190 pointField regionCentres(globalRegion.nRegions(), point::max);
192 forAll(globalRegion, cellI)
194 label regionI = globalRegion[cellI];
196 if (regionCentres[regionI] == point::max)
198 regionCentres[regionI] = cellCentres()[cellI];
202 // Do decomposition on agglomeration
203 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204 if (decompositionDict_.found("weightField"))
206 scalarField regionWeights(globalRegion.nRegions(), 0);
208 word weightName = decompositionDict_.lookup("weightField");
210 volScalarField weights
223 forAll(globalRegion, cellI)
225 label regionI = globalRegion[cellI];
227 regionWeights[regionI] += weights.internalField()[cellI];
230 cellToProc_ = decomposePtr().decompose
240 cellToProc_ = decomposePtr().decompose
249 Info<< "\nFinished decomposition in "
250 << decompositionTime.elapsedCpuTime()
255 // ************************************************************************* //