initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / applications / utilities / postProcessing / dataConversion / foamToEnsightParts / foamToEnsightParts.C
blob7b61fabb2213ad0e6ead78cf38034c837818e686
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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 Application
26     foamToEnsightParts
28 Description
29     Translates OpenFOAM data to Ensight format.
30     An Ensight part is created for each cellZone and patch.
32 Usage
33     - foamToEnsightParts [OPTION] \n
34     Translates OpenFOAM data to Ensight format
36     @param -ascii \n
37     Write Ensight data in ASCII format instead of "C Binary"
39     @param -noZero \n
40     Exclude the often incomplete initial conditions.
42     @param -index \<start\>\n
43     Ignore the time index contained in the time file and use a
44     simple indexing when creating the @c Ensight/data/######## files.
46     @param -noMesh \n
47     Suppress writing the geometry. Can be useful for converting partial
48     results for a static geometry.
50 Note
51     - no parallel data.
52     - writes to @a Ensight directory to avoid collisions with foamToEnsight.
54 \*---------------------------------------------------------------------------*/
56 #include "argList.H"
57 #include "timeSelector.H"
59 #include "volFields.H"
60 #include "OFstream.H"
61 #include "IOmanip.H"
62 #include "IOobjectList.H"
63 #include "scalarIOField.H"
64 #include "tensorIOField.H"
66 #include "ensightParts.H"
67 #include "ensightOutputFunctions.H"
69 using namespace Foam;
71 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
73 // Main program:
75 int main(int argc, char *argv[])
77     // enable -constant
78     // probably don't need -zeroTime though, since the fields are vetted
79     // afterwards anyhow
80     timeSelector::addOptions(true, false);
81     argList::noParallel();
82     argList::validOptions.insert("ascii", "");
83     argList::validOptions.insert("index",  "start");
84     argList::validOptions.insert("noMesh", "");
86     // the volume field types that we handle
87     wordHashSet volFieldTypes;
88     volFieldTypes.insert(volScalarField::typeName);
89     volFieldTypes.insert(volVectorField::typeName);
90     volFieldTypes.insert(volSphericalTensorField::typeName);
91     volFieldTypes.insert(volSymmTensorField::typeName);
92     volFieldTypes.insert(volTensorField::typeName);
94     // the lagrangian field types that we handle
95     wordHashSet cloudFieldTypes;
96     cloudFieldTypes.insert(scalarIOField::typeName);
97     cloudFieldTypes.insert(vectorIOField::typeName);
98     cloudFieldTypes.insert(tensorIOField::typeName);
100     const char* geometryName = "geometry";
102 #   include "setRootCase.H"
103 #   include "createTime.H"
105     // get times list
106     instantList timeDirs = timeSelector::select0(runTime, args);
108     // default to binary output, unless otherwise specified
109     IOstream::streamFormat format = IOstream::BINARY;
110     if (args.optionFound("ascii"))
111     {
112         format = IOstream::ASCII;
113     }
115     // control for renumbering iterations
116     bool optIndex = false;
117     label indexingNumber = 0;
118     if (args.optionFound("index"))
119     {
120         optIndex = true;
121         indexingNumber = args.optionRead<label>("index");
122     }
124     // always write the geometry, unless the -noMesh option is specified
125     bool optNoMesh = args.optionFound("noMesh");
127     fileName ensightDir = args.rootPath()/args.globalCaseName()/"Ensight";
128     fileName dataDir = ensightDir/"data";
129     fileName caseFileName = "Ensight.case";
130     fileName dataMask = fileName("data")/ensightFile::mask();
132     // Ensight and Ensight/data directories must exist
133     // do not remove old data - we might wish to convert new results
134     // or a particular time interval
135     if (isDir(ensightDir))
136     {
137         Info<<"Warning: reusing existing directory" << nl
138             << "    " << ensightDir << endl;
139     }
140     mkDir(ensightDir);
141     mkDir(dataDir);
143 #   include "createNamedMesh.H"
145     // Mesh instance (region0 gets filtered out)
146     fileName regionPrefix;
148     if (regionName != polyMesh::defaultRegion)
149     {
150         regionPrefix = regionName;
151     }
153     // Construct the list of ensight parts for the entire mesh
154     ensightParts partsList(mesh);
156     // write summary information
157     {
158         OFstream partsInfoFile(ensightDir/"partsInfo");
160         partsInfoFile
161             << "// summary of ensight parts" << nl << nl;
162         partsList.writeSummary(partsInfoFile);
163     }
165 #   include "checkHasMovingMesh.H"
166 #   include "findFields.H"
168     if (hasMovingMesh && optNoMesh)
169     {
170         Info<< "mesh is moving: ignoring '-noMesh' option" << endl;
171         optNoMesh = false;
172     }
175     // map times used
176     Map<scalar>  timeIndices;
178     // Track the time indices used by the volume fields
179     DynamicList<label> fieldTimesUsed;
181     // Track the time indices used by each cloud
182     HashTable<DynamicList<label> > cloudTimesUsed;
184     // Create a new DynamicList for each cloud
185     forAllConstIter(HashTable<HashTable<word> >, cloudFields, cloudIter)
186     {
187         cloudTimesUsed.insert(cloudIter.key(), DynamicList<label>());
188     }
191     forAll(timeDirs, timeI)
192     {
193         runTime.setTime(timeDirs[timeI], timeI);
195 #       include "getTimeIndex.H"
197         // remember the time index
198         fieldTimesUsed.append(timeIndex);
200         // the data/ITER subdirectory must exist
201         fileName subDir = ensightFile::subDir(timeIndex);
202         mkDir(dataDir/subDir);
204         // place a timestamp in the directory for future reference
205         {
206             OFstream timeStamp(dataDir/subDir/"time");
207             timeStamp
208                 << "#   timestep time" << nl
209                 << subDir.c_str() << " " << runTime.timeName() << nl;
210         }
212 #       include "moveMesh.H"
214         if (timeI == 0 || mesh.moving())
215         {
216             if (mesh.moving())
217             {
218                 partsList.recalculate(mesh);
219             }
221             if (!optNoMesh)
222             {
223                 fileName geomDir;
224                 if (hasMovingMesh)
225                 {
226                     geomDir = dataDir/subDir;
227                 }
229                 ensightGeoFile geoFile(ensightDir/geomDir/geometryName, format);
230                 partsList.writeGeometry(geoFile);
231                 Info<< nl;
232             }
233         }
235         Info<< "write volume field (" << flush;
237         forAllConstIter(HashTable<word>, volumeFields, fieldIter)
238         {
239             const word& fieldName = fieldIter.key();
240             const word& fieldType = fieldIter();
242             IOobject fieldObject
243             (
244                 fieldName,
245                 mesh.time().timeName(),
246                 mesh,
247                 IOobject::MUST_READ,
248                 IOobject::NO_WRITE
249             );
251             if (fieldType == volScalarField::typeName)
252             {
253                 ensightVolField<scalar>
254                 (
255                     partsList,
256                     fieldObject,
257                     mesh,
258                     dataDir,
259                     subDir,
260                     format
261                 );
263             }
264             else if (fieldType == volVectorField::typeName)
265             {
266                 ensightVolField<vector>
267                 (
268                     partsList,
269                     fieldObject,
270                     mesh,
271                     dataDir,
272                     subDir,
273                     format
274                 );
276             }
277             else if (fieldType == volSphericalTensorField::typeName)
278             {
279                 ensightVolField<sphericalTensor>
280                 (
281                     partsList,
282                     fieldObject,
283                     mesh,
284                     dataDir,
285                     subDir,
286                     format
287                 );
289             }
290             else if (fieldType == volSymmTensorField::typeName)
291             {
292                 ensightVolField<symmTensor>
293                 (
294                     partsList,
295                     fieldObject,
296                     mesh,
297                     dataDir,
298                     subDir,
299                     format
300                 );
301             }
302             else if (fieldType == volTensorField::typeName)
303             {
304                 ensightVolField<tensor>
305                 (
306                     partsList,
307                     fieldObject,
308                     mesh,
309                     dataDir,
310                     subDir,
311                     format
312                 );
313             }
314         }
315         Info<< " )" << endl;
317         // check for clouds
318         forAllConstIter(HashTable<HashTable<word> >, cloudFields, cloudIter)
319         {
320             const word& cloudName = cloudIter.key();
322             if
323             (
324                 !isDir
325                 (
326                     runTime.timePath()/regionPrefix/
327                     cloud::prefix/cloudName
328                 )
329             )
330             {
331                 continue;
332             }
334             IOobjectList cloudObjs
335             (
336                 mesh,
337                 runTime.timeName(),
338                 cloud::prefix/cloudName
339             );
341             // check that the positions field is present for this time
342             if (cloudObjs.lookup("positions"))
343             {
344                 ensightParticlePositions
345                 (
346                     mesh,
347                     dataDir,
348                     subDir,
349                     cloudName,
350                     format
351                 );
352             }
353             else
354             {
355                 continue;
356             }
358             Info<< "write " << cloudName << " (" << flush;
360             forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
361             {
362                 const word& fieldName = fieldIter.key();
363                 const word& fieldType = fieldIter();
365                 IOobject *fieldObject = cloudObjs.lookup(fieldName);
367                 if (!fieldObject)
368                 {
369                     Info<< "missing "
370                         << runTime.timeName()/cloud::prefix/cloudName
371                         / fieldName
372                         << endl;
373                     continue;
374                 }
376                 if (fieldType == scalarIOField::typeName)
377                 {
378                     ensightLagrangianField<scalar>
379                     (
380                         *fieldObject,
381                         dataDir,
382                         subDir,
383                         cloudName,
384                         format
385                     );
387                 }
388                 else if (fieldType == vectorIOField::typeName)
389                 {
390                     ensightLagrangianField<vector>
391                     (
392                         *fieldObject,
393                         dataDir,
394                         subDir,
395                         cloudName,
396                         format
397                     );
399                 }
400                 else if (fieldType == tensorIOField::typeName)
401                 {
402                     ensightLagrangianField<tensor>
403                     (
404                         *fieldObject,
405                         dataDir,
406                         subDir,
407                         cloudName,
408                         format
409                     );
411                 }
412             }
414             Info<< " )" << endl;
416             // remember the time index
417             cloudTimesUsed[cloudName].append(timeIndex);
418         }
419     }
421 #   include "ensightOutputCase.H"
423     Info<< "\nEnd\n"<< endl;
425     return 0;
429 // ************************************************************************* //