Commit 1f1aec15 authored by Andrew Bauer's avatar Andrew Bauer
Browse files

Fix OpenFOAM reader incorrect caching

If the CacheMesh option is set to off the mesh and corresponding
subreaders were still being stored and this caused a high
memory overhead. This fixes that issue.
parent f365ba65
Pipeline #45841 failed with stage
......@@ -250,8 +250,6 @@ public:
};
typedef vtkFoamArrayVector<vtkDataArray> vtkFoamLabelArrayVector;
typedef vtkFoamArrayVector<vtkIntArray> vtkFoamIntArrayVector;
typedef vtkFoamArrayVector<vtkFloatArray> vtkFoamFloatArrayVector;
struct vtkFoamLabelVectorVector;
template <typename ArrayT> struct vtkFoamLabelVectorVectorImpl;
......@@ -9327,7 +9325,7 @@ int vtkOpenFOAMReader::RequestInformation(vtkInformation *vtkNotUsed(request), v
// vtkPOpenFOAMReader
this->NumberOfReaders = 0;
if (!this->MakeInformationVector(outputVector, vtkStdString(""))
if (!this->MakeInformationVector(outputVector, vtkStdString(""), true)
|| !this->MakeMetaDataAtTimeStep(true))
{
return 0;
......@@ -9476,9 +9474,12 @@ void vtkOpenFOAMReader::SetTimeInformation(vtkInformationVector *outputVector,
//-----------------------------------------------------------------------------
int vtkOpenFOAMReader::MakeInformationVector(
vtkInformationVector *outputVector, const vtkStdString& procName)
vtkInformationVector *outputVector, const vtkStdString& procName, bool updateOldName)
{
*this->FileNameOld = vtkStdString(this->FileName);
if (updateOldName)
{
*this->FileNameOld = vtkStdString(this->FileName);
}
// clear prior case information
this->Readers->RemoveAllItems();
......@@ -9504,7 +9505,7 @@ int vtkOpenFOAMReader::MakeInformationVector(
this->Readers->AddItem(masterReader);
if (outputVector != NULL)
if (outputVector != nullptr)
{
this->SetTimeInformation(outputVector, masterReader->GetTimeValues());
}
......
......@@ -303,7 +303,7 @@ public:
void SetRefresh() { this->Refresh = true; this->Modified(); }
void SetParent(vtkOpenFOAMReader *parent) { this->Parent = parent; }
int MakeInformationVector(vtkInformationVector *, const vtkStdString &);
int MakeInformationVector(vtkInformationVector *, const vtkStdString &, bool updateOldName);
bool SetTimeValue(const double);
vtkDoubleArray *GetTimeValues();
int MakeMetaDataAtTimeStep(const bool);
......@@ -348,6 +348,7 @@ protected:
char *FileName;
vtkCharArray *CasePath;
friend class vtkPOpenFOAMReader; // in order to access Readers from a separate class
vtkCollection *Readers;
// DataArraySelection for Patch / Region Data
......
......@@ -29,6 +29,7 @@
#include "vtkIntArray.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkMultiProcessController.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkSortDataArray.h"
#include "vtkStdString.h"
......@@ -154,7 +155,7 @@ int vtkPOpenFOAMReader::RequestInformation(vtkInformation *request,
this->Superclass::Readers->RemoveAllItems();
this->Superclass::NumberOfReaders = 0;
vtkStringArray *procNames = vtkStringArray::New();
vtkNew<vtkStringArray> procNames;
vtkDoubleArray *timeValues;
// recreate case information
......@@ -198,7 +199,7 @@ int vtkPOpenFOAMReader::RequestInformation(vtkInformation *request,
dir->Delete();
// sort processor subdirectories by processor numbers
vtkSortDataArray::Sort(procNos, procNames);
vtkSortDataArray::Sort(procNos, procNames.GetPointer());
procNos->Delete();
// get time directories from the first processor subdirectory
......@@ -211,9 +212,8 @@ int vtkPOpenFOAMReader::RequestInformation(vtkInformation *request,
masterReader->SetUse64BitLabels(this->Use64BitLabels);
masterReader->SetUse64BitFloats(this->Use64BitFloats);
if (!masterReader->MakeInformationVector(outputVector, procNames
->GetValue(0)) || !masterReader->MakeMetaDataAtTimeStep(true))
->GetValue(0), true) || !masterReader->MakeMetaDataAtTimeStep(true))
{
procNames->Delete();
masterReader->Delete();
this->BroadcastStatus(ret = 0);
return 0;
......@@ -244,7 +244,7 @@ int vtkPOpenFOAMReader::RequestInformation(vtkInformation *request,
return 0;
}
this->Broadcast(procNames);
this->Broadcast(procNames.GetPointer());
this->Controller->Broadcast(timeValues, 0);
if (this->ProcessId != 0)
{
......@@ -269,7 +269,7 @@ int vtkPOpenFOAMReader::RequestInformation(vtkInformation *request,
subReader->SetUse64BitLabels(this->Use64BitLabels);
subReader->SetUse64BitFloats(this->Use64BitFloats);
// if getting metadata failed simply delete the reader instance
if (subReader->MakeInformationVector(NULL, procNames->GetValue(procI))
if (subReader->MakeInformationVector(NULL, procNames->GetValue(procI), true)
&& subReader->MakeMetaDataAtTimeStep(true))
{
this->Superclass::Readers->AddItem(subReader);
......@@ -282,8 +282,6 @@ int vtkPOpenFOAMReader::RequestInformation(vtkInformation *request,
subReader->Delete();
}
procNames->Delete();
this->GatherMetaData();
this->Superclass::Refresh = false;
}
......@@ -299,6 +297,18 @@ int vtkPOpenFOAMReader::RequestInformation(vtkInformation *request,
int vtkPOpenFOAMReader::RequestData(vtkInformation *request,
vtkInformationVector **inputVector, vtkInformationVector *outputVector)
{
if (this->NumberOfReaders == 0)
{
if (!this->MakeInformationVector(nullptr, vtkStdString(""), false))
{
return 0;
}
if (this->CaseType != RECONSTRUCTED_CASE)
{
this->GenerateReaders();
}
}
if (this->CaseType == RECONSTRUCTED_CASE)
{
int ret = 1;
......@@ -385,9 +395,135 @@ int vtkPOpenFOAMReader::RequestData(vtkInformation *request,
this->Superclass::UpdateStatus();
this->MTimeOld = this->GetMTime();
if (!this->CacheMesh)
{
vtkOpenFOAMReader *reader;
this->Superclass::CurrentReaderIndex = 0;
this->Superclass::Readers->InitTraversal();
while ((reader
= vtkOpenFOAMReader::SafeDownCast(this->Superclass::Readers->GetNextItemAsObject()))
!= NULL)
{
reader->Readers->RemoveAllItems();
}
this->Readers->RemoveAllItems();
this->NumberOfReaders = 0;
}
return ret;
}
//-----------------------------------------------------------------------------
int vtkPOpenFOAMReader::GenerateReaders()
{
this->Superclass::Readers->RemoveAllItems();
this->Superclass::NumberOfReaders = 0;
vtkNew<vtkStringArray> procNames;
// recreate case information
vtkStdString masterCasePath, controlDictPath;
this->Superclass::CreateCasePath(masterCasePath, controlDictPath);
this->Superclass::CreateCharArrayFromString(this->Superclass::CasePath,
"CasePath", masterCasePath);
int ret = 1;
if (this->ProcessId == 0)
{
// search and list processor subdirectories
vtkDirectory *dir = vtkDirectory::New();
if (!dir->Open(masterCasePath.c_str()))
{
vtkErrorMacro(<< "Can't open " << masterCasePath.c_str());
dir->Delete();
this->BroadcastStatus(ret = 0);
return 0;
}
vtkIntArray *procNos = vtkIntArray::New();
for (int fileI = 0; fileI < dir->GetNumberOfFiles(); fileI++)
{
const vtkStdString subDir(dir->GetFile(fileI));
if (subDir.substr(0, 9) == "processor")
{
const vtkStdString procNoStr(subDir.substr(9, vtkStdString::npos));
char *conversionEnd;
const int procNo = strtol(procNoStr.c_str(), &conversionEnd, 10);
if (procNoStr.c_str() + procNoStr.length() == conversionEnd && procNo
>= 0)
{
procNos->InsertNextValue(procNo);
procNames->InsertNextValue(subDir);
}
}
}
procNos->Squeeze();
procNames->Squeeze();
dir->Delete();
// sort processor subdirectories by processor numbers
vtkSortDataArray::Sort(procNos, procNames.GetPointer());
procNos->Delete();
// get time directories from the first processor subdirectory
if (procNames->GetNumberOfTuples() > 0)
{
vtkOpenFOAMReader *masterReader = vtkOpenFOAMReader::New();
masterReader->SetFileName(this->FileName);
masterReader->SetParent(this);
masterReader->SetSkipZeroTime(this->SkipZeroTime);
masterReader->SetUse64BitLabels(this->Use64BitLabels);
masterReader->SetUse64BitFloats(this->Use64BitFloats);
if (!masterReader->MakeInformationVector(nullptr, procNames
->GetValue(0), false) || !masterReader->MakeMetaDataAtTimeStep(true))
{
masterReader->Delete();
this->BroadcastStatus(ret = 0);
vtkErrorMacro(<< "The master process returned an error.");
return 0;
}
this->Superclass::Readers->AddItem(masterReader);
masterReader->Delete();
}
}
if (this->NumProcesses > 1)
{
// if there was an error in process 0 abort all processes
this->BroadcastStatus(ret);
if (ret == 0)
{
return 0;
}
this->Broadcast(procNames.GetPointer());
}
// create reader instances for other processor subdirectories
// skip processor0 since it's already created
for (int procI = (this->ProcessId ? this->ProcessId : this->NumProcesses); procI
< procNames->GetNumberOfTuples(); procI += this->NumProcesses)
{
vtkOpenFOAMReader *subReader = vtkOpenFOAMReader::New();
subReader->SetFileName(this->FileName);
subReader->SetParent(this);
subReader->SetUse64BitLabels(this->Use64BitLabels);
subReader->SetUse64BitFloats(this->Use64BitFloats);
// if getting metadata failed simply delete the reader instance
if (subReader->MakeInformationVector(NULL, procNames->GetValue(procI), false)
&& subReader->MakeMetaDataAtTimeStep(true))
{
this->Superclass::Readers->AddItem(subReader);
}
else
{
vtkWarningMacro(<<"Removing reader for processor subdirectory "
<< procNames->GetValue(procI).c_str());
}
subReader->Delete();
}
}
//-----------------------------------------------------------------------------
void vtkPOpenFOAMReader::BroadcastStatus(int &status)
{
......
......@@ -71,6 +71,8 @@ protected:
int RequestData(vtkInformation *, vtkInformationVector **,
vtkInformationVector *) VTK_OVERRIDE;
int GenerateReaders();
private:
vtkMultiProcessController *Controller;
caseType CaseType;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment