vtkSurfaceWriter.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) 2019-2022 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 \*---------------------------------------------------------------------------*/
27 
28 #include "vtkSurfaceWriter.H"
29 #include "foamVtkSurfaceWriter.H"
30 #include "surfaceWriterMethods.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 namespace surfaceWriters
38 {
39  defineTypeName(vtkWriter);
40  addToRunTimeSelectionTable(surfaceWriter, vtkWriter, word);
41  addToRunTimeSelectionTable(surfaceWriter, vtkWriter, wordDict);
42 
43  // Accept vtp ending as well
45  (
46  surfaceWriter,
47  vtkWriter,
48  word,
49  vtp
50  );
52  (
53  surfaceWriter,
54  vtkWriter,
55  wordDict,
56  vtp
57  );
58 }
59 }
60 
61 
62 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
63 
65 :
66  surfaceWriter(),
67  fmtType_(static_cast<unsigned>(vtk::formatType::INLINE_BASE64)),
68  precision_(IOstream::defaultPrecision()),
69  writeNormal_(false),
70  writer_(nullptr)
71 {}
72 
73 
75 (
76  const vtk::outputOptions& opts
77 )
78 :
79  surfaceWriter(),
80  fmtType_(static_cast<unsigned>(opts.fmt())),
81  precision_(opts.precision()),
82  writeNormal_(false),
83  writer_(nullptr)
84 {}
85 
86 
88 (
89  const dictionary& options
90 )
91 :
92  surfaceWriter(options),
93  fmtType_(static_cast<unsigned>(vtk::formatType::INLINE_BASE64)),
94  precision_
95  (
96  options.getOrDefault("precision", IOstream::defaultPrecision())
97  ),
98  writeNormal_(options.getOrDefault("normal", false)),
99  writer_(nullptr)
100 {
101  // format: ascii | binary
102  // legacy: true | false
103 
105 
106  opts.ascii
107  (
110  );
111 
112  opts.legacy(options.getOrDefault("legacy", false));
114  // Convert back to raw data type
115  fmtType_ = static_cast<unsigned>(opts.fmt());
116 }
117 
118 
120 (
121  const meshedSurf& surf,
122  const fileName& outputPath,
123  bool parallel,
124  const dictionary& options
125 )
126 :
127  vtkWriter(options)
128 {
129  open(surf, outputPath, parallel);
130 }
131 
132 
134 (
135  const pointField& points,
136  const faceList& faces,
137  const fileName& outputPath,
138  bool parallel,
139  const dictionary& options
140 )
141 :
142  vtkWriter(options)
143 {
144  open(points, faces, outputPath, parallel);
145 }
146 
147 
148 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
149 
151 {
152  close();
153 }
154 
155 
156 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
157 
159 {
160  writer_.clear();
162 }
163 
164 
166 {
167  writer_.clear();
169 }
170 
171 
173 {
174  writer_.clear();
176 }
177 
178 
180 {
181  writer_.clear();
183 }
184 
185 
187 {
188  checkOpen();
189 
190  if (needsUpdate())
191  {
192  writer_.clear();
193  }
194  merge();
195 
196  // From raw unsigned values to vtk::outputOptions
197  vtk::outputOptions opts(static_cast<vtk::formatType>(fmtType_), precision_);
198 
199 
200  // Geometry: rootdir/<TIME>/surfaceName.{vtk|vtp}
201 
202  fileName outputFile = outputPath_;
203  if (useTimeDir() && !timeName().empty())
204  {
205  // Splice in time-directory
206  outputFile = outputPath_.path() / timeName() / outputPath_.name();
207  }
208  outputFile.ext(vtk::surfaceWriter::ext(opts));
209 
210  if (verbose_)
211  {
212  Info<< "Writing geometry to " << outputFile << endl;
213  }
214 
215  // const meshedSurf& surf = surface();
216  const meshedSurfRef& surf = adjustSurface();
217 
218  if (!writer_ && (UPstream::master() || !parallel_))
219  {
220  writer_.reset
221  (
222  new vtk::surfaceWriter
223  (
224  surf.points(),
225  surf.faces(),
226  opts,
227  outputFile,
228  false // serial!
229  )
230  );
231 
232  if (this->hasTime())
233  {
234  // Time name in title
235  writer_->setTime(currTime_);
236  writer_->writeTimeValue();
237  }
238  else
239  {
240  // Surface name in title
241  writer_->beginFile(outputPath_.stem());
242  }
243 
244  writer_->writeGeometry();
245 
246  if (writeNormal_)
247  {
248  const faceList& fcs = surf.faces();
249  const pointField& pts = surf.points();
250 
251  Field<vector> normals(fcs.size());
252  forAll(fcs, facei)
253  {
254  normals[facei] = fcs[facei].areaNormal(pts);
255  }
256 
257  label nCellData = 1;
258 
259  if (!this->isPointData())
260  {
261  // Ill-defined with legacy() if nFields_ not properly set...
262  nCellData += nFields_;
263  }
264 
265  writer_->beginCellData(nCellData);
266  writer_->write("area-normal", normals);
267  }
268  }
269 
270  wroteGeom_ = true;
271  return outputFile;
272 }
273 
274 
275 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
276 
277 template<class Type>
278 Foam::fileName Foam::surfaceWriters::vtkWriter::writeTemplate
279 (
280  const word& fieldName,
281  const Field<Type>& localValues
282 )
283 {
284  // Field: rootdir/<TIME>/surfaceName.{vtk|vtp}
285 
286  // Open file, writing geometry (if required)
287  fileName outputFile = this->write();
288 
289  // Implicit geometry merge()
290  tmp<Field<Type>> tfield = adjustField(fieldName, mergeField(localValues));
291 
292  if (verbose_)
293  {
294  Info<< " to " << outputFile << endl;
295  }
296 
297 
298  if (UPstream::master() || !parallel_)
299  {
300  if (!nFields_ && writer_->legacy())
301  {
302  // Emit error message, but attempt to recover anyhow
303  nFields_ = 1;
304 
306  << "Using VTK legacy format, but did not define nFields!"
307  << nl
308  << "Assuming nFields=1 (may be incorrect) and continuing..."
309  << nl
310  << " Field " << fieldName << " to " << outputFile << nl;
311 
312  Info<< FatalError;
313  Info<< endl;
314  }
315 
316  if (this->isPointData())
317  {
318  writer_->beginPointData(nFields_);
319  }
320  else
321  {
322  writer_->beginCellData(nFields_);
323  }
324 
325  writer_->write(fieldName, tfield());
326  }
327 
328  wroteGeom_ = true;
329  return outputFile;
330 }
331 
332 
333 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
334 
335 // Field writing methods
337 
338 
339 // ************************************************************************* //
addNamedToRunTimeSelectionTable(surfaceWriter, vtkWriter, word, vtp)
A class for handling file names.
Definition: fileName.H:72
A surfaceWriter for VTK legacy (.vtk) or XML (.vtp) format.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
"ascii" (normal default)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:169
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
word ext() const
Return file name extension (part after last .)
Definition: fileNameI.H:211
virtual void endTime()
End time step. Clears existing backend.
Macros for easy insertion into run-time selection tables.
Abstract definition of a meshed surface defined by faces and points.
Definition: meshedSurf.H:43
virtual ~vtkWriter()
Destructor. Calls close()
virtual void close()
Finish output, clears backend.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
virtual void beginTime(const Time &t)
Begin time step. Clears existing backend.
Encapsulated combinations of output format options. This is primarily useful when defining the output...
List< face > faceList
List of faces.
Definition: faceListFwd.H:39
word timeName
Definition: getTimeIndex.H:3
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
virtual void endTime()
End a time-step.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const pointField & points
word ext() const
File extension for current format type.
A class for handling words, derived from Foam::string.
Definition: word.H:63
formatType
The output format type for file contents.
Definition: foamVtkCore.H:66
bool ascii() const noexcept
True if output format is ASCII.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
vtk::formatType fmt() const noexcept
The output format type.
virtual void close()
Finish output, performing any necessary cleanup.
Convenience macros for instantiating surfaceWriter methods.
defineTypeName(abaqusWriter)
An instant of time. Contains the time value and name. Uses Foam::Time when formatting the name...
Definition: instant.H:53
An IOstream is an abstract base class for all input/output systems; be they streams, files, token lists etc.
Definition: IOstream.H:82
vtkWriter()
Default construct.
static streamFormat formatEnum(const word &fmtName, const streamFormat deflt=streamFormat::ASCII)
Lookup streamFormat enum corresponding to the string (ascii | binary).
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
bool legacy() const noexcept
True if writer uses legacy file format.
defineSurfaceWriterWriteFields(Foam::surfaceWriters::vtkWriter)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Base class for surface writers.
XML inline base64, base64Formatter.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
A class for managing temporary objects.
Definition: HashPtrTable.H:50
addToRunTimeSelectionTable(surfaceWriter, abaqusWriter, word)
virtual fileName write()
Write surface geometry to file.
virtual void beginTime(const Time &t)
Begin a time-step.
Namespace for OpenFOAM.
const pointField & pts