27 #include "vtkPVFoamReader.h"
43 #include "vtkDataArraySelection.h"
44 #include "vtkMultiBlockDataSet.h"
45 #include "vtkRenderer.h"
46 #include "vtkTextActor.h"
47 #include "vtkTextProperty.h"
59 void Foam::vtkPVFoam::clearReconstructors()
61 fvReconstructorPtr_.clear();
62 pointReconstructorPtr_.clear();
63 lagrangianReconstructors_.clear();
64 LagrangianMeshes_.clear();
65 LagrangianReconstructors_.clear();
69 void Foam::vtkPVFoam::clearFoamMesh()
73 !reader_->GetCacheMesh()
75 procMeshesPtr_.valid()
76 && reader_->GetDecomposedCase() != procMeshesPtr_->haveProcs()
80 clearReconstructors();
82 procMeshesPtr_.clear();
87 void Foam::vtkPVFoam::resetCounters()
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();
102 void Foam::vtkPVFoam::reduceMemory()
104 forAll(regionPolyDecomp_, i)
106 regionPolyDecomp_[i].clear();
109 forAll(zonePolyDecomp_, i)
111 zonePolyDecomp_[i].clear();
116 setPolyDecomp_[i].clear();
127 const Time& runTime =
128 reader_->GetDecomposedCase()
129 ? procDbsPtr_->proc0Time()
130 : procDbsPtr_->completeTime();
137 int nearestIndex = timeIndex_;
138 for (
int requestI = 0; requestI < nRequest; ++requestI)
141 if (index >= 0 && index != timeIndex_)
143 nearestIndex = index;
149 if (nearestIndex < 0) nearestIndex = 0;
152 if (timeIndex_ != nearestIndex)
155 timeIndex_ = nearestIndex;
156 procDbsPtr_->setTime(times[nearestIndex], nearestIndex);
163 if (procMeshesPtr_.valid())
165 if (reader_->GetDecomposedCase())
167 stat = procMeshesPtr_->readUpdateReconstruct(
true);
171 stat = procMeshesPtr_->readUpdateComplete();
177 clearReconstructors();
182 if (procMeshesPtr_.valid())
184 procMeshesPtr_->completeMesh().stitcher().reconnect
186 reader_->GetInterpolateVolFields()
194 void Foam::vtkPVFoam::topoChangePartsStatus()
196 vtkDataArraySelection* selection = reader_->GetPartSelection();
198 const label nElem = selection->GetNumberOfArrays();
201 if (partStatus_.size() != nElem)
203 partStatus_.setSize(nElem);
209 partDataset_.setSize(nElem);
213 forAll(partStatus_, partId)
215 const int setting = selection->GetArraySetting(partId);
217 if (partStatus_[partId] != setting)
219 partStatus_[partId] = setting;
229 const char*
const FileNameCStr,
230 vtkPVFoamReader* reader
234 procDbsPtr_(nullptr),
235 procMeshesPtr_(nullptr),
236 meshRegion_(polyMesh::defaultRegion),
237 meshDir_(polyMesh::meshSubDir),
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")
251 <<
"fileName=" << FileNameCStr <<
endl;
253 fileName FileName(FileNameCStr);
256 fileName fullCasePath(FileName.path());
258 if (!
isDir(fullCasePath))
return;
260 if (fullCasePath ==
".")
262 fullCasePath =
cwd();
265 if (fullCasePath.name().find(
"processors", 0) == 0)
270 fullCasePath = fullCasePath.path()/fileName(FileName.name()).lessExt();
273 if (fullCasePath.name().find(
"processor", 0) == 0)
278 const fileName globalCase = fullCasePath.
path();
280 setEnv(
"FOAM_CASE", globalCase,
true);
281 setEnv(
"FOAM_CASENAME", globalCase.name(),
true);
285 setEnv(
"FOAM_CASE", fullCasePath,
true);
286 setEnv(
"FOAM_CASENAME", fullCasePath.name(),
true);
290 string caseName(FileName.name(
true));
295 if (beg != string::npos && end != string::npos)
297 meshMesh_ = caseName.substr(beg+1, end-beg-1);
298 meshPath_ =
"meshes"/meshMesh_;
299 meshDir_ = meshPath_/polyMesh::meshSubDir;
302 beg = caseName.find_last_of(
'{');
303 end = caseName.find(
'}', beg);
305 if (beg != string::npos && end != string::npos)
307 meshRegion_ = caseName.substr(beg+1, end-beg-1);
308 meshDir_ = meshPath_/meshRegion_/polyMesh::meshSubDir;
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;
319 dlLibraryTable dlTable;
320 string libsString(
getEnv(
"FOAM_LIBS"));
321 if (!libsString.empty())
323 IStringStream is(libsString);
327 dlTable.open(libNames[i]);
334 new processorRunTimes
336 Time::controlDictName,
337 fileName(fullCasePath.path()),
338 fileName(fullCasePath.name()),
348 configDict_.merge(dictionary(IFstream(configDictFiles[cdfi])()));
369 vtkDataArraySelection* partSelection = reader_->GetPartSelection();
373 !partSelection->GetNumberOfArrays() && !procMeshesPtr_.valid();
381 enabledEntries[0] =
"internalMesh";
385 enabledEntries = getSelectedArrayEntries(partSelection,
false);
389 partSelection->RemoveAllArrays();
392 updateInfoInternalMesh(partSelection);
393 updateInfoPatches(partSelection, enabledEntries,
first);
394 updateInfoSets(partSelection);
395 updateInfoZones(partSelection);
396 updateInfolagrangian(partSelection);
397 updateInfoLagrangian(partSelection);
400 setSelectedArrayEntries(partSelection, enabledEntries);
402 if (debug) getSelectedArrayEntries(partSelection);
406 updateInfolagrangianFields();
407 updateInfoLagrangianFields();
411 void Foam::vtkPVFoam::updateFoamMesh()
419 if (!procMeshesPtr_.valid())
421 const bool haveMeshMesh = !meshMesh_.empty();
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;
433 new domainDecomposition
441 if (reader_->GetDecomposedCase())
443 procMeshesPtr_->readReconstruct(
true);
447 procMeshesPtr_->readComplete();
453 <<
"Using existing OpenFOAM mesh" <<
endl;
457 if (procMeshesPtr_.valid())
459 procMeshesPtr_->completeMesh().stitcher().reconnect
461 reader_->GetInterpolateVolFields()
469 vtkMultiBlockDataSet* output,
470 vtkMultiBlockDataSet* lagrangianOutput,
471 vtkMultiBlockDataSet* LagrangianOutput
476 reader_->UpdateProgress(0.1);
479 topoChangePartsStatus();
481 reader_->UpdateProgress(0.15);
485 reader_->UpdateProgress(0.4);
490 convertMeshVolume(output, blockNo);
491 convertMeshPatches(output, blockNo);
493 reader_->UpdateProgress(0.6);
495 if (reader_->GetIncludeZones())
497 convertMeshCellZones(output, blockNo);
498 convertMeshFaceZones(output, blockNo);
499 convertMeshPointZones(output, blockNo);
501 reader_->UpdateProgress(0.65);
504 if (reader_->GetIncludeSets())
506 convertMeshCellSets(output, blockNo);
507 convertMeshFaceSets(output, blockNo);
508 convertMeshPointSets(output, blockNo);
510 reader_->UpdateProgress(0.7);
513 convertMeshlagrangian(lagrangianOutput, blockNo);
514 convertMeshLagrangian(LagrangianOutput, blockNo);
516 reader_->UpdateProgress(0.8);
519 convertFields(output);
520 convertlagrangianFields(lagrangianOutput);
521 convertLagrangianFields(LagrangianOutput);
523 reader_->UpdateProgress(0.95);
531 reader_->UpdateProgress(1.0);
538 auto findTimesForRunTime = [
this](
const Time& runTime)
545 for (; timei < timeLst.size(); ++timei)
549 typeIOobject<pointIOField>
552 timeLst[timei].
name(),
562 label nTimes = timeLst.size() - timei;
565 if (timei == 0 && nTimes > 1)
575 if (nTimes > 1 && reader_->GetSkipZeroTime())
577 if (
mag(timeLst[timei].value()) < small)
584 return instantList(SubList<instant>(timeLst, nTimes, timei));
589 if (procDbsPtr_.valid())
594 first || !reader_->GetDecomposedCase()
595 ? findTimesForRunTime(procDbsPtr_->completeTime())
599 first || reader_->GetDecomposedCase()
600 ? findTimesForRunTime(procDbsPtr_->proc0Time())
604 times.
resize(completeTimes.size() + procTimes.size());
605 label completeTimei = 0, procTimei = 0, timei = 0;
608 completeTimei < completeTimes.size()
609 && procTimei < procTimes.size()
612 const bool completeNext =
613 completeTimes[completeTimei].value()
614 < procTimes[procTimei].value();
616 const bool procNext =
617 completeTimes[completeTimei].value()
618 > procTimes[procTimei].value();
622 ? completeTimes[completeTimei]
623 : procTimes[procTimei];
625 if (!procNext) completeTimei ++;
626 if (!completeNext) procTimei ++;
628 while (completeTimei < completeTimes.size())
630 times[timei ++] = completeTimes[completeTimei ++];
632 while (procTimei < procTimes.size())
634 times[timei ++] = procTimes[procTimei ++];
642 nTimeSteps = times.size();
643 double* timeSteps =
new double[times.size()];
646 timeSteps[timei] = times[timei].value();
660 vtkRenderer* renderer,
664 if (!procMeshesPtr_.valid())
return;
669 renderer->RemoveViewProp(patchTextActorsPtrs_[
patchi]);
670 patchTextActorsPtrs_[
patchi]->Delete();
672 patchTextActorsPtrs_.clear();
679 reader_->GetPartSelection(),
683 if (selectedPatches.empty())
return;
685 const polyBoundaryMesh& pbMesh =
686 procMeshesPtr_->completeMesh().boundaryMesh();
694 List<DynamicList<point>> zoneCentre(pbMesh.size());
699 const polyPatch& pp = pbMesh[
patchi];
702 if (!selectedPatches.found(pp.name()))
continue;
707 boolList featEdge(pp.nEdges(),
false);
711 const labelList& eFaces = edgeFaces[edgeI];
713 if (eFaces.size() == 1)
717 featEdge[edgeI] =
true;
719 else if (
mag(
n[eFaces[0]] &
n[eFaces[1]]) < 0.5)
721 featEdge[edgeI] =
true;
726 patchZones
pZones(pp, featEdge);
742 zoneCentre[
patchi][zoneI] += pp[facei].centre(pp.points());
748 zoneCentre[
patchi][zoneI] /= zoneNFaces[zoneI];
755 const label MAXPATCHZONES = 20;
757 label displayZoneI = 0;
761 displayZoneI +=
min(MAXPATCHZONES, nZones[
patchi]);
765 patchTextActorsPtrs_.setSize(displayZoneI);
772 const polyPatch& pp = pbMesh[
patchi];
774 label globalZoneI = 0;
779 if (nZones[
patchi] >= MAXPATCHZONES)
781 increment = nZones[
patchi]/MAXPATCHZONES;
784 for (
label i = 0; i < nDisplayZones; i++)
788 txt->SetInput(pp.name().c_str());
791 vtkTextProperty* tprop = txt->GetTextProperty();
792 tprop->SetFontFamilyToArial();
795 tprop->SetLineSpacing(1.0);
796 tprop->SetFontSize(12);
797 tprop->SetColor(1.0, 0.0, 0.0);
798 tprop->SetJustificationToCentered();
801 txt->GetPositionCoordinate()->SetCoordinateSystemToWorld();
803 txt->GetPositionCoordinate()->SetValue
805 zoneCentre[
patchi][globalZoneI].
x(),
806 zoneCentre[
patchi][globalZoneI].
y(),
807 zoneCentre[
patchi][globalZoneI].z()
811 renderer->AddViewProp(txt);
815 patchTextActorsPtrs_[displayZoneI] = txt;
817 globalZoneI += increment;
823 patchTextActorsPtrs_.setSize(displayZoneI);
830 os <<
indent <<
"Number of nodes: " << (procMeshesPtr_.valid()
831 ? procMeshesPtr_->completeMesh().nPoints() : 0) <<
"\n";
833 os <<
indent <<
"Number of cells: " << (procMeshesPtr_.valid()
834 ? procMeshesPtr_->completeMesh().nCells() : 0) <<
"\n";
836 const label nTimeSteps =
839 : reader_->GetDecomposedCase()
840 ? procDbsPtr_->proc0Time().times().size()
841 : procDbsPtr_->completeTime().times().size();
843 os <<
indent <<
"Number of available time steps: " << nTimeSteps <<
"\n";
845 os <<
indent <<
"mesh: " << meshMesh_ <<
"\n";
847 os <<
indent <<
"mesh region: " << meshRegion_ <<
"\n";
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
#define forAll(list, i)
Loop across all elements in list.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
void resize(const label)
Alias for setSize(const label)
void setSize(const label)
Reset size of List.
static const word & constant()
Return constant name.
static label findClosestTimeIndex(const instantList &, const scalar, const word &constantName="constant")
Search instantList for the time index closest to the given time.
fileName path() const
Return directory path name (part before last /)
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.
static word defaultRegion
Return the default region name.
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.
void updateInfo()
Update information for selection dialogs.
IOporosityModelList pZones(mesh)
Functions to search 'etc' directories for configuration files etc.
#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)
const fileOperation & fileHandler()
Get current file handler.
fileName cwd()
Return current working directory path name.
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable.
List< fileName > fileNameList
A List of fileNames.
List< label > labelList
A List of labels.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Ostream & endl(Ostream &os)
Add newline and flush stream.
List< bool > boolList
Bool container classes.
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
labelList first(const UList< labelPair > &p)
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
List< instant > instantList
List of instants.
List< labelList > labelListList
A List of labelList.
defineTypeNameAndDebug(combustionModel, 0)
bool isDir(const fileName &, const bool followLink=true)
Does the name exist as a directory in the file system?
Field< vector > vectorField
Specialisation of Field<T> for vector.
string getEnv(const word &)
Return environment variable of given name.
fileNameList findEtcFiles(const fileName &, bool mandatory=false, bool findFirst=false)
Search for files from user/group/shipped directories.
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
HashSet wordHashSet
A HashSet with word keys.
List< string > stringList
A List of strings.
Ostream & indent(Ostream &os)
Indent stream.