1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 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
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
26 Translates FOAM data to EnSight format.
28 An Ensight part is created for the internalMesh and for each patch.
31 - foamToEnsight [OPTION] \n
32 Translates OpenFOAM data to Ensight format
35 Write Ensight data in ASCII format instead of "C Binary"
37 @param -patches patchList \n
38 Specify particular patches to write.
39 Specifying an empty list suppresses writing the internalMesh.
42 Suppress writing any patches.
45 Parallel support for cloud data is not supported
46 - writes to @a EnSight directory to avoid collisions with foamToEnsightParts
48 \*---------------------------------------------------------------------------*/
51 #include "timeSelector.H"
52 #include "IOobjectList.H"
56 #include "volFields.H"
58 #include "labelIOField.H"
59 #include "scalarIOField.H"
60 #include "tensorIOField.H"
62 #include "ensightMesh.H"
63 #include "ensightField.H"
65 #include "ensightParticlePositions.H"
66 #include "ensightCloudField.H"
72 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
76 const fileNameList& nameList,
82 if (nameList[i] == name)
94 int main(int argc, char *argv[])
96 argList::validOptions.insert("ascii", "" );
97 argList::validOptions.insert("patches", "patchList");
98 argList::validOptions.insert("noPatches", "");
100 # include "addTimeOptions.H"
101 # include "setRootCase.H"
104 bool binary = !args.optionFound("ascii");
106 # include "createTime.H"
108 // get the available time-steps
109 instantList Times = runTime.times();
111 # include "checkTimeOptions.H"
113 runTime.setTime(Times[startTime], startTime);
115 # include "createNamedMesh.H"
117 // Mesh instance (region0 gets filtered out)
118 fileName regionPrefix = "";
120 if (regionName != polyMesh::defaultRegion)
122 regionPrefix = regionName;
125 const label nVolFieldTypes = 5;
126 const word volFieldTypes[] =
128 volScalarField::typeName,
129 volVectorField::typeName,
130 volSphericalTensorField::typeName,
131 volSymmTensorField::typeName,
132 volTensorField::typeName
135 // Path to EnSight folder at case level only
136 // - For parallel cases, data only written from master
137 fileName ensightDir = args.rootPath()/args.globalCaseName()/"EnSight";
139 if (Pstream::master())
141 if (isDir(ensightDir))
149 // Start of case file header output
150 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
152 const word prepend = args.globalCaseName() + '.';
154 OFstream *ensightCaseFilePtr = NULL;
155 if (Pstream::master())
157 fileName caseFileName = prepend + "case";
158 Info<< nl << "write case: " << caseFileName.c_str() << endl;
160 // the case file is always ASCII
161 ensightCaseFilePtr = new OFstream
163 ensightDir/caseFileName,
164 ios_base::out|ios_base::trunc,
170 << "type: ensight gold" << nl << nl;
173 OFstream& ensightCaseFile = *ensightCaseFilePtr;
175 // Construct the EnSight mesh
176 ensightMesh eMesh(mesh, args, binary);
178 // Set Time to the last time before looking for the lagrangian objects
179 runTime.setTime(Times[Times.size()-1], Times.size()-1);
181 IOobjectList objects(mesh, runTime.timeName());
183 # include "checkMeshMoving.H"
185 wordHashSet allCloudNames;
186 if (Pstream::master())
188 word geomFileName = prepend + "000";
190 // test pre check variable if there is a moving mesh
193 geomFileName = prepend + "***";
199 << (geomFileName + ".mesh").c_str() << nl;
202 // Identify if lagrangian data exists at each time, and add clouds
203 // to the 'allCloudNames' hash set
204 for (label n=startTime; n<endTime; n++)
206 runTime.setTime(Times[n], n);
208 fileNameList cloudDirs = readDir
210 runTime.timePath()/regionPrefix/cloud::prefix,
214 forAll(cloudDirs, cloudI)
216 IOobjectList cloudObjs
220 cloud::prefix/cloudDirs[cloudI]
223 IOobject* positionsPtr = cloudObjs.lookup("positions");
227 allCloudNames.insert(cloudDirs[cloudI]);
232 HashTable<HashTable<word> > allCloudFields;
233 forAllConstIter(wordHashSet, allCloudNames, cloudIter)
235 // Add the name of the cloud(s) to the case file header
236 if (Pstream::master())
248 // Create a new hash table for each cloud
249 allCloudFields.insert(cloudIter.key(), HashTable<word>());
251 // Identify the new cloud in the hash table
252 HashTable<HashTable<word> >::iterator newCloudIter =
253 allCloudFields.find(cloudIter.key());
255 // Loop over all times to build list of fields and field types
257 for (label n=startTime; n<endTime; n++)
259 runTime.setTime(Times[n], n);
261 IOobjectList cloudObjs
265 cloud::prefix/cloudIter.key()
268 forAllConstIter(IOobjectList, cloudObjs, fieldIter)
270 const IOobject obj = *fieldIter();
272 if (obj.name() != "positions")
274 // Add field and field type
275 newCloudIter().insert
278 obj.headerClassName()
285 label nTimeSteps = 0;
286 for (label n=startTime; n<endTime; n++)
289 runTime.setTime(Times[n], n);
290 label timeIndex = n - startTime;
292 word timeName = itoa(timeIndex);
293 word timeFile = prepend + timeName;
295 Info<< "Translating time = " << runTime.timeName() << nl;
297 # include "moveMesh.H"
299 if (timeIndex == 0 || mesh.moving())
311 // Start of field data output
312 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
314 if (timeIndex == 0 && Pstream::master())
316 ensightCaseFile<< nl << "VARIABLE" << nl;
320 // Cell field data output
321 // ~~~~~~~~~~~~~~~~~~~~~~
323 for (label i=0; i<nVolFieldTypes; i++)
325 wordList fieldNames = objects.names(volFieldTypes[i]);
327 for (label j=0; j<fieldNames.size(); j++)
329 word fieldName = fieldNames[j];
331 # include "checkData.H"
341 mesh.time().timeName(),
347 if (volFieldTypes[i] == volScalarField::typeName)
360 else if (volFieldTypes[i] == volVectorField::typeName)
373 else if (volFieldTypes[i] == volSphericalTensorField::typeName)
375 ensightField<sphericalTensor>
386 else if (volFieldTypes[i] == volSymmTensorField::typeName)
388 ensightField<symmTensor>
399 else if (volFieldTypes[i] == volTensorField::typeName)
416 // Cloud field data output
417 // ~~~~~~~~~~~~~~~~~~~~~~~
419 forAllConstIter(HashTable<HashTable<word> >, allCloudFields, cloudIter)
421 const word& cloudName = cloudIter.key();
423 fileNameList currentCloudDirs = readDir
425 runTime.timePath()/regionPrefix/cloud::prefix,
429 bool cloudExists = inFileNameList(currentCloudDirs, cloudName);
430 ensightParticlePositions
439 forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
441 const word& fieldName = fieldIter.key();
442 const word& fieldType = fieldIter();
447 mesh.time().timeName(),
448 cloud::prefix/cloudName,
453 bool fieldExists = fieldObject.headerOk();
454 if (fieldType == scalarIOField::typeName)
456 ensightCloudField<scalar>
467 else if (fieldType == vectorIOField::typeName)
469 ensightCloudField<vector>
482 Info<< "Unable to convert field type " << fieldType
483 << " for field " << fieldName << endl;
489 # include "ensightCaseTail.H"
491 if (Pstream::master())
493 delete ensightCaseFilePtr;
496 Info<< "End\n" << endl;
502 // ************************************************************************* //