mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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:
@ -112,10 +112,7 @@ vtkPV3FoamReader::~vtkPV3FoamReader()
|
||||
{
|
||||
vtkDebugMacro(<<"Deconstructor");
|
||||
|
||||
if (foamData_)
|
||||
{
|
||||
delete foamData_;
|
||||
}
|
||||
delete foamData_;
|
||||
|
||||
if (FileName)
|
||||
{
|
||||
@ -186,6 +183,16 @@ int vtkPV3FoamReader::RequestInformation
|
||||
int nTimeSteps = 0;
|
||||
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
|
||||
for (int infoI = 0; infoI < nInfo; ++infoI)
|
||||
{
|
||||
@ -248,6 +255,13 @@ int vtkPV3FoamReader::RequestData
|
||||
return 0;
|
||||
}
|
||||
|
||||
// catch previous error
|
||||
if (!foamData_)
|
||||
{
|
||||
vtkErrorMacro("Reader failed - perhaps no mesh?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nInfo = outputVector->GetNumberOfInformationObjects();
|
||||
|
||||
if (Foam::vtkPV3Foam::debug)
|
||||
@ -262,6 +276,7 @@ int vtkPV3FoamReader::RequestData
|
||||
// take port0 as the lead for other outputs
|
||||
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
||||
|
||||
|
||||
vtkMultiBlockDataSet* output = vtkMultiBlockDataSet::SafeDownCast
|
||||
(
|
||||
outInfo->Get
|
||||
|
||||
@ -204,7 +204,8 @@ Foam::vtkPV3Foam::vtkPV3Foam
|
||||
reader_(reader),
|
||||
dbPtr_(NULL),
|
||||
meshPtr_(NULL),
|
||||
nMesh_(0),
|
||||
meshRegion_(polyMesh::defaultRegion),
|
||||
meshDir_(polyMesh::meshSubDir),
|
||||
timeIndex_(-1),
|
||||
meshChanged_(true),
|
||||
fieldsChanged_(true),
|
||||
@ -246,10 +247,33 @@ Foam::vtkPV3Foam::vtkPV3Foam
|
||||
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)
|
||||
{
|
||||
Info<< "fullCasePath=" << fullCasePath << nl
|
||||
<< "FOAM_CASE=" << getEnv("FOAM_CASE") << endl;
|
||||
<< "FOAM_CASE=" << getEnv("FOAM_CASE") << nl
|
||||
<< "region=" << meshRegion_ << endl;
|
||||
}
|
||||
|
||||
// Create time object
|
||||
@ -366,15 +390,20 @@ void Foam::vtkPV3Foam::updateFoamMesh()
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Creating Foam mesh" << endl;
|
||||
Info<< "Creating Foam mesh for region " << meshRegion_
|
||||
<< " at time=" << dbPtr_().timeName()
|
||||
<< endl;
|
||||
|
||||
}
|
||||
|
||||
meshPtr_ = new fvMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fvMesh::defaultRegion,
|
||||
meshRegion_,
|
||||
dbPtr_().timeName(),
|
||||
dbPtr_()
|
||||
dbPtr_(),
|
||||
IOobject::MUST_READ
|
||||
)
|
||||
);
|
||||
|
||||
@ -476,11 +505,26 @@ double* Foam::vtkPV3Foam::findTimes(int& nTimeSteps)
|
||||
Time& runTime = dbPtr_();
|
||||
instantList timeLst = runTime.times();
|
||||
|
||||
// always skip "constant" time, unless there are no other times
|
||||
nTimes = timeLst.size();
|
||||
// find the first time for which this mesh appears to exist
|
||||
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;
|
||||
--nTimes;
|
||||
@ -697,7 +741,6 @@ void Foam::vtkPV3Foam::removePatchNames(vtkRenderer* renderer)
|
||||
|
||||
void Foam::vtkPV3Foam::PrintSelf(ostream& os, vtkIndent indent) const
|
||||
{
|
||||
os << indent << "Number of meshes: " << nMesh_ << "\n";
|
||||
os << indent << "Number of nodes: "
|
||||
<< (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: "
|
||||
<< (dbPtr_.valid() ? dbPtr_().times().size() : 0) << endl;
|
||||
|
||||
os << indent << "mesh region: " << meshRegion_ << "\n";
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -92,11 +92,8 @@ class polyPatch;
|
||||
class faceSet;
|
||||
class pointSet;
|
||||
|
||||
template<class Type>
|
||||
class IOField;
|
||||
|
||||
template<class Type>
|
||||
class List;
|
||||
template<class Type> class IOField;
|
||||
template<class Type> class List;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class vtkPV3Foam Declaration
|
||||
@ -248,9 +245,11 @@ class vtkPV3Foam
|
||||
//- Foam mesh
|
||||
fvMesh* meshPtr_;
|
||||
|
||||
//- Number of meshes
|
||||
// TODO - for info only - only set up to process ONE mesh
|
||||
int nMesh_;
|
||||
//- The mesh region
|
||||
word meshRegion_;
|
||||
|
||||
//- The mesh directory for the region
|
||||
fileName meshDir_;
|
||||
|
||||
//- The time index
|
||||
int timeIndex_;
|
||||
|
||||
@ -72,6 +72,8 @@ void Foam::vtkPV3Foam::convertVolFields
|
||||
vtkMultiBlockDataSet* output
|
||||
)
|
||||
{
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
wordHashSet selectedFields = getSelected
|
||||
(
|
||||
reader_->GetVolFieldSelection()
|
||||
@ -82,8 +84,8 @@ void Foam::vtkPV3Foam::convertVolFields
|
||||
return;
|
||||
}
|
||||
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
// Get objects (fields) for this time - only keep selected fields
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList objects(mesh, dbPtr_().timeName());
|
||||
pruneObjectList(objects, selectedFields);
|
||||
|
||||
@ -158,6 +160,8 @@ void Foam::vtkPV3Foam::convertPointFields
|
||||
vtkMultiBlockDataSet* output
|
||||
)
|
||||
{
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
wordHashSet selectedFields = getSelected
|
||||
(
|
||||
reader_->GetPointFieldSelection()
|
||||
@ -168,8 +172,8 @@ void Foam::vtkPV3Foam::convertPointFields
|
||||
return;
|
||||
}
|
||||
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
// Get objects (fields) for this time - only keep selected fields
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList objects(mesh, dbPtr_().timeName());
|
||||
pruneObjectList(objects, selectedFields);
|
||||
|
||||
@ -257,8 +261,10 @@ void Foam::vtkPV3Foam::convertLagrangianFields
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Get the Lagrangian fields for this time and this cloud
|
||||
// but only keep selected fields
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList objects
|
||||
(
|
||||
mesh,
|
||||
|
||||
@ -64,7 +64,7 @@ void Foam::vtkPV3Foam::convertMeshVolume
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
const word partName = "internalMesh";
|
||||
@ -239,7 +239,6 @@ void Foam::vtkPV3Foam::convertMeshCellZones
|
||||
}
|
||||
|
||||
const cellZoneMesh& zMesh = mesh.cellZones();
|
||||
|
||||
for (int partId = selector.start(); partId < selector.end(); ++partId)
|
||||
{
|
||||
const word zoneName = getPartName(partId);
|
||||
@ -408,7 +407,6 @@ void Foam::vtkPV3Foam::convertMeshFaceZones
|
||||
}
|
||||
|
||||
const faceZoneMesh& zMesh = mesh.faceZones();
|
||||
|
||||
for (int partId = selector.start(); partId < selector.end(); ++partId)
|
||||
{
|
||||
const word zoneName = getPartName(partId);
|
||||
@ -515,6 +513,7 @@ void Foam::vtkPV3Foam::convertMeshPointZones
|
||||
partInfo& selector = partInfoPointZones_;
|
||||
selector.block(blockNo); // set output block
|
||||
label datasetNo = 0; // restart at dataset 0
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -522,12 +521,9 @@ void Foam::vtkPV3Foam::convertMeshPointZones
|
||||
printMemory();
|
||||
}
|
||||
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (selector.size())
|
||||
{
|
||||
const pointZoneMesh& zMesh = mesh.pointZones();
|
||||
|
||||
for (int partId = selector.start(); partId < selector.end(); ++partId)
|
||||
{
|
||||
word zoneName = getPartName(partId);
|
||||
|
||||
@ -57,6 +57,8 @@ vtkPolyData* Foam::vtkPV3Foam::lagrangianVTKMesh
|
||||
printMemory();
|
||||
}
|
||||
|
||||
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList sprayObjs
|
||||
(
|
||||
mesh,
|
||||
|
||||
@ -91,11 +91,11 @@ Foam::wordList Foam::vtkPV3Foam::readZoneNames(const word& zoneType)
|
||||
zoneType,
|
||||
dbPtr_().findInstance
|
||||
(
|
||||
polyMesh::meshSubDir,
|
||||
meshDir_,
|
||||
zoneType,
|
||||
IOobject::READ_IF_PRESENT
|
||||
),
|
||||
polyMesh::meshSubDir,
|
||||
meshDir_,
|
||||
dbPtr_(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
@ -126,10 +126,6 @@ void Foam::vtkPV3Foam::updateInfoInternalMesh()
|
||||
|
||||
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...)
|
||||
//- Add internal mesh as first entry
|
||||
partInfoVolume_ = partSelection->GetNumberOfArrays();
|
||||
@ -155,10 +151,19 @@ void Foam::vtkPV3Foam::updateInfoLagrangian()
|
||||
<< " " << 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
|
||||
fileNameList cloudDirs
|
||||
(
|
||||
readDir(dbPtr_->timePath()/"lagrangian", fileName::DIRECTORY)
|
||||
readDir(dbPtr_->timePath()/lagrangianPrefix, fileName::DIRECTORY)
|
||||
);
|
||||
|
||||
vtkDataArraySelection* partSelection = reader_->GetPartSelection();
|
||||
@ -221,43 +226,50 @@ void Foam::vtkPV3Foam::updateInfoPatches()
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read patches
|
||||
polyBoundaryMeshEntries patchEntries
|
||||
// mesh not loaded - read from file
|
||||
// but this could fail if we've supplied a bad region name
|
||||
IOobject ioObj
|
||||
(
|
||||
IOobject
|
||||
"boundary",
|
||||
dbPtr_().findInstance
|
||||
(
|
||||
meshDir_,
|
||||
"boundary",
|
||||
dbPtr_().findInstance(polyMesh::meshSubDir, "boundary"),
|
||||
polyMesh::meshSubDir,
|
||||
dbPtr_(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
IOobject::READ_IF_PRESENT
|
||||
),
|
||||
meshDir_,
|
||||
dbPtr_(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
// Add (non-zero) patches to the list of mesh parts
|
||||
forAll(patchEntries, entryI)
|
||||
// this should only ever fail if the mesh region doesn't exist
|
||||
if (ioObj.headerOk())
|
||||
{
|
||||
label nFaces
|
||||
(
|
||||
readLabel(patchEntries[entryI].dict().lookup("nFaces"))
|
||||
);
|
||||
polyBoundaryMeshEntries patchEntries(ioObj);
|
||||
|
||||
// Valid patch if nFace > 0
|
||||
if (nFaces)
|
||||
// Add (non-zero) patches to the list of mesh parts
|
||||
forAll(patchEntries, entryI)
|
||||
{
|
||||
// Add patch to GUI list
|
||||
partSelection->AddArray
|
||||
label nFaces
|
||||
(
|
||||
(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;
|
||||
|
||||
if (debug)
|
||||
@ -380,8 +392,8 @@ void Foam::vtkPV3Foam::updateInfoSets()
|
||||
IOobjectList objects
|
||||
(
|
||||
dbPtr_(),
|
||||
dbPtr_().findInstance(polyMesh::meshSubDir, "faces"),
|
||||
polyMesh::meshSubDir/"sets"
|
||||
dbPtr_().findInstance(meshDir_, "faces", IOobject::READ_IF_PRESENT),
|
||||
meshDir_/"sets"
|
||||
);
|
||||
|
||||
|
||||
@ -449,11 +461,19 @@ void Foam::vtkPV3Foam::updateInfoLagrangianFields()
|
||||
|
||||
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
|
||||
(
|
||||
dbPtr_(),
|
||||
dbPtr_().timeName(),
|
||||
"lagrangian"/cloudName
|
||||
lagrangianPrefix/cloudName
|
||||
);
|
||||
|
||||
addToSelection<IOField<label> >
|
||||
|
||||
@ -59,8 +59,16 @@ void Foam::vtkPV3Foam::updateInfoFields
|
||||
|
||||
select->RemoveAllArrays();
|
||||
|
||||
// Search for list of objects for this time
|
||||
IOobjectList objects(dbPtr_(), dbPtr_().timeName());
|
||||
// use the db directly since this might be called without a mesh,
|
||||
// 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
|
||||
addToSelection<GeometricField<scalar, patchType, meshType> >
|
||||
|
||||
Reference in New Issue
Block a user