ensightCase.H
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) 2016-2023 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Class
27  Foam::ensightCase
28 
29 Description
30  Supports writing of ensight cases as well as providing common factory
31  methods to open new files.
32 
33 SourceFiles
34  ensightCase.C
35  ensightCaseI.H
36  ensightCaseOptions.C
37  ensightCaseTemplates.C
38 
39 \*---------------------------------------------------------------------------*/
40 
41 #ifndef Foam_ensightCase_H
42 #define Foam_ensightCase_H
43 
44 #include "autoPtr.H"
45 #include "HashSet.H"
46 #include "InfoProxy.H"
47 #include "Map.H"
48 #include "HashSet.H"
49 #include "Pstream.H"
50 #include "ensightGeoFile.H"
51 #include <memory>
52 
53 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54 
55 namespace Foam
56 {
57 
58 // Forward Declarations
59 class bitSet;
60 class dictionary;
61 class ensightCase;
62 class instant;
63 class OSstream;
64 class Time;
65 
66 /*---------------------------------------------------------------------------*\
67  Class ensightCase Declaration
68 \*---------------------------------------------------------------------------*/
69 
71 {
72 public:
73 
74  // Forward Declarations
75  class options;
76 
77  // Public Data
78 
79  //- The name for data subdirectory: "data"
80  static const char* dataDirName;
81 
82  //- The name for geometry files: "geometry"
83  static const char* geometryName;
84 
85 
86 private:
87 
88  // Private Data
89 
90  //- Case writing options
91  const std::unique_ptr<options> options_;
92 
93  //- Output stream (master only)
94  mutable std::unique_ptr<OFstream> os_;
95 
96  //- Output path (absolute)
97  fileName ensightDir_;
98 
99  //- Case name (with ".case" ending)
100  word caseName_;
101 
102  //- Track state changes since last write
103  mutable bool changed_;
104 
105  //- Time index (timeset 1)
106  label timeIndex_;
107 
108  //- Time value (timeset 1)
109  scalar timeValue_;
110 
111  //- Record of time index/value used (eg, field values).
112  // These values will be used for timeset 1.
113  Map<scalar> timesUsed_;
114 
115  //- Record time indices when geometry is written.
116  // These values will be used to decide if timeset 1
117  // or a separate timeset are used.
118  // The special index '-1' is used for static geometry.
119  mutable labelHashSet geomTimes_;
120 
121  //- Record time indices when clouds are written.
122  // These values will be used to decide if timeset 1
123  // or a separate timeset are used.
124  mutable labelHashSet cloudTimes_;
125 
126  //- Fields/Variables with the ensight type
127  mutable HashTable<string> variables_;
128 
129  //- Remember fields that are to be treated as point data
130  mutable HashSet<string> nodeVariables_;
131 
132  //- Cloud names and variables
133  mutable HashTable<HashTable<string>> cloudVars_;
134 
135 
136  // Private Member Functions
137 
138  //- The data directory
139  fileName dataDir() const;
140 
141  //- Initial file management (master only)
142  void initialize();
143 
144  //- Check if timeset uses different times than from time-set 1
145  label checkTimeset(const labelHashSet& lookup) const;
146 
147  //- Write the header into the case file.
148  void writeHeader() const;
149 
150  //- Write the timeset 1 into the case file.
151  // Return the time correction in effect
152  scalar writeTimeset() const;
153 
154  //- Write the timeset into the case file.
155  void writeTimeset
156  (
157  const label ts,
158  const labelHashSet& lookup,
159  const scalar timeCorrection = 0
160  ) const;
161 
162 
163  //- Note the geometry being used
164  void noteGeometry(const bool moving) const;
165 
166  //- Note the cloud being used
167  void noteCloud(const word& cloudName) const;
168 
169  //- Note the cloud/variable being used
170  void noteCloud
171  (
172  const word& cloudName,
173  const word& varName,
174  const char* ensightType
175  ) const;
176 
177  //- Note the field variable being used
178  void noteVariable
179  (
180  const word& varName,
181  const char* ensightType
182  ) const;
183 
184 
185  //- Open stream for new data file (on master), using the current index.
186  // File is without initial description lines.
187  autoPtr<ensightFile> createDataFile(const word& name) const;
188 
189  //- Open stream for new cloud file (on master).
190  // File is without initial description lines.
191  autoPtr<ensightFile> createCloudFile
192  (
193  const word& cloudName,
194  const word& name
195  ) const;
196 
197 
198  //- No copy construct
199  ensightCase(const ensightCase&) = delete;
200 
201  //- No copy assignment
202  void operator=(const ensightCase&) = delete;
203 
204 
205 public:
206 
207  // Constructors
208 
209  //- Construct from components
211  (
212  const fileName& ensightDir,
213  const word& caseName,
214  const options& opts
215  );
216 
217  //- Construct from components with all default options
219  (
220  const fileName& ensightDir,
221  const word& caseName,
223  );
224 
225 
226  //- Destructor
227  ~ensightCase() = default;
228 
229 
230  // Static Functions
231 
232  //- Stringified zero-padded integer value
233  static word padded(const int nwidth, const label value);
234 
235 
236  // Member Functions
237 
238  // Access
239 
240  //- Reference to the case options
241  inline const ensightCase::options& option() const;
242 
243  //- The output file format (ascii/binary)
244  inline IOstreamOption::streamFormat format() const;
245 
246  //- The nominal path to the case file
247  inline const fileName& path() const noexcept;
248 
249  //- The output '*' mask
250  inline const word& mask() const;
251 
252  //- Consistent zero-padded integer value
253  inline word padded(const label i) const;
254 
255  //- Force use of values per node instead of per element
256  inline bool nodeValues() const;
257 
258  //- Write clouds into their own directory instead in "data" directory
259  inline bool separateCloud() const;
260 
261 
262  // Edit
263 
264  //- Set time for time-set 1, using next available index.
265  // Create corresponding sub-directory.
266  // Do not mix between nextTime and setTime in an application.
267  void nextTime(const scalar t);
268 
269  //- Set time for time-set 1, using next available index.
270  // Create corresponding sub-directory.
271  // Do not mix between nextTime and setTime in an application.
272  void nextTime(const instant& t);
273 
274  //- Set current index and time for time-set 1.
275  // Create corresponding sub-directory
276  // \note do not mix between nextTime and setTime in an application.
277  void setTime(const scalar t, const label index);
278 
279  //- Set current index and time for time-set 1.
280  // Create corresponding sub-directory
281  // \note do not mix between nextTime and setTime in an application.
282  void setTime(const instant& t, const label index);
283 
284 
285  // Addition of entries to case file
286 
287  //- Open stream for new geometry file (on master).
288  autoPtr<ensightGeoFile> newGeometry(bool moving = false) const;
289 
290  //- Open stream for new cloud positions (on master).
291  // Note the use of ensightFile, not ensightGeoFile.
293  (
294  const word& cloudName
295  ) const;
296 
297  //- Open stream for new data file (on master), with current index.
298  // Optionally marking as containing POINT_DATA
299  template<class Type>
301  (
302  const word& varName,
303  const bool isPointData = false
304  ) const;
305 
306  //- Open stream for new data file (on master), with current index
307  //- and marking as containing POINT_DATA
308  template<class Type>
309  autoPtr<ensightFile> newPointData(const word& varName) const;
310 
311  //- Open stream for new cloud data file (on master), with current index.
312  template<class Type>
314  (
315  const word& cloudName,
316  const word& varName
317  ) const;
318 
319 
320  // Output
321 
322  //- Rewind the output stream (master only).
323  void rewind() const;
324 
325  //- Write the case file
326  void write() const;
327 
328  //- Output stream (master only).
329  inline Ostream& operator()() const;
330 
331  //- Print some general information.
332  Ostream& printInfo(Ostream& os) const;
333 
334 
335  // Output Helpers
336 
337  //- Set output time format for ensight case file
338  static void setTimeFormat
339  (
340  OSstream& os,
341  IOstreamOption::floatFormat timeFmt,
342  const int timePrec
343  );
344 
345  //- Set output time format for ensight case file
346  static void setTimeFormat
347  (
348  OSstream& os,
349  const ensightCase::options& opts
350  );
351 
352  //- Print time-set for ensight case file with a single time
353  static void printTimeset
354  (
355  OSstream& os,
356  const label ts,
357  const scalar timeValue
358  );
359 
360  //- Print time-set for ensight case file, with N times and 0-based
361  //- file numbering
362  //
363  // \verbatim
364  // TIME
365  // time set: ts
366  // number of steps: ns
367  // filename start number: 0
368  // filename increment: 1
369  // time values: time_1 time_2 ... time_ns
370  // \endverbatim
371  static void printTimeset
372  (
373  OSstream& os,
374  const label ts,
375  const UList<scalar>& times
376  );
377 
378  //- Print time-set for ensight case file, with N times, 0-based
379  //- file numbering but perhaps non-contiguous
380  //
381  // \verbatim
382  // TIME
383  // time set: ts
384  // number of steps: ns
385  // filename numbers: idx_1 idx_2 ... idx_ns
386  // time values: time_1 time_2 ... time_ns
387  // \endverbatim
388  static void printTimeset
389  (
390  OSstream& os,
391  const label ts,
392  const UList<scalar>& times,
393  const bitSet& indices
394  );
395 };
396 
397 
398 /*---------------------------------------------------------------------------*\
399  Class ensightCase::options Declaration
400 \*---------------------------------------------------------------------------*/
401 
402 //- Configuration options for the ensightCase
403 class ensightCase::options
404 {
405  // Private Data
406 
407  //- The output file format (ascii/binary)
409 
410  //- Remove existing directory and sub-directories on creation
411  bool overwrite_;
412 
413  //- Force use of values per node instead of per element
414  bool nodeValues_;
415 
416  //- Write clouds into their own directory
417  bool separateCloud_;
418 
419  //- Time format for case file (default: scientific)
420  IOstreamOption::floatFormat timeFormat_;
421 
422  //- Time precision for case file (default: 5)
423  int timePrecision_;
424 
425  //- Width of mask for subdirectories
426  int width_;
427 
428  //- The '*' mask appropriate for subdirectories
429  word mask_;
430 
431  //- The printf format for zero-padded subdirectory numbers
432  string printf_;
433 
434 
435 public:
436 
437  // Constructors
438 
439  //- Construct with the specified format (default is binary)
440  explicit options
441  (
443  );
444 
445  //- If present, construct with the format specified in the dictionary
446  //- or use default (binary)
447  options
448  (
451  const word& formatKeyword,
452  const dictionary& dict,
454  );
455 
456 
457  // Member Functions
458 
459  // Access
460 
461  //- The output file format (ascii/binary)
462  IOstreamOption::streamFormat format() const noexcept { return format_; }
463 
464  //- Time format for case file (general/fixed/scientific)
465  IOstreamOption::floatFormat timeFormat() const noexcept
466  {
467  return timeFormat_;
468  }
469 
470  //- Time precision for case file
471  int timePrecision() const noexcept { return timePrecision_; }
472 
473  //- The '*' mask appropriate for sub-directories
474  const word& mask() const noexcept { return mask_; }
475 
476  //- Consistent zero-padded integer value
477  word padded(const label i) const;
478 
479  //- Return current width of mask and padded.
480  int width() const noexcept { return width_; }
481 
482  //- Remove existing directory and sub-directories on creation
483  bool overwrite() const noexcept { return overwrite_; }
484 
485  //- Write clouds into their own directory instead in "data" directory
486  bool separateCloud() const noexcept { return separateCloud_; }
487 
488 
489  // Edit
490 
491  //- Set width of mask and padded.
492  // Default width is 8 digits, max width is 31 digits.
493  void width(const int i);
494 
495  //- Set the time format for case file
496  void timeFormat(IOstreamOption::floatFormat fmt) noexcept
497  {
498  timeFormat_ = fmt;
499  }
500 
501  //- Set the time precision for case file
502  void timePrecision(int prec) noexcept { timePrecision_ = prec; }
503 
504  //- Set the time format for case file
505  void timeFormat(const word& key, const dictionary& dict);
506 
507  //- Set the time precision for case file
508  void timePrecision(const word& key, const dictionary& dict);
509 
510  //- Remove existing directory and sub-directories on creation
511  void overwrite(bool on) noexcept { overwrite_ = on; }
512 
513  //- Write clouds into their own directory instead in "data" directory
514  void separateCloud(bool on) noexcept { separateCloud_ = on; }
515 
516 
517  // Housekeeping
518 
519  //- Forced use of values per node instead of per element
520  bool nodeValues() const noexcept { return nodeValues_; }
521 
522  //- Force use of values per node instead of per element
523  // Deprecated(2020-02) - The newData() method with a second parameter
524  // is more flexible.
525  // \deprecated(2020-02) - newData() with second parameter
526  void nodeValues(bool on) noexcept { nodeValues_ = on; }
527 };
528 
529 
530 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
531 
532 } // End namespace Foam
533 
534 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
535 
536 #include "ensightCaseI.H"
537 
538 #ifdef NoRepository
539  #include "ensightCaseTemplates.C"
540 #endif
541 
542 #endif
543 
544 // ************************************************************************* //
static void printTimeset(OSstream &os, const label ts, const scalar timeValue)
Print time-set for ensight case file with a single time.
Definition: ensightCase.C:91
Ensight output with specialized write() for strings, integers and floats. Correctly handles binary wr...
Definition: ensightFile.H:46
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:50
dictionary dict
A class for handling file names.
Definition: fileName.H:72
static void setTimeFormat(OSstream &os, IOstreamOption::floatFormat timeFmt, const int timePrec)
Set output time format for ensight case file.
Definition: ensightCase.C:53
static void writeHeader(Ostream &os, const word &fieldName)
autoPtr< ensightFile > newCloudData(const word &cloudName, const word &varName) const
Open stream for new cloud data file (on master), with current index.
static word padded(const int nwidth, const label value)
Stringified zero-padded integer value.
Definition: ensightCase.C:38
Supports writing of ensight cases as well as providing common factory methods to open new files...
Definition: ensightCase.H:65
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
floatFormat
Float formats (eg, time directory name formats)
Specialized Ensight output with extra geometry file header.
void nextTime(const scalar t)
Set time for time-set 1, using next available index.
Definition: ensightCase.C:596
void rewind() const
Rewind the output stream (master only).
Definition: ensightCase.C:892
A simple container for options an IOstream can normally have.
Lookup type of boundary radiation properties.
Definition: lookup.H:57
Configuration options for the ensightCase.
Definition: ensightCase.H:530
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
const word cloudName(propsDict.get< word >("cloud"))
autoPtr< ensightFile > newData(const word &varName, const bool isPointData=false) const
Open stream for new data file (on master), with current index.
A class for handling words, derived from Foam::string.
Definition: word.H:63
static const char * geometryName
The name for geometry files: "geometry".
Definition: ensightCase.H:82
IOstreamOption::streamFormat format() const
The output file format (ascii/binary)
Definition: ensightCaseI.H:29
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
const fileName & path() const noexcept
The nominal path to the case file.
Definition: ensightCaseI.H:35
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:105
bool separateCloud() const
Write clouds into their own directory instead in "data" directory.
Definition: ensightCaseI.H:59
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: Scalar.H:258
const ensightCase::options & option() const
Reference to the case options.
Definition: ensightCaseI.H:23
autoPtr< ensightGeoFile > newGeometry(bool moving=false) const
Open stream for new geometry file (on master).
Definition: ensightCase.C:834
OBJstream os(runTime.globalPath()/outputName)
bool nodeValues() const
Force use of values per node instead of per element.
Definition: ensightCaseI.H:53
An instant of time. Contains the time value and name. Uses Foam::Time when formatting the name...
Definition: instant.H:53
void write() const
Write the case file.
Definition: ensightCase.C:640
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
~ensightCase()=default
Destructor.
streamFormat
Data format (ascii | binary)
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
static const char * dataDirName
The name for data subdirectory: "data".
Definition: ensightCase.H:70
const word & mask() const
The output &#39;*&#39; mask.
Definition: ensightCaseI.H:41
Ostream & printInfo(Ostream &os) const
Print some general information.
Definition: ensightCase.C:901
autoPtr< ensightFile > newCloud(const word &cloudName) const
Open stream for new cloud positions (on master).
Definition: ensightCase.C:868
autoPtr< ensightFile > newPointData(const word &varName) const
Open stream for new data file (on master), with current index and marking as containing POINT_DATA...
void setTime(const scalar t, const label index)
Set current index and time for time-set 1.
Definition: ensightCase.C:609
Namespace for OpenFOAM.