PV3FoamReader gets (single) mesh region handling

- handling multiple regions require multiple readers
  - a region is currently recognized by the file name, anything after the
    '=' delimiter (eg, "case=region.OpenFOAM") is used to determine the
    mesh region, but might be changed in the future
    eg, 'case%region', 'case^region', 'case~region', 'case{region}' ...

Note:
  - Having a separate reader for each region instead attempting to handle
    all the mesh regions in a single reader is the better solution.
    It is not only simpler, but allows distinct field selections for
    each region
Todo:
  - Haven't a test for Lagrangian and multi-regions.
This commit is contained in:
Mark Olesen
2008-08-08 23:23:06 +02:00
parent 752c8eaeba
commit 9427a34c2a
8 changed files with 155 additions and 64 deletions

View File

@ -112,10 +112,7 @@ vtkPV3FoamReader::~vtkPV3FoamReader()
{ {
vtkDebugMacro(<<"Deconstructor"); vtkDebugMacro(<<"Deconstructor");
if (foamData_) delete foamData_;
{
delete foamData_;
}
if (FileName) if (FileName)
{ {
@ -186,6 +183,16 @@ int vtkPV3FoamReader::RequestInformation
int nTimeSteps = 0; int nTimeSteps = 0;
double* timeSteps = foamData_->findTimes(nTimeSteps); double* timeSteps = foamData_->findTimes(nTimeSteps);
if (!nTimeSteps)
{
vtkErrorMacro("could not find valid OpenFOAM mesh");
// delete foamData and flag it as fatal error
delete foamData_;
foamData_ = NULL;
return 0;
}
// set identical time steps for all ports // set identical time steps for all ports
for (int infoI = 0; infoI < nInfo; ++infoI) for (int infoI = 0; infoI < nInfo; ++infoI)
{ {
@ -248,6 +255,13 @@ int vtkPV3FoamReader::RequestData
return 0; return 0;
} }
// catch previous error
if (!foamData_)
{
vtkErrorMacro("Reader failed - perhaps no mesh?");
return 0;
}
int nInfo = outputVector->GetNumberOfInformationObjects(); int nInfo = outputVector->GetNumberOfInformationObjects();
if (Foam::vtkPV3Foam::debug) if (Foam::vtkPV3Foam::debug)
@ -262,6 +276,7 @@ int vtkPV3FoamReader::RequestData
// take port0 as the lead for other outputs // take port0 as the lead for other outputs
vtkInformation *outInfo = outputVector->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
( (
outInfo->Get outInfo->Get

View File

@ -204,7 +204,8 @@ Foam::vtkPV3Foam::vtkPV3Foam
reader_(reader), reader_(reader),
dbPtr_(NULL), dbPtr_(NULL),
meshPtr_(NULL), meshPtr_(NULL),
nMesh_(0), meshRegion_(polyMesh::defaultRegion),
meshDir_(polyMesh::meshSubDir),
timeIndex_(-1), timeIndex_(-1),
meshChanged_(true), meshChanged_(true),
fieldsChanged_(true), fieldsChanged_(true),
@ -246,10 +247,33 @@ Foam::vtkPV3Foam::vtkPV3Foam
setEnv("FOAM_CASE", fullCasePath, true); setEnv("FOAM_CASE", fullCasePath, true);
} }
// get the caseName, and look for '=regionName' in it
// we could also be more stringent and insist that the
// prefix match the directory name, etc ..
fileName caseName(fileName(FileName).lessExt());
string::size_type delimiter = caseName.find("=");
if (delimiter != string::npos)
{
meshRegion_ = caseName.substr(delimiter+1);
// some safety
if (!meshRegion_.size())
{
meshRegion_ = polyMesh::defaultRegion;
}
if (meshRegion_ != polyMesh::defaultRegion)
{
meshDir_ = meshRegion_/polyMesh::meshSubDir;
}
}
if (debug) if (debug)
{ {
Info<< "fullCasePath=" << fullCasePath << nl Info<< "fullCasePath=" << fullCasePath << nl
<< "FOAM_CASE=" << getEnv("FOAM_CASE") << endl; << "FOAM_CASE=" << getEnv("FOAM_CASE") << nl
<< "region=" << meshRegion_ << endl;
} }
// Create time object // Create time object
@ -366,15 +390,20 @@ void Foam::vtkPV3Foam::updateFoamMesh()
{ {
if (debug) if (debug)
{ {
Info<< "Creating Foam mesh" << endl; Info<< "Creating Foam mesh for region " << meshRegion_
<< " at time=" << dbPtr_().timeName()
<< endl;
} }
meshPtr_ = new fvMesh meshPtr_ = new fvMesh
( (
IOobject IOobject
( (
fvMesh::defaultRegion, meshRegion_,
dbPtr_().timeName(), dbPtr_().timeName(),
dbPtr_() dbPtr_(),
IOobject::MUST_READ
) )
); );
@ -476,11 +505,26 @@ double* Foam::vtkPV3Foam::findTimes(int& nTimeSteps)
Time& runTime = dbPtr_(); Time& runTime = dbPtr_();
instantList timeLst = runTime.times(); instantList timeLst = runTime.times();
// always skip "constant" time, unless there are no other times // find the first time for which this mesh appears to exist
nTimes = timeLst.size();
label timeI = 0; label timeI = 0;
for (; timeI < timeLst.size(); ++timeI)
{
const word& timeName = timeLst[timeI].name();
if (nTimes > 1) if
(
file(runTime.path()/timeName/meshDir_/"points")
&& IOobject("points", timeName, meshDir_, runTime).headerOk()
)
{
break;
}
}
nTimes = timeLst.size() - timeI;
// always skip "constant" time if possible
if (timeI == 0 && nTimes > 1)
{ {
timeI = 1; timeI = 1;
--nTimes; --nTimes;
@ -697,7 +741,6 @@ void Foam::vtkPV3Foam::removePatchNames(vtkRenderer* renderer)
void Foam::vtkPV3Foam::PrintSelf(ostream& os, vtkIndent indent) const void Foam::vtkPV3Foam::PrintSelf(ostream& os, vtkIndent indent) const
{ {
os << indent << "Number of meshes: " << nMesh_ << "\n";
os << indent << "Number of nodes: " os << indent << "Number of nodes: "
<< (meshPtr_ ? meshPtr_->nPoints() : 0) << "\n"; << (meshPtr_ ? meshPtr_->nPoints() : 0) << "\n";
@ -706,6 +749,8 @@ void Foam::vtkPV3Foam::PrintSelf(ostream& os, vtkIndent indent) const
os << indent << "Number of available time steps: " os << indent << "Number of available time steps: "
<< (dbPtr_.valid() ? dbPtr_().times().size() : 0) << endl; << (dbPtr_.valid() ? dbPtr_().times().size() : 0) << endl;
os << indent << "mesh region: " << meshRegion_ << "\n";
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -92,11 +92,8 @@ class polyPatch;
class faceSet; class faceSet;
class pointSet; class pointSet;
template<class Type> template<class Type> class IOField;
class IOField; template<class Type> class List;
template<class Type>
class List;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class vtkPV3Foam Declaration Class vtkPV3Foam Declaration
@ -248,9 +245,11 @@ class vtkPV3Foam
//- Foam mesh //- Foam mesh
fvMesh* meshPtr_; fvMesh* meshPtr_;
//- Number of meshes //- The mesh region
// TODO - for info only - only set up to process ONE mesh word meshRegion_;
int nMesh_;
//- The mesh directory for the region
fileName meshDir_;
//- The time index //- The time index
int timeIndex_; int timeIndex_;

View File

@ -72,6 +72,8 @@ void Foam::vtkPV3Foam::convertVolFields
vtkMultiBlockDataSet* output vtkMultiBlockDataSet* output
) )
{ {
const fvMesh& mesh = *meshPtr_;
wordHashSet selectedFields = getSelected wordHashSet selectedFields = getSelected
( (
reader_->GetVolFieldSelection() reader_->GetVolFieldSelection()
@ -82,8 +84,8 @@ void Foam::vtkPV3Foam::convertVolFields
return; return;
} }
const fvMesh& mesh = *meshPtr_;
// Get objects (fields) for this time - only keep selected fields // Get objects (fields) for this time - only keep selected fields
// the region name is already in the mesh db
IOobjectList objects(mesh, dbPtr_().timeName()); IOobjectList objects(mesh, dbPtr_().timeName());
pruneObjectList(objects, selectedFields); pruneObjectList(objects, selectedFields);
@ -158,6 +160,8 @@ void Foam::vtkPV3Foam::convertPointFields
vtkMultiBlockDataSet* output vtkMultiBlockDataSet* output
) )
{ {
const fvMesh& mesh = *meshPtr_;
wordHashSet selectedFields = getSelected wordHashSet selectedFields = getSelected
( (
reader_->GetPointFieldSelection() reader_->GetPointFieldSelection()
@ -168,8 +172,8 @@ void Foam::vtkPV3Foam::convertPointFields
return; return;
} }
const fvMesh& mesh = *meshPtr_;
// Get objects (fields) for this time - only keep selected fields // Get objects (fields) for this time - only keep selected fields
// the region name is already in the mesh db
IOobjectList objects(mesh, dbPtr_().timeName()); IOobjectList objects(mesh, dbPtr_().timeName());
pruneObjectList(objects, selectedFields); pruneObjectList(objects, selectedFields);
@ -257,8 +261,10 @@ void Foam::vtkPV3Foam::convertLagrangianFields
continue; continue;
} }
// Get the Lagrangian fields for this time and this cloud // Get the Lagrangian fields for this time and this cloud
// but only keep selected fields // but only keep selected fields
// the region name is already in the mesh db
IOobjectList objects IOobjectList objects
( (
mesh, mesh,

View File

@ -64,7 +64,7 @@ void Foam::vtkPV3Foam::convertMeshVolume
} }
// Convert the internalMesh // Convert the internalMesh
// TODO: multiple mesh regions // this looks like more than one part, but it isn't
for (int partId = selector.start(); partId < selector.end(); ++partId) for (int partId = selector.start(); partId < selector.end(); ++partId)
{ {
const word partName = "internalMesh"; const word partName = "internalMesh";
@ -239,7 +239,6 @@ void Foam::vtkPV3Foam::convertMeshCellZones
} }
const cellZoneMesh& zMesh = mesh.cellZones(); const cellZoneMesh& zMesh = mesh.cellZones();
for (int partId = selector.start(); partId < selector.end(); ++partId) for (int partId = selector.start(); partId < selector.end(); ++partId)
{ {
const word zoneName = getPartName(partId); const word zoneName = getPartName(partId);
@ -408,7 +407,6 @@ void Foam::vtkPV3Foam::convertMeshFaceZones
} }
const faceZoneMesh& zMesh = mesh.faceZones(); const faceZoneMesh& zMesh = mesh.faceZones();
for (int partId = selector.start(); partId < selector.end(); ++partId) for (int partId = selector.start(); partId < selector.end(); ++partId)
{ {
const word zoneName = getPartName(partId); const word zoneName = getPartName(partId);
@ -515,6 +513,7 @@ void Foam::vtkPV3Foam::convertMeshPointZones
partInfo& selector = partInfoPointZones_; partInfo& selector = partInfoPointZones_;
selector.block(blockNo); // set output block selector.block(blockNo); // set output block
label datasetNo = 0; // restart at dataset 0 label datasetNo = 0; // restart at dataset 0
const fvMesh& mesh = *meshPtr_;
if (debug) if (debug)
{ {
@ -522,12 +521,9 @@ void Foam::vtkPV3Foam::convertMeshPointZones
printMemory(); printMemory();
} }
const fvMesh& mesh = *meshPtr_;
if (selector.size()) if (selector.size())
{ {
const pointZoneMesh& zMesh = mesh.pointZones(); const pointZoneMesh& zMesh = mesh.pointZones();
for (int partId = selector.start(); partId < selector.end(); ++partId) for (int partId = selector.start(); partId < selector.end(); ++partId)
{ {
word zoneName = getPartName(partId); word zoneName = getPartName(partId);

View File

@ -57,6 +57,8 @@ vtkPolyData* Foam::vtkPV3Foam::lagrangianVTKMesh
printMemory(); printMemory();
} }
// the region name is already in the mesh db
IOobjectList sprayObjs IOobjectList sprayObjs
( (
mesh, mesh,

View File

@ -91,11 +91,11 @@ Foam::wordList Foam::vtkPV3Foam::readZoneNames(const word& zoneType)
zoneType, zoneType,
dbPtr_().findInstance dbPtr_().findInstance
( (
polyMesh::meshSubDir, meshDir_,
zoneType, zoneType,
IOobject::READ_IF_PRESENT IOobject::READ_IF_PRESENT
), ),
polyMesh::meshSubDir, meshDir_,
dbPtr_(), dbPtr_(),
IOobject::READ_IF_PRESENT, IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE, IOobject::NO_WRITE,
@ -126,10 +126,6 @@ void Foam::vtkPV3Foam::updateInfoInternalMesh()
vtkDataArraySelection* partSelection = reader_->GetPartSelection(); vtkDataArraySelection* partSelection = reader_->GetPartSelection();
// Determine number of meshes available
HashTable<const fvMesh*> meshObjects = dbPtr_().lookupClass<const fvMesh>();
nMesh_ = meshObjects.size();
// Determine mesh parts (internalMesh, patches...) // Determine mesh parts (internalMesh, patches...)
//- Add internal mesh as first entry //- Add internal mesh as first entry
partInfoVolume_ = partSelection->GetNumberOfArrays(); partInfoVolume_ = partSelection->GetNumberOfArrays();
@ -155,10 +151,19 @@ void Foam::vtkPV3Foam::updateInfoLagrangian()
<< " " << dbPtr_->timePath()/"lagrangian" << endl; << " " << dbPtr_->timePath()/"lagrangian" << endl;
} }
// use the db directly since this might be called without a mesh,
// but the region must get added back in
fileName lagrangianPrefix("lagrangian");
if (meshRegion_ != polyMesh::defaultRegion)
{
lagrangianPrefix = meshRegion_/"lagrangian";
}
// Search for list of lagrangian objects for this time // Search for list of lagrangian objects for this time
fileNameList cloudDirs fileNameList cloudDirs
( (
readDir(dbPtr_->timePath()/"lagrangian", fileName::DIRECTORY) readDir(dbPtr_->timePath()/lagrangianPrefix, fileName::DIRECTORY)
); );
vtkDataArraySelection* partSelection = reader_->GetPartSelection(); vtkDataArraySelection* partSelection = reader_->GetPartSelection();
@ -221,43 +226,50 @@ void Foam::vtkPV3Foam::updateInfoPatches()
} }
else else
{ {
// Read patches // mesh not loaded - read from file
polyBoundaryMeshEntries patchEntries // but this could fail if we've supplied a bad region name
IOobject ioObj
( (
IOobject "boundary",
dbPtr_().findInstance
( (
meshDir_,
"boundary", "boundary",
dbPtr_().findInstance(polyMesh::meshSubDir, "boundary"), IOobject::READ_IF_PRESENT
polyMesh::meshSubDir, ),
dbPtr_(), meshDir_,
IOobject::MUST_READ, dbPtr_(),
IOobject::NO_WRITE, IOobject::READ_IF_PRESENT,
false IOobject::NO_WRITE,
) false
); );
// Add (non-zero) patches to the list of mesh parts // this should only ever fail if the mesh region doesn't exist
forAll(patchEntries, entryI) if (ioObj.headerOk())
{ {
label nFaces polyBoundaryMeshEntries patchEntries(ioObj);
(
readLabel(patchEntries[entryI].dict().lookup("nFaces"))
);
// Valid patch if nFace > 0 // Add (non-zero) patches to the list of mesh parts
if (nFaces) forAll(patchEntries, entryI)
{ {
// Add patch to GUI list label nFaces
partSelection->AddArray
( (
(patchEntries[entryI].keyword() + " - patch").c_str() readLabel(patchEntries[entryI].dict().lookup("nFaces"))
); );
++nPatches; // Valid patch if nFace > 0 - add patch to GUI list
if (nFaces)
{
partSelection->AddArray
(
(patchEntries[entryI].keyword() + " - patch").c_str()
);
++nPatches;
}
} }
} }
} }
partInfoPatches_ += nPatches; partInfoPatches_ += nPatches;
if (debug) if (debug)
@ -380,8 +392,8 @@ void Foam::vtkPV3Foam::updateInfoSets()
IOobjectList objects IOobjectList objects
( (
dbPtr_(), dbPtr_(),
dbPtr_().findInstance(polyMesh::meshSubDir, "faces"), dbPtr_().findInstance(meshDir_, "faces", IOobject::READ_IF_PRESENT),
polyMesh::meshSubDir/"sets" meshDir_/"sets"
); );
@ -449,11 +461,19 @@ void Foam::vtkPV3Foam::updateInfoLagrangianFields()
word cloudName = getPartName(partId); word cloudName = getPartName(partId);
// use the db directly since this might be called without a mesh,
// but the region must get added back in
fileName lagrangianPrefix("lagrangian");
if (meshRegion_ != polyMesh::defaultRegion)
{
lagrangianPrefix = meshRegion_/"lagrangian";
}
IOobjectList objects IOobjectList objects
( (
dbPtr_(), dbPtr_(),
dbPtr_().timeName(), dbPtr_().timeName(),
"lagrangian"/cloudName lagrangianPrefix/cloudName
); );
addToSelection<IOField<label> > addToSelection<IOField<label> >

View File

@ -59,8 +59,16 @@ void Foam::vtkPV3Foam::updateInfoFields
select->RemoveAllArrays(); select->RemoveAllArrays();
// Search for list of objects for this time // use the db directly since this might be called without a mesh,
IOobjectList objects(dbPtr_(), dbPtr_().timeName()); // but the region must get added back in
word regionPrefix;
if (meshRegion_ != polyMesh::defaultRegion)
{
regionPrefix = meshRegion_;
}
// Search for list of objects for this time and mesh region
IOobjectList objects(dbPtr_(), dbPtr_().timeName(), regionPrefix);
//- Add volume fields to GUI //- Add volume fields to GUI
addToSelection<GeometricField<scalar, patchType, meshType> > addToSelection<GeometricField<scalar, patchType, meshType> >