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-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 
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,
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 {
121  vtk::writeList(fmt, values);
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 {
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<std::pair<label, Type>> countValues
144  (
145  UPstream::listGatherValues<std::pair<label, Type>>
146  (
147  std::pair<label, Type>(count, val)
148  )
149  );
150 
151  if (Pstream::master())
152  {
153  for (const auto& countVal : countValues)
154  {
155  // Write [count, value] tuple
156  vtk::write(fmt, countVal.first, countVal.second);
157  }
158  }
159 }
160 
161 
162 template<class Type>
164 (
165  vtk::formatter& fmt,
166  const UList<Type>& values
167 )
168 {
170  {
171  // Non-contiguous data does not make sense
173  << "Contiguous data only" << endl
175  }
176 
177 
178  // Gather sizes - master information, offsets are irrelevant
179  const globalIndex procAddr
180  (
181  UPstream::listGatherValues<label>(values.size()),
182  globalIndex::SIZES
183  );
184 
185 
186  if (Pstream::master())
187  {
188  // Write master data
189  vtk::writeList(fmt, values);
190 
191  // Receive and write
192  DynamicList<Type> recvData(procAddr.maxNonLocalSize());
193 
194  for (const label proci : procAddr.subProcs())
195  {
196  recvData.resize_nocopy(procAddr.localSize(proci));
198  (
199  UPstream::commsTypes::scheduled,
200  proci,
201  recvData.data_bytes(),
202  recvData.size_bytes()
203  );
204  vtk::writeList(fmt, recvData);
205  }
206  }
207  else
208  {
209  // Send
211  (
212  UPstream::commsTypes::scheduled,
213  Pstream::masterNo(),
214  values.cdata_bytes(),
215  values.size_bytes()
216  );
217  }
218 }
219 
220 
221 template<class Type>
223 (
224  vtk::formatter& fmt,
225  const UList<Type>& values,
226  const labelUList& addressing
227 )
228 {
230  {
231  // Non-contiguous data does not make sense
233  << "Contiguous data only" << endl
235  }
236 
237 
238  List<Type> sendData;
239  if (!Pstream::master())
240  {
241  sendData = UIndirectList<Type>(values, addressing);
242  }
243 
244  // Gather sizes - master information, offsets are irrelevant
245  const globalIndex procAddr
246  (
247  UPstream::listGatherValues<label>(sendData.size()),
248  globalIndex::SIZES
249  );
250 
251 
252  if (Pstream::master())
253  {
254  // Write master data
255  vtk::writeList(fmt, values, addressing);
256 
257  // Receive and write
258  DynamicList<Type> recvData(procAddr.maxNonLocalSize());
259 
260  for (const label proci : procAddr.subProcs())
261  {
262  recvData.resize_nocopy(procAddr.localSize(proci));
264  (
265  UPstream::commsTypes::scheduled,
266  proci,
267  recvData.data_bytes(),
268  recvData.size_bytes()
269  );
270  vtk::writeList(fmt, recvData);
271  }
272  }
273  else
274  {
276  (
277  UPstream::commsTypes::scheduled,
278  Pstream::masterNo(),
279  sendData.cdata_bytes(),
280  sendData.size_bytes()
281  );
282  }
283 }
284 
285 
286 template<class Type>
288 (
289  vtk::formatter& fmt,
290  const UList<Type>& values,
291  const bitSet& selected
292 )
293 {
295  {
296  // Non-contiguous data does not make sense
298  << "Contiguous data only" << endl
300  }
301 
302 
303  List<Type> sendData;
304  if (!Pstream::master())
305  {
306  sendData = subset(selected, values);
307  }
308 
309  // Gather sizes - master information, offsets are irrelevant
310  const globalIndex procAddr
311  (
312  UPstream::listGatherValues<label>(sendData.size()),
313  globalIndex::SIZES
314  );
315 
316 
317  if (Pstream::master())
318  {
319  // Write master data
320  vtk::writeList(fmt, values, selected);
321 
322  // Receive and write
323  DynamicList<Type> recvData(procAddr.maxNonLocalSize());
324 
325  for (const label proci : procAddr.subProcs())
326  {
327  recvData.resize_nocopy(procAddr.localSize(proci));
329  (
330  UPstream::commsTypes::scheduled,
331  proci,
332  recvData.data_bytes(),
333  recvData.size_bytes()
334  );
335  vtk::writeList(fmt, recvData);
336  }
337  }
338  else
339  {
341  (
342  UPstream::commsTypes::scheduled,
343  Pstream::masterNo(),
344  sendData.cdata_bytes(),
345  sendData.size_bytes()
346  );
347  }
348 }
349 
350 
351 template<class Type>
353 (
354  vtk::formatter& fmt,
355  const UList<Type>& values1,
356  const UList<Type>& values2
357 )
358 {
360  {
361  // Non-contiguous data does not make sense
363  << "Contiguous data only" << endl
365  }
366 
367 
368  // Gather sizes - master information and offsets are irrelevant
369  const globalIndex procAddr1
370  (
371  UPstream::listGatherValues<label>(values1.size()),
372  globalIndex::SIZES
373  );
374  const globalIndex procAddr2
375  (
376  UPstream::listGatherValues<label>(values2.size()),
377  globalIndex::SIZES
378  );
379 
380 
381  if (Pstream::master())
382  {
383  // Write master data
384  vtk::writeList(fmt, values1);
385  vtk::writeList(fmt, values2);
386 
387  // Receive and write
388  DynamicList<Type> recvData
389  (
390  max(procAddr1.maxNonLocalSize(), procAddr2.maxNonLocalSize())
391  );
392 
393  for (const label proci : procAddr1.subProcs())
394  {
395  // values1
396  recvData.resize_nocopy(procAddr1.localSize(proci));
398  (
399  UPstream::commsTypes::scheduled,
400  proci,
401  recvData.data_bytes(),
402  recvData.size_bytes()
403  );
404  vtk::writeList(fmt, recvData);
405 
406  // values2
407  recvData.resize_nocopy(procAddr2.localSize(proci));
409  (
410  UPstream::commsTypes::scheduled,
411  proci,
412  recvData.data_bytes(),
413  recvData.size_bytes()
414  );
415  vtk::writeList(fmt, recvData);
416  }
417  }
418  else
419  {
421  (
422  UPstream::commsTypes::scheduled,
423  Pstream::masterNo(),
424  values1.cdata_bytes(),
425  values1.size_bytes()
426  );
427 
429  (
430  UPstream::commsTypes::scheduled,
431  Pstream::masterNo(),
432  values2.cdata_bytes(),
433  values2.size_bytes()
434  );
435  }
436 }
437 
438 
439 template<class Type>
441 (
442  vtk::formatter& fmt,
443  const UList<Type>& values1,
444  const UList<Type>& values2,
445  const labelUList& addressing
446 )
447 {
449  {
450  // Non-contiguous data does not make sense
452  << "Contiguous data only" << endl
454  }
455 
456 
457  List<Type> sendData2;
458  if (!Pstream::master())
459  {
460  sendData2 = UIndirectList<Type>(values2, addressing);
461  }
462 
463 
464  // Gather sizes - master information, offsets are irrelevant
465  const globalIndex procAddr1
466  (
467  UPstream::listGatherValues<label>(values1.size()),
468  globalIndex::SIZES
469  );
470  const globalIndex procAddr2
471  (
472  UPstream::listGatherValues<label>(sendData2.size()),
473  globalIndex::SIZES
474  );
475 
476 
477  if (Pstream::master())
478  {
479  // Write master data
480 
481  vtk::writeList(fmt, values1);
482  vtk::writeList(fmt, values2, addressing);
483 
484  // Receive and write
485  DynamicList<Type> recvData
486  (
487  max(procAddr1.maxNonLocalSize(), procAddr2.maxNonLocalSize())
488  );
489 
490  for (const label proci : procAddr1.subProcs())
491  {
492  // values1
493  recvData.resize_nocopy(procAddr1.localSize(proci));
495  (
496  UPstream::commsTypes::scheduled,
497  proci,
498  recvData.data_bytes(),
499  recvData.size_bytes()
500  );
501  vtk::writeList(fmt, recvData);
502 
503  // values2
504  recvData.resize_nocopy(procAddr2.localSize(proci));
506  (
507  UPstream::commsTypes::scheduled,
508  proci,
509  recvData.data_bytes(),
510  recvData.size_bytes()
511  );
512  vtk::writeList(fmt, recvData);
513  }
514  }
515  else
516  {
518  (
519  UPstream::commsTypes::scheduled,
520  Pstream::masterNo(),
521  values1.cdata_bytes(),
522  values1.size_bytes()
523  );
524 
526  (
527  UPstream::commsTypes::scheduled,
528  Pstream::masterNo(),
529  sendData2.cdata_bytes(),
530  sendData2.size_bytes()
531  );
532  }
533 }
534 
535 
536 // ************************************************************************* //
Foam::UList::cdata_bytes
const char * cdata_bytes() const noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:244
Foam::component
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
Definition: FieldFieldFunctions.C:44
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
Foam::DynamicList< Type >
Foam::HashTableOps::values
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:149
globalIndex.H
Foam::subset
List< T > subset(const BoolListType &select, const UList< T > &input, const bool invert=false)
Extract elements of the input list when select is true.
Foam::globalIndex::localSize
label localSize() const
My local size.
Definition: globalIndexI.H:187
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::vtk::writeListsParallel
void writeListsParallel(vtk::formatter &fmt, const UList< Type > &values1, const UList< Type > &values2)
Write a list of values and another list of values.
Definition: foamVtkOutputTemplates.C:353
Foam::blockMeshTools::read
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
Definition: blockMeshTools.C:57
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::vtk::writeValueParallel
void writeValueParallel(vtk::formatter &fmt, const Type &val, const label count=1)
Component-wise write of a value (N times) in parallel.
Definition: foamVtkOutputTemplates.C:128
Foam::vtk::writeList
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
Definition: foamVtkOutput.C:112
Foam::vtk::writeLists
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.
Definition: foamVtkOutputTemplates.C:114
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::FatalError
error FatalError
Pstream.H
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::globalIndex::subProcs
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes)
Definition: globalIndexI.H:121
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::pTraits
A traits class, which is primarily used for primitives.
Definition: pTraits.H:56
Foam::FixedList
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:104
Foam::globalIndex::maxNonLocalSize
label maxNonLocalSize() const
The max of localSizes, excluding current processor.
Definition: globalIndexI.H:200
Foam::UList< Type >
Foam::direction
uint8_t direction
Definition: direction.H:52
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:36
Foam::DynamicList::resize_nocopy
void resize_nocopy(const label len)
Definition: DynamicListI.H:363
Foam::UIndirectList
A List with indirect addressing.
Definition: faMatrix.H:60
ListOps.H
Various functions to operate on Lists.
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::vtk::writeListParallel
void writeListParallel(vtk::formatter &fmt, const UList< Type > &values)
Write a list of values.
Definition: foamVtkOutputTemplates.C:164
Foam::vtk::formatter::write
virtual void write(const uint8_t val)=0
Foam::UList::size_bytes
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition: UListI.H:258
Foam::is_contiguous
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:75
Foam::vtk::formatter
Abstract class for a VTK output stream formatter.
Definition: foamVtkFormatter.H:68