Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / applications / utilities / parallelProcessing / decomposeSets / decomposeSets.C
blob497b1ba9f2663bdc05da08a7115bb6361a5e7f9c
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 Application
25     reconstructPar
27 Description
28     Decompose point, face and cell sets after the case has been decomposed
30 \*---------------------------------------------------------------------------*/
32 #include "fvCFD.H"
33 #include "processorMeshes.H"
34 #include "cellSet.H"
35 #include "faceSet.H"
36 #include "pointSet.H"
37 #include "IOobjectList.H"
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 int main(int argc, char *argv[])
43     argList::noParallel();
44 #   include "addRegionOption.H"
46     // Add option to write empty sets
47     argList::validOptions.insert("writeEmptySets", "");
48     argList::validOptions.insert("liveObjectsOnly", "");
50 #   include "setRootCase.H"
51 #   include "createTime.H"
53     Info<< "Time = " << runTime.timeName() << endl;
55     bool writeEmptySets = args.optionFound("writeEmptySets");
56     bool liveObjectsOnly = args.optionFound("liveObjectsOnly");
58     // Determine the processor count directly
59     label nProcs = 0;
60     while (isDir(args.path()/(word("processor") + name(nProcs))))
61     {
62         ++nProcs;
63     }
65     if (!nProcs)
66     {
67         FatalErrorIn(args.executable())
68             << "No processor* directories found"
69             << exit(FatalError);
70     }
72     PtrList<Time> databases(nProcs);
74     forAll (databases, procI)
75     {
76         databases.set
77         (
78             procI,
79             new Time
80             (
81                 Time::controlDictName,
82                 args.rootPath(),
83                 args.caseName()/fileName(word("processor") + name(procI))
84             )
85         );
86     }
88 #   include "createNamedMesh.H"
90     // Set all times on processor meshes equal to decomposed mesh
91     forAll (databases, procI)
92     {
93         databases[procI].setTime(runTime.timeName(), runTime.timeIndex());
94     }
96     // Read all meshes and addressing to reconstructed mesh
97     processorMeshes procMeshes(databases, regionName);
99     // Find all sets on complete mesh
102     // Search for list of objects for the time of the mesh
103     IOobjectList objects
104     (
105         mesh,
106         mesh.facesInstance(),
107         polyMesh::meshSubDir/"sets"
108     );
110     Info<< "Searched : " << mesh.facesInstance()/polyMesh::meshSubDir/"sets"
111         << nl
112         << "Found    : " << objects.names() << nl
113         << endl;
116     IOobjectList pointObjects(objects.lookupClass(pointSet::typeName));
118     for
119     (
120         IOobjectList::const_iterator iter = pointObjects.begin();
121         iter != pointObjects.end();
122         ++iter
123     )
124     {
125         // Set not in memory. Load it.
126         pointSet set(*iter());
128         // Go through all processors
129         forAll (procMeshes.meshes(), procI)
130         {
131             const labelList& addr = procMeshes.pointProcAddressing()[procI];
133             const label nProcPoints = procMeshes.meshes()[procI].nPoints();
135             labelHashSet procSet;
137             forAll (addr, pointI)
138             {
139                 // Skip list when nPoints is reached
140                 if (liveObjectsOnly && pointI >= nProcPoints)
141                 {
142                     break;
143                 }
145                 if (set.found(addr[pointI]))
146                 {
147                     procSet.insert(pointI);
148                 }
149             }
151             if (!procSet.empty() || writeEmptySets)
152             {
153                 // Set created, write it
154                 Info<< "Writing point set " << set.name()
155                     << " on processor " << procI << endl;
156                 pointSet ps
157                 (
158                     procMeshes.meshes()[procI],
159                     set.name(),
160                     procSet,
161                     IOobject::NO_WRITE
162                 );
163                 ps.write();
164             }
165         }
166     }
168     IOobjectList faceObjects(objects.lookupClass(faceSet::typeName));
170     for
171     (
172         IOobjectList::const_iterator iter = faceObjects.begin();
173         iter != faceObjects.end();
174         ++iter
175     )
176     {
177         // Set not in memory. Load it.
178         faceSet set(*iter());
180         // Go through all processors
181         forAll (procMeshes.meshes(), procI)
182         {
183             const labelList& addr = procMeshes.faceProcAddressing()[procI];
185             const label nProcFaces = procMeshes.meshes()[procI].nFaces();
187             labelHashSet procSet;
189             forAll (addr, faceI)
190             {
191                 // Skip list when nPoints is reached
192                 if (liveObjectsOnly && faceI >= nProcFaces)
193                 {
194                     break;
195                 }
197                 // Note faceProcAddressing peculiarity:
198                 // change of sign and offset.  HJ, 7/Mar/2011
199                 if (set.found(mag(addr[faceI]) - 1))
200                 {
201                     procSet.insert(faceI);
202                 }
203             }
205             if (!procSet.empty() || writeEmptySets)
206             {
207                 // Set created, write it
208                 Info<< "Writing face set " << set.name()
209                     << " on processor " << procI << endl;
210                 faceSet fs
211                 (
212                     procMeshes.meshes()[procI],
213                     set.name(),
214                     procSet,
215                     IOobject::NO_WRITE
216                 );
217                 fs.write();
218             }
219         }
220     }
222     IOobjectList cellObjects(objects.lookupClass(cellSet::typeName));
224     for
225     (
226         IOobjectList::const_iterator iter = cellObjects.begin();
227         iter != cellObjects.end();
228         ++iter
229     )
230     {
231         // Set not in memory. Load it.
232         cellSet set(*iter());
234         // Go through all processors
235         forAll (procMeshes.meshes(), procI)
236         {
237             const labelList& addr = procMeshes.cellProcAddressing()[procI];
239             // There are no retired cells: no special handling required
241             labelHashSet procSet;
243             forAll (addr, cellI)
244             {
245                 if (set.found(addr[cellI]))
246                 {
247                     procSet.insert(cellI);
248                 }
249             }
251             if (!procSet.empty() || writeEmptySets)
252             {
253                 // Set created, write it
254                 Info<< "Writing cell set " << set.name()
255                     << " on processor " << procI << endl;
256                 cellSet cs
257                 (
258                     procMeshes.meshes()[procI],
259                     set.name(),
260                     procSet,
261                     IOobject::NO_WRITE
262                 );
263                 cs.write();
264             }
265         }
266     }
269     Info<< "End.\n" << endl;
271     return 0;
275 // ************************************************************************* //