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-2022 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 declareSurfaceFieldMethod
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  // Selectors
330 
331  //- True if New is likely to succeed for this writeType
332  static bool supportedType(const word& writeType);
333 
334  //- Return a reference to the selected surfaceWriter
335  static autoPtr<surfaceWriter> New(const word& writeType);
336 
337  //- Return a reference to the selected surfaceWriter
338  // Select with extra write option
339  static autoPtr<surfaceWriter> New
340  (
341  const word& writeType,
342  const dictionary& writeOptions
343  );
344 
345 
346  // Constructors
347 
348  //- Default construct
349  surfaceWriter();
350 
351  //- Default construct with specified options
352  explicit surfaceWriter(const dictionary& options);
353 
354 
355  //- Destructor. Calls close()
356  virtual ~surfaceWriter();
357 
358 
359  // Member Functions
360 
361  // Capability
362 
363  //- The writer is enabled. If the writer is not enabled, it may be
364  //- possible for the caller to skip various preparatory operations.
365  // This method is primarily useful for the null writer
366  virtual bool enabled() const
367  {
368  return true;
369  }
370 
371  //- True if the surface format requires geometry in a separate file.
372  virtual bool separateGeometry() const
373  {
374  return false;
375  }
376 
377  //- True if the writer format uses faceIds as part of its output.
378  // Element ids are used by various CAE formats
379  // (abaqus, nastran, starcd, ...)
380  virtual bool usesFaceIds() const
381  {
382  return false;
383  }
384 
385 
386  // Bookkeeping
387 
388  //- Does the writer need an update (eg, lagging behind surface changes)
389  virtual bool needsUpdate() const;
390 
391  //- Geometry or fields written since the last open?
392  virtual bool wroteData() const;
393 
394  //- Mark that surface changed and the writer will need an update,
395  //- and set nFields = 0.
396  // May also free up unneeded data.
397  // Return false if it was previously already expired.
398  virtual bool expire();
399 
400  //- Close any open output, remove association with a surface and
401  //- expire the writer. The parallel flag remains untouched.
402  virtual void clear();
403 
404 
405  // Surface association
406 
407  //- Change association with a surface, expire the writer
408  //- with defined parallel/serial treatment
409  virtual void setSurface
410  (
411  const meshedSurf& surf,
412  bool parallel
413  );
414 
415  //- Change association with a surface, expire the writer
416  //- with defined parallel/serial treatment
417  virtual void setSurface
418  (
419  const pointField& points,
420  const faceList& faces,
421  bool parallel
422  );
423 
424  //- Change association with a surface, expire the writer
425  //- with the current parallel/serial treatment
426  virtual void setSurface
427  (
428  const meshedSurf& surf
429  );
430 
431  //- Change association with a surface, expire the writer
432  //- with the current parallel/serial treatment
433  virtual void setSurface
434  (
435  const pointField& points,
436  const faceList& faces
437  );
438 
439 
440  // Queries, Access
441 
442  //- Test if outputPath has been set
443  inline bool is_open() const noexcept;
444 
445  //- Writer is associated with a surface
446  bool hasSurface() const;
447 
448  //- The surface to write is empty if the global number of faces is zero
449  bool empty() const;
450 
451  //- The global number of faces for the associated surface
452  label size() const;
453 
454  //- The number of expected output fields.
455  // Currently only used by the legacy VTK format.
456  inline label nFields() const noexcept;
457 
458  //- Set the number of expected output fields
459  // Currently only used by the legacy VTK format.
460  // \return old value
461  inline label nFields(const label n) noexcept;
462 
463  //- Are the field data to be treated as point data?
464  inline bool isPointData() const noexcept;
465 
466  //- Set handling of field data to face/point data
467  // \return old value
468  inline bool isPointData(const bool on) noexcept;
469 
470  //- Should a time directory be spliced into the output path?
471  inline bool useTimeDir() const noexcept;
472 
473  //- Enable/disable use of spliced output path
474  // \return old value
475  inline bool useTimeDir(const bool on) noexcept;
476 
477  //- Get output verbosity
478  inline bool verbose() const noexcept;
479 
480  //- Enable/disable verbose output
481  // \return old value
482  inline bool verbose(const bool on) noexcept;
483 
484  //- The current value of the point merge dimension (metre)
485  inline scalar mergeDim() const noexcept;
486 
487  //- Change the point merge dimension (metre)
488  // \return old value
489  inline scalar mergeDim(const scalar dist) noexcept;
490 
491  //- The current value of the geometry scaling
492  inline scalar scale() const noexcept;
493 
494  //- Change the geometry scaling
495  // \return old value
496  inline scalar scale(const scalar factor) noexcept;
497 
498  //- The current (cartesian) coordinate system transformation
499  inline const coordSystem::cartesian& transform() const noexcept;
500 
501 
502  // Time
503 
504  //- True if there is a known time
505  inline bool hasTime() const;
506 
507  //- The current time value/name
508  inline const word& timeName() const;
509 
510  //- The current time value/name
511  inline scalar timeValue() const;
512 
513 
514  //- Set the current time
515  void setTime(const instant& inst);
516 
517  //- Set current time from timeValue, auto generating the name
518  void setTime(scalar timeValue);
519 
520  //- Set current time from timeValue and timeName
521  void setTime(scalar timeValue, const word& timeName);
522 
523  //- Clear the current time
524  void unsetTime();
525 
526 
527  //- Begin a time-step
528  virtual void beginTime(const Time& t);
529 
530  //- Begin a time-step
531  virtual void beginTime(const instant& inst);
532 
533  //- End a time-step
534  virtual void endTime();
535 
536 
537  // Output
538 
539  //- Open for output on specified path, using existing surface
540  virtual void open(const fileName& outputPath);
541 
542  //- Open from components
543  virtual void open
544  (
545  const pointField& points,
546  const faceList& faces,
547  const fileName& outputPath,
548  bool parallel
549  );
550 
551  //- Open from components
552  virtual void open
553  (
554  const meshedSurf& surf,
555  const fileName& outputPath,
556  bool parallel
557  );
558 
559  //- Open from components, with the current parallel/serial treatment
560  virtual void open
561  (
562  const pointField& points,
563  const faceList& faces,
564  const fileName& outputPath
565  );
566 
567  //- Open from components, with the current parallel/serial treatment
568  virtual void open
569  (
570  const meshedSurf& surf,
571  const fileName& outputPath
572  );
573 
574  //- Finish output, performing any necessary cleanup
575  virtual void close();
576 
577 
578  // Write
579 
580  //- Write separate surface geometry to file.
581  virtual fileName write() = 0;
582 
583 
584 #undef declareSurfaceWriterWriteMethod
585 #define declareSurfaceWriterWriteMethod(Type) \
586  \
587  virtual fileName write \
588  ( \
589  const word& fieldName, \
590  const Field<Type>& values \
591  ) = 0
592 
599 
600 
601 #undef declareSurfaceWriterWriteMethod
602 #define declareSurfaceWriterWriteMethod(Type) \
603  \
604  \
605  virtual fileName write \
606  ( \
607  const word& fieldName, \
608  const Field<Type>& values \
609  ) // override
610 
611 
612  // Other IO
613 
614  //- Return info proxy,
615  //- used to print information to a stream
616  virtual InfoProxy<surfaceWriter> info() const noexcept
617  {
618  return *this;
619  }
620 
621  //- Output info proxy
622  friend Ostream& operator<<
623  (
624  Ostream& os,
625  const InfoProxy<surfaceWriter>& iproxy
626  );
627 
628 
629  // Housekeeping
630 
631  #ifdef Foam_surfaceWriter_directAccess
632 
633  //- Access number of expected output fields.
634  label& nFields() { return nFields_; }
635 
636  //- Access handling of face/point data
637  bool& isPointData() { return isPointData_; }
638 
639  //- Access handling of spliced output path
640  bool& useTimeDir() { return useTimeDir_; }
641 
642  //- Access output verbosity
643  bool& verbose() { return verbose_; }
644 
645  //- Access value of the point merge dimension
646  scalar& mergeDim() { return mergeDim_; }
647 
648  #endif
649 };
650 
651 
652 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
653 
654 } // End namespace Foam
655 
656 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
657 
658 #include "surfaceWriterI.H"
659 
660 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
661 
662 #endif
663 
664 // ************************************************************************* //
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:72
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)
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:43
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.
void unsetTime()
Clear the current time.
static autoPtr< surfaceWriter > New(const word &writeType)
Return a reference to the selected surfaceWriter.
Definition: surfaceWriter.C:80
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.