foamVtkOutputTemplates.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-2025 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 "globalIndex.H"
29 #include "Pstream.H"
30 #include "ListOps.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 template<class Type>
35 inline void Foam::vtk::write
36 (
37  vtk::formatter& fmt,
38  const Type& val,
39  const label n
40 )
41 {
43 
44  for (label i=0; i < n; ++i)
45  {
46  for (direction cmpt=0; cmpt < nCmpt; ++cmpt)
47  {
48  fmt.write(component(val, cmpt));
49  }
50  }
51 }
52 
53 
54 template<class Type>
56 (
57  vtk::formatter& fmt,
58  const UList<Type>& values
59 )
60 {
61  for (const Type& val : values)
62  {
63  vtk::write(fmt, val);
64  }
65 }
66 
67 
68 template<class Type, unsigned N>
70 (
71  vtk::formatter& fmt,
72  const FixedList<Type, N>& values
73 )
74 {
75  for (const Type& val : values)
76  {
77  vtk::write(fmt, val);
78  }
79 }
80 
81 
82 template<class Type>
84 (
85  vtk::formatter& fmt,
86  const UList<Type>& values,
87  const labelUList& addressing
88 )
89 {
90  for (const label idx : addressing)
91  {
92  vtk::write(fmt, values[idx]);
93  }
94 }
95 
96 
97 template<class Type>
99 (
100  vtk::formatter& fmt,
101  const UList<Type>& values,
102  const bitSet& selected
103 )
104 {
105  for (const label idx : selected)
106  {
107  vtk::write(fmt, values[idx]);
108  }
109 }
110 
111 
112 template<class Type>
114 (
115  vtk::formatter& fmt,
116  const UList<Type>& values,
117  const UList<Type>& indirect,
118  const labelUList& addressing
119 )
120 {
122  vtk::writeList(fmt, indirect, addressing);
123 }
124 
125 
126 template<class Type>
128 (
129  vtk::formatter& fmt,
130  const Type& val,
131  const label count
132 )
133 {
134  if constexpr (!is_contiguous_v<Type>)
135  {
136  // Non-contiguous data does not make sense
138  << "Contiguous data only" << endl
140  }
141 
142  // Gather [count, value] tuples, including from master
143  const List<label> counts(UPstream::listGatherValues(count));
144  const List<Type> values(UPstream::listGatherValues(val));
145 
146  if (Pstream::master())
147  {
148  forAll(counts, i)
149  {
150  // Write [count, value] tuple
151  vtk::write(fmt, counts[i], values[i]);
152  }
153  }
154 }
155 
156 
157 template<class Type>
159 (
160  vtk::formatter& fmt,
161  const UList<Type>& values
162 )
163 {
164  if constexpr (!is_contiguous_v<Type>)
165  {
166  // Non-contiguous data does not make sense
168  << "Contiguous data only" << endl
170  }
171 
172 
173  // Gather sizes (offsets irrelevant)
174  const globalIndex procAddr(globalIndex::gatherOnly{}, values.size());
175 
176 
177  if (Pstream::master())
178  {
179  // Write master data
180  vtk::writeList(fmt, values);
181 
182  // Receive and write
183  DynamicList<Type> recvData(procAddr.maxNonLocalSize());
184 
185  for (const label proci : procAddr.subProcs())
186  {
187  const label procSize = procAddr.localSize(proci);
188 
189  if (procSize)
190  {
191  recvData.resize_nocopy(procSize);
193  (
194  UPstream::commsTypes::scheduled,
195  proci,
196  recvData
197  );
198  vtk::writeList(fmt, recvData);
199  }
200  }
201  }
202  else
203  {
204  if (values.size())
205  {
207  (
208  UPstream::commsTypes::scheduled,
209  UPstream::masterNo(),
210  values
211  );
212  }
213  }
214 }
215 
216 
217 template<class Type>
219 (
220  vtk::formatter& fmt,
221  const UList<Type>& values,
222  const labelUList& addressing
223 )
224 {
225  if constexpr (!is_contiguous_v<Type>)
226  {
227  // Non-contiguous data does not make sense
229  << "Contiguous data only" << endl
231  }
232 
233 
234  List<Type> sendData;
235  if (!Pstream::master())
236  {
237  sendData = UIndirectList<Type>(values, addressing);
238  }
239 
240  // Gather sizes (offsets irrelevant)
241  const globalIndex procAddr(globalIndex::gatherOnly{}, sendData.size());
242 
243 
244  if (Pstream::master())
245  {
246  // Write master data
247  vtk::writeList(fmt, values, addressing);
248 
249  // Receive and write
250  DynamicList<Type> recvData(procAddr.maxNonLocalSize());
251 
252  for (const label proci : procAddr.subProcs())
253  {
254  const label procSize = procAddr.localSize(proci);
255 
256  if (procSize)
257  {
258  recvData.resize_nocopy(procSize);
260  (
261  UPstream::commsTypes::scheduled,
262  proci,
263  recvData
264  );
265  vtk::writeList(fmt, recvData);
266  }
267  }
268  }
269  else
270  {
271  if (sendData.size())
272  {
274  (
275  UPstream::commsTypes::scheduled,
276  UPstream::masterNo(),
277  sendData
278  );
279  }
280  }
281 }
282 
283 
284 template<class Type>
286 (
287  vtk::formatter& fmt,
288  const UList<Type>& values,
289  const bitSet& selected
290 )
291 {
292  if constexpr (!is_contiguous_v<Type>)
293  {
294  // Non-contiguous data does not make sense
296  << "Contiguous data only" << endl
298  }
299 
300 
301  List<Type> sendData;
302  if (!Pstream::master())
303  {
304  sendData = subset(selected, values);
305  }
306 
307  // Gather sizes (offsets irrelevant)
308  const globalIndex procAddr(globalIndex::gatherOnly{}, sendData.size());
309 
310 
311  if (Pstream::master())
312  {
313  // Write master data
314  vtk::writeList(fmt, values, selected);
315 
316  // Receive and write
317  DynamicList<Type> recvData(procAddr.maxNonLocalSize());
318 
319  for (const label proci : procAddr.subProcs())
320  {
321  const label procSize = procAddr.localSize(proci);
322 
323  if (procSize)
324  {
325  recvData.resize_nocopy(procSize);
326 
328  (
329  UPstream::commsTypes::scheduled,
330  proci,
331  recvData
332  );
333  vtk::writeList(fmt, recvData);
334  }
335  }
336  }
337  else
338  {
339  if (sendData.size())
340  {
342  (
343  UPstream::commsTypes::scheduled,
344  UPstream::masterNo(),
345  sendData
346  );
347  }
348  }
349 }
350 
351 
352 template<class Type>
354 (
355  vtk::formatter& fmt,
356  const UList<Type>& values1,
357  const UList<Type>& values2
358 )
359 {
360  if constexpr (!is_contiguous_v<Type>)
361  {
362  // Non-contiguous data does not make sense
364  << "Contiguous data only" << endl
366  }
367 
368 
369  // Gather sizes (offsets irrelevant)
370  const globalIndex procAddr1(globalIndex::gatherOnly{}, values1.size());
371  const globalIndex procAddr2(globalIndex::gatherOnly{}, values2.size());
372 
373 
374  if (Pstream::master())
375  {
376  // Write master data
377  vtk::writeList(fmt, values1);
378  vtk::writeList(fmt, values2);
379 
380  // Receive and write
381  DynamicList<Type> recvData
382  (
383  max(procAddr1.maxNonLocalSize(), procAddr2.maxNonLocalSize())
384  );
385 
386  for (const label proci : procAddr1.subProcs())
387  {
388  // values1
389  label procSize = procAddr1.localSize(proci);
390 
391  if (procSize)
392  {
393  recvData.resize_nocopy(procSize);
395  (
396  UPstream::commsTypes::scheduled,
397  proci,
398  recvData
399  );
400  vtk::writeList(fmt, recvData);
401  }
402 
403  // values2
404  procSize = procAddr2.localSize(proci);
405 
406  if (procSize)
407  {
408  recvData.resize_nocopy(procSize);
410  (
411  UPstream::commsTypes::scheduled,
412  proci,
413  recvData
414  );
415  vtk::writeList(fmt, recvData);
416  }
417  }
418  }
419  else
420  {
421  if (values1.size())
422  {
424  (
425  UPstream::commsTypes::scheduled,
426  UPstream::masterNo(),
427  values1
428  );
429  }
430 
431  if (values2.size())
432  {
434  (
435  UPstream::commsTypes::scheduled,
436  UPstream::masterNo(),
437  values2
438  );
439  }
440  }
441 }
442 
443 
444 template<class Type>
446 (
447  vtk::formatter& fmt,
448  const UList<Type>& values1,
449  const UList<Type>& values2,
450  const labelUList& addressing
451 )
452 {
453  if constexpr (!is_contiguous_v<Type>)
454  {
455  // Non-contiguous data does not make sense
457  << "Contiguous data only" << endl
459  }
460 
461 
462  List<Type> sendData2;
463  if (!Pstream::master())
464  {
465  sendData2 = UIndirectList<Type>(values2, addressing);
466  }
467 
468 
469  // Gather sizes (offsets irrelevant)
470  const globalIndex procAddr1(globalIndex::gatherOnly{}, values1.size());
471  const globalIndex procAddr2(globalIndex::gatherOnly{}, sendData2.size());
472 
473 
474  if (Pstream::master())
475  {
476  // Write master data
477 
478  vtk::writeList(fmt, values1);
479  vtk::writeList(fmt, values2, addressing);
480 
481  // Receive and write
482  DynamicList<Type> recvData
483  (
484  max(procAddr1.maxNonLocalSize(), procAddr2.maxNonLocalSize())
485  );
486 
487  for (const label proci : procAddr1.subProcs())
488  {
489  // values1
490  label procSize = procAddr1.localSize(proci);
491 
492  if (procSize)
493  {
494  recvData.resize_nocopy(procSize);
496  (
497  UPstream::commsTypes::scheduled,
498  proci,
499  recvData
500  );
501  vtk::writeList(fmt, recvData);
502  }
503 
504  // values2
505  procSize = procAddr2.localSize(proci);
506 
507  if (procSize)
508  {
509  recvData.resize_nocopy(procSize);
511  (
512  UPstream::commsTypes::scheduled,
513  proci,
514  recvData
515  );
516  vtk::writeList(fmt, recvData);
517  }
518  }
519  }
520  else
521  {
522  if (values1.size())
523  {
525  (
526  UPstream::commsTypes::scheduled,
527  UPstream::masterNo(),
528  values1
529  );
530  }
531 
532  if (sendData2.size())
533  {
535  (
536  UPstream::commsTypes::scheduled,
537  UPstream::masterNo(),
538  sendData2
539  );
540  }
541  }
542 }
543 
544 
545 // ************************************************************************* //
uint8_t direction
Definition: direction.H:46
void writeLists(vtk::formatter &fmt, const UList< Type > &values1, const UList< Type > &values2, const labelUList &addressing)
Write a list of values and a list of values via indirect addressing.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
Abstract class for a VTK output stream formatter.
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:600
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:529
A traits class, which is primarily used for primitives and vector-space.
Definition: pTraits.H:61
void writeListsParallel(vtk::formatter &fmt, const UList< Type > &values1, const UList< Type > &values2)
Write a list of values and another list of values.
UList< label > labelUList
A UList of labels.
Definition: UList.H:76
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
List< T > subset(const BoolListType &select, const UList< T > &input, const bool invert=false)
Extract elements of the input list when select is true.
globalIndex procAddr(aMesh.nFaces())
virtual void write(const uint8_t val)=0
label n
void writeListParallel(vtk::formatter &fmt, const UList< Type > &values)
Write a list of values.
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
void writeValueParallel(vtk::formatter &fmt, const Type &val, const label count=1)
Component-wise write of a value (N times) in parallel.