1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "domainDecomposition.H"
27 #include "decompositionMethod.H"
29 #include "cyclicPolyPatch.H"
31 #include "regionSplit.H"
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 void domainDecomposition::distributeCells()
37 Info<< "\nCalculating distribution of cells" << endl;
39 cpuTime decompositionTime;
42 // See if any faces need to have owner and neighbour on same processor
43 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45 labelHashSet sameProcFaces;
47 if (decompositionDict_.found("preservePatches"))
49 wordList pNames(decompositionDict_.lookup("preservePatches"));
51 Info<< "Keeping owner and neighbour of faces in patches " << pNames
52 << " on same processor" << endl;
54 const polyBoundaryMesh& patches = boundaryMesh();
58 label patchI = patches.findPatchID(pNames[i]);
62 FatalErrorIn("domainDecomposition::distributeCells()")
63 << "Unknown preservePatch " << pNames[i]
64 << nl << "Valid patches are " << patches.names()
68 const polyPatch& pp = patches[patchI];
72 sameProcFaces.insert(pp.start() + i);
76 if (decompositionDict_.found("preserveFaceZones"))
78 wordList zNames(decompositionDict_.lookup("preserveFaceZones"));
80 Info<< "Keeping owner and neighbour of faces in zones " << zNames
81 << " on same processor" << endl;
83 const faceZoneMesh& fZones = faceZones();
87 label zoneI = fZones.findZoneID(zNames[i]);
91 FatalErrorIn("domainDecomposition::distributeCells()")
92 << "Unknown preserveFaceZone " << zNames[i]
93 << endl << "Valid faceZones are " << fZones.names()
97 const faceZone& fz = fZones[zoneI];
101 sameProcFaces.insert(fz[i]);
107 // Construct decomposition method and either do decomposition on
108 // cell centres or on agglomeration
111 autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
117 if (sameProcFaces.empty())
119 cellToProc_ = decomposePtr().decompose(cellCentres());
123 Info<< "Selected " << sameProcFaces.size()
124 << " faces whose owner and neighbour cell should be kept on the"
125 << " same processor" << endl;
127 // Faces where owner and neighbour are not 'connected' (= all except
129 boolList blockedFace(nFaces(), true);
131 forAllConstIter(labelHashSet, sameProcFaces, iter)
133 blockedFace[iter.key()] = false;
136 // Connect coupled boundary faces
137 const polyBoundaryMesh& patches = boundaryMesh();
139 forAll(patches, patchI)
141 const polyPatch& pp = patches[patchI];
147 blockedFace[pp.start() + i] = false;
152 // Determine global regions, separated by blockedFaces
153 regionSplit globalRegion(*this, blockedFace);
156 // Determine region cell centres
157 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
159 // This just takes the first cell in the region. Otherwise the problem
160 // is with cyclics - if we'd average the region centre might be
161 // somewhere in the middle of the domain which might not be anywhere
162 // near any of the cells.
164 const point greatPoint(GREAT, GREAT, GREAT);
166 pointField regionCentres(globalRegion.nRegions(), greatPoint);
168 forAll(globalRegion, cellI)
170 label regionI = globalRegion[cellI];
172 if (regionCentres[regionI] == greatPoint)
174 regionCentres[regionI] = cellCentres()[cellI];
178 // Do decomposition on agglomeration
179 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180 cellToProc_ = decomposePtr().decompose(globalRegion, regionCentres);
183 Info<< "\nFinished decomposition in "
184 << decompositionTime.elapsedCpuTime()
189 // ************************************************************************* //