1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 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 "domainDecomposition.H"
28 #include "decompositionMethod.H"
30 #include "cyclicPolyPatch.H"
32 #include "regionSplit.H"
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 void domainDecomposition::distributeCells()
38 Info<< "\nCalculating distribution of cells" << endl;
40 cpuTime decompositionTime;
43 // See if any faces need to have owner and neighbour on same processor
44 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46 labelHashSet sameProcFaces;
48 if (decompositionDict_.found("preservePatches"))
50 wordList pNames(decompositionDict_.lookup("preservePatches"));
52 Info<< "Keeping owner and neighbour of faces in patches " << pNames
53 << " on same processor" << endl;
55 const polyBoundaryMesh& patches = boundaryMesh();
59 label patchI = patches.findPatchID(pNames[i]);
63 FatalErrorIn("domainDecomposition::distributeCells()")
64 << "Unknown preservePatch " << pNames[i]
65 << endl << "Valid patches are " << patches.names()
69 const polyPatch& pp = patches[patchI];
73 sameProcFaces.insert(pp.start() + i);
77 if (decompositionDict_.found("preserveFaceZones"))
79 wordList zNames(decompositionDict_.lookup("preserveFaceZones"));
81 Info<< "Keeping owner and neighbour of faces in zones " << zNames
82 << " on same processor" << endl;
84 const faceZoneMesh& fZones = faceZones();
88 label zoneI = fZones.findZoneID(zNames[i]);
92 FatalErrorIn("domainDecomposition::distributeCells()")
93 << "Unknown preserveFaceZone " << zNames[i]
94 << endl << "Valid faceZones are " << fZones.names()
98 const faceZone& fz = fZones[zoneI];
102 sameProcFaces.insert(fz[i]);
107 if (sameProcFaces.size() > 0)
109 Info<< "Selected " << sameProcFaces.size()
110 << " faces whose owner and neighbour cell should be kept on the"
111 << " same processor" << endl;
116 // Construct decomposition method and either do decomposition on
117 // cell centres or on agglomeration
120 autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
126 if (sameProcFaces.size() == 0)
128 cellToProc_ = decomposePtr().decompose(cellCentres());
132 // Faces where owner and neighbour are not 'connected' (= all except
134 boolList blockedFace(nFaces(), true);
136 forAllConstIter(labelHashSet, sameProcFaces, iter)
138 blockedFace[iter.key()] = false;
141 // Connect coupled boundary faces
142 const polyBoundaryMesh& patches = boundaryMesh();
144 forAll(patches, patchI)
146 const polyPatch& pp = patches[patchI];
152 blockedFace[pp.start()+i] = false;
157 // Determine global regions, separated by blockedFaces
158 regionSplit globalRegion(*this, blockedFace);
161 // Determine region cell centres
162 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164 // This just takes the first cell in the region. Otherwise the problem
165 // is with cyclics - if we'd average the region centre might be
166 // somewhere in the middle of the domain which might not be anywhere
167 // near any of the cells.
169 const point greatPoint(GREAT, GREAT, GREAT);
171 pointField regionCentres(globalRegion.nRegions(), greatPoint);
173 forAll(globalRegion, cellI)
175 label regionI = globalRegion[cellI];
177 if (regionCentres[regionI] == greatPoint)
179 regionCentres[regionI] = cellCentres()[cellI];
183 // Do decomposition on agglomeration
184 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185 cellToProc_ = decomposePtr().decompose(globalRegion, regionCentres);
188 Info<< "\nFinished decomposition in "
189 << decompositionTime.elapsedCpuTime()
194 // ************************************************************************* //