foamVtkSurfaceFieldWriter.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) 2016-2024 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 
29 #include "fvsPatchFields.H"
30 #include "surfaceFields.H"
31 
32 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 
37 // Flatten boundary field values into a contiguous list
38 template<class Type>
40 (
42 )
43 {
44  const polyBoundaryMesh& pbm = field.mesh().boundaryMesh();
45 
46  List<Type> flat(pbm.nFaces(), Foam::zero{});
47 
48  forAll(field.boundaryField(), patchi)
49  {
50  const polyPatch& pp = pbm[patchi];
51  const auto& pfld = field.boundaryField()[patchi];
52 
53  // Note: restrict transcribing to actual size of the patch field
54  // - handles "empty" patch type etc.
55  SubList<Type>(flat, pfld.size(), pp.offset()) = pfld;
56  }
57 
58  return flat;
59 }
60 
61 } // End namespace Foam
62 
63 
64 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
65 
67 (
68  const fvMesh& mesh,
69  const vtk::outputOptions opts
70 )
71 :
72  vtk::fileWriter(vtk::fileTag::POLY_DATA, opts),
73  mesh_(mesh),
74  numberOfPoints_(0)
75 {
76  opts_.append(false); // No append mode (horrible for streaming)
77  opts_.legacy(false); // Disallow legacy (inconvenient)
78 }
79 
80 
82 (
83  const fvMesh& mesh,
84  const fileName& file,
85  bool parallel
86 )
87 :
89 {
90  open(file, parallel);
91 }
92 
93 
95 (
96  const fvMesh& mesh,
97  const vtk::outputOptions opts,
98  const fileName& file,
99  bool parallel
100 )
101 :
102  surfaceFieldWriter(mesh, opts)
103 {
104  open(file, parallel);
105 }
106 
107 
108 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
109 
110 bool Foam::vtk::surfaceFieldWriter::beginFile(std::string title)
111 {
112  if (title.size())
113  {
114  return vtk::fileWriter::beginFile(title);
115  }
116 
117 
118  // Provide Default title
119 
120  if (legacy())
121  {
122  return vtk::fileWriter::beginFile("surfaceFields");
123  }
124 
125 
126  // XML (inline)
127 
129  (
130  "surfaceFields "
131  "case='" + mesh_.time().globalCaseName()
132  + "' region='" + mesh_.name()
133  + "' time='" + mesh_.time().timeName()
134  + "' index='" + Foam::name(mesh_.time().timeIndex())
135  + "'"
136  );
137 }
138 
139 
141 {
142  enter_Piece();
143 
144  // Output
145 
146  const pointField& centres = mesh_.faceCentres();
147 
148  // PointData for each face.
149  numberOfPoints_ = centres.size();
150 
151  if (parallel_)
152  {
153  reduce(numberOfPoints_, sumOp<label>());
154  }
155 
156  // <Piece>
157  if (format_)
158  {
159  format()
160  .tag
161  (
163  fileAttr::NUMBER_OF_POINTS, numberOfPoints_
164  );
165  }
166 
167  // <Point>
168  this->beginPoints(numberOfPoints_);
169 
170  if (parallel_)
171  {
172  // Centres for internal faces
174  (
175  format_.ref(),
176  SubList<point>(centres, mesh_.nInternalFaces())
177  );
178 
179  // Centres for boundary faces
181  (
182  format_.ref(),
183  SubList<point>(centres, mesh_.boundaryMesh().range())
184  );
185  }
186  else
187  {
188  // Non-parallel: use a normal write
189 
190  vtk::writeList(format(), centres);
191  }
193  this->endPoints();
194 
195  return true;
196 }
197 
198 
200 {
201  // No legacy, no CellData
202  return enter_CellData(0, 0);
203 }
204 
205 
207 {
208  // No legacy
209  return enter_PointData(numberOfPoints_, 0);
210 }
211 
212 
214 {
215  if (isState(outputState::POINT_DATA))
216  {
217  ++nPointData_;
218  }
219  else
220  {
222  << " for field " << field.name() << nl << endl
223  << exit(FatalError);
224  }
225 
226  label nFaces = field.mesh().nFaces();
227 
228  if (parallel_)
229  {
230  reduce(nFaces, sumOp<label>());
231  }
232 
233  if (nFaces != numberOfPoints_)
234  {
236  << "Expecting " << numberOfPoints_
237  << " faces, but found " << nFaces
238  << exit(FatalError);
239  }
240 
241  this->beginDataArray<vector>(field.name(), nFaces);
242 
243 
244  // Internal field
245  const SubList<vector> internal(field, mesh_.nInternalFaces());
246 
247  // Boundary field (flattened)
249 
250 
251  if (parallel_)
252  {
253  // Internal field
254  vtk::writeListParallel(format_.ref(), internal);
255 
256  // Boundary field
257  vtk::writeListParallel(format_.ref(), boundary);
258  }
259  else
260  {
261  // Non-parallel
262 
263  // Internal field
264  vtk::writeList(format_.ref(), internal);
265 
266  // Boundary field
267  vtk::writeList(format_.ref(), boundary);
268  }
269 
270 
271  this->endDataArray();
272 }
273 
274 
275 // ************************************************************************* //
Foam::surfaceFields.
faceListList boundary
const polyBoundaryMesh & pbm
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
rDeltaTY field()
A class for handling file names.
Definition: fileName.H:72
virtual bool beginPointData(label nFields=0)
Begin PointData output section.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
Base class for VTK output writers that handle geometry and fields (eg, vtp, vtu data). These output formats are structured as DECLARED, FIELD_DATA, PIECE followed by any CELL_DATA or POINT_DATA.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static List< Type > flattenBoundary(const GeometricField< Type, fvsPatchField, surfaceMesh > &field)
Generic GeometricField class.
virtual bool beginFile(std::string title="")
Write file header (non-collective)
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:360
bool legacy() const noexcept
Commonly used query.
surfaceFieldWriter(const surfaceFieldWriter &)=delete
No copy construct.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
Encapsulated combinations of output format options. This is primarily useful when defining the output...
void beginPoints(std::ostream &os, label nPoints)
Emit header for POINTS (with trailing newline).
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
const fileName & globalCaseName() const noexcept
Return global case name.
Definition: TimePathsI.H:72
label timeIndex() const noexcept
Return the current time index.
Definition: TimeStateI.H:43
void write(const surfaceVectorField &field)
Write field.
virtual bool writeGeometry()
Write cloud positions.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition: Time.C:714
Write surfaces fields (as PointData) in VTP format. Legacy VTK format is intentionally not supported...
word format(conversionProperties.get< word >("format"))
label nFaces() const noexcept
The number of boundary faces in the underlying mesh.
virtual bool beginFile(std::string title="")
Write file header (non-collective)
fileTag
Some common XML tags for vtk files.
Definition: foamVtkCore.H:122
const word & name() const
Return reference to name.
Definition: fvMesh.H:387
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
void writeListParallel(vtk::formatter &fmt, const UList< Type > &values)
Write a list of values.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
void reduce(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) using linear/tree communication schedule.
virtual bool beginCellData(label nFields=0)
Begin CellData output section for specified number of fields.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Namespace for OpenFOAM.