surfaceWriter.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) 2011-2012 OpenFOAM Foundation
9  Copyright (C) 2015-2024 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 Namespace
28  Foam::surfaceWriters
29 
30 Description
31  Namespace for surface writers
32 
33 Class
34  Foam::surfaceWriter
35 
36 Description
37  Base class for surface writers.
38 
39  The surfaceWriter interface is rather large since we need a writer that
40  can either be initially defined without a surface association
41  and have that added at a later stage, or be defined with a surface
42  association.
43 
44  \verbatim
45  formatOptions
46  {
47  default
48  {
49  verbose true;
50  commsType scheduled;
51 
52  fieldLevel
53  {
54  "p.*" 1e5; // Absolute -> gauge [Pa]
55  T 273.15; // [K] -> [C]
56  U #eval{ 10/sqrt(3) }; // Uniform magU=10
57  }
58  }
59 
60  someFormat // Eg, ensight, vtk, etc
61  {
62  fieldScale
63  {
64  "p.*" 0.01; // [Pa] -> [mbar]
65  }
66 
67  scale 1000; // [m] -> [mm]
68  transform
69  {
70  origin (0 0 0);
71  rotationCentre (0 0 0);
72  rotation axisAngle;
73  axis (1 0 0);
74  angle 45;
75  }
76  }
77  }
78  \endverbatim
79 
80  Format options:
81  \table
82  Property | Description | Reqd | Default
83  verbose | Additional output verbosity | no | no
84  commsType | Communication type | no | scheduled
85  scale | Output geometry scaling | no | 1
86  transform | Output coordinate transform | no |
87  fieldLevel | Subtract field level before scaling | no | empty dict
88  fieldScale | Output field scaling | no | empty dict
89  \endtable
90 
91 Note
92  The \c transform sub-dictionary also supports a \c rotationCentre
93  keyword which applies \em untranslate by that amount prior to the rotation,
94  and subsequently followed by a \em translate.
95 
96  For surface formats that require geometry in a separate file,
97  it is the responsibility of the implementation (not the caller)
98  to ensure that this occurs.
99 
100 SourceFiles
101  surfaceWriter.C
102  surfaceWriterI.H
103 
104 \*---------------------------------------------------------------------------*/
105 
106 #ifndef Foam_surfaceWriter_H
107 #define Foam_surfaceWriter_H
108 
109 #include "typeInfo.H"
110 #include "autoPtr.H"
111 #include "tmp.H"
112 #include "cartesianCS.H"
113 #include "Field.H"
114 #include "fileName.H"
115 #include "instant.H"
116 #include "mergedSurf.H"
117 #include "meshedSurfRef.H"
118 #include "UPstream.H"
119 #include "InfoProxy.H"
120 #include "runTimeSelectionTables.H"
121 
122 // Deprecated methods
123 // #define Foam_surfaceWriter_directAccess
124 
125 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
126 
127 namespace Foam
128 {
129 
130 // Forward Declarations
131 class Time;
132 class surfaceWriter;
133 
134 Ostream& operator<<(Ostream& os, const InfoProxy<surfaceWriter>& ip);
135 
136 
137 /*---------------------------------------------------------------------------*\
138  Class surfaceWriter Declaration
139 \*---------------------------------------------------------------------------*/
140 
141 class surfaceWriter
142 {
143 protected:
144 
145  // Private Data
146 
147  //- Reference to surface or surface components
148  meshedSurfRef surf_;
149 
150  //- Surface after merging (parallel)
151  mutable mergedSurf mergedSurf_;
152 
153  //- The surface after point coordinate transforms and scaling
154  mutable meshedSurfRef adjustedSurf_;
155 
156  //- Dimension for merging
157  scalar mergeDim_;
158 
159  //- Output geometry scaling after rotate/translate
160  scalar geometryScale_;
161 
162  //- The centre of rotation (untranslate, translate)
164 
165  //- Local coordinate system transformation
166  coordSystem::cartesian geometryTransform_;
167 
168 
169 protected:
170 
171  // Protected Data
173  //- The topology/surface is up-to-date?
174  mutable bool upToDate_;
175 
176  //- Track if geometry has been written since the last open
177  mutable bool wroteGeom_;
178 
179  //- Writing in parallel (via master)
180  bool parallel_;
182  //- Insert additional time sub-directory in the output path
183  bool useTimeDir_;
184 
185  //- Is point vs cell data
187 
188  //- Additional output verbosity
189  bool verbose_;
190 
191  //- Communication type (for field merging)
193 
194  //- The number of fields
195  label nFields_;
197  //- The current time value/name
199 
200  //- The full output directory and file (surface) name
202 
203  //- Field level to remove (on output)
205 
206  //- Field scaling (on output)
208 
209 
210  // Protected Member Functions
212  //- Verify that the outputPath_ has been set or FatalError
213  void checkOpen() const;
214 
215  //- Merge surfaces if they are not already upToDate (parallel)
216  //- or simply mark the surface as being up-to-date
217  virtual bool merge() const;
218 
219  //- Merge surfaces (if not upToDate) and return merged (parallel)
220  //- or regular surface (non-parallel)
221  const meshedSurf& surface() const;
222 
223  //- Merge surfaces (if not upToDate) and return merged (parallel)
224  //- or regular surface (non-parallel)
225  //- and apply any coordinate system changes and/or output scaling.
226  const meshedSurfRef& adjustSurface() const;
227 
228  //- Gather (merge) fields with renumbering and shrinking for point data
229  template<class Type>
232  //- Apply refLevel and fieldScaling
233  template<class Type>
235  (
236  const word& fieldName,
237  const tmp<Field<Type>>& tfield
238  ) const;
239 
240 #undef declareSurfaceFieldMethods
241 #define declareSurfaceFieldMethods(Type) \
242  \
243  tmp<Field<Type>> mergeField(const Field<Type>& fld) const; \
244  \
245  tmp<Field<Type>> adjustField \
246  ( \
247  const word& fieldName, \
248  const tmp<Field<Type>>& tfield \
249  ) const;
250 
257 
258  #undef declareSurfaceFieldMethods
259 
260  //- Dummy templated write operation
261  template<class Type>
263  (
264  const word& fieldName,
265  const Field<Type>& localValues
266  )
267  {
268  if (!wroteGeom_)
269  {
270  return this->write();
271  }
272  return fileName::null;
273  }
274 
275 public:
277  // Public Data
278 
279  //- The default merge dimension (1e-8)
280  static scalar defaultMergeDim;
281 
282 
283  //- Runtime type information
284  TypeName("surfaceWriter");
285 
286 
287  // Declare run-time constructor selection table
289  (
290  autoPtr,
292  word,
293  (),
294  ()
295  );
296 
298  (
299  autoPtr,
301  wordDict,
302  (
303  const dictionary& writeOpts
304  ),
305  (writeOpts)
306  );
307 
308 
309  // Helpers
310 
311  //- Same as fileFormats::getFormatOptions
313  (
314  const dictionary& dict,
315  const word& formatName,
316  const word& entryName = "formatOptions"
317  );
318 
319  //- Same as fileFormats::getFormatOptions
321  (
322  const dictionary& dict,
323  const dictionary& surfDict,
324  const word& formatName,
325  const word& entryName = "formatOptions"
326  );
327 
328 
329  // Factory Methods / Selectors
330 
331  //- True if New is likely to succeed for this writeType
332  static bool supportedType(const word& writeType);
333 
334  //- Optional select construct surfaceWriter.
335  // Return nullptr if the specified type is not supported.
336  static autoPtr<surfaceWriter> TryNew(const word& writeType);
337 
338  //- Optional select construct surfaceWriter with extra write options.
339  // Return nullptr if the specified type is not supported.
340  static autoPtr<surfaceWriter> TryNew
341  (
342  const word& writeType,
343  const dictionary& writeOptions
344  );
345 
346  //- Select construct a surfaceWriter
347  static autoPtr<surfaceWriter> New(const word& writeType);
348 
349  //- Select construct a surfaceWriter with extra write options.
351  (
352  const word& writeType,
353  const dictionary& writeOptions
354  );
355 
356 
357  // Constructors
358 
359  //- Default construct
360  surfaceWriter();
361 
362  //- Default construct with specified options
363  explicit surfaceWriter(const dictionary& options);
364 
366  //- Destructor. Calls close()
367  virtual ~surfaceWriter();
368 
369 
370  // Member Functions
371 
372  // Capability
373 
374  //- The writer is enabled. If the writer is not enabled, it may be
375  //- possible for the caller to skip various preparatory operations.
376  // This method is primarily useful for the null writer
377  virtual bool enabled() const
378  {
379  return true;
380  }
381 
382  //- True if the surface format requires geometry in a separate file.
383  virtual bool separateGeometry() const
384  {
385  return false;
386  }
387 
388  //- True if the writer format uses faceIds as part of its output.
389  // Element ids are used by various CAE formats
390  // (abaqus, nastran, starcd, ...)
391  virtual bool usesFaceIds() const
392  {
393  return false;
394  }
395 
396 
397  // Bookkeeping
398 
399  //- Does the writer need an update (eg, lagging behind surface changes)
400  virtual bool needsUpdate() const;
401 
402  //- Geometry or fields written since the last open?
403  virtual bool wroteData() const;
404 
405  //- Mark that surface changed and the writer will need an update,
406  //- and set nFields = 0.
407  // May also free up unneeded data.
408  // Return false if it was previously already expired.
409  virtual bool expire();
410 
411  //- Close any open output, remove association with a surface and
412  //- expire the writer. The parallel flag remains untouched.
413  virtual void clear();
414 
415 
416  // Surface association
417 
418  //- Change association with a surface, expire the writer
419  //- with defined parallel/serial treatment
420  virtual void setSurface
421  (
422  const meshedSurf& surf,
423  bool parallel
424  );
425 
426  //- Change association with a surface, expire the writer
427  //- with defined parallel/serial treatment
428  virtual void setSurface
429  (
430  const pointField& points,
431  const faceList& faces,
432  bool parallel
433  );
434 
435  //- Change association with a surface, expire the writer
436  //- with the current parallel/serial treatment
437  virtual void setSurface
438  (
439  const meshedSurf& surf
440  );
441 
442  //- Change association with a surface, expire the writer
443  //- with the current parallel/serial treatment
444  virtual void setSurface
445  (
446  const pointField& points,
447  const faceList& faces
448  );
449 
450 
451  // Queries, Access
452 
453  //- Test if outputPath has been set
454  inline bool is_open() const noexcept;
455 
456  //- Writer is associated with a surface
457  bool hasSurface() const;
458 
459  //- The surface to write is empty if the global number of faces is zero
460  bool empty() const;
461 
462  //- The global number of faces for the associated surface
463  label size() const;
464 
465  //- The number of expected output fields.
466  // Currently only used by the legacy VTK format.
467  inline label nFields() const noexcept;
468 
469  //- Set the number of expected output fields
470  // Currently only used by the legacy VTK format.
471  // \return old value
472  inline label nFields(const label n) noexcept;
473 
474  //- Are the field data to be treated as point data?
475  inline bool isPointData() const noexcept;
476 
477  //- Set handling of field data to face/point data
478  // \return old value
479  inline bool isPointData(const bool on) noexcept;
480 
481  //- Should a time directory be spliced into the output path?
482  inline bool useTimeDir() const noexcept;
483 
484  //- Enable/disable use of spliced output path
485  // \return old value
486  inline bool useTimeDir(const bool on) noexcept;
487 
488  //- Get output verbosity
489  inline bool verbose() const noexcept;
490 
491  //- Enable/disable verbose output
492  // \return old value
493  inline bool verbose(const bool on) noexcept;
494 
495  //- The current value of the point merge dimension (metre)
496  inline scalar mergeDim() const noexcept;
498  //- Change the point merge dimension (metre)
499  // \return old value
500  inline scalar mergeDim(const scalar dist) noexcept;
501 
502  //- The current value of the geometry scaling
503  inline scalar scale() const noexcept;
504 
505  //- Change the geometry scaling
506  // \return old value
507  inline scalar scale(const scalar factor) noexcept;
509  //- The current (cartesian) coordinate system transformation
510  inline const coordSystem::cartesian& transform() const noexcept;
511 
512 
513  // Time
514 
515  //- True if there is a known time
516  inline bool hasTime() const;
517 
518  //- The current time value/name
519  inline const word& timeName() const;
520 
521  //- The current time value/name
522  inline scalar timeValue() const;
523 
524 
525  //- Set the current time
526  void setTime(const instant& inst);
527 
528  //- Set current time from timeValue, auto generating the name
529  void setTime(scalar timeValue);
530 
531  //- Set current time from timeValue and timeName
532  void setTime(scalar timeValue, const word& timeName);
533 
534  //- Clear the current time
535  void unsetTime();
536 
537 
538  //- Begin a time-step
539  virtual void beginTime(const Time& t);
540 
541  //- Begin a time-step
542  virtual void beginTime(const instant& inst);
543 
544  //- End a time-step
545  virtual void endTime();
546 
547 
548  // Output
549 
550  //- Open for output on specified path, using existing surface
551  virtual void open(const fileName& outputPath);
552 
553  //- Open from components
554  virtual void open
555  (
556  const pointField& points,
557  const faceList& faces,
558  const fileName& outputPath,
559  bool parallel
560  );
561 
562  //- Open from components
563  virtual void open
564  (
565  const meshedSurf& surf,
566  const fileName& outputPath,
567  bool parallel
568  );
569 
570  //- Open from components, with the current parallel/serial treatment
571  virtual void open
572  (
573  const pointField& points,
574  const faceList& faces,
575  const fileName& outputPath
576  );
577 
578  //- Open from components, with the current parallel/serial treatment
579  virtual void open
580  (
581  const meshedSurf& surf,
582  const fileName& outputPath
583  );
584 
585  //- Finish output, performing any necessary cleanup
586  virtual void close();
587 
588 
589  // Write
590 
591  //- Write separate surface geometry to file.
592  virtual fileName write() = 0;
593 
594 
595 #undef declareSurfaceWriterWriteMethod
596 #define declareSurfaceWriterWriteMethod(Type) \
597  \
598  virtual fileName write \
599  ( \
600  const word& fieldName, \
601  const Field<Type>& values \
602  ) = 0
603 
610 
611 
612 #undef declareSurfaceWriterWriteMethod
613 #define declareSurfaceWriterWriteMethod(Type) \
614  \
615  \
616  virtual fileName write \
617  ( \
618  const word& fieldName, \
619  const Field<Type>& values \
620  ) // override
621 
622 
623  // Other IO
624 
625  //- Return info proxy,
626  //- used to print information to a stream
627  virtual InfoProxy<surfaceWriter> info() const noexcept
628  {
629  return *this;
630  }
631 
632  //- Output info proxy
633  friend Ostream& operator<<
634  (
635  Ostream& os,
636  const InfoProxy<surfaceWriter>& iproxy
637  );
638 
639 
640  // Housekeeping
641 
642  #ifdef Foam_surfaceWriter_directAccess
643 
644  //- Access number of expected output fields.
645  label& nFields() { return nFields_; }
646 
647  //- Access handling of face/point data
648  bool& isPointData() { return isPointData_; }
649 
650  //- Access handling of spliced output path
651  bool& useTimeDir() { return useTimeDir_; }
652 
653  //- Access output verbosity
654  bool& verbose() { return verbose_; }
655 
656  //- Access value of the point merge dimension
657  scalar& mergeDim() { return mergeDim_; }
658 
659  #endif
660 };
661 
662 
663 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
664 
665 } // End namespace Foam
666 
667 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
668 
669 #include "surfaceWriterI.H"
670 
671 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
672 
673 #endif
674 
675 // ************************************************************************* //
bool hasTime() const
True if there is a known time.
virtual bool usesFaceIds() const
True if the writer format uses faceIds as part of its output.
declareRunTimeSelectionTable(autoPtr, surfaceWriter, word,(),())
dictionary dict
bool is_open() const noexcept
Test if outputPath has been set.
label size() const
The global number of faces for the associated surface.
virtual bool expire()
Mark that surface changed and the writer will need an update, and set nFields = 0.
A class for handling file names.
Definition: fileName.H:72
surfaceWriter()
Default construct.
commsTypes
Communications types.
Definition: UPstream.H:77
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
bool empty() const
The surface to write is empty if the global number of faces is zero.
dictionary fieldLevel_
Field level to remove (on output)
void checkOpen() const
Verify that the outputPath_ has been set or FatalError.
virtual void open(const fileName &outputPath)
Open for output on specified path, using existing surface.
static const fileName null
An empty fileName.
Definition: fileName.H:111
const meshedSurf & surface() const
Merge surfaces (if not upToDate) and return merged (parallel) or regular surface (non-parallel) ...
const meshedSurfRef & adjustSurface() const
Merge surfaces (if not upToDate) and return merged (parallel) or regular surface (non-parallel) and a...
point geometryCentre_
The centre of rotation (untranslate, translate)
virtual bool separateGeometry() const
True if the surface format requires geometry in a separate file.
meshedSurfRef adjustedSurf_
The surface after point coordinate transforms and scaling.
bool parallel_
Writing in parallel (via master)
static bool supportedType(const word &writeType)
True if New is likely to succeed for this writeType.
Definition: surfaceWriter.C:45
scalar timeValue() const
The current time value/name.
fileName writeTemplate(const word &fieldName, const Field< Type > &localValues)
Dummy templated write operation.
bool wroteGeom_
Track if geometry has been written since the last open.
static dictionary formatOptions(const dictionary &dict, const word &formatName, const word &entryName="formatOptions")
Same as fileFormats::getFormatOptions.
Definition: surfaceWriter.C:57
mergedSurf mergedSurf_
Surface after merging (parallel)
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
virtual InfoProxy< surfaceWriter > info() const noexcept
Return info proxy, used to print information to a stream.
UPstream::commsTypes commType_
Communication type (for field merging)
virtual ~surfaceWriter()
Destructor. Calls close()
Abstract definition of a meshed surface defined by faces and points.
Definition: meshedSurf.H:43
bool isPointData() const noexcept
Are the field data to be treated as point data?
const word & timeName() const
The current time value/name.
static scalar defaultMergeDim
The default merge dimension (1e-8)
List< face > faceList
List of faces.
Definition: faceListFwd.H:39
virtual void clear()
Close any open output, remove association with a surface and expire the writer. The parallel flag rem...
virtual void setSurface(const meshedSurf &surf, bool parallel)
Change association with a surface, expire the writer with defined parallel/serial treatment...
#define declareSurfaceFieldMethods(Type)
virtual void endTime()
End a time-step.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
bool useTimeDir_
Insert additional time sub-directory in the output path.
label nFields_
The number of fields.
const pointField & points
Generic templated field type.
Definition: Field.H:62
Implements a meshed surface by referencing another meshed surface or faces/points components...
Definition: meshedSurfRef.H:47
A class for handling words, derived from Foam::string.
Definition: word.H:63
virtual bool needsUpdate() const
Does the writer need an update (eg, lagging behind surface changes)
coordSystem::cartesian geometryTransform_
Local coordinate system transformation.
scalar mergeDim() const noexcept
The current value of the point merge dimension (metre)
scalar geometryScale_
Output geometry scaling after rotate/translate.
bool verbose() const noexcept
Get output verbosity.
bool hasSurface() const
Writer is associated with a surface.
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
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
OBJstream os(runTime.globalPath()/outputName)
tmp< Field< Type > > mergeFieldTemplate(const Field< Type > &fld) const
Gather (merge) fields with renumbering and shrinking for point data.
bool isPointData_
Is point vs cell data.
virtual void close()
Finish output, performing any necessary cleanup.
TypeName("surfaceWriter")
Runtime type information.
tmp< Field< Type > > adjustFieldTemplate(const word &fieldName, const tmp< Field< Type >> &tfield) const
Apply refLevel and fieldScaling.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
dictionary fieldScale_
Field scaling (on output)
Basic run-time type information using word as the type&#39;s name. Used to enhance the standard RTTI to c...
An instant of time. Contains the time value and name. Uses Foam::Time when formatting the name...
Definition: instant.H:53
scalar mergeDim_
Dimension for merging.
label nFields() const noexcept
The number of expected output fields.
A helper class for outputting values to Ostream.
Definition: ensightCells.H:44
vector point
Point is a vector.
Definition: point.H:37
bool useTimeDir() const noexcept
Should a time directory be spliced into the output path?
fileName outputPath_
The full output directory and file (surface) name.
virtual bool wroteData() const
Geometry or fields written since the last open?
const coordSystem::cartesian & transform() const noexcept
The current (cartesian) coordinate system transformation.
virtual bool merge() const
Merge surfaces if they are not already upToDate (parallel) or simply mark the surface as being up-to-...
label n
virtual bool enabled() const
The writer is enabled. If the writer is not enabled, it may be possible for the caller to skip variou...
Base class for surface writers.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
bool verbose_
Additional output verbosity.
virtual fileName write()=0
Write separate surface geometry to file.
Macros to ease declaration of run-time selection tables.
A class for managing temporary objects.
Definition: HashPtrTable.H:50
Tensor of scalars, i.e. Tensor<scalar>.
#define declareSurfaceWriterWriteMethod(Type)
meshedSurfRef surf_
Reference to surface or surface components.
instant currTime_
The current time value/name.
static autoPtr< surfaceWriter > TryNew(const word &writeType)
Optional select construct surfaceWriter.
Definition: surfaceWriter.C:80
void unsetTime()
Clear the current time.
static autoPtr< surfaceWriter > New(const word &writeType)
Select construct a surfaceWriter.
bool upToDate_
The topology/surface is up-to-date?
virtual void beginTime(const Time &t)
Begin a time-step.
Namespace for OpenFOAM.
void setTime(const instant &inst)
Set the current time.
scalar scale() const noexcept
The current value of the geometry scaling.