foamVtkFileWriter.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) 2018 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 "foamVtkFileWriter.H"
29 #include "OSspecific.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 const Foam::Enum
34 <
36 >
38 ({
39  { outputState::CLOSED, "closed" },
40  { outputState::OPENED, "opened" },
41  { outputState::DECLARED, "declared" },
42  { outputState::FIELD_DATA, "FieldData" },
43  { outputState::PIECE, "Piece" },
44  { outputState::CELL_DATA, "CellData" },
45  { outputState::POINT_DATA, "PointData" },
46 });
47 
48 
49 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
50 
52 {
53  // Finish other output
54  endFieldData();
55 
56  if (isState(outputState::OPENED))
57  {
58  beginFile();
59  }
60  if (notState(outputState::DECLARED))
61  {
63  << "Bad writer state (" << stateNames[state_]
64  << ") - should be (" << stateNames[outputState::DECLARED] << ')'
65  << exit(FatalError);
66  }
68  nCellData_ = nPointData_ = 0;
69 
70  return true;
71 }
72 
73 
75 {
76  // Finish other output
77  endCellData();
78  endPointData();
79 
80  if (notState(outputState::PIECE))
81  {
82  // Skip if not in Piece
83  return false;
84  }
85  state_ = outputState::DECLARED; // Mark as having been flushed
86 
87  if (format_)
88  {
89  format().endPiece();
90  }
91 
92  return true;
93 }
94 
95 
96 bool Foam::vtk::fileWriter::enter_CellData(label nEntries, label nFields)
97 {
98  // Already in CellData?
99  if (isState(outputState::CELL_DATA)) return false;
100 
101  // Finish other output
102  endPointData();
103 
104  if (notState(outputState::PIECE))
105  {
107  << "Bad writer state (" << stateNames[state_]
108  << ") - should be (" << stateNames[outputState::PIECE] << ')'
109  << exit(FatalError);
110  }
111 
112  nCellData_ = 0;
113 
114  // Do nothing for legacy when nFields == 0
115  if (legacy() && !nFields) return false;
116 
117  state_ = outputState::CELL_DATA;
118 
119  if (format_)
120  {
121  if (legacy())
122  {
123  legacy::beginCellData(format(), nEntries, nFields);
124  }
125  else
126  {
127  format().beginCellData();
128  }
129  }
130 
131  return true;
132 }
133 
134 
135 bool Foam::vtk::fileWriter::enter_PointData(label nEntries, label nFields)
136 {
137  // Already in PointData?
138  if (isState(outputState::POINT_DATA)) return false;
139 
140  // Finish other output
141  endCellData();
142 
143  if (notState(outputState::PIECE))
144  {
146  << "Bad writer state (" << stateNames[state_]
147  << ") - should be (" << stateNames[outputState::PIECE] << ')'
148  << exit(FatalError);
149  }
150 
151  nPointData_ = 0;
152 
153  // Do nothing for legacy when nFields == 0
154  if (legacy() && !nFields) return false;
155 
156  state_ = outputState::POINT_DATA;
157 
158  if (format_)
159  {
160  if (legacy())
161  {
162  legacy::beginPointData(format(), nEntries, nFields);
163  }
164  else
165  {
166  format().beginPointData();
167  }
168  }
169 
170  return true;
171 }
172 
173 
175 {
176  // Finish other output
177  endFieldData();
178  endPiece();
179 
180  if (isState(outputState::DECLARED))
181  {
182  if (format_ && !legacy())
183  {
184  format().endTag(contentType_).endVTKFile();
185  }
186  state_ = outputState::OPENED; // Mark as having been flushed
187  }
188 
189  // Must now be in CLOSED or OPENED states only
190 
191  if (isState(outputState::CLOSED) || isState(outputState::OPENED))
192  {
193  return true;
194  }
195 
197  << "Bad writer state (" << stateNames[state_]
198  << ") - should be (" << stateNames[outputState::CLOSED]
199  << ") or (" << stateNames[outputState::OPENED]
200  << ") for contentType (" << vtk::fileTagNames[contentType_]
201  << nl << endl;
202 
203  return false;
204 }
205 
206 
207 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
208 
210 (
211  const vtk::fileTag contentType,
212  const vtk::outputOptions opts
213 )
214 :
215  contentType_(contentType),
216  opts_(opts),
217  parallel_(false),
218  state_(outputState::CLOSED),
219  nCellData_(0),
220  nPointData_(0),
221  outputFile_(),
222  format_(),
223  os_()
224 {
225  // We do not currently support append mode at all
226  opts_.append(false);
227 }
228 
229 
230 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
231 
233 {
234  close();
235 }
236 
237 
238 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
239 
240 bool Foam::vtk::fileWriter::open(const fileName& file, bool parallel)
241 {
242  if (notState(outputState::CLOSED))
243  {
245  << "Bad writer state (" << stateNames[state_]
246  << ") - should be (" << stateNames[outputState::CLOSED] << ')'
247  << exit(FatalError);
248  }
249 
250  if (format_)
251  {
252  format_.clear();
253  os_.close();
254  }
255  nCellData_ = nPointData_ = 0;
256  outputFile_ = file;
257 
258  if
259  (
260  legacy()
261  ? outputFile_.hasExt(vtk::fileExtension[contentType_])
262  : outputFile_.hasExt(vtk::legacy::fileExtension)
263  )
264  {
265  // Inappropriate extension. Legacy instead of xml, or vice versa.
266 
267  outputFile_.removeExt();
268  }
269 
270  if (!outputFile_.hasExt(ext()))
271  {
272  // Add extension if required
273  outputFile_.ext(ext());
274  }
275 
276 
277  // Only set parallel flag if really is a parallel run.
278  parallel_ = parallel && Pstream::parRun();
279 
280  // Open a file and attach a formatter
281  // - on master (always)
282  // - on slave if not parallel
283  //
284  // This means we can always check if format_ is defined to know if output
285  // is desired on any particular process.
286 
287  if (Pstream::master() || !parallel_)
288  {
289  mkDir(outputFile_.path());
290 
291  os_.open(outputFile_);
292 
293  format_ = opts_.newFormatter(os_);
294  }
295 
296  state_ = outputState::OPENED;
297  return true;
298 }
299 
300 
302 {
303  exit_File();
304 
305  if (format_)
306  {
307  format_.clear();
308  os_.close();
309  }
310 
311  state_ = outputState::CLOSED;
312  outputFile_.clear();
313  nCellData_ = nPointData_ = 0;
314 }
315 
316 
317 bool Foam::vtk::fileWriter::beginFile(std::string title)
318 {
319  if (isState(outputState::DECLARED))
320  {
321  // Skip if already emitted
322  return false;
323  }
324  if (notState(outputState::OPENED))
325  {
327  << "Bad writer state (" << stateNames[state_]
328  << ") - should be (" << stateNames[outputState::OPENED] << ')'
329  << exit(FatalError);
330  }
331  state_ = outputState::DECLARED;
332 
333  if (format_)
334  {
335  if (legacy())
336  {
337  legacy::fileHeader(format(), title, contentType_);
338  }
339  else
340  {
341  // XML (inline)
342 
343  format().xmlHeader();
344 
345  if (title.size())
346  {
347  format().xmlComment(title);
348  }
349 
350  format().beginVTKFile(contentType_);
351  }
352  }
353 
354  return true;
355 }
356 
357 
359 {
360  // Do nothing for legacy when nFields == 0
361  if (legacy() && !nFields) return false;
362 
363  if (isState(outputState::OPENED))
364  {
365  beginFile();
366  }
367  if (notState(outputState::DECLARED))
368  {
370  << "Bad writer state (" << stateNames[state_]
371  << ") - should be (" << stateNames[outputState::DECLARED] << ')'
372  << exit(FatalError);
373  }
374  state_ = outputState::FIELD_DATA;
375 
376  if (format_)
377  {
378  if (legacy())
379  {
380  legacy::beginFieldData(format(), nFields);
381  }
382  else
383  {
384  format().beginFieldData();
385  }
386  }
387 
388  return true;
389 }
390 
391 
393 {
394  if (notState(outputState::FIELD_DATA))
395  {
396  // Skip if not in FieldData
397  return false;
398  }
399  state_ = outputState::DECLARED; // Toggle back to DECLARED
400 
401  if (format_ && !legacy())
402  {
403  format().endFieldData();
404  }
405 
406  return true;
407 }
408 
409 
411 {
412  if (notState(outputState::CELL_DATA))
413  {
414  // Skip if not in CellData
415  return false;
416  }
417  state_ = outputState::PIECE; // Toggle back to PIECE
418 
419  if (format_ && !legacy())
420  {
421  format().endCellData();
422  }
423 
424  return true;
425 }
426 
427 
429 {
430  if (notState(outputState::POINT_DATA))
431  {
432  // Skip if not in PointData
433  return false;
434  }
435  state_ = outputState::PIECE; // Toggle back to PIECE
436 
437  if (format_ && !legacy())
438  {
439  format().endPointData();
440  }
441 
442  return true;
443 }
444 
445 
447 {
448  // Convenience - switch to FieldData
449  if (isState(outputState::OPENED) || isState(outputState::DECLARED))
450  {
451  beginFieldData(1);
452  }
453  if (notState(outputState::FIELD_DATA))
454  {
456  << "Bad writer state (" << stateNames[state_]
457  << ") - should be (" << stateNames[outputState::FIELD_DATA] << ')'
458  << exit(FatalError);
459  }
460 
461  // No collectives - can skip on slave processors
462  if (!format_) return;
463 
464  if (legacy())
465  {
466  legacy::writeTimeValue(format(), timeValue);
467  }
468  else
469  {
470  format().writeTimeValue(timeValue);
471  }
472 }
473 
474 
475 // ************************************************************************* //
Foam::vtk::outputOptions
Encapsulated combinations of output format options. This is primarily useful when defining the output...
Definition: foamVtkOutputOptions.H:59
Foam::vtk::fileWriter::enter_Piece
bool enter_Piece()
Trigger change state to Piece. Resets nCellData_, nPointData_.
Definition: foamVtkFileWriter.C:51
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
Foam::vtk::fileWriter::close
void close()
End the file contents and close the file after writing.
Definition: foamVtkFileWriter.C:301
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::vtk::legacy::fileExtension
const word fileExtension
Legacy file extension ("vtk")
Foam::vtk::fileWriter::enter_CellData
bool enter_CellData(label nEntries, label nFields)
Trigger change state to CellData.
Definition: foamVtkFileWriter.C:96
Foam::expressions::patchExpr::POINT_DATA
Point data.
Definition: patchExprFwd.H:60
Foam::vtk::fileExtension
const Foam::Enum< fileTag > fileExtension
File extension (without ".") for some vtk XML file content types.
Foam::vtk::fileWriter::endCellData
bool endCellData()
Explicitly end CellData output and switch to PIECE state.
Definition: foamVtkFileWriter.C:410
Foam::vtk::fileWriter::writeTimeValue
void writeTimeValue(scalar timeValue)
Write "TimeValue" FieldData (name as per Catalyst output)
Definition: foamVtkFileWriter.C:446
foamVtkFileWriter.H
Foam::UPstream::parRun
static bool & parRun()
Test if this a parallel run, or allow modify access.
Definition: UPstream.H:434
Foam::vtk::fileWriter::beginFieldData
bool beginFieldData(label nFields=0)
Begin FieldData output section for specified number of fields.
Definition: foamVtkFileWriter.C:358
Foam::vtk::fileWriter::notState
bool notState(outputState test) const
True if the output state does not correspond to the test state.
Definition: foamVtkFileWriterI.H:48
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:458
Foam::vtk::legacy::beginPointData
void beginPointData(vtk::formatter &fmt, label nPoints, label nFields)
Emit legacy POINT_DATA nPoints, FIELD FieldData nFields.
Definition: foamVtkOutputI.H:169
Foam::vtk::fileWriter::beginFile
virtual bool beginFile(std::string title="")
Write file header (non-collective)
Definition: foamVtkFileWriter.C:317
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::vtk::legacy::beginFieldData
void beginFieldData(vtk::formatter &fmt, label nFields)
Emit legacy FIELD FieldData nFields.
Definition: foamVtkOutputI.H:144
Foam::vtk::fileWriter::stateNames
static const Enum< outputState > stateNames
Names for the output state (for messages, not for file output).
Definition: foamVtkFileWriter.H:85
Foam::vtk::fileWriter::nPointData_
label nPointData_
The number of PointData written for the Piece thus far.
Definition: foamVtkFileWriter.H:104
Foam::vtk::fileWriter::state_
outputState state_
The output state.
Definition: foamVtkFileWriter.H:98
Foam::vtk::fileWriter::open
bool open(const fileName &file, bool parallel=Pstream::parRun())
Open file for writing (creates parent directory).
Definition: foamVtkFileWriter.C:240
format
word format(conversionProperties.get< word >("format"))
Foam::vtk::fileWriter::fileWriter
fileWriter(const fileWriter &)=delete
No copy construct.
Foam::vtk::legacy::writeTimeValue
void writeTimeValue(vtk::formatter &fmt, scalar timeValue)
Emit "TimeValue" for a FIELD entry (name as per Catalyst output)
Definition: foamVtkOutputI.H:184
Foam::vtk::fileWriter::enter_PointData
bool enter_PointData(label nEntries, label nFields)
Trigger change state to PointData.
Definition: foamVtkFileWriter.C:135
Foam::fileName::removeExt
bool removeExt()
Remove extension, returning true if string changed.
Definition: fileNameI.H:259
Foam::vtk::fileWriter::~fileWriter
virtual ~fileWriter()
Destructor.
Definition: foamVtkFileWriter.C:232
Foam::vtk::fileWriter::endPiece
bool endPiece()
Explicitly end Piece output and switch to DECLARED state.
Definition: foamVtkFileWriter.C:74
Foam::FatalError
error FatalError
Foam::vtk::legacy::fileHeader
void fileHeader(std::ostream &os, const std::string &title, bool binary)
Emit header for legacy file.
Definition: foamVtkOutput.C:213
Foam::vtk::fileTag::FIELD_DATA
"FieldData"
Foam::vtk::fileWriter::endPointData
bool endPointData()
Explicitly end PointData output and switch to PIECE state.
Definition: foamVtkFileWriter.C:428
Foam::vtk::fileTag
fileTag
Some common XML tags for vtk files.
Definition: foamVtkCore.H:113
Foam::vtk::fileTagNames
const Foam::Enum< fileTag > fileTagNames
Strings corresponding to the vtk XML tags.
Foam::vtk::fileTag::POINT_DATA
"PointData"
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::vtk::legacy::beginCellData
void beginCellData(vtk::formatter &fmt, label nCells, label nFields)
Emit legacy CELL_DATA nCells, FIELD FieldData nFields.
Definition: foamVtkOutputI.H:154
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::vtk::fileWriter::exit_File
bool exit_File()
Emit file footer (end data, end piece, end file)
Definition: foamVtkFileWriter.C:174
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::vtk::fileTag::CELL_DATA
"CellData"
Foam::vtk::fileWriter::nCellData_
label nCellData_
The number of CellData written for the Piece thus far.
Definition: foamVtkFileWriter.H:101
Foam::vtk::fileTag::PIECE
"Piece"
Foam::vtk::fileWriter::outputState
outputState
Internal tracking of the output state.
Definition: foamVtkFileWriter.H:73
Foam::vtk::fileWriter::endFieldData
bool endFieldData()
Explicitly end FieldData output and switch to DECLARED state.
Definition: foamVtkFileWriter.C:392
Foam::vtk::fileWriter::isState
bool isState(outputState test) const
True if the output state corresponds to the test state.
Definition: foamVtkFileWriterI.H:42
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303