vtkPVFoamVolFields.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 InClass
25  vtkPVFoam
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #ifndef vtkPVFoamVolFields_H
30 #define vtkPVFoamVolFields_H
31 
32 #include "vtkPVFoam.H"
33 #include "vtkPVFoamReader.h"
34 #include "vtkPVFoamSurfaceField.H"
35 #include "vtkPVFoamPatchField.H"
36 #include "vtkOpenFOAMTupleRemap.H"
37 
38 // OpenFOAM includes
39 #include "domainDecomposition.H"
40 #include "emptyFvPatchField.H"
41 #include "faceSet.H"
42 #include "volFields.H"
43 #include "volPointInterpolation.H"
44 #include "fvFieldReconstructor.H"
45 
46 // VTK includes
47 #include "vtkFloatArray.h"
48 #include "vtkUnstructuredGrid.h"
49 
50 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
51 
52 template<class Type>
53 void Foam::vtkPVFoam::convertVolFields
54 (
55  const PtrList<PrimitivePatchInterpolation<primitivePatch>>& ppInterpList,
56  const IOobjectList& objects,
57  const bool interpFields,
58  vtkMultiBlockDataSet* output
59 )
60 {
61  const polyBoundaryMesh& patches =
62  procMeshesPtr_->completeMesh().poly().boundary();
63 
64  forAllConstIter(IOobjectList, objects, iter)
65  {
66  // Restrict to GeometricField<Type, ...>
67  if (iter()->headerClassName() != VolField<Type>::typeName)
68  {
69  continue;
70  }
71 
72  // Load the field
73  tmp<VolField<Type>> ttf;
74 
76 
77  try
78  {
79  if (reader_->GetDecomposedCase())
80  {
81  if (!fvReconstructorPtr_.valid())
82  {
83  fvReconstructorPtr_.set
84  (
85  new fvFieldReconstructor
86  (
87  procMeshesPtr_->completeMesh(),
88  procMeshesPtr_->procMeshes(),
89  procMeshesPtr_->procFaceAddressing(),
90  procMeshesPtr_->procCellAddressing(),
91  procMeshesPtr_->procFaceAddressingBf()
92  )
93  );
94  }
95 
96  ttf =
97  fvReconstructorPtr_
98  ->reconstructVolField<Type>(*iter());
99  }
100  else
101  {
102  ttf = new VolField<Type>
103  (
104  *iter(),
105  procMeshesPtr_->completeMesh()
106  );
107  }
108  }
109  catch (IOerror& err)
110  {
111  Warning<< err << endl;
112  continue;
113  }
114 
116 
117  const VolField<Type>& tf = ttf();
118 
119  // Interpolated field (demand driven)
120  autoPtr<PointField<Type>> ptfPtr;
121  if (interpFields)
122  {
124  << "Interpolating field " << tf.name() << endl;
125 
126  ptfPtr.reset
127  (
129  );
130  }
131 
132  // Convert activated internalMesh regions
133  convertVolFieldBlock
134  (
135  tf,
136  ptfPtr,
137  output,
138  arrayRangeVolume_,
139  regionPolyDecomp_
140  );
141 
142  // Convert activated cellZones
143  convertVolFieldBlock
144  (
145  tf,
146  ptfPtr,
147  output,
148  arrayRangeCellZones_,
149  zonePolyDecomp_
150  );
151 
152  // Convert activated cellSets
153  convertVolFieldBlock
154  (
155  tf,
156  ptfPtr,
157  output,
158  arrayRangeCellSets_,
159  setPolyDecomp_
160  );
161 
162 
163  // Convert patches - if activated
164  for
165  (
166  int partId = arrayRangePatches_.start();
167  partId < arrayRangePatches_.end();
168  ++partId
169  )
170  {
171  const word patchName = getPartName(partId);
172  const label datasetNo = partDataset_[partId];
173  const label patchId = patches.findIndex(patchName);
174 
175  if (!partStatus_[partId] || datasetNo < 0 || patchId < 0) continue;
176 
177  const fvPatchField<Type>& ptf = tf.boundaryField()[patchId];
178 
179  if
180  (
181  isType<emptyFvPatchField<Type>>(ptf)
182  ||
183  (
184  reader_->GetExtrapolatePatches()
185  && !patches[patchId].constraint()
186  )
187  )
188  {
189  fvPatch p(ptf.patch().poly(), tf.mesh().boundary());
190 
191  tmp<Field<Type>> tpptf
192  (
193  fvPatchField<Type>(p, tf).patchInternalField()
194  );
195 
196  convertPatchField
197  (
198  tf.name(),
199  tpptf(),
200  output,
201  arrayRangePatches_,
202  datasetNo
203  );
204 
205  if (interpFields)
206  {
207  convertPatchPointField
208  (
209  tf.name(),
210  ppInterpList[patchId].faceToPointInterpolate(tpptf)(),
211  output,
212  arrayRangePatches_,
213  datasetNo
214  );
215  }
216  }
217  else
218  {
219  convertPatchField
220  (
221  tf.name(),
222  ptf,
223  output,
224  arrayRangePatches_,
225  datasetNo
226  );
227 
228  if (interpFields)
229  {
230  convertPatchPointField
231  (
232  tf.name(),
233  ppInterpList[patchId].faceToPointInterpolate(ptf)(),
234  output,
235  arrayRangePatches_,
236  datasetNo
237  );
238  }
239  }
240  }
241 
242  // Convert face zones - if activated
243  for
244  (
245  int partId = arrayRangeFaceZones_.start();
246  partId < arrayRangeFaceZones_.end();
247  ++partId
248  )
249  {
250  const word zoneName = getPartName(partId);
251  const label datasetNo = partDataset_[partId];
252 
253  if (!partStatus_[partId] || datasetNo < 0) continue;
254 
255  const faceZoneList& zMesh = tf.mesh().faceZones();
256  const label zoneId = zMesh.findIndex(zoneName);
257 
258  if (zoneId < 0) continue;
259 
260  convertSurfaceField
261  (
262  tf,
263  output,
264  arrayRangeFaceZones_,
265  datasetNo,
266  tf.mesh(),
267  zMesh[zoneId]
268  );
269  }
270 
271  // Convert face sets - if activated
272  for
273  (
274  int partId = arrayRangeFaceSets_.start();
275  partId < arrayRangeFaceSets_.end();
276  ++partId
277  )
278  {
279  const word selectName = getPartName(partId);
280  const label datasetNo = partDataset_[partId];
281 
282  if (!partStatus_[partId] || datasetNo < 0) continue;
283 
284  const autoPtr<faceSet> fSetPtr =
285  reader_->GetDecomposedCase()
286  ? procMeshesPtr_->reconstructSet<faceSet>(selectName)
287  : autoPtr<faceSet>(new faceSet(tf.mesh(), selectName));
288 
289  convertSurfaceField
290  (
291  tf,
292  output,
293  arrayRangeFaceSets_,
294  datasetNo,
295  tf.mesh(),
296  fSetPtr().toc()
297  );
298  }
299  }
300 }
301 
302 
303 template<class Type>
304 void Foam::vtkPVFoam::convertVolInternalFields
305 (
306  const IOobjectList& objects,
307  vtkMultiBlockDataSet* output
308 )
309 {
310  forAllConstIter(IOobjectList, objects, iter)
311  {
312  // Restrict to GeometricField<Type, ...>::Internal
313  if (iter()->headerClassName() != VolInternalField<Type>::typeName)
314  {
315  continue;
316  }
317 
318  // Load the field
319  tmp<VolInternalField<Type>> ttf;
320 
322 
323  try
324  {
325  if (reader_->GetDecomposedCase())
326  {
327  if (!fvReconstructorPtr_.valid())
328  {
329  fvReconstructorPtr_.set
330  (
331  new fvFieldReconstructor
332  (
333  procMeshesPtr_->completeMesh(),
334  procMeshesPtr_->procMeshes(),
335  procMeshesPtr_->procFaceAddressing(),
336  procMeshesPtr_->procCellAddressing(),
337  procMeshesPtr_->procFaceAddressingBf()
338  )
339  );
340  }
341 
342  ttf =
343  fvReconstructorPtr_
344  ->reconstructVolInternalField<Type>(*iter());
345  }
346  else
347  {
348  ttf =
349  new VolInternalField<Type>
350  (
351  *iter(),
352  procMeshesPtr_->completeMesh()
353  );
354  }
355  }
356  catch (IOerror& err)
357  {
358  Warning<< err << endl;
359  continue;
360  }
361 
363 
364  const VolInternalField<Type>& tf = ttf();
365 
366  // Convert activated internalMesh regions
367  convertVolInternalFieldBlock<Type>
368  (
369  tf,
370  output,
371  arrayRangeVolume_,
372  regionPolyDecomp_
373  );
374 
375  // Convert activated cellZones
376  convertVolInternalFieldBlock<Type>
377  (
378  tf,
379  output,
380  arrayRangeCellZones_,
381  zonePolyDecomp_
382  );
383 
384  // Convert activated cellSets
385  convertVolInternalFieldBlock<Type>
386  (
387  tf,
388  output,
389  arrayRangeCellSets_,
390  setPolyDecomp_
391  );
392  }
393 }
394 
395 
396 template<class Type>
397 void Foam::vtkPVFoam::convertVolFieldBlock
398 (
399  const VolField<Type>& tf,
400  autoPtr<PointField<Type>>& ptfPtr,
401  vtkMultiBlockDataSet* output,
402  const arrayRange& range,
403  const List<polyDecomp>& decompLst
404 )
405 {
406  for (int partId = range.start(); partId < range.end(); ++partId)
407  {
408  const label datasetNo = partDataset_[partId];
409 
410  if (datasetNo >= 0 && partStatus_[partId])
411  {
412  convertVolInternalField<Type>
413  (
414  tf,
415  output,
416  range,
417  datasetNo,
418  decompLst[datasetNo]
419  );
420 
421  if (ptfPtr.valid())
422  {
423  convertPointField
424  (
425  ptfPtr(),
426  tf,
427  output,
428  range,
429  datasetNo,
430  decompLst[datasetNo]
431  );
432  }
433  }
434  }
435 }
436 
437 
438 template<class Type>
439 void Foam::vtkPVFoam::convertVolInternalFieldBlock
440 (
441  const VolInternalField<Type>& tf,
442  vtkMultiBlockDataSet* output,
443  const arrayRange& range,
444  const List<polyDecomp>& decompLst
445 )
446 {
447  for (int partId = range.start(); partId < range.end(); ++partId)
448  {
449  const label datasetNo = partDataset_[partId];
450 
451  if (datasetNo >= 0 && partStatus_[partId])
452  {
453  convertVolInternalField<Type>
454  (
455  tf,
456  output,
457  range,
458  datasetNo,
459  decompLst[datasetNo]
460  );
461  }
462  }
463 }
464 
465 
466 template<class Type>
467 void Foam::vtkPVFoam::convertVolInternalField
468 (
469  const VolInternalField<Type>& tf,
470  vtkMultiBlockDataSet* output,
471  const arrayRange& range,
472  const label datasetNo,
473  const polyDecomp& decompInfo
474 )
475 {
476  const label nComp = pTraits<Type>::nComponents;
477  const labelList& superCells = decompInfo.superCells();
478 
479  vtkFloatArray* celldata = vtkFloatArray::New();
480  celldata->SetNumberOfTuples(superCells.size());
481  celldata->SetNumberOfComponents(nComp);
482  celldata->Allocate(nComp*superCells.size());
483  celldata->SetName(tf.name().c_str());
484 
486  << "Converting Vol field: " << tf.name()
487  << " size=" << tf.size() << " (" << superCells.size()
488  << "), nComp=" << nComp << endl;
489 
490  float vec[nComp];
491  forAll(superCells, i)
492  {
493  const Type& t = tf[superCells[i]];
494  for (direction d=0; d<nComp; ++d)
495  {
496  vec[d] = component(t, d);
497  }
498  vtkOpenFOAMTupleRemap<Type>(vec);
499 
500  celldata->InsertTuple(i, vec);
501  }
502 
503  vtkUnstructuredGrid::SafeDownCast
504  (
505  GetDataSetFromBlock(output, range, datasetNo)
506  ) ->GetCellData()
507  ->AddArray(celldata);
508 
509  celldata->Delete();
510 }
511 
512 
513 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
514 
515 #endif
516 
517 // ************************************************************************* //
scalar range
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
static volPointInterpolation & New(const word &name, const fvMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void throwExceptions()
Definition: error.H:115
void dontThrowExceptions()
Definition: error.H:120
Traits class for primitives.
Definition: pTraits.H:53
Motion of the mesh specified as a list of pointMeshMovers.
tmp< PointField< Type > > interpolate(const VolField< Type > &) const
Interpolate volField using inverse distance weighting.
const tensorField & tf
label patchId(-1)
const fvPatchList & patches
#define DebugInFunction
Report an information message using Foam::Info.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
bool isType(const Type &t)
Check the typeid.
Definition: typeInfo.H:170
void component(GeometricField< typename GeometricField< Type, GeoMesh, PrimitiveField1 >::cmptType, GeoMesh, PrimitiveField1 > &gcf, const GeometricField< Type, GeoMesh, PrimitiveField2 > &gf, const direction d)
typename VolField< Type >::Internal VolInternalField
Definition: volFieldsFwd.H:59
IOerror FatalIOError
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
uint8_t direction
Definition: direction.H:45
messageStream Warning
objects
volScalarField & p