vtkPVFoam.C
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-2025 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 \*---------------------------------------------------------------------------*/
25 
26 #include "vtkPVFoam.H"
27 #include "vtkPVFoamReader.h"
28 
29 // OpenFOAM includes
30 #include "domainDecomposition.H"
31 #include "fvFieldReconstructor.H"
35 #include "fvMeshStitcher.H"
36 #include "patchZones.H"
37 #include "fileOperation.H"
38 #include "IFstream.H"
39 #include "OSspecific.H"
40 #include "etcFiles.H"
41 
42 // VTK includes
43 #include "vtkDataArraySelection.h"
44 #include "vtkMultiBlockDataSet.h"
45 #include "vtkRenderer.h"
46 #include "vtkTextActor.h"
47 #include "vtkTextProperty.h"
48 
49 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
50 
51 namespace Foam
52 {
53  defineTypeNameAndDebug(vtkPVFoam, 0);
54 }
55 
56 
57 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
58 
59 void Foam::vtkPVFoam::clearReconstructors()
60 {
61  fvReconstructorPtr_.clear();
62  pointReconstructorPtr_.clear();
63  lagrangianReconstructors_.clear();
64  LagrangianMeshes_.clear();
65  LagrangianReconstructors_.clear();
66 }
67 
68 
69 void Foam::vtkPVFoam::clearFoamMesh()
70 {
71  if
72  (
73  !reader_->GetCacheMesh()
74  || (
75  procMeshesPtr_.valid()
76  && reader_->GetDecomposedCase() != procMeshesPtr_->haveProcs()
77  )
78  )
79  {
80  clearReconstructors();
81 
82  procMeshesPtr_.clear();
83  }
84 }
85 
86 
87 void Foam::vtkPVFoam::resetCounters()
88 {
89  arrayRangeVolume_.reset();
90  arrayRangePatches_.reset();
91  arrayRangelagrangian_.reset();
92  arrayRangeLagrangian_.reset();
93  arrayRangeCellZones_.reset();
94  arrayRangeFaceZones_.reset();
95  arrayRangePointZones_.reset();
96  arrayRangeCellSets_.reset();
97  arrayRangeFaceSets_.reset();
98  arrayRangePointSets_.reset();
99 }
100 
101 
102 void Foam::vtkPVFoam::reduceMemory()
103 {
104  forAll(regionPolyDecomp_, i)
105  {
106  regionPolyDecomp_[i].clear();
107  }
108 
109  forAll(zonePolyDecomp_, i)
110  {
111  zonePolyDecomp_[i].clear();
112  }
113 
114  forAll(setPolyDecomp_, i)
115  {
116  setPolyDecomp_[i].clear();
117  }
118 
119  clearFoamMesh();
120 }
121 
122 
123 int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
124 {
126 
127  const Time& runTime =
128  reader_->GetDecomposedCase()
129  ? procDbsPtr_->proc0Time()
130  : procDbsPtr_->completeTime();
131 
132  // Get times list. Flush first to force refresh.
133  fileHandler().flush();
134  const instantList times = runTime.times();
135 
136  // Find the nearest index to the selected time
137  int nearestIndex = timeIndex_;
138  for (int requestI = 0; requestI < nRequest; ++requestI)
139  {
140  int index = Time::findClosestTimeIndex(times, requestTimes[requestI]);
141  if (index >= 0 && index != timeIndex_)
142  {
143  nearestIndex = index;
144  break;
145  }
146  }
147 
148  // Clip the index to zero
149  if (nearestIndex < 0) nearestIndex = 0;
150 
151  // If the time has changed...
152  if (timeIndex_ != nearestIndex)
153  {
154  // Set the time
155  timeIndex_ = nearestIndex;
156  procDbsPtr_->setTime(times[nearestIndex], nearestIndex);
157 
158  // Clear the mesh if necessary
159  clearFoamMesh();
160 
161  // Update the mesh
163  if (procMeshesPtr_.valid())
164  {
165  if (reader_->GetDecomposedCase())
166  {
167  stat = procMeshesPtr_->readUpdateReconstruct(true);
168  }
169  else
170  {
171  stat = procMeshesPtr_->readUpdateComplete();
172  }
173  }
174 
175  if (stat > fvMesh::POINTS_MOVED)
176  {
177  clearReconstructors();
178  }
179  }
180 
181  // Re-stitch if necessary
182  if (procMeshesPtr_.valid())
183  {
184  procMeshesPtr_->completeMesh().stitcher().reconnect
185  (
186  reader_->GetInterpolateVolFields()
187  );
188  }
189 
190  return nearestIndex;
191 }
192 
193 
194 void Foam::vtkPVFoam::topoChangePartsStatus()
195 {
196  vtkDataArraySelection* selection = reader_->GetPartSelection();
197 
198  const label nElem = selection->GetNumberOfArrays();
199 
200  // Clear the part statuses
201  if (partStatus_.size() != nElem)
202  {
203  partStatus_.setSize(nElem);
204  partStatus_ = false;
205  }
206 
207  // Clear the part datasets. Note that this is not optimal as it means we
208  // are not reusing existing data sets.
209  partDataset_.setSize(nElem);
210  partDataset_ = -1;
211 
212  // Read the selected mesh parts (zones, patches ...) and add to list
213  forAll(partStatus_, partId)
214  {
215  const int setting = selection->GetArraySetting(partId);
216 
217  if (partStatus_[partId] != setting)
218  {
219  partStatus_[partId] = setting;
220  }
221  }
222 }
223 
224 
225 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
226 
228 (
229  const char* const FileNameCStr,
230  vtkPVFoamReader* reader
231 )
232 :
233  reader_(reader),
234  procDbsPtr_(nullptr),
235  procMeshesPtr_(nullptr),
236  meshRegion_(polyMesh::defaultRegion),
237  meshDir_(polyMesh::meshSubDir),
238  timeIndex_(-1),
239  arrayRangeVolume_("unzoned"),
240  arrayRangePatches_("patches"),
241  arrayRangelagrangian_("lagrangian"),
242  arrayRangeLagrangian_("Lagrangian"),
243  arrayRangeCellZones_("cellZone"),
244  arrayRangeFaceZones_("faceZone"),
245  arrayRangePointZones_("pointZone"),
246  arrayRangeCellSets_("cellSet"),
247  arrayRangeFaceSets_("faceSet"),
248  arrayRangePointSets_("pointSet")
249 {
251  << "fileName=" << FileNameCStr << endl;
252 
253  fileName FileName(FileNameCStr);
254 
255  // Avoid argList and get rootPath/caseName directly from the file
256  fileName fullCasePath(FileName.path());
257 
258  if (!isDir(fullCasePath)) return;
259 
260  if (fullCasePath == ".")
261  {
262  fullCasePath = cwd();
263  }
264 
265  if (fullCasePath.name().find("processors", 0) == 0)
266  {
267  // FileName e.g. "cavity/processors256/processor1.OpenFOAM
268  // Remove the processors section so it goes into processorDDD
269  // checking below.
270  fullCasePath = fullCasePath.path()/fileName(FileName.name()).lessExt();
271  }
272 
273  if (fullCasePath.name().find("processor", 0) == 0)
274  {
275  // Give filehandler opportunity to analyse number of processors
276  (void)fileHandler().filePath(fullCasePath);
277 
278  const fileName globalCase = fullCasePath.path();
279 
280  setEnv("FOAM_CASE", globalCase, true);
281  setEnv("FOAM_CASENAME", globalCase.name(), true);
282  }
283  else
284  {
285  setEnv("FOAM_CASE", fullCasePath, true);
286  setEnv("FOAM_CASENAME", fullCasePath.name(), true);
287  }
288 
289  // Parse the mesh and region names from 'case(mesh){region}' in FileName
290  string caseName(FileName.name(true));
291 
292  string::size_type beg = caseName.find_last_of('(');
293  string::size_type end = caseName.find(')', beg);
294 
295  if (beg != string::npos && end != string::npos)
296  {
297  meshMesh_ = caseName.substr(beg+1, end-beg-1);
298  meshPath_ = "meshes"/meshMesh_;
299  meshDir_ = meshPath_/polyMesh::meshSubDir;
300  }
301 
302  beg = caseName.find_last_of('{');
303  end = caseName.find('}', beg);
304 
305  if (beg != string::npos && end != string::npos)
306  {
307  meshRegion_ = caseName.substr(beg+1, end-beg-1);
308  meshDir_ = meshPath_/meshRegion_/polyMesh::meshSubDir;
309  }
310 
311  DebugInfo
312  << " fullCasePath=" << fullCasePath << nl
313  << " FOAM_CASE=" << getEnv("FOAM_CASE") << nl
314  << " FOAM_CASENAME=" << getEnv("FOAM_CASENAME") << nl
315  << " mesh=" << meshMesh_ << nl
316  << " region=" << meshRegion_ << endl;
317 
318  // Pre-load any libraries
319  dlLibraryTable dlTable;
320  string libsString(getEnv("FOAM_LIBS"));
321  if (!libsString.empty())
322  {
323  IStringStream is(libsString);
324  fileNameList libNames(is);
325  forAll(libNames, i)
326  {
327  dlTable.open(libNames[i]);
328  }
329  }
330 
331  // Create time object
332  procDbsPtr_.reset
333  (
334  new processorRunTimes
335  (
336  Time::controlDictName,
337  fileName(fullCasePath.path()),
338  fileName(fullCasePath.name()),
339  false,
341  )
342  );
343 
344  // Read the configuration
345  fileNameList configDictFiles = findEtcFiles("paraFoam", false);
346  forAllReverse(configDictFiles, cdfi)
347  {
348  configDict_.merge(dictionary(IFstream(configDictFiles[cdfi])()));
349  }
350 
351  updateInfo();
352 }
353 
354 
355 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
356 
358 {}
359 
360 
361 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
362 
364 {
366 
367  resetCounters();
368 
369  vtkDataArraySelection* partSelection = reader_->GetPartSelection();
370 
371  // Determine whether or not this is the first update
372  const bool first =
373  !partSelection->GetNumberOfArrays() && !procMeshesPtr_.valid();
374 
375  // Enable 'internalMesh' on the first call, otherwise or preserve the
376  // previously enabled selections
377  stringList enabledEntries;
378  if (first)
379  {
380  enabledEntries.setSize(1);
381  enabledEntries[0] = "internalMesh";
382  }
383  else
384  {
385  enabledEntries = getSelectedArrayEntries(partSelection, false);
386  }
387 
388  // Clear current mesh parts list
389  partSelection->RemoveAllArrays();
390 
391  // Update mesh parts list - add Lagrangian at the bottom
392  updateInfoInternalMesh(partSelection);
393  updateInfoPatches(partSelection, enabledEntries, first);
394  updateInfoSets(partSelection);
395  updateInfoZones(partSelection);
396  updateInfolagrangian(partSelection);
397  updateInfoLagrangian(partSelection);
398 
399  // Restore the enabled selections
400  setSelectedArrayEntries(partSelection, enabledEntries);
401 
402  if (debug) getSelectedArrayEntries(partSelection);
403 
404  // Update fields
405  updateInfoFields();
406  updateInfolagrangianFields();
407  updateInfoLagrangianFields();
408 }
409 
410 
411 void Foam::vtkPVFoam::updateFoamMesh()
412 {
414 
415  // Clear the mesh if necessary
416  clearFoamMesh();
417 
418  // Create the OpenFOAM mesh if it does not yet exist
419  if (!procMeshesPtr_.valid())
420  {
421  const bool haveMeshMesh = !meshMesh_.empty();
422  const bool haveMeshRegion = meshRegion_ != polyMesh::defaultRegion;
423 
424  DebugInfo
425  << "Creating OpenFOAM mesh"
426  << (haveMeshMesh ? " for mesh " + meshMesh_ : "").c_str()
427  << (haveMeshMesh && haveMeshRegion ? " and" : "")
428  << (haveMeshRegion ? " for region " + meshRegion_ : "").c_str()
429  << " at time=" << procDbsPtr_().completeTime().name() << endl;
430 
431  procMeshesPtr_.reset
432  (
433  new domainDecomposition
434  (
435  procDbsPtr_(),
436  meshPath_,
437  meshRegion_
438  )
439  );
440 
441  if (reader_->GetDecomposedCase())
442  {
443  procMeshesPtr_->readReconstruct(true);
444  }
445  else
446  {
447  procMeshesPtr_->readComplete();
448  }
449  }
450  else
451  {
452  DebugInfo
453  << "Using existing OpenFOAM mesh" << endl;
454  }
455 
456  // Stitch if necessary
457  if (procMeshesPtr_.valid())
458  {
459  procMeshesPtr_->completeMesh().stitcher().reconnect
460  (
461  reader_->GetInterpolateVolFields()
462  );
463  }
464 }
465 
466 
468 (
469  vtkMultiBlockDataSet* output,
470  vtkMultiBlockDataSet* lagrangianOutput,
471  vtkMultiBlockDataSet* LagrangianOutput
472 )
473 {
475 
476  reader_->UpdateProgress(0.1);
477 
478  // Set up mesh parts selection(s)
479  topoChangePartsStatus();
480 
481  reader_->UpdateProgress(0.15);
482 
483  // Update the OpenFOAM mesh
484  updateFoamMesh();
485  reader_->UpdateProgress(0.4);
486 
487  // Convert meshes - start port0 at block=0
488  int blockNo = 0;
489 
490  convertMeshVolume(output, blockNo);
491  convertMeshPatches(output, blockNo);
492 
493  reader_->UpdateProgress(0.6);
494 
495  if (reader_->GetIncludeZones())
496  {
497  convertMeshCellZones(output, blockNo);
498  convertMeshFaceZones(output, blockNo);
499  convertMeshPointZones(output, blockNo);
500 
501  reader_->UpdateProgress(0.65);
502  }
503 
504  if (reader_->GetIncludeSets())
505  {
506  convertMeshCellSets(output, blockNo);
507  convertMeshFaceSets(output, blockNo);
508  convertMeshPointSets(output, blockNo);
509 
510  reader_->UpdateProgress(0.7);
511  }
512 
513  convertMeshlagrangian(lagrangianOutput, blockNo);
514  convertMeshLagrangian(LagrangianOutput, blockNo);
515 
516  reader_->UpdateProgress(0.8);
517 
518  // Update fields
519  convertFields(output);
520  convertlagrangianFields(lagrangianOutput);
521  convertLagrangianFields(LagrangianOutput);
522 
523  reader_->UpdateProgress(0.95);
524 }
525 
526 
528 {
529  // Reclaim some memory
530  reduceMemory();
531  reader_->UpdateProgress(1.0);
532 }
533 
534 
535 double* Foam::vtkPVFoam::findTimes(const bool first, int& nTimeSteps)
536 {
537  // Read the available times in a given database
538  auto findTimesForRunTime = [this](const Time& runTime)
539  {
540  // Get all the times for this database
541  const instantList timeLst = runTime.times();
542 
543  // Find the first time for which this mesh appears to exist
544  label timei = 0;
545  for (; timei < timeLst.size(); ++timei)
546  {
547  if
548  (
549  typeIOobject<pointIOField>
550  (
551  "points",
552  timeLst[timei].name(),
553  meshDir_,
554  runTime
555  ).headerOk()
556  )
557  {
558  break;
559  }
560  }
561 
562  label nTimes = timeLst.size() - timei;
563 
564  // Skip "constant" time whenever possible
565  if (timei == 0 && nTimes > 1)
566  {
567  if (timeLst[timei].name() == Time::constant())
568  {
569  ++timei;
570  --nTimes;
571  }
572  }
573 
574  // Skip "0/" time if requested and possible
575  if (nTimes > 1 && reader_->GetSkipZeroTime())
576  {
577  if (mag(timeLst[timei].value()) < small)
578  {
579  ++timei;
580  --nTimes;
581  }
582  }
583 
584  return instantList(SubList<instant>(timeLst, nTimes, timei));
585  };
586 
587  // Get a list of available instants
588  instantList times;
589  if (procDbsPtr_.valid())
590  {
591  // Get times from complete and/or processor databases. Use both if this
592  // is the first execution.
593  const instantList completeTimes =
594  first || !reader_->GetDecomposedCase()
595  ? findTimesForRunTime(procDbsPtr_->completeTime())
596  : instantList();
597 
598  const instantList procTimes =
599  first || reader_->GetDecomposedCase()
600  ? findTimesForRunTime(procDbsPtr_->proc0Time())
601  : instantList();
602 
603  // Merge the lists of times
604  times.resize(completeTimes.size() + procTimes.size());
605  label completeTimei = 0, procTimei = 0, timei = 0;
606  while
607  (
608  completeTimei < completeTimes.size()
609  && procTimei < procTimes.size()
610  )
611  {
612  const bool completeNext =
613  completeTimes[completeTimei].value()
614  < procTimes[procTimei].value();
615 
616  const bool procNext =
617  completeTimes[completeTimei].value()
618  > procTimes[procTimei].value();
619 
620  times[timei ++] =
621  completeNext
622  ? completeTimes[completeTimei]
623  : procTimes[procTimei];
624 
625  if (!procNext) completeTimei ++;
626  if (!completeNext) procTimei ++;
627  }
628  while (completeTimei < completeTimes.size())
629  {
630  times[timei ++] = completeTimes[completeTimei ++];
631  }
632  while (procTimei < procTimes.size())
633  {
634  times[timei ++] = procTimes[procTimei ++];
635  }
636  times.resize(timei);
637  }
638 
639  // If we have some times, convert to a bare array for VTK and return
640  if (times.size())
641  {
642  nTimeSteps = times.size();
643  double* timeSteps = new double[times.size()];
644  forAll(times, timei)
645  {
646  timeSteps[timei] = times[timei].value();
647  }
648  return timeSteps;
649  }
650  else
651  {
652  nTimeSteps = 0;
653  return nullptr;
654  }
655 }
656 
657 
659 (
660  vtkRenderer* renderer,
661  const bool show
662 )
663 {
664  if (!procMeshesPtr_.valid()) return;
665 
666  // Always remove old actors first
667  forAll(patchTextActorsPtrs_, patchi)
668  {
669  renderer->RemoveViewProp(patchTextActorsPtrs_[patchi]);
670  patchTextActorsPtrs_[patchi]->Delete();
671  }
672  patchTextActorsPtrs_.clear();
673 
674  if (show)
675  {
676  // Get the display patches, strip off any suffix
677  const wordHashSet selectedPatches = getSelected
678  (
679  reader_->GetPartSelection(),
680  arrayRangePatches_
681  );
682 
683  if (selectedPatches.empty()) return;
684 
685  const polyBoundaryMesh& pbMesh =
686  procMeshesPtr_->completeMesh().boundaryMesh();
687 
688  // Find the total number of zones
689  // Each zone will take the patch name
690  // Number of zones per patch ... zero zones should be skipped
691  labelList nZones(pbMesh.size(), 0);
692 
693  // Per global zone number the average face centre position
694  List<DynamicList<point>> zoneCentre(pbMesh.size());
695 
696  // Loop through all patches to determine zones, and centre of each zone
697  forAll(pbMesh, patchi)
698  {
699  const polyPatch& pp = pbMesh[patchi];
700 
701  // Only include the patch if it is selected
702  if (!selectedPatches.found(pp.name())) continue;
703 
704  const labelListList& edgeFaces = pp.edgeFaces();
705  const vectorField& n = pp.faceNormals();
706 
707  boolList featEdge(pp.nEdges(), false);
708 
709  forAll(edgeFaces, edgeI)
710  {
711  const labelList& eFaces = edgeFaces[edgeI];
712 
713  if (eFaces.size() == 1)
714  {
715  // Note: could also do ones with > 2 faces but this gives
716  // too many zones for baffles
717  featEdge[edgeI] = true;
718  }
719  else if (mag(n[eFaces[0]] & n[eFaces[1]]) < 0.5)
720  {
721  featEdge[edgeI] = true;
722  }
723  }
724 
725  // Do topological analysis of patch, find disconnected regions
726  patchZones pZones(pp, featEdge);
727 
728  nZones[patchi] = pZones.nZones();
729 
730  labelList zoneNFaces(pZones.nZones(), 0);
731 
732  // Create storage for additional zone centres
733  forAll(zoneNFaces, zoneI)
734  {
735  zoneCentre[patchi].append(Zero);
736  }
737 
738  // Do averaging per individual zone
739  forAll(pp, facei)
740  {
741  label zoneI = pZones[facei];
742  zoneCentre[patchi][zoneI] += pp[facei].centre(pp.points());
743  zoneNFaces[zoneI]++;
744  }
745 
746  forAll(zoneCentre[patchi], zoneI)
747  {
748  zoneCentre[patchi][zoneI] /= zoneNFaces[zoneI];
749  }
750  }
751 
752  // Count number of zones we're actually going to display.
753  // This is truncated to a max per patch
754 
755  const label MAXPATCHZONES = 20;
756 
757  label displayZoneI = 0;
758 
759  forAll(pbMesh, patchi)
760  {
761  displayZoneI += min(MAXPATCHZONES, nZones[patchi]);
762  }
763 
764  // Set the size of the patch labels to max number of zones
765  patchTextActorsPtrs_.setSize(displayZoneI);
766 
767  // Actor index
768  displayZoneI = 0;
769 
770  forAll(pbMesh, patchi)
771  {
772  const polyPatch& pp = pbMesh[patchi];
773 
774  label globalZoneI = 0;
775 
776  // Only selected patches will have a non-zero number of zones
777  label nDisplayZones = min(MAXPATCHZONES, nZones[patchi]);
778  label increment = 1;
779  if (nZones[patchi] >= MAXPATCHZONES)
780  {
781  increment = nZones[patchi]/MAXPATCHZONES;
782  }
783 
784  for (label i = 0; i < nDisplayZones; i++)
785  {
786  vtkTextActor* txt = vtkTextActor::New();
787 
788  txt->SetInput(pp.name().c_str());
789 
790  // Set text properties
791  vtkTextProperty* tprop = txt->GetTextProperty();
792  tprop->SetFontFamilyToArial();
793  tprop->BoldOff();
794  tprop->ShadowOff();
795  tprop->SetLineSpacing(1.0);
796  tprop->SetFontSize(12);
797  tprop->SetColor(1.0, 0.0, 0.0);
798  tprop->SetJustificationToCentered();
799 
800  // Set text to use 3-D world co-ordinates
801  txt->GetPositionCoordinate()->SetCoordinateSystemToWorld();
802 
803  txt->GetPositionCoordinate()->SetValue
804  (
805  zoneCentre[patchi][globalZoneI].x(),
806  zoneCentre[patchi][globalZoneI].y(),
807  zoneCentre[patchi][globalZoneI].z()
808  );
809 
810  // Add text to each renderer
811  renderer->AddViewProp(txt);
812 
813  // Maintain a list of text labels added so that they can be
814  // removed later
815  patchTextActorsPtrs_[displayZoneI] = txt;
816 
817  globalZoneI += increment;
818  displayZoneI++;
819  }
820  }
821 
822  // Resize the patch names list to the actual number of patch names added
823  patchTextActorsPtrs_.setSize(displayZoneI);
824  }
825 }
826 
827 
828 void Foam::vtkPVFoam::PrintSelf(ostream& os, vtkIndent indent) const
829 {
830  os << indent << "Number of nodes: " << (procMeshesPtr_.valid()
831  ? procMeshesPtr_->completeMesh().nPoints() : 0) << "\n";
832 
833  os << indent << "Number of cells: " << (procMeshesPtr_.valid()
834  ? procMeshesPtr_->completeMesh().nCells() : 0) << "\n";
835 
836  const label nTimeSteps =
837  procDbsPtr_.empty()
838  ? 0
839  : reader_->GetDecomposedCase()
840  ? procDbsPtr_->proc0Time().times().size()
841  : procDbsPtr_->completeTime().times().size();
842 
843  os << indent << "Number of available time steps: " << nTimeSteps << "\n";
844 
845  os << indent << "mesh: " << meshMesh_ << "\n";
846 
847  os << indent << "mesh region: " << meshRegion_ << "\n";
848 }
849 
850 
851 // ************************************************************************* //
scalar y
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:445
void resize(const label)
Alias for setSize(const label)
Definition: ListI.H:138
void setSize(const label)
Reset size of List.
Definition: List.C:281
static const word & constant()
Return constant name.
Definition: TimePaths.H:122
static label findClosestTimeIndex(const instantList &, const scalar, const word &constantName="constant")
Search instantList for the time index closest to the given time.
Definition: Time.C:749
fileName path() const
Return directory path name (part before last /)
Definition: fileName.C:284
virtual void flush() const
Forcibly wait until all output done. Flush any cached data.
virtual fileName filePath(const bool globalFile, const IOobject &) const =0
Search for an object. globalFile : also check undecomposed case.
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: fvMesh.H:105
@ POINTS_MOVED
Definition: fvMesh.H:107
@ TOPO_PATCH_CHANGE
Definition: fvMesh.H:110
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:270
double * findTimes(const bool first, int &nTimeSteps)
Allocate and return a list of selected times.
int setTime(int count, const double requestTimes[])
Set the runTime to the first plausible request time,.
void PrintSelf(ostream &, vtkIndent) const
Debug information.
void Update(vtkMultiBlockDataSet *output, vtkMultiBlockDataSet *lagrangianOutput, vtkMultiBlockDataSet *LagrangianOutput)
Update.
void renderPatchNames(vtkRenderer *, const bool show)
Add/remove patch names to/from the view.
vtkPVFoam(const char *const FileName, vtkPVFoamReader *reader)
Construct from components.
void CleanUp()
Clean any storage.
~vtkPVFoam()
Destructor.
void updateInfo()
Update information for selection dialogs.
IOporosityModelList pZones(mesh)
Functions to search 'etc' directories for configuration files etc.
label patchi
#define DebugInfo
Report an information message using Foam::Info.
#define DebugInFunction
Report an information message using Foam::Info.
autoPtr< CompressibleMomentumTransportModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const viscosity &viscosity)
Namespace for OpenFOAM.
const fileOperation & fileHandler()
Get current file handler.
fileName cwd()
Return current working directory path name.
Definition: POSIX.C:241
static const zero Zero
Definition: zero.H:97
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable.
Definition: POSIX.C:115
List< fileName > fileNameList
A List of fileNames.
Definition: fileNameList.H:50
List< label > labelList
A List of labels.
Definition: labelList.H:56
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:258
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
List< instant > instantList
List of instants.
Definition: instantList.H:42
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
defineTypeNameAndDebug(combustionModel, 0)
bool isDir(const fileName &, const bool followLink=true)
Does the name exist as a directory in the file system?
Definition: POSIX.C:539
Field< vector > vectorField
Specialisation of Field<T> for vector.
string getEnv(const word &)
Return environment variable of given name.
Definition: POSIX.C:97
fileNameList findEtcFiles(const fileName &, bool mandatory=false, bool findFirst=false)
Search for files from user/group/shipped directories.
Definition: etcFiles.C:119
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:210
List< string > stringList
A List of strings.
Definition: stringList.H:50
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:228
static const char nl
Definition: Ostream.H:267