FreeFOAM The Cross-Platform CFD Toolkit
foamToEnsightParts.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 Application
25  foamToEnsightParts
26 
27 Description
28  Translates OpenFOAM data to Ensight format.
29  An Ensight part is created for each cellZone and patch.
30 
31 Usage
32  - foamToEnsightParts [OPTION] \n
33  Translates OpenFOAM data to Ensight format
34 
35  @param -ascii \n
36  Write Ensight data in ASCII format instead of "C Binary"
37 
38  @param -noZero \n
39  Exclude the often incomplete initial conditions.
40 
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.
44 
45  @param -noMesh \n
46  Suppress writing the geometry. Can be useful for converting partial
47  results for a static geometry.
48 
49  @param -case <dir> \n
50  Case directory.
51 
52  @param -constant \n
53  Include the constant directory.
54 
55  @param -latestTime \n
56  Only apply to the latest time step.
57 
58  @param -time <time>\n
59  Apply only to specified time.
60 
61  @param -help \n
62  Display help message.
63 
64  @param -doc \n
65  Display Doxygen API documentation page for this application.
66 
67  @param -srcDoc \n
68  Display Doxygen source documentation page for this application.
69 
70 Note
71  - no parallel data.
72  - writes to @a Ensight directory to avoid collisions with foamToEnsight.
73 
74 \*---------------------------------------------------------------------------*/
75 
76 #include <OpenFOAM/argList.H>
77 #include <OpenFOAM/timeSelector.H>
78 
79 #include <finiteVolume/volFields.H>
80 #include <OpenFOAM/OFstream.H>
81 #include <OpenFOAM/IOmanip.H>
82 #include <OpenFOAM/IOobjectList.H>
83 #include <OpenFOAM/scalarIOField.H>
84 #include <OpenFOAM/tensorIOField.H>
85 
87 #include "ensightOutputFunctions.H"
88 
89 using namespace Foam;
90 
91 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
92 
93 // Main program:
94 
95 int main(int argc, char *argv[])
96 {
97  // enable -constant
98  // probably don't need -zeroTime though, since the fields are vetted
99  // afterwards anyhow
100  timeSelector::addOptions(true, false);
102  argList::validOptions.insert("ascii", "");
103  argList::validOptions.insert("index", "start");
104  argList::validOptions.insert("noMesh", "");
105 
106  // the volume field types that we handle
107  wordHashSet volFieldTypes;
108  volFieldTypes.insert(volScalarField::typeName);
109  volFieldTypes.insert(volVectorField::typeName);
111  volFieldTypes.insert(volSymmTensorField::typeName);
112  volFieldTypes.insert(volTensorField::typeName);
113 
114  // the lagrangian field types that we handle
115  wordHashSet cloudFieldTypes;
116  cloudFieldTypes.insert(scalarIOField::typeName);
117  cloudFieldTypes.insert(vectorIOField::typeName);
118  cloudFieldTypes.insert(tensorIOField::typeName);
119 
120  const char* geometryName = "geometry";
121 
122 # include <OpenFOAM/setRootCase.H>
123 # include <OpenFOAM/createTime.H>
124 
125  // get times list
127 
128  // default to binary output, unless otherwise specified
130  if (args.optionFound("ascii"))
131  {
132  format = IOstream::ASCII;
133  }
134 
135  // control for renumbering iterations
136  bool optIndex = false;
137  label indexingNumber = 0;
138  if (args.optionFound("index"))
139  {
140  optIndex = true;
141  indexingNumber = args.optionRead<label>("index");
142  }
143 
144  // always write the geometry, unless the -noMesh option is specified
145  bool optNoMesh = args.optionFound("noMesh");
146 
147  fileName ensightDir = args.rootPath()/args.globalCaseName()/"Ensight";
148  fileName dataDir = ensightDir/"data";
149  fileName caseFileName = "Ensight.case";
150  fileName dataMask = fileName("data")/ensightFile::mask();
151 
152  // Ensight and Ensight/data directories must exist
153  // do not remove old data - we might wish to convert new results
154  // or a particular time interval
155  if (isDir(ensightDir))
156  {
157  Info<<"Warning: reusing existing directory" << nl
158  << " " << ensightDir << endl;
159  }
160  mkDir(ensightDir);
161  mkDir(dataDir);
162 
163 # include <OpenFOAM/createNamedMesh.H>
164 
165  // Mesh instance (region0 gets filtered out)
166  fileName regionPrefix;
167 
169  {
170  regionPrefix = regionName;
171  }
172 
173  // Construct the list of ensight parts for the entire mesh
174  ensightParts partsList(mesh);
175 
176  // write summary information
177  {
178  OFstream partsInfoFile(ensightDir/"partsInfo");
179 
180  partsInfoFile
181  << "// summary of ensight parts" << nl << nl;
182  partsList.writeSummary(partsInfoFile);
183  }
184 
185 # include "checkHasMovingMesh.H"
186 # include "findFields.H"
187 
188  if (hasMovingMesh && optNoMesh)
189  {
190  Info<< "mesh is moving: ignoring '-noMesh' option" << endl;
191  optNoMesh = false;
192  }
193 
194 
195  // map times used
196  Map<scalar> timeIndices;
197 
198  // Track the time indices used by the volume fields
199  DynamicList<label> fieldTimesUsed;
200 
201  // Track the time indices used by each cloud
202  // Use autoPtr to help GCC compilers (< 4.3) which suffer from core
203  // language defect 391, i.e. require a copy-ctor to be present when passing
204  // a temporary as an rvalue.
206 
207  // Create a new DynamicList for each cloud
209  {
210  cloudTimesUsed.insert(cloudIter.key(),
212  }
213 
214 
215  forAll(timeDirs, timeI)
216  {
217  runTime.setTime(timeDirs[timeI], timeI);
218 
219 # include "getTimeIndex.H"
220 
221  // remember the time index
222  fieldTimesUsed.append(timeIndex);
223 
224  // the data/ITER subdirectory must exist
226  mkDir(dataDir/subDir);
227 
228  // place a timestamp in the directory for future reference
229  {
230  OFstream timeStamp(dataDir/subDir/"time");
231  timeStamp
232  << "# timestep time" << nl
233  << subDir.c_str() << " " << runTime.timeName() << nl;
234  }
235 
236 # include "moveMesh.H"
237 
238  if (timeI == 0 || mesh.moving())
239  {
240  if (mesh.moving())
241  {
242  partsList.recalculate(mesh);
243  }
244 
245  if (!optNoMesh)
246  {
247  fileName geomDir;
248  if (hasMovingMesh)
249  {
250  geomDir = dataDir/subDir;
251  }
252 
253  ensightGeoFile geoFile(ensightDir/geomDir/geometryName, format);
254  partsList.writeGeometry(geoFile);
255  Info<< nl;
256  }
257  }
258 
259  Info<< "write volume field (" << flush;
260 
262  {
263  const word& fieldName = fieldIter.key();
264  const word& fieldType = fieldIter();
265 
267  (
268  fieldName,
269  mesh.time().timeName(),
270  mesh,
273  );
274 
275  if (fieldType == volScalarField::typeName)
276  {
277  ensightVolField<scalar>
278  (
279  partsList,
280  fieldObject,
281  mesh,
282  dataDir,
283  subDir,
284  format
285  );
286 
287  }
288  else if (fieldType == volVectorField::typeName)
289  {
290  ensightVolField<vector>
291  (
292  partsList,
293  fieldObject,
294  mesh,
295  dataDir,
296  subDir,
297  format
298  );
299 
300  }
301  else if (fieldType == volSphericalTensorField::typeName)
302  {
303  ensightVolField<sphericalTensor>
304  (
305  partsList,
306  fieldObject,
307  mesh,
308  dataDir,
309  subDir,
310  format
311  );
312 
313  }
314  else if (fieldType == volSymmTensorField::typeName)
315  {
316  ensightVolField<symmTensor>
317  (
318  partsList,
319  fieldObject,
320  mesh,
321  dataDir,
322  subDir,
323  format
324  );
325  }
326  else if (fieldType == volTensorField::typeName)
327  {
328  ensightVolField<tensor>
329  (
330  partsList,
331  fieldObject,
332  mesh,
333  dataDir,
334  subDir,
335  format
336  );
337  }
338  }
339  Info<< " )" << endl;
340 
341  // check for clouds
343  {
344  const word& cloudName = cloudIter.key();
345 
346  if
347  (
348  !isDir
349  (
350  runTime.timePath()/regionPrefix/
352  )
353  )
354  {
355  continue;
356  }
357 
358  IOobjectList cloudObjs
359  (
360  mesh,
361  runTime.timeName(),
363  );
364 
365  // check that the positions field is present for this time
366  if (cloudObjs.lookup("positions"))
367  {
369  (
370  mesh,
371  dataDir,
372  subDir,
373  cloudName,
374  format
375  );
376  }
377  else
378  {
379  continue;
380  }
381 
382  Info<< "write " << cloudName << " (" << flush;
383 
384  forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
385  {
386  const word& fieldName = fieldIter.key();
387  const word& fieldType = fieldIter();
388 
389  IOobject *fieldObject = cloudObjs.lookup(fieldName);
390 
391  if (!fieldObject)
392  {
393  Info<< "missing "
394  << runTime.timeName()/cloud::prefix/cloudName
395  / fieldName
396  << endl;
397  continue;
398  }
399 
400  if (fieldType == scalarIOField::typeName)
401  {
402  ensightLagrangianField<scalar>
403  (
404  *fieldObject,
405  dataDir,
406  subDir,
407  cloudName,
408  format
409  );
410 
411  }
412  else if (fieldType == vectorIOField::typeName)
413  {
414  ensightLagrangianField<vector>
415  (
416  *fieldObject,
417  dataDir,
418  subDir,
419  cloudName,
420  format
421  );
422 
423  }
424  else if (fieldType == tensorIOField::typeName)
425  {
426  ensightLagrangianField<tensor>
427  (
428  *fieldObject,
429  dataDir,
430  subDir,
431  cloudName,
432  format
433  );
434 
435  }
436  }
437 
438  Info<< " )" << endl;
439 
440  // remember the time index
441  cloudTimesUsed[cloudName]->append(timeIndex);
442  }
443  }
444 
445 # include "ensightOutputCase.H"
446 
447  Info<< "\nEnd\n"<< endl;
448 
449  return 0;
450 }
451 
452 
453 // ************************ vim: set sw=4 sts=4 et: ************************ //