Commit fa0b0343 authored by Mark Olesen's avatar Mark Olesen
Browse files

PV3FoamReader - neater multiblocks and dual output ports

  - normal mesh data on port0
  - Lagrangian data on port1
  - no fixed block numbers for dividing internalMesh, patches, zones etc.
    This helps avoid ugly gaps in the multiblock output
  - avoid segfault if Lagrangian fields are converted without positions

  TODO:
  - can we label the output ports?
  - the selection of Lagrangian data and fields is wonky.
parent 5d715694
......@@ -36,6 +36,7 @@
vtkCxxRevisionMacro(vtkPV3FoamReader, "$Revision: 1.5$");
vtkStandardNewMacro(vtkPV3FoamReader);
#undef EXPERIMENTAL_TIME_CACHING
vtkPV3FoamReader::vtkPV3FoamReader()
{
......@@ -47,7 +48,16 @@ vtkPV3FoamReader::vtkPV3FoamReader()
FileName = NULL;
foamData_ = NULL;
output1_ = NULL;
output0_ = NULL;
// Add second output for the Lagrangian
this->SetNumberOfOutputPorts(2);
vtkMultiBlockDataSet *lagrangian;
lagrangian = vtkMultiBlockDataSet::New();
lagrangian->ReleaseData();
this->GetExecutive()->SetOutputData(1, lagrangian);
lagrangian->Delete();
TimeStep = 0;
TimeStepRange[0] = 0;
......@@ -60,8 +70,7 @@ vtkPV3FoamReader::vtkPV3FoamReader()
IncludeZones = 0;
ShowPatchNames = 0;
UpdateGUI = 1;
UpdateGUIOld = 1;
UpdateGUI = 0;
RegionSelection = vtkDataArraySelection::New();
VolFieldSelection = vtkDataArraySelection::New();
......@@ -114,6 +123,12 @@ vtkPV3FoamReader::~vtkPV3FoamReader()
delete [] FileName;
}
if (output0_)
{
output0_->Delete();
}
RegionSelection->RemoveObserver(this->SelectionObserver);
VolFieldSelection->RemoveObserver(this->SelectionObserver);
PointFieldSelection->RemoveObserver(this->SelectionObserver);
......@@ -149,22 +164,19 @@ int vtkPV3FoamReader::RequestInformation
return 0;
}
vtkInformation *outInfo = outputVector->GetInformationObject(0);
int nInfo = outputVector->GetNumberOfInformationObjects();
if (!foamData_)
if (Foam::vtkPV3Foam::debug)
{
vtkDebugMacro("RequestInformation: creating foamData_");
vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
(
outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT())
);
if (Foam::vtkPV3Foam::debug)
cout<<"RequestInformation with " << nInfo << " item(s)\n";
for (int infoI = 0; infoI < nInfo; ++infoI)
{
cout<< "constructed vtkPV3Foam with output: ";
output->Print(cout);
outputVector->GetInformationObject(infoI)->Print(cout);
}
}
if (!foamData_)
{
foamData_ = new Foam::vtkPV3Foam(FileName, this);
}
else
......@@ -175,12 +187,17 @@ int vtkPV3FoamReader::RequestInformation
int nTimeSteps = 0;
double* timeSteps = foamData_->findTimes(nTimeSteps);
outInfo->Set
(
vtkStreamingDemandDrivenPipeline::TIME_STEPS(),
timeSteps,
nTimeSteps
);
// set identical time steps for all ports
for (int infoI = 0; infoI < nInfo; ++infoI)
{
outputVector->GetInformationObject(infoI)->Set
(
vtkStreamingDemandDrivenPipeline::TIME_STEPS(),
timeSteps,
nTimeSteps
);
}
double timeRange[2];
if (nTimeSteps)
......@@ -190,21 +207,25 @@ int vtkPV3FoamReader::RequestInformation
if (Foam::vtkPV3Foam::debug > 1)
{
cout<<"nTimeSteps " << nTimeSteps << "\n";
cout<<"timeRange " << timeRange[0] << " to " << timeRange[1] << "\n";
cout<<"nTimeSteps " << nTimeSteps << "\n"
<<"timeRange " << timeRange[0] << " to " << timeRange[1]
<< "\n";
for (int i = 0; i < nTimeSteps; ++i)
for (int timeI = 0; timeI < nTimeSteps; ++timeI)
{
cout<< "step[" << i << "] = " << timeSteps[i] << "\n";
cout<< "step[" << timeI << "] = " << timeSteps[timeI] << "\n";
}
}
outInfo->Set
(
vtkStreamingDemandDrivenPipeline::TIME_RANGE(),
timeRange,
2
);
for (int infoI = 0; infoI < nInfo; ++infoI)
{
outputVector->GetInformationObject(infoI)->Set
(
vtkStreamingDemandDrivenPipeline::TIME_RANGE(),
timeRange,
2
);
}
}
delete timeSteps;
......@@ -229,75 +250,41 @@ int vtkPV3FoamReader::RequestData
return 0;
}
int nInfo = outputVector->GetNumberOfInformationObjects();
if (Foam::vtkPV3Foam::debug)
{
int nInfo = outputVector->GetNumberOfInformationObjects();
cout<<"requestData with " << nInfo << " items\n";
for (int i = 0; i < nInfo; ++i)
cout<<"RequestData with " << nInfo << " item(s)\n";
for (int infoI = 0; infoI < nInfo; ++infoI)
{
vtkInformation *info = outputVector->GetInformationObject(i);
info->Print(cout);
outputVector->GetInformationObject(infoI)->Print(cout);
}
}
vtkInformation* outInfo = outputVector->GetInformationObject(0);
// take port0 as the lead for other outputs
vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
(
outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT())
);
if (Foam::vtkPV3Foam::debug)
{
vtkInformation* outputInfo = this->GetOutputPortInformation(0);
outputInfo->Print(cout);
vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
outInfo->Get
(
outputInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT())
);
if (output)
{
output->Print(cout);
}
else
{
cout<< "no output\n";
}
vtkInformation* execInfo = this->GetExecutive()->GetOutputInformation(0);
execInfo->Print(cout);
vtkMultiBlockDataSet::DATA_OBJECT()
)
);
outInfo->Print(cout);
vtkMultiBlockDataSet* dobj = vtkMultiBlockDataSet::SafeDownCast
vtkMultiBlockDataSet* lagrangianOutput = vtkMultiBlockDataSet::SafeDownCast
(
outputVector->GetInformationObject(1)->Get
(
outInfo->Get(vtkMultiBlockDataSet::DATA_OBJECT())
);
if (dobj)
{
dobj->Print(cout);
vtkInformation* dobjInfo = dobj->GetInformation();
dobjInfo->Print(cout);
}
else
{
cout<< "no data_object\n";
}
}
vtkMultiBlockDataSet::DATA_OBJECT()
)
);
if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()))
{
if (Foam::vtkPV3Foam::debug)
{
cout<<"Has UPDATE_TIME_STEPS\n";
cout<<"output->GetNumberOfBlocks() = "
<< output->GetNumberOfBlocks() << "\n";
}
// Get the requested time step.
// We only supprt requests of a single time step
// We only support requests for a single time step
int nRequestedTimeSteps = outInfo->Length
(
vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()
......@@ -313,24 +300,56 @@ int vtkPV3FoamReader::RequestData
}
}
if
(
(UpdateGUIOld == GetUpdateGUI())
|| (output->GetNumberOfBlocks() == 0)
)
if (Foam::vtkPV3Foam::debug)
{
cout<< "update output with "
<< output->GetNumberOfBlocks() << " blocks\n";
}
#ifdef EXPERIMENTAL_TIME_CACHING
bool needsUpdate = false;
if (!output0_)
{
output0_ = vtkMultiBlockDataSet::New();
needsUpdate = true;
}
// This experimental bit of code seems to work for the geometry,
// but trashes the fields and still triggers the GeometryFilter
if (needsUpdate)
{
foamData_->Update(output);
output0_->ShallowCopy(output);
}
else
{
output->ShallowCopy(output0_);
}
if (ShowPatchNames == 1)
if (Foam::vtkPV3Foam::debug)
{
if (needsUpdate)
{
addPatchNamesToView();
cout<< "full UPDATE ---------\n";
}
else
{
removePatchNamesFromView();
cout<< "cached UPDATE ---------\n";
}
cout<< "UPDATED output: ";
output->Print(cout);
cout<< "UPDATED output0_: ";
output0_->Print(cout);
}
UpdateGUIOld = GetUpdateGUI();
#else
foamData_->Update(output, lagrangianOutput);
#endif
return 1;
}
......@@ -597,4 +616,19 @@ void vtkPV3FoamReader::SelectionModified()
Modified();
}
int vtkPV3FoamReader::FillOutputPortInformation
(
int port,
vtkInformation* info
)
{
if (port == 0)
{
return this->Superclass::FillOutputPortInformation(port, info);
}
info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
return 1;
}
// ************************************************************************* //
......@@ -157,11 +157,12 @@ protected:
vtkInformationVector*
);
virtual int FillOutputPortInformation(int, vtkInformation*);
// The observer to modify this object when the array selections
// are modified
vtkCallbackCommand* SelectionObserver;
private:
vtkPV3FoamReader(const vtkPV3FoamReader&); // Not implemented.
......@@ -183,16 +184,16 @@ private:
int IncludeZones;
int ShowPatchNames;
//- Dummy variable/switch for provoking a reader update
int UpdateGUI;
int UpdateGUIOld;
vtkDataArraySelection* RegionSelection;
vtkDataArraySelection* VolFieldSelection;
vtkDataArraySelection* PointFieldSelection;
vtkDataArraySelection* LagrangianFieldSelection;
//- Access to the output port1
vtkMultiBlockDataSet* output1_;
//- Cached data for output port0
vtkMultiBlockDataSet* output0_;
//BTX
Foam::vtkPV3Foam* foamData_;
......
......@@ -4,8 +4,8 @@ vtkPV3FoamAddLagrangianMesh.C
vtkPV3FoamAddPatchMesh.C
vtkPV3FoamAddZoneMesh.C
vtkPV3FoamAddSetMesh.C
vtkPV3FoamUpdate.C
vtkPV3FoamUpdateInformation.C
vtkPV3FoamConvertMesh.C
vtkPV3FoamConvertFields.C
LIB = $(FOAM_LIBBIN)/libvtkPV3Foam
......@@ -213,6 +213,8 @@ bool Foam::vtkPV3Foam::setTime(const double& requestedTime)
if (meshPtr_->readUpdate() != polyMesh::UNCHANGED)
{
meshChanged_ = true;
reader_->UpdateProgress(0.05);
// patches, zones etc might have changed
UpdateInformation();
}
......@@ -464,15 +466,15 @@ Foam::vtkPV3Foam::vtkPV3Foam
reader_(reader),
dbPtr_(NULL),
meshPtr_(NULL),
selectInfoVolume_(VOLUME, "unzoned"),
selectInfoPatches_(PATCHES, "patches"),
selectInfoLagrangian_(LAGRANGIAN, "lagrangian"),
selectInfoCellZones_(CELLZONE, "cellZone"),
selectInfoFaceZones_(FACEZONE, "faceZone"),
selectInfoPointZones_(POINTZONE, "pointZone"),
selectInfoCellSets_(CELLSET, "cellSet"),
selectInfoFaceSets_(FACESET, "faceSet"),
selectInfoPointSets_(POINTSET, "pointSet"),
selectInfoVolume_("unzoned"),
selectInfoPatches_("patches"),
selectInfoLagrangian_("lagrangian"),
selectInfoCellZones_("cellZone"),
selectInfoFaceZones_("faceZone"),
selectInfoPointZones_("pointZone"),
selectInfoCellSets_("cellSet"),
selectInfoFaceSets_("faceSet"),
selectInfoPointSets_("pointSet"),
patchTextActorsPtrs_(0),
nMesh_(0),
timeIndex_(-1),
......@@ -543,11 +545,7 @@ Foam::vtkPV3Foam::~vtkPV3Foam()
Info<< "<end> Foam::vtkPV3Foam::~vtkPV3Foam" << endl;
}
if (meshPtr_)
{
delete meshPtr_;
meshPtr_ = NULL;
}
delete meshPtr_;
}
......@@ -575,10 +573,11 @@ void Foam::vtkPV3Foam::UpdateInformation()
}
else
{
// preserve the currently selected values
// preserve the enabled selections
selectedEntries = getSelectedArrayEntries
(
arraySelection
arraySelection,
false
);
}
......@@ -600,7 +599,7 @@ void Foam::vtkPV3Foam::UpdateInformation()
updateInformationZones();
}
// restore the currently enabled values
// restore the enabled selections
setSelectedArrayEntries
(
arraySelection,
......@@ -635,23 +634,72 @@ void Foam::vtkPV3Foam::UpdateInformation()
}
void Foam::vtkPV3Foam::updateFoamMesh()
{
if (debug)
{
Info<< "<beg> Foam::vtkPV3Foam::updateFoamMesh" << endl;
printMemory();
}
if (!reader_->GetCacheMesh())
{
delete meshPtr_;
meshPtr_ = NULL;
}
// Check to see if the FOAM mesh has been created
if (!meshPtr_)
{
if (debug)
{
Info<< "Creating Foam mesh" << endl;
}
meshPtr_ = new fvMesh
(
IOobject
(
fvMesh::defaultRegion,
dbPtr_().timeName(),
dbPtr_()
)
);
meshChanged_ = true;
}
else
{
if (debug)
{
Info<< "Using existing Foam mesh" << endl;
}
}
if (debug)
{
Info<< "<end> Foam::vtkPV3Foam::updateFoamMesh" << endl;
printMemory();
}
}
void Foam::vtkPV3Foam::Update
(
vtkMultiBlockDataSet* output
vtkMultiBlockDataSet* output,
vtkMultiBlockDataSet* lagrangianOutput
)
{
if (debug)
{
cout<< "<beg> Foam::vtkPV3Foam::Update" << nl
<<"Update\n";
output->Print(cout);
cout<< "<beg> Foam::vtkPV3Foam::Update - output with "
<< output->GetNumberOfBlocks() << " and "
<< lagrangianOutput->GetNumberOfBlocks() << " blocks\n";
cout<<"Internally:\n";
output->Print(cout);
cout<< " has " << output->GetNumberOfBlocks() << " blocks\n";
lagrangianOutput->Print(cout);
printMemory();
}
reader_->UpdateProgress(0.1);
// Set up region selection(s)
updateSelectedRegions();
......@@ -661,65 +709,37 @@ void Foam::vtkPV3Foam::Update
reader_->UpdateProgress(0.2);
// Convert meshes
convertMeshVolume(output);
convertMeshLagrangian(output);
convertMeshPatches(output);
int blockNo = 0;
convertMeshVolume(output, blockNo);
convertMeshPatches(output, blockNo);
reader_->UpdateProgress(0.4);
if (reader_->GetIncludeZones())
{
convertMeshCellZones(output);
convertMeshFaceZones(output);
convertMeshPointZones(output);
convertMeshCellZones(output, blockNo);
convertMeshFaceZones(output, blockNo);
convertMeshPointZones(output, blockNo);
}
if (reader_->GetIncludeSets())
{
convertMeshCellSets(output);
convertMeshFaceSets(output);
convertMeshPointSets(output);
convertMeshCellSets(output, blockNo);
convertMeshFaceSets(output, blockNo);
convertMeshPointSets(output, blockNo);
}
blockNo = 0;
convertMeshLagrangian(lagrangianOutput, blockNo);
reader_->UpdateProgress(0.8);
// Update fields
updateVolFields(output);
updatePointFields(output);
updateLagrangianFields(output);
convertVolFields(output);
convertPointFields(output);
convertLagrangianFields(lagrangianOutput);
reader_->UpdateProgress(1.0);
if (debug)
{
Info<< "Number of data sets after update" << nl
<< " VOLUME = "
<< GetNumberOfDataSets(output, selectInfoVolume_) << nl
<< " PATCHES = "
<< GetNumberOfDataSets(output, selectInfoPatches_) << nl
<< " LAGRANGIAN = "
<< GetNumberOfDataSets(output, selectInfoLagrangian_) << nl
<< " CELLZONE = "
<< GetNumberOfDataSets(output, selectInfoCellZones_) << nl
<< " FACEZONE = "
<< GetNumberOfDataSets(output, selectInfoFaceZones_) << nl
<< " POINTZONE = "
<< GetNumberOfDataSets(output, selectInfoPointZones_) << nl
<< " CELLSET = "
<< GetNumberOfDataSets(output, selectInfoCellSets_) << nl
<< " FACESET = "
<< GetNumberOfDataSets(output, selectInfoFaceSets_) << nl
<< " POINTSET = "
<< GetNumberOfDataSets(output, selectInfoPointSets_) << nl;
// traverse blocks:
cout<< "nBlocks = " << output->GetNumberOfBlocks() << "\n";