foamVtkPatchWriterTemplates.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-2021 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 "foamVtkOutput.H"
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 template<class Type, template<class> class PatchField>
35 (
37 )
38 {
40  {
41  ++nPointData_;
42  }
43  else
44  {
46  << " for field " << field.name() << nl << endl
47  << exit(FatalError);
48  }
49 
50 
51  label nPoints = nLocalPoints_;
52 
53  if (parallel_)
54  {
56  }
57 
58 
59  this->beginDataArray<Type>(field.name(), nPoints);
60 
61  if (parallel_ ? Pstream::master() : true)
62  {
63  for (const label patchId : patchIDs_)
64  {
65  const auto& pfld = field.boundaryField()[patchId];
66 
67  // Only valuePointPatchField is actually derived from Field
68  const auto* vpp = isA<Field<Type>>(pfld);
69  if (vpp)
70  {
71  vtk::writeList(format(), *vpp);
72  }
73  else
74  {
75  vtk::writeList(format(), pfld.patchInternalField()());
76  }
77  }
78  }
79 
80 
81  if (parallel_)
82  {
83  // Patch Ids are identical across all processes
84  const label nPatches = patchIDs_.size();
85 
86  if (Pstream::master())
87  {
88  Field<Type> recv;
89 
90  // Receive each patch field and write
91  for (const int subproci : Pstream::subProcs())
92  {
93  IPstream fromProc(Pstream::commsTypes::blocking, subproci);
94 
95  for (label i=0; i < nPatches; ++i)
96  {
97  fromProc >> recv;
98 
99  vtk::writeList(format(), recv);
100  }
101  }
102  }
103  else
104  {
105  // Send each patch field
106  OPstream toProc
107  (
110  );
111 
112  for (const label patchId : patchIDs_)
113  {
114  const auto& pfld = field.boundaryField()[patchId];
115 
116  // Only valuePointPatchField is actually derived from Field
117  const auto* vpp = isA<Field<Type>>(pfld);
118  if (vpp)
119  {
120  toProc << *vpp;
121  }
122  else
123  {
124  toProc << pfld.patchInternalField();
125  }
126  }
127  }
128  }
129 
131  this->endDataArray();
132 }
133 
134 
135 template<class Type, template<class> class PatchField>
137 (
139 )
140 {
141  if (isState(outputState::CELL_DATA))
142  {
143  ++nCellData_;
144  }
145  else
146  {
148  << " for field " << field.name() << nl << endl
149  << exit(FatalError);
150  }
151 
152  label nFaces = nLocalPolys_;
153 
154  if (parallel_)
155  {
156  reduce(nFaces, sumOp<label>());
157  }
158 
159 
160  this->beginDataArray<Type>(field.name(), nFaces);
161 
162  if (parallel_ ? Pstream::master() : true)
163  {
164  for (const label patchId : patchIDs_)
165  {
166  const auto& pfld = field.boundaryField()[patchId];
167 
168  if (useNearCellValue_)
169  {
170  vtk::writeList(format(), pfld.patchInternalField()());
171  }
172  else
173  {
174  vtk::writeList(format(), pfld);
175  }
176  }
177  }
178 
179  if (parallel_)
180  {
181  // Patch Ids are identical across all processes
182  const label nPatches = patchIDs_.size();
183 
184  if (Pstream::master())
185  {
186  Field<Type> recv;
187 
188  // Receive each patch field and write
189  for (const int subproci : Pstream::subProcs())
190  {
191  IPstream fromProc(Pstream::commsTypes::blocking, subproci);
192 
193  for (label i=0; i < nPatches; ++i)
194  {
195  fromProc >> recv;
196 
197  vtk::writeList(format(), recv);
198  }
199  }
200  }
201  else
202  {
203  // Send each patch field
204  OPstream toProc
205  (
208  );
209 
210  for (const label patchId : patchIDs_)
211  {
212  const auto& pfld = field.boundaryField()[patchId];
213 
214  if (useNearCellValue_)
215  {
216  toProc << pfld.patchInternalField()();
217  }
218  else
219  {
220  toProc << static_cast<const Field<Type>&>(pfld);
221  }
222  }
223  }
224  }
225 
227  this->endDataArray();
228 }
229 
230 
231 template<class Type>
233 (
236 )
237 {
238  if (isState(outputState::POINT_DATA))
239  {
240  ++nPointData_;
241  }
242  else
243  {
245  << " for field " << field.name() << nl << endl
246  << exit(FatalError);
247  }
248 
249  label nPoints = nLocalPoints_;
250 
251  if (parallel_)
252  {
253  reduce(nPoints, sumOp<label>());
254  }
255 
256 
257  this->beginDataArray<Type>(field.name(), nPoints);
258 
259  if (parallel_ ? Pstream::master() : true)
260  {
261  for (const label patchId : patchIDs_)
262  {
263  const auto& pfld = field.boundaryField()[patchId];
264 
265  if (useNearCellValue_)
266  {
267  auto tfield =
269  (
270  pfld.patchInternalField()()
271  );
272 
273  vtk::writeList(format(), tfield());
274  }
275  else
276  {
277  auto tfield = pInter.faceToPointInterpolate(pfld);
278 
279  vtk::writeList(format(), tfield());
280  }
281  }
282  }
283 
284 
285  if (parallel_)
286  {
287  // Patch Ids are identical across all processes
288  const label nPatches = patchIDs_.size();
289 
290  if (Pstream::master())
291  {
292  Field<Type> recv;
293 
294  // Receive each patch field and write
295  for (const int subproci : Pstream::subProcs())
296  {
297  IPstream fromProc(Pstream::commsTypes::blocking, subproci);
298 
299  for (label i=0; i < nPatches; ++i)
300  {
301  fromProc >> recv;
302 
303  vtk::writeList(format(), recv);
304  }
305  }
306  }
307  else
308  {
309  // Send each patch field
310  OPstream toProc
311  (
314  );
315 
316  for (const label patchId : patchIDs_)
317  {
318  const auto& pfld = field.boundaryField()[patchId];
319 
320  if (useNearCellValue_)
321  {
322  auto tfield =
324  (
325  pfld.patchInternalField()()
326  );
327 
328  toProc << tfield();
329  }
330  else
331  {
332  auto tfield = pInter.faceToPointInterpolate(pfld);
333 
334  toProc << tfield();
335  }
336  }
337  }
338  }
339 
340 
341  this->endDataArray();
342 }
343 
344 
345 // ************************************************************************* //
label nPatches
Definition: readKivaGrid.H:396
label patchId(-1)
Interpolation class within a primitive patch. Allows interpolation from points to faces and vice vers...
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
"blocking" : (MPI_Bsend, MPI_Recv)
rDeltaTY field()
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
vtk::formatter & format()
The VTK formatter in use. FatalError for off-processor.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#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
void endDataArray()
Flush formatter and end of DataArray output (non-legacy)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Generic GeometricField class.
Definition: areaFieldsFwd.H:50
label nPointData_
The number of PointData written for the Piece thus far.
bool isState(outputState test) const noexcept
True if output state corresponds to the test state.
bool parallel_
Parallel writing (via master)
Input inter-processor communications stream.
Definition: IPstream.H:49
Ostream & reportBadState(Ostream &, outputState expected) const
Generate message reporting bad writer state.
Generic templated field type.
Definition: Field.H:62
label nPoints
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition: UPstream.H:1059
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
label nLocalPoints_
Local number of points.
Output inter-processor communications stream.
Definition: OPstream.H:49
word format(conversionProperties.get< word >("format"))
labelList patchIDs_
The selected patch ids.
tmp< Field< Type > > faceToPointInterpolate(const Field< Type > &ff) const
Interpolate from faces to points.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:1185
void write(const GeometricField< Type, PatchField, pointMesh > &field)
Write point field.