1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
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
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/>.
25 Translates OpenFOAM data to EnSight format.
27 An Ensight part is created for the internalMesh and for each patch.
30 - foamToEnsight [OPTION] \n
31 Translates OpenFOAM data to Ensight format
34 Write Ensight data in ASCII format instead of "C Binary"
36 \param -patches patchList \n
37 Specify particular patches to write.
38 Specifying an empty list suppresses writing the internalMesh.
41 Suppress writing any patches.
43 \param -faceZones zoneList \n
44 Specify faceZones to write, with wildcards
47 Parallel support for cloud data is not supported
48 - writes to \a EnSight directory to avoid collisions with foamToEnsightParts
50 \*---------------------------------------------------------------------------*/
53 #include "timeSelector.H"
54 #include "IOobjectList.H"
58 #include "volFields.H"
60 #include "labelIOField.H"
61 #include "scalarIOField.H"
62 #include "tensorIOField.H"
64 #include "ensightMesh.H"
65 #include "ensightField.H"
67 #include "ensightParticlePositions.H"
68 #include "ensightCloudField.H"
74 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
78 const fileNameList& nameList,
84 if (nameList[i] == name)
96 int main(int argc, char *argv[])
98 timeSelector::addOptions();
99 # include "addRegionOption.H"
101 argList::addBoolOption
104 "write in ASCII format instead of 'C Binary'"
106 argList::addBoolOption
109 "write values in nodes"
111 argList::addBoolOption
114 "suppress writing any patches"
120 "specify particular patches to write - eg '(outlet \"inlet.*\")'. "
121 "An empty list suppresses writing the internalMesh."
127 "specify faceZones to write - eg '( slice \"mfp-.*\" )'."
130 # include "setRootCase.H"
133 const bool binary = !args.optionFound("ascii");
134 const bool nodeValues = args.optionFound("nodeValues");
136 # include "createTime.H"
138 instantList Times = timeSelector::select0(runTime, args);
140 # include "createNamedMesh.H"
142 // Mesh instance (region0 gets filtered out)
143 fileName regionPrefix = "";
145 if (regionName != polyMesh::defaultRegion)
147 regionPrefix = regionName;
150 const label nVolFieldTypes = 5;
151 const word volFieldTypes[] =
153 volScalarField::typeName,
154 volVectorField::typeName,
155 volSphericalTensorField::typeName,
156 volSymmTensorField::typeName,
157 volTensorField::typeName
160 // Path to EnSight folder at case level only
161 // - For parallel cases, data only written from master
162 fileName ensightDir = args.rootPath()/args.globalCaseName()/"EnSight";
164 if (Pstream::master())
166 if (isDir(ensightDir))
174 // Start of case file header output
175 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
177 const word prepend = args.globalCaseName() + '.';
179 OFstream *ensightCaseFilePtr = NULL;
180 if (Pstream::master())
182 fileName caseFileName = prepend + "case";
183 Info<< nl << "write case: " << caseFileName.c_str() << endl;
185 // the case file is always ASCII
186 ensightCaseFilePtr = new OFstream
188 ensightDir/caseFileName,
194 << "type: ensight gold" << nl << nl;
197 OFstream& ensightCaseFile = *ensightCaseFilePtr;
199 // Construct the EnSight mesh
200 const bool selectedPatches = args.optionFound("patches");
201 wordReList patchPatterns;
204 patchPatterns = wordReList(args.optionLookup("patches")());
206 const bool selectedZones = args.optionFound("faceZones");
207 wordReList zonePatterns;
210 zonePatterns = wordReList(args.optionLookup("faceZones")());
216 args.optionFound("noPatches"),
224 // Set Time to the last time before looking for the lagrangian objects
225 runTime.setTime(Times.last(), Times.size()-1);
227 IOobjectList objects(mesh, runTime.timeName());
229 # include "checkMeshMoving.H"
231 wordHashSet allCloudNames;
232 if (Pstream::master())
234 word geomFileName = prepend + "000";
236 // test pre check variable if there is a moving mesh
239 geomFileName = prepend + "***";
245 << (geomFileName + ".mesh").c_str() << nl;
248 // Identify if lagrangian data exists at each time, and add clouds
249 // to the 'allCloudNames' hash set
252 runTime.setTime(Times[timeI], timeI);
254 fileNameList cloudDirs = readDir
256 runTime.timePath()/regionPrefix/cloud::prefix,
260 forAll(cloudDirs, cloudI)
262 IOobjectList cloudObjs
266 cloud::prefix/cloudDirs[cloudI]
269 IOobject* positionsPtr = cloudObjs.lookup("positions");
273 allCloudNames.insert(cloudDirs[cloudI]);
278 HashTable<HashTable<word> > allCloudFields;
279 forAllConstIter(wordHashSet, allCloudNames, cloudIter)
281 // Add the name of the cloud(s) to the case file header
282 if (Pstream::master())
294 // Create a new hash table for each cloud
295 allCloudFields.insert(cloudIter.key(), HashTable<word>());
297 // Identify the new cloud in the hash table
298 HashTable<HashTable<word> >::iterator newCloudIter =
299 allCloudFields.find(cloudIter.key());
301 // Loop over all times to build list of fields and field types
305 runTime.setTime(Times[timeI], timeI);
307 IOobjectList cloudObjs
311 cloud::prefix/cloudIter.key()
314 forAllConstIter(IOobjectList, cloudObjs, fieldIter)
316 const IOobject obj = *fieldIter();
318 if (obj.name() != "positions")
320 // Add field and field type
321 newCloudIter().insert
324 obj.headerClassName()
331 label nTimeSteps = 0;
332 forAll(Times, timeIndex)
335 runTime.setTime(Times[timeIndex], timeIndex);
337 word timeName = itoa(timeIndex);
338 word timeFile = prepend + timeName;
340 Info<< "Translating time = " << runTime.timeName() << nl;
342 polyMesh::readUpdateState meshState = mesh.readUpdate();
344 if (meshState != polyMesh::UNCHANGED)
349 if (timeIndex == 0 || (meshState != polyMesh::UNCHANGED))
361 // Start of field data output
362 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
364 if (timeIndex == 0 && Pstream::master())
366 ensightCaseFile<< nl << "VARIABLE" << nl;
370 // Cell field data output
371 // ~~~~~~~~~~~~~~~~~~~~~~
373 for (label i=0; i<nVolFieldTypes; i++)
375 wordList fieldNames = objects.names(volFieldTypes[i]);
377 forAll(fieldNames, j)
379 const word& fieldName = fieldNames[j];
381 # include "checkData.H"
391 mesh.time().timeName(),
397 if (volFieldTypes[i] == volScalarField::typeName)
411 else if (volFieldTypes[i] == volVectorField::typeName)
425 else if (volFieldTypes[i] == volSphericalTensorField::typeName)
427 ensightField<sphericalTensor>
439 else if (volFieldTypes[i] == volSymmTensorField::typeName)
441 ensightField<symmTensor>
453 else if (volFieldTypes[i] == volTensorField::typeName)
471 // Cloud field data output
472 // ~~~~~~~~~~~~~~~~~~~~~~~
474 forAllConstIter(HashTable<HashTable<word> >, allCloudFields, cloudIter)
476 const word& cloudName = cloudIter.key();
478 fileNameList currentCloudDirs = readDir
480 runTime.timePath()/regionPrefix/cloud::prefix,
484 bool cloudExists = inFileNameList(currentCloudDirs, cloudName);
485 ensightParticlePositions
494 forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
496 const word& fieldName = fieldIter.key();
497 const word& fieldType = fieldIter();
502 mesh.time().timeName(),
503 cloud::prefix/cloudName,
508 bool fieldExists = fieldObject.headerOk();
509 if (fieldType == scalarIOField::typeName)
511 ensightCloudField<scalar>
522 else if (fieldType == vectorIOField::typeName)
524 ensightCloudField<vector>
537 Info<< "Unable to convert field type " << fieldType
538 << " for field " << fieldName << endl;
544 # include "ensightCaseTail.H"
546 if (Pstream::master())
548 delete ensightCaseFilePtr;
551 Info<< "End\n" << endl;
557 // ************************************************************************* //