Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / applications / utilities / parallelProcessing / decomposePar / distributeCells.C
blob578d815c75fdae02c8c6b8d44af8de3c93cb548c
1 /*---------------------------------------------------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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"
28 #include "cpuTime.H"
29 #include "cyclicPolyPatch.H"
30 #include "cellSet.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"))
48     {
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();
56         forAll(pNames, i)
57         {
58             label patchI = patches.findPatchID(pNames[i]);
60             if (patchI == -1)
61             {
62                 FatalErrorIn("domainDecomposition::distributeCells()")
63                     << "Unknown preservePatch " << pNames[i]
64                     << nl << "Valid patches are " << patches.names()
65                     << exit(FatalError);
66             }
68             const polyPatch& pp = patches[patchI];
70             forAll(pp, i)
71             {
72                 sameProcFaces.insert(pp.start() + i);
73             }
74         }
75     }
76     if (decompositionDict_.found("preserveFaceZones"))
77     {
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();
85         forAll(zNames, i)
86         {
87             label zoneI = fZones.findZoneID(zNames[i]);
89             if (zoneI == -1)
90             {
91                 FatalErrorIn("domainDecomposition::distributeCells()")
92                     << "Unknown preserveFaceZone " << zNames[i]
93                     << endl << "Valid faceZones are " << fZones.names()
94                     << exit(FatalError);
95             }
97             const faceZone& fz = fZones[zoneI];
99             forAll(fz, i)
100             {
101                 sameProcFaces.insert(fz[i]);
102             }
103         }
104     }
107     // Construct decomposition method and either do decomposition on
108     // cell centres or on agglomeration
111     autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
112     (
113         decompositionDict_,
114         *this
115     );
117     if (sameProcFaces.empty())
118     {
119         cellToProc_ = decomposePtr().decompose(cellCentres());
120     }
121     else
122     {
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
128         // sameProcFaces)
129         boolList blockedFace(nFaces(), true);
131         forAllConstIter(labelHashSet, sameProcFaces, iter)
132         {
133             blockedFace[iter.key()] = false;
134         }
136         // Connect coupled boundary faces
137         const polyBoundaryMesh& patches =  boundaryMesh();
139         forAll(patches, patchI)
140         {
141             const polyPatch& pp = patches[patchI];
143             if (pp.coupled())
144             {
145                 forAll(pp, i)
146                 {
147                     blockedFace[pp.start() + i] = false;
148                 }
149             }
150         }
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)
169         {
170             label regionI = globalRegion[cellI];
172             if (regionCentres[regionI] == greatPoint)
173             {
174                 regionCentres[regionI] = cellCentres()[cellI];
175             }
176         }
178         // Do decomposition on agglomeration
179         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180         cellToProc_ = decomposePtr().decompose(globalRegion, regionCentres);
181     }
183     Info<< "\nFinished decomposition in "
184         << decompositionTime.elapsedCpuTime()
185         << " s" << endl;
189 // ************************************************************************* //