Transferred copyright to the OpenFOAM Foundation
[OpenFOAM-2.0.x.git] / applications / utilities / postProcessing / dataConversion / foamToEnsightParts / foamToEnsightParts.C
bloba96179e9707417622b55273bb0186c894405cbc2
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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, see <http://www.gnu.org/licenses/>.
24 Application
25     foamToEnsightParts
27 Description
28     Translates OpenFOAM data to Ensight format.
29     An Ensight part is created for each cellZone and patch.
31 Usage
32     - foamToEnsightParts [OPTION] \n
33     Translates OpenFOAM data to Ensight format
35     \param -ascii \n
36     Write Ensight data in ASCII format instead of "C Binary"
38     \param -noZero \n
39     Exclude the often incomplete initial conditions.
41     \param -index \<start\>\n
42     Ignore the time index contained in the time file and use a
43     simple indexing when creating the \c Ensight/data/######## files.
45     \param -noMesh \n
46     Suppress writing the geometry. Can be useful for converting partial
47     results for a static geometry.
49 Note
50     - no parallel data.
51     - writes to \a Ensight directory to avoid collisions with foamToEnsight.
53 \*---------------------------------------------------------------------------*/
55 #include "argList.H"
56 #include "timeSelector.H"
58 #include "volFields.H"
59 #include "OFstream.H"
60 #include "IOmanip.H"
61 #include "IOobjectList.H"
62 #include "scalarIOField.H"
63 #include "tensorIOField.H"
65 #include "ensightParts.H"
66 #include "ensightOutputFunctions.H"
68 using namespace Foam;
70 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
72 // Main program:
74 int main(int argc, char *argv[])
76     // enable -constant
77     // probably don't need -zeroTime though, since the fields are vetted
78     // afterwards anyhow
79     timeSelector::addOptions(true, false);
80     argList::noParallel();
81     argList::addBoolOption
82     (
83         "ascii",
84         "write in ASCII format instead of 'C Binary'"
85     );
86     argList::addOption
87     (
88         "index",
89         "start",
90         "ignore the time index contained in the uniform/time file "
91         "and use simple indexing when creating the files"
92     );
93     argList::addBoolOption
94     (
95         "noMesh",
96         "suppress writing the geometry. "
97         "Can be useful for converting partial results for a static geometry"
98     );
100     // the volume field types that we handle
101     wordHashSet volFieldTypes;
102     volFieldTypes.insert(volScalarField::typeName);
103     volFieldTypes.insert(volVectorField::typeName);
104     volFieldTypes.insert(volSphericalTensorField::typeName);
105     volFieldTypes.insert(volSymmTensorField::typeName);
106     volFieldTypes.insert(volTensorField::typeName);
108     // the lagrangian field types that we handle
109     wordHashSet cloudFieldTypes;
110     cloudFieldTypes.insert(scalarIOField::typeName);
111     cloudFieldTypes.insert(vectorIOField::typeName);
112     cloudFieldTypes.insert(tensorIOField::typeName);
114     const char* geometryName = "geometry";
116 #   include "setRootCase.H"
117 #   include "createTime.H"
119     // get times list
120     instantList timeDirs = timeSelector::select0(runTime, args);
122     // default to binary output, unless otherwise specified
123     IOstream::streamFormat format = IOstream::BINARY;
124     if (args.optionFound("ascii"))
125     {
126         format = IOstream::ASCII;
127     }
129     // control for renumbering iterations
130     label indexingNumber = 0;
131     bool optIndex = args.optionReadIfPresent("index", indexingNumber);
133     // always write the geometry, unless the -noMesh option is specified
134     bool optNoMesh = args.optionFound("noMesh");
136     fileName ensightDir = args.rootPath()/args.globalCaseName()/"Ensight";
137     fileName dataDir = ensightDir/"data";
138     fileName caseFileName = "Ensight.case";
139     fileName dataMask = fileName("data")/ensightFile::mask();
141     // Ensight and Ensight/data directories must exist
142     // do not remove old data - we might wish to convert new results
143     // or a particular time interval
144     if (isDir(ensightDir))
145     {
146         Info<<"Warning: re-using existing directory" << nl
147             << "    " << ensightDir << endl;
148     }
149     mkDir(ensightDir);
150     mkDir(dataDir);
152 #   include "createNamedMesh.H"
154     // Mesh instance (region0 gets filtered out)
155     fileName regionPrefix;
157     if (regionName != polyMesh::defaultRegion)
158     {
159         regionPrefix = regionName;
160     }
162     // Construct the list of ensight parts for the entire mesh
163     ensightParts partsList(mesh);
165     // write summary information
166     {
167         OFstream partsInfoFile(ensightDir/"partsInfo");
169         partsInfoFile
170             << "// summary of ensight parts" << nl << nl;
171         partsList.writeSummary(partsInfoFile);
172     }
174 #   include "checkHasMovingMesh.H"
175 #   include "findFields.H"
177     if (hasMovingMesh && optNoMesh)
178     {
179         Info<< "mesh is moving: ignoring '-noMesh' option" << endl;
180         optNoMesh = false;
181     }
184     // map times used
185     Map<scalar>  timeIndices;
187     // Track the time indices used by the volume fields
188     DynamicList<label> fieldTimesUsed;
190     // Track the time indices used by each cloud
191     HashTable<DynamicList<label> > cloudTimesUsed;
193     // Create a new DynamicList for each cloud
194     forAllConstIter(HashTable<HashTable<word> >, cloudFields, cloudIter)
195     {
196         cloudTimesUsed.insert(cloudIter.key(), DynamicList<label>());
197     }
200     forAll(timeDirs, timeI)
201     {
202         runTime.setTime(timeDirs[timeI], timeI);
204 #       include "getTimeIndex.H"
206         // remember the time index
207         fieldTimesUsed.append(timeIndex);
209         // the data/ITER subdirectory must exist
210         fileName subDir = ensightFile::subDir(timeIndex);
211         mkDir(dataDir/subDir);
213         // place a timestamp in the directory for future reference
214         {
215             OFstream timeStamp(dataDir/subDir/"time");
216             timeStamp
217                 << "#   timestep time" << nl
218                 << subDir.c_str() << " " << runTime.timeName() << nl;
219         }
221 #       include "moveMesh.H"
223         if (timeI == 0 || mesh.moving())
224         {
225             if (mesh.moving())
226             {
227                 partsList.recalculate(mesh);
228             }
230             if (!optNoMesh)
231             {
232                 fileName geomDir;
233                 if (hasMovingMesh)
234                 {
235                     geomDir = dataDir/subDir;
236                 }
238                 ensightGeoFile geoFile(ensightDir/geomDir/geometryName, format);
239                 partsList.writeGeometry(geoFile);
240                 Info<< nl;
241             }
242         }
244         Info<< "write volume field (" << flush;
246         forAllConstIter(HashTable<word>, volumeFields, fieldIter)
247         {
248             const word& fieldName = fieldIter.key();
249             const word& fieldType = fieldIter();
251             IOobject fieldObject
252             (
253                 fieldName,
254                 mesh.time().timeName(),
255                 mesh,
256                 IOobject::MUST_READ,
257                 IOobject::NO_WRITE
258             );
260             if (fieldType == volScalarField::typeName)
261             {
262                 ensightVolField<scalar>
263                 (
264                     partsList,
265                     fieldObject,
266                     mesh,
267                     dataDir,
268                     subDir,
269                     format
270                 );
272             }
273             else if (fieldType == volVectorField::typeName)
274             {
275                 ensightVolField<vector>
276                 (
277                     partsList,
278                     fieldObject,
279                     mesh,
280                     dataDir,
281                     subDir,
282                     format
283                 );
285             }
286             else if (fieldType == volSphericalTensorField::typeName)
287             {
288                 ensightVolField<sphericalTensor>
289                 (
290                     partsList,
291                     fieldObject,
292                     mesh,
293                     dataDir,
294                     subDir,
295                     format
296                 );
298             }
299             else if (fieldType == volSymmTensorField::typeName)
300             {
301                 ensightVolField<symmTensor>
302                 (
303                     partsList,
304                     fieldObject,
305                     mesh,
306                     dataDir,
307                     subDir,
308                     format
309                 );
310             }
311             else if (fieldType == volTensorField::typeName)
312             {
313                 ensightVolField<tensor>
314                 (
315                     partsList,
316                     fieldObject,
317                     mesh,
318                     dataDir,
319                     subDir,
320                     format
321                 );
322             }
323         }
324         Info<< " )" << endl;
326         // check for clouds
327         forAllConstIter(HashTable<HashTable<word> >, cloudFields, cloudIter)
328         {
329             const word& cloudName = cloudIter.key();
331             if
332             (
333                 !isDir
334                 (
335                     runTime.timePath()/regionPrefix/
336                     cloud::prefix/cloudName
337                 )
338             )
339             {
340                 continue;
341             }
343             IOobjectList cloudObjs
344             (
345                 mesh,
346                 runTime.timeName(),
347                 cloud::prefix/cloudName
348             );
350             // check that the positions field is present for this time
351             if (cloudObjs.lookup("positions"))
352             {
353                 ensightParticlePositions
354                 (
355                     mesh,
356                     dataDir,
357                     subDir,
358                     cloudName,
359                     format
360                 );
361             }
362             else
363             {
364                 continue;
365             }
367             Info<< "write " << cloudName << " (" << flush;
369             forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
370             {
371                 const word& fieldName = fieldIter.key();
372                 const word& fieldType = fieldIter();
374                 IOobject *fieldObject = cloudObjs.lookup(fieldName);
376                 if (!fieldObject)
377                 {
378                     Info<< "missing "
379                         << runTime.timeName()/cloud::prefix/cloudName
380                         / fieldName
381                         << endl;
382                     continue;
383                 }
385                 if (fieldType == scalarIOField::typeName)
386                 {
387                     ensightLagrangianField<scalar>
388                     (
389                         *fieldObject,
390                         dataDir,
391                         subDir,
392                         cloudName,
393                         format
394                     );
396                 }
397                 else if (fieldType == vectorIOField::typeName)
398                 {
399                     ensightLagrangianField<vector>
400                     (
401                         *fieldObject,
402                         dataDir,
403                         subDir,
404                         cloudName,
405                         format
406                     );
408                 }
409                 else if (fieldType == tensorIOField::typeName)
410                 {
411                     ensightLagrangianField<tensor>
412                     (
413                         *fieldObject,
414                         dataDir,
415                         subDir,
416                         cloudName,
417                         format
418                     );
420                 }
421             }
423             Info<< " )" << endl;
425             // remember the time index
426             cloudTimesUsed[cloudName].append(timeIndex);
427         }
428     }
430 #   include "ensightOutputCase.H"
432     Info<< "\nEnd\n"<< endl;
434     return 0;
438 // ************************************************************************* //