foamToEnsight.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  foamToEnsight
29 
30 Group
31  grpPostProcessingUtilitie
32 
33 Description
34  Translate OpenFOAM data to EnSight format.
35  An Ensight part is created for cellZones (unzoned cells are "internalMesh")
36  and patches.
37 
38  - Handles volume fields, dimensioned fields, point fields
39  - Handles mesh topology changes.
40 
41 Usage
42  \b foamToEnsight [OPTION]
43 
44  Options:
45  - \par -ascii
46  Write Ensight data in ASCII format instead of "C Binary"
47 
48  - \par -fields <fields>
49  Specify single or multiple fields to write (all by default)
50  For example,
51  \verbatim
52  -fields T
53  -fields '(p T U \"alpha.*\")'
54  \endverbatim
55  The quoting is required to avoid shell expansions and to pass the
56  information as a single argument.
57 
58  - \par -nearCellValue
59  Use zero-gradient cell values on patches
60 
61  - \par -nodeValues
62  Force interpolation of values to nodes
63 
64  - \par -no-boundary
65  Suppress output for all boundary patches
66 
67  - \par -no-internal
68  Suppress output for internal (volume) mesh
69 
70  - \par -no-cellZones
71  Suppress cellZone handling
72 
73  - \par -no-lagrangian
74  Suppress writing lagrangian positions and fields.
75 
76  - \par -no-mesh
77  Suppress writing the geometry. Can be useful for converting partial
78  results for a static geometry.
79 
80  - \par -no-point-data
81  Suppress conversion of pointFields. No interpolated PointData.
82 
83  - \par -noZero
84  Exclude the often incomplete initial conditions.
85 
86  - \par -index <start>
87  Use consecutive indexing for \c data/######## files with the
88  specified start index.
89  Ignore the time index contained in the uniform/time file.
90 
91  - \par -name <subdir>
92  Define sub-directory name to use for Ensight data (default: "EnSight")
93 
94  - \par -width <n>
95  Width of Ensight data subdir (default: 8)
96 
97  - \par -cellZones NAME | LIST
98  Specify single zone or multiple cell zones (name or regex) to write
99 
100  - \par -faceZones NAME | LIST
101  Specify single zone or multiple face zones (name or regex) to write
102 
103  - \par -patches NAME | LIST
104  Specify single patch or multiple patches (name or regex) to write
105  For example,
106  \verbatim
107  -patches top
108  -patches '( front \".*back\" )'
109  \endverbatim
110 
111  - \par -excludePatches NAME | LIST
112  Exclude single or multiple patches (name or regex) from writing.
113  For example,
114  \verbatim
115  -excludePatches '( inlet_1 inlet_2 "proc.*" )'
116  \endverbatim
117 
118 \*---------------------------------------------------------------------------*/
119 
120 #include "argList.H"
121 #include "timeSelector.H"
122 #include "IOobjectList.H"
123 #include "IOmanip.H"
124 #include "OFstream.H"
125 #include "PstreamCombineReduceOps.H"
126 #include "HashOps.H"
127 
128 #include "fvc.H"
129 #include "fvMesh.H"
130 #include "fieldTypes.H"
131 #include "volFields.H"
132 #include "scalarIOField.H"
133 #include "vectorIOField.H"
134 
135 // file-format/conversion
136 #include "ensightCase.H"
137 #include "ensightGeoFile.H"
138 #include "ensightMesh.H"
139 #include "ensightOutputCloud.H"
140 #include "ensightOutputVolField.H"
141 
142 // local files
143 #include "readFields.H"
144 #include "writeVolFields.H"
145 #include "writeDimFields.H"
146 #include "writePointFields.H"
147 
148 #include "memInfo.H"
149 
150 #undef foamToEnsight_useTimeIndex
151 
152 using namespace Foam;
153 
154 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
155 
156 int main(int argc, char *argv[])
157 {
159  (
160  "Translate OpenFOAM data to Ensight format with individual parts"
161  " for cellZones, unzoned cells and patches"
162  );
164 
165  // Less frequently used - reduce some clutter
166  argList::setAdvanced("decomposeParDict");
167  argList::setAdvanced("noFunctionObjects");
168 
169  #include "addRegionOption.H"
170 
172  (
173  "ascii",
174  "Write in ASCII format instead of 'C Binary'"
175  );
177  (
178  "index",
179  "start",
180  "Starting index for consecutive number of Ensight data/ files."
181  " Ignore the time index contained in the uniform/time file."
182  , true // mark as an advanced option
183  );
185  (
186  "name",
187  "subdir",
188  "Sub-directory name for Ensight output (default: 'EnSight')"
189  );
191  (
192  "no-overwrite",
193  "Suppress removal of existing EnSight output directory"
194  );
196  (
197  "width",
198  "n",
199  "Width of Ensight data subdir"
200  );
202  (
203  "nearCellValue",
204  "Use zero-gradient cell values on patches"
205  , true // mark as an advanced option
206  );
208  (
209  "nodeValues",
210  "Force interpolation of values to nodes"
211  , true // mark as an advanced option
212  );
214  (
215  "no-boundary", // noPatches
216  "Suppress writing any patches"
217  );
218  argList::addOptionCompat("no-boundary", {"noPatches", 1806});
219 
221  (
222  "no-internal",
223  "Suppress writing the internal mesh"
224  );
226  (
227  "no-cellZones",
228  "Suppress writing any cellZones"
229  );
231  (
232  "no-lagrangian", // noLagrangian
233  "Suppress writing lagrangian positions and fields"
234  );
235  argList::addOptionCompat("no-lagrangian", {"noLagrangian", 1806});
236 
238  (
239  "no-point-data",
240  "Suppress conversion of pointFields, disable -nodeValues"
241  );
243  (
244  "no-mesh", // noMesh
245  "Suppress writing the geometry."
246  " Can be useful for converting partial results for a static geometry"
247  , true // mark as an advanced option
248  );
249 
250  // Future?
251  // argList::addBoolOption
252  // (
253  // "one-boundary", // allPatches
254  // "Combine all patches into a single part"
255  // );
256 
258  (
259  "patches",
260  "wordRes",
261  "Specify single patch or multiple patches to write\n"
262  "Eg, 'inlet' or '(outlet \"inlet.*\")'"
263  );
265  (
266  "excludePatches",
267  "wordRes",
268  "Exclude single or multiple patches from writing\n"
269  "Eg, 'outlet' or '( inlet \".*Wall\" )'"
270  , true // mark as an advanced option
271  );
273  (
274  "faceZones",
275  "wordRes",
276  "Specify single or multiple faceZones to write\n"
277  "Eg, 'cells' or '( slice \"mfp-.*\" )'."
278  );
280  (
281  "fields",
282  "wordRes",
283  "Specify single or multiple fields to write (all by default)\n"
284  "Eg, 'T' or '( \"U.*\" )'"
285  );
287  (
288  "cellZones",
289  "wordRes",
290  "Specify single or multiple cellZones to write\n"
291  "Eg, 'cells' or '( slice \"mfp-.*\" )'."
292  );
293  argList::addOptionCompat("cellZones", {"cellZone", 1912});
294 
295 
296  #include "setRootCase.H"
297 
298  // Default to binary output, unless otherwise specified
300  (
301  args.found("ascii")
304  );
305 
306  cpuTime timer;
307  memInfo mem;
308  Info<< "Initial memory " << mem.update().size() << " kB" << endl;
309 
310  #include "createTime.H"
311 
313 
314  #include "createNamedMesh.H"
315 
316  fileName regionPrefix; // Mesh instance (region0 gets filtered out)
318  {
319  regionPrefix = regionName;
320  }
321 
322 
323  //
324  // Configuration
325  //
326  const bool doBoundary = !args.found("no-boundary");
327  const bool doInternal = !args.found("no-internal");
328  const bool doCellZones = !args.found("no-cellZones");
329  const bool doLagrangian = !args.found("no-lagrangian");
330  const bool doPointValues = !args.found("no-point-data");
331  const bool nearCellValue = args.found("nearCellValue") && doBoundary;
332 
333  // Control for numbering iterations
334  label indexingNumber(0);
335  const bool doConsecutive = args.readIfPresent("index", indexingNumber);
336 
337 
338  // Write the geometry, unless otherwise specified
339  bool doGeometry = !args.found("no-mesh");
340 
341  if (nearCellValue)
342  {
343  Info<< "Using neighbouring cell value instead of patch value"
344  << nl << endl;
345  }
346  if (!doPointValues)
347  {
348  Info<< "Point fields and interpolated point data"
349  << " disabled with the '-no-point-data' option"
350  << nl;
351  }
352 
353  //
354  // General (case) output options
355  //
356  ensightCase::options caseOpts(format);
357 
358  // Forced point interpolation?
359  caseOpts.nodeValues(doPointValues && args.found("nodeValues"));
360  caseOpts.width(args.getOrDefault<label>("width", 8));
361  caseOpts.overwrite(!args.found("no-overwrite")); // Remove existing?
362 
363  // Can also have separate directory for lagrangian
364  // caseOpts.separateCloud(true);
365 
366  // Define sub-directory name to use for EnSight data.
367  // The path to the ensight directory is at case level only
368  // - For parallel cases, data only written from master
369  fileName outputDir = args.getOrDefault<word>("name", "EnSight");
370  if (!outputDir.isAbsolute())
371  {
372  outputDir = args.globalPath()/outputDir;
373  }
374 
375  ensightMesh::options writeOpts;
376  writeOpts.useBoundaryMesh(doBoundary);
377  writeOpts.useInternalMesh(doInternal);
378  writeOpts.useCellZones(doCellZones);
379 
380  if (args.found("patches"))
381  {
382  writeOpts.patchSelection(args.getList<wordRe>("patches"));
383  }
384  if (args.found("excludePatches"))
385  {
386  writeOpts.patchExclude(args.getList<wordRe>("excludePatches"));
387  }
388 
389  if (args.found("faceZones"))
390  {
391  writeOpts.faceZoneSelection(args.getList<wordRe>("faceZones"));
392  }
393  if (args.found("cellZones"))
394  {
395  writeOpts.cellZoneSelection(args.getList<wordRe>("cellZones"));
396  }
397 
398  // Report the setup
399  writeOpts.print(Info);
400 
401 
402  //
403  // Output configuration (field related)
404  //
405 
406  wordRes fieldPatterns;
407  args.readListIfPresent<wordRe>("fields", fieldPatterns);
408 
409  // New ensight case file, initialize header etc.
410  ensightCase ensCase(outputDir, args.globalCaseName(), caseOpts);
411 
412  // Construct ensight mesh
413  ensightMesh ensMesh(mesh, writeOpts);
414 
415  if (Pstream::master())
416  {
417  Info<< "Converting " << timeDirs.size() << " time steps" << nl;
418  ensCase.printInfo(Info) << endl;
419  }
420 
421  #include "checkMeshMoving.H"
422  #include "findCloudFields.H"
423 
424  // test the pre-check variable if there is a moving mesh
425  // time-set for geometries
426  // TODO: split off into separate time-set,
427  // but need to verify ensight spec
428 
429  Info<< "Startup in "
430  << timer.cpuTimeIncrement() << " s, "
431  << mem.update().size() << " kB" << nl << endl;
432 
433 
434  // Initially all possible objects that are available at the final time
435  wordHashSet testedObjectNames;
436  {
437  IOobjectList objects(mesh, timeDirs.last().name());
438 
439  if (!fieldPatterns.empty())
440  {
441  objects.filterObjects(fieldPatterns);
442  }
443 
444  // Remove "*_0" restart fields
445  objects.prune_0();
446 
447  if (!doPointValues)
448  {
449  // Prune point fields if disabled
450  objects.filterClasses
451  (
452  [](const word& clsName)
453  {
454  return fieldTypes::point.found(clsName);
455  },
456  true // prune
457  );
458  }
459 
460  wordList objectNames(objects.sortedNames());
461 
462  // Check availability for all times...
463  checkData(mesh, timeDirs, objectNames);
464 
465  testedObjectNames = objectNames;
466  }
467 
468  if (hasMovingMesh && !doGeometry)
469  {
470  Info<< "has moving mesh: ignoring '-no-mesh' option" << endl;
471  doGeometry = true;
472  }
473 
474  forAll(timeDirs, timei)
475  {
476  runTime.setTime(timeDirs[timei], timei);
477 
478  // Index for the Ensight case
479  #include "getTimeIndex.H"
480 
481  ensCase.setTime(timeDirs[timei], timeIndex);
482 
483  Info<< "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
484 
486  const bool moving = (meshState != polyMesh::UNCHANGED);
487 
488  if (moving)
489  {
490  ensMesh.expire();
491  ensMesh.correct();
492  }
493 
494  if (timei == 0 || moving)
495  {
496  if (doGeometry)
497  {
498  autoPtr<ensightGeoFile> os = ensCase.newGeometry(hasMovingMesh);
499  ensMesh.write(os);
500  }
501  }
502 
503  // Objects at this time
504  IOobjectList objects(mesh, runTime.timeName());
505 
506  // Restrict to objects that are available for all times
507  objects.filterObjects(testedObjectNames);
508 
509  // Volume, internal, point fields
510  #include "convertVolumeFields.H"
511 
512  // Lagrangian fields
513  #include "convertLagrangian.H"
514 
515  Info<< "Wrote in "
516  << timer.cpuTimeIncrement() << " s, "
517  << mem.update().size() << " kB" << nl << nl;
518  }
519 
520  ensCase.write();
521 
522  Info<< "\nEnd: "
523  << timer.elapsedCpuTime() << " s, "
524  << mem.update().peak() << " kB (peak)" << nl << endl;
525 
526  return 0;
527 }
528 
529 
530 // ************************************************************************* //
Foam::ensightMesh::options::useCellZones
bool useCellZones() const
Using cellZones?
Definition: ensightMeshOptions.C:93
volFields.H
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::ensightMesh::options::useBoundaryMesh
bool useBoundaryMesh() const
Using boundary?
Definition: ensightMeshOptions.C:87
Foam::ensightMesh
Encapsulation of volume meshes for writing in ensight format. It manages cellZones,...
Definition: ensightMesh.H:82
ensightCase.H
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::polyMesh::defaultRegion
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:312
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:286
Foam::checkData
label checkData(const fvMesh &mesh, const instantList &timeDirs, wordList &objectNames)
Check if fields are good to use (available at all times)
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:785
Foam::ensightMesh::options::faceZoneSelection
const wordRes & faceZoneSelection() const
Selection of faceZones. Empty if unspecified.
Definition: ensightMeshOptions.C:282
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
Foam::argList::addOptionCompat
static void addOptionCompat(const word &optName, std::pair< const char *, int > compat)
Specify an alias for the option name.
Definition: argList.C:369
Foam::memInfo::peak
int peak() const
Peak memory (VmPeak in /proc/PID/status) at last update()
Definition: memInfo.H:103
Foam::argList::readListIfPresent
bool readListIfPresent(const word &optName, List< T > &list) const
Definition: argListI.H:373
IOobjectList.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
scalarIOField.H
Foam::HashSet< word >
Foam::argList::readIfPresent
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:302
Foam::wordRe
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition: wordRe.H:72
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOobjectList::filterObjects
label filterObjects(const UnaryPredicate &pred, const bool pruning=false)
Filter to retain or prune given object names.
OFstream.H
Foam::fvMesh::readUpdate
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in time.
Definition: fvMesh.C:519
PstreamCombineReduceOps.H
Combination-Reduction operation for a parallel run. The information from all nodes is collected on th...
format
word format(conversionProperties.get< word >("format"))
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
Foam::memInfo::update
const memInfo & update()
Update according to /proc/PID/status and /proc/memory contents.
Definition: memInfo.C:64
ensightMesh.H
Foam::ensightMesh::options::useInternalMesh
bool useInternalMesh() const
Using internal?
Definition: ensightMeshOptions.C:81
Foam::ensightMesh::options::cellZoneSelection
const wordRes & cellZoneSelection() const
Selection of faceZones. Empty if unspecified.
Definition: ensightMeshOptions.C:288
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
argList.H
addRegionOption.H
IOmanip.H
Istream and Ostream manipulators taking arguments.
Foam::polyMesh::UNCHANGED
Definition: polyMesh.H:93
Foam::argList::setAdvanced
static void setAdvanced(const word &optName, bool advanced=true)
Set an existing option as being 'advanced' or normal.
Definition: argList.C:355
Foam::fieldTypes::point
const wordList point
Standard point field types (scalar, vector, tensor, etc)
Foam::cpuTimeCxx
Starts timing CPU usage and return elapsed time from start.
Definition: cpuTimeCxx.H:53
Foam::IOstreamOption::streamFormat
streamFormat
Data format (ascii | binary)
Definition: IOstreamOption.H:70
createNamedMesh.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
ensightOutputVolField.H
A collection of functions for writing volField content in ensight format.
Foam::memInfo
Memory usage information for the current process, and the system memory that is free.
Definition: memInfo.H:62
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::IOobjectList
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:55
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:439
Foam::polyMesh::readUpdateState
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:91
Foam::ensightCase
Supports writing of ensight cases as well as providing common factory methods to open new files.
Definition: ensightCase.H:67
vectorIOField.H
Foam::argList::addBoolOption
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:325
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::ensightMesh::options::patchSelection
const wordRes & patchSelection() const
Selection of patches. Empty if unspecified.
Definition: ensightMeshOptions.C:270
setRootCase.H
Foam::IOstreamOption::BINARY
"binary"
Definition: IOstreamOption.H:73
ensightGeoFile.H
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
hasMovingMesh
bool hasMovingMesh
Definition: checkMeshMoving.H:3
checkMeshMoving.H
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::ensightMesh::options
Configuration options for the ensightMesh.
Definition: ensightMesh.H:213
Foam::timeSelector::addOptions
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
Definition: timeSelector.C:108
Foam::List< instant >
Foam::Time::setTime
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:1006
Foam::timer
Implements a timeout mechanism via sigalarm.
Definition: timer.H:83
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
Foam::argList::globalPath
fileName globalPath() const
Return the full path to the global case.
Definition: argListI.H:87
timeSelector.H
ensightOutputCloud.H
A collection of functions for writing clouds as ensight file content.
createTime.H
Foam::ensightCase::options
Configuration options for the ensightCase.
Definition: ensightCase.H:328
Foam::argList::getList
List< T > getList(const label index) const
Get a List of values from the argument at index.
fvc.H
Foam::ensightMesh::options::print
void print(Ostream &os) const
Report values.
Definition: ensightMeshOptions.C:294
timeIndex
label timeIndex
Definition: getTimeIndex.H:4
Foam::memInfo::size
int size() const
Memory size (VmSize in /proc/PID/status) at last update()
Definition: memInfo.H:109
Foam::timeSelector::select0
static instantList select0(Time &runTime, const argList &args)
Definition: timeSelector.C:241
Foam::argList::addOption
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:336
args
Foam::argList args(argc, argv)
fieldTypes.H
Header files for all the primitive types that Fields are instantiated for.
findCloudFields.H
Foam::argList::globalCaseName
const fileName & globalCaseName() const
Return global case name.
Definition: argListI.H:75
Foam::fileName::isAbsolute
static bool isAbsolute(const std::string &str)
Return true if string starts with a '/'.
Definition: fileNameI.H:136
HashOps.H
Foam::ensightMesh::options::patchExclude
const wordRes & patchExclude() const
Selection of black listed patches. Empty if unspecified.
Definition: ensightMeshOptions.C:276
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:157