Commit 62aab00a authored by George Zagaris's avatar George Zagaris
Browse files

ENH:Move internal flash reader to separate header

This commit moves the internal enzo reader to a
separate header. The reason for doing this is
primarily to allow the re-use of the internal enzo
reader for the corresponding particles reader.
parent f299ef9d
......@@ -39,1764 +39,9 @@
#define H5_USE_16_API
#include <hdf5.h>
vtkStandardNewMacro(vtkAMRFlashReader);
//==============================================================================
// I N T E R N A L F L A S H R E A D E R
//==============================================================================
#define FLASH_READER_MAX_DIMS 3
#define FLASH_READER_LEAF_BLOCK 1
#define FLASH_READER_FLASH3_FFV8 8
#define FLASH_READER_FLASH3_FFV9 9
typedef struct tagFlashReaderIntegerScalar
{
char Name[20]; // name of the integer scalar
int Value; // value of the integer scalar
} FlashReaderIntegerScalar;
typedef struct tagFlashReaderDoubleScalar
{
char Name[20]; // name of the real scalar
double Value; // value of the real scalar
} FlashReaderDoubleScalar;
typedef struct tagFlashReaderSimulationParameters
{
int NumberOfBlocks; // number of all blocks
int NumberOfTimeSteps; // number of time steps
int NumberOfXDivisions; // number of divisions per block along x axis
int NumberOfYDivisions; // number of divisions per block along y axis
int NumberOfZDivisions; // number of divisions per block along z axis
double Time; // the time of this step
double TimeStep; // time interval
double RedShift;
} FlashReaderSimulationParameters;
typedef struct tagBlock
{
int Index; // Id of the block
int Level; // LOD level
int Type; // a leaf block?
int ParentId; // Id of the parent block
int ChildrenIds[8]; // Ids of the children blocks
int NeighborIds[6]; // Ids of the neighboring blocks
int ProcessorId; // Id of the processor
int MinGlobalDivisionIds[3]; // first (global) division index
int MaxGlobalDivisionIds[3]; // last (global) division index
double Center[3]; // center of the block
double MinBounds[3]; // lower left of the bounding box
double MaxBounds[3]; // upper right of the bounding box
} Block;
typedef struct tagFlashReaderSimulationInformation
{
int FileFormatVersion;
char SetupCall[400];
char FileCreationTime[80];
char FlashVersion[80];
char BuildData[80];
char BuildDirectory[80];
char build_machine[80];
char CFlags[400];
char FFlags[400];
char SetupTimeStamp[80];
char BuildTimeStamp[80];
} FlashReaderSimulationInformation;
static vtkstd::string GetSeparatedParticleName( const vtkstd::string & variable )
{
vtkstd::string sepaName = variable;
if ( sepaName.length() > 9 && sepaName.substr(0,9) == "particle_" )
{
sepaName = vtkstd::string( "Particles/" ) + sepaName.substr( 9 );
}
else
{
sepaName = vtkstd::string( "Particles/" ) + sepaName;
}
return sepaName;
}
// ----------------------------------------------------------------------------
// Class vtkFlashReaderInternal (begin)
// ----------------------------------------------------------------------------
class vtkFlashReaderInternal
{
public:
vtkFlashReaderInternal() { this->Init(); }
~vtkFlashReaderInternal() { this->Init(); }
int NumberOfBlocks; // number of ALL blocks
int NumberOfLevels; // number of levels
int FileFormatVersion; // version of file format
int NumberOfParticles; // number of particles
int NumberOfLeafBlocks; // number of leaf blocks
int NumberOfDimensions; // number of dimensions
int NumberOfProcessors; // number of processors
int HaveProcessorsInfo; // processor Ids available?
int BlockGridDimensions[3]; // number of grid points
int BlockCellDimensions[3]; // number of divisions
int NumberOfChildrenPerBlock; // number of children per block
int NumberOfNeighborsPerBlock; // number of neighbors per block
char * FileName; // Flash data file name
hid_t FileIndex; // file handle
double MinBounds[3]; // lower left of the bounding-box
double MaxBounds[3]; // upper right of the bounding box
FlashReaderSimulationParameters SimulationParameters; // CFD simulation
FlashReaderSimulationInformation SimulationInformation; // CFD simulation
// blocks
vtkstd::vector< Block > Blocks;
vtkstd::vector< int > LeafBlocks;
vtkstd::vector< vtkstd::string > AttributeNames;
// particles
vtkstd::string ParticleName;
vtkstd::vector< hid_t > ParticleAttributeTypes;
vtkstd::vector< vtkstd::string > ParticleAttributeNames;
vtkstd::map< vtkstd::string, int > ParticleAttributeNamesToIds;
int GetCycle();
double GetTime();
void Init();
void SetFileName( char * fileName ) { this->FileName = fileName; }
void ReadMetaData();
void ReadProcessorIds();
void ReadDoubleScalars( hid_t fileIndx );
void ReadIntegerScalars( hid_t fileIndx );
void ReadVersionInformation( hid_t fileIndx );
void ReadSimulationParameters
( hid_t fileIndx, bool bTmCycle = false ); // time and cycle only
void GetBlockMinMaxGlobalDivisionIds();
void ReadBlockTypes();
void ReadBlockBounds();
void ReadBlockCenters();
void ReadBlockStructures();
void ReadRefinementLevels();
void ReadDataAttributeNames();
void ReadParticlesComponent
( hid_t dataIndx, const char * compName, double * dataBuff );
void ReadParticleAttributes();
void ReadParticleAttributesFLASH3();
void GetBlockAttribute( const char *atribute, int blockIdx,
vtkDataSet *pDataSet );
};
//-----------------------------------------------------------------------------
void vtkFlashReaderInternal::GetBlockAttribute(
const char *atribute, int blockIdx, vtkDataSet *pDataSet )
{
// this function must be called by GetBlock( ... )
this->ReadMetaData();
if ( atribute == NULL || blockIdx < 0 ||
pDataSet == NULL || blockIdx >= this->NumberOfBlocks )
{
// vtkDebugMacro( "Data attribute name or vtkDataSet NULL, or " <<
// "invalid block index." << endl );
return;
}
// remove the prefix ("mesh_blockandlevel/" or "mesh_blockandproc/") to get
// the actual attribute name
vtkstd::string tempName = atribute;
size_t slashPos = tempName.find( "/" );
vtkstd::string attrName = tempName.substr ( slashPos + 1 );
hid_t dataIndx = H5Dopen
( this->FileIndex, attrName.c_str() );
if ( dataIndx < 0 )
{
// vtkErrorMacro( "Invalid attribute name." << endl );
return;
}
hid_t spaceIdx = H5Dget_space( dataIndx );
hsize_t dataDims[4]; // dataDims[0] == number of blocks
hsize_t numbDims = H5Sget_simple_extent_dims( spaceIdx, dataDims, NULL );
if ( numbDims != 4 )
{
// vtkErrorMacro( "Error with reading the data dimensions." << endl );
return;
}
int numTupls = dataDims[1] * dataDims[2] * dataDims[3];
hsize_t startVec[5];
hsize_t stridVec[5];
hsize_t countVec[5];
startVec[0] = blockIdx;
startVec[1] = 0;
startVec[2] = 0;
startVec[3] = 0;
stridVec[0] = 1;
stridVec[1] = 1;
stridVec[2] = 1;
stridVec[3] = 1;
countVec[0] = 1;
countVec[1] = dataDims[1];
countVec[2] = dataDims[2];
countVec[3] = dataDims[3];
// file space index
hid_t filSpace = H5Screate_simple( 4, dataDims, NULL );
H5Sselect_hyperslab ( filSpace, H5S_SELECT_SET, startVec,
stridVec, countVec, NULL );
startVec[0] = 0;
startVec[1] = 0;
startVec[2] = 0;
startVec[3] = 0;
stridVec[0] = 1;
stridVec[1] = 1;
stridVec[2] = 1;
stridVec[3] = 1;
countVec[0] = 1;
countVec[1] = dataDims[1];
countVec[2] = dataDims[2];
countVec[3] = dataDims[3];
hid_t memSpace = H5Screate_simple( 4, dataDims, NULL );
H5Sselect_hyperslab ( memSpace, H5S_SELECT_SET, startVec,
stridVec, countVec, NULL );
vtkDoubleArray * dataAray = vtkDoubleArray::New();
dataAray->SetName( atribute );
dataAray->SetNumberOfTuples( numTupls );
double * arrayPtr = static_cast < double * >
( dataAray->GetPointer( 0 ) );
int i;
hid_t hRawType = H5Dget_type( dataIndx );
hid_t dataType = H5Tget_native_type( hRawType, H5T_DIR_ASCEND );
if ( H5Tequal( dataType, H5T_NATIVE_DOUBLE ) )
{
H5Dread( dataIndx, dataType, memSpace,
filSpace, H5P_DEFAULT, arrayPtr );
}
else
if ( H5Tequal( dataType, H5T_NATIVE_FLOAT ) )
{
float * dataFlts = new float [ numTupls ];
H5Dread( dataIndx, dataType, memSpace,
filSpace, H5P_DEFAULT, dataFlts );
for ( i = 0; i < numTupls; i ++ )
{
arrayPtr[i] = dataFlts[i];
}
delete [] dataFlts;
dataFlts = NULL;
}
else
if ( H5Tequal( dataType, H5T_NATIVE_INT ) )
{
int * dataInts = new int [ numTupls ];
H5Dread( dataIndx, dataType, memSpace,
filSpace, H5P_DEFAULT, dataInts );
for ( i = 0; i < numTupls; i ++ )
{
arrayPtr[i] = dataInts[i];
}
delete[] dataInts;
dataInts = NULL;
}
else
if ( H5Tequal( dataType, H5T_NATIVE_UINT ) )
{
unsigned int * unsgnInt = new unsigned int [ numTupls ];
H5Dread( dataIndx, dataType, memSpace,
filSpace, H5P_DEFAULT, unsgnInt );
for ( i = 0; i < numTupls; i ++ )
{
arrayPtr[i] = unsgnInt[i];
}
delete[] unsgnInt;
unsgnInt = NULL;
}
else
{
// vtkErrorMacro( "Invalid data attribute type." << endl );
}
H5Sclose( filSpace );
H5Sclose( memSpace );
H5Sclose( spaceIdx );
H5Tclose( dataType );
H5Tclose( hRawType );
H5Dclose( dataIndx );
pDataSet->GetCellData()->AddArray ( dataAray );
dataAray->Delete();
dataAray = NULL;
arrayPtr = NULL;
}
//-----------------------------------------------------------------------------
void vtkFlashReaderInternal::Init()
{
this->FileName = NULL;
this->FileIndex = -1;
this->MinBounds[0] =
this->MinBounds[1] =
this->MinBounds[2] = VTK_DOUBLE_MAX;
this->MaxBounds[0] =
this->MaxBounds[1] =
this->MaxBounds[2] =-VTK_DOUBLE_MAX;
this->NumberOfBlocks = 0;
this->NumberOfLevels = 0;
this->FileFormatVersion =-1;
this->NumberOfParticles = 0;
this->NumberOfLeafBlocks = 0;
this->NumberOfDimensions = 0;
this->NumberOfProcessors = 0;
this->HaveProcessorsInfo = 0;
this->BlockGridDimensions[0] = 1;
this->BlockGridDimensions[1] = 1;
this->BlockGridDimensions[2] = 1;
this->BlockCellDimensions[0] = 1;
this->BlockCellDimensions[1] = 1;
this->BlockCellDimensions[2] = 1;
this->NumberOfChildrenPerBlock = 0;
this->NumberOfNeighborsPerBlock = 0;
this->Blocks.clear();
this->LeafBlocks.clear();
this->AttributeNames.clear();
this->ParticleName = "";
this->ParticleAttributeTypes.clear();
this->ParticleAttributeNames.clear();
this->ParticleAttributeNamesToIds.clear();
}
// ----------------------------------------------------------------------------
int vtkFlashReaderInternal::GetCycle()
{
const bool bTmCycle = true;
hid_t fileIndx = H5Fopen( this->FileName, H5F_ACC_RDONLY, H5P_DEFAULT );
if ( fileIndx < 0 )
{
return -VTK_INT_MAX;
}
this->ReadVersionInformation( fileIndx );
this->ReadSimulationParameters( fileIndx, bTmCycle );
H5Fclose( fileIndx );
return this->SimulationParameters.NumberOfTimeSteps;
}
// ----------------------------------------------------------------------------
double vtkFlashReaderInternal::GetTime()
{
const bool bTmCycle = true;
hid_t fileIndx = H5Fopen( this->FileName, H5F_ACC_RDONLY, H5P_DEFAULT);
if ( fileIndx < 0 )
{
return -VTK_DOUBLE_MAX;
}
this->ReadVersionInformation( fileIndx );
this->ReadSimulationParameters( fileIndx, bTmCycle );
H5Fclose( fileIndx );
return this->SimulationParameters.Time;
}
//-----------------------------------------------------------------------------
void vtkFlashReaderInternal::ReadMetaData()
{
if ( this->FileIndex >= 0 )
{
return;
}
// file handle
this->FileIndex = H5Fopen( this->FileName, H5F_ACC_RDONLY, H5P_DEFAULT );
if ( this->FileIndex < 0 )
{
vtkGenericWarningMacro( "Failed to open file " << this->FileName <<
"." << endl );
return;
}
// file format version
this->ReadVersionInformation( this->FileIndex );
if ( this->FileFormatVersion < FLASH_READER_FLASH3_FFV8 )
{
this->ReadParticleAttributes(); // FLASH2 version
}
else
{
this->ReadParticleAttributesFLASH3(); // FLASH3 version
}
// block structures
this->ReadBlockStructures();
if ( this->NumberOfParticles == 0 && this->NumberOfBlocks == 0 )
{
vtkGenericWarningMacro( "Invalid Flash file, without any " <<
"block/particle." << endl );
return;
}
// obtain further information about blocks
if ( this->NumberOfBlocks > 0 )
{
this->ReadBlockBounds();
this->ReadRefinementLevels();
this->ReadSimulationParameters( this->FileIndex );
this->ReadDataAttributeNames();
this->GetBlockMinMaxGlobalDivisionIds();
this->ReadBlockTypes();
this->ReadBlockCenters();
this->ReadProcessorIds();
}
}
//-----------------------------------------------------------------------------
void vtkFlashReaderInternal::ReadProcessorIds()
{
hid_t rootIndx = H5Gopen( this->FileIndex, "/" );
if ( rootIndx < 0 )
{
vtkGenericWarningMacro( "Failed to open the root group" << endl );
return;
}
hsize_t numbObjs;
herr_t errorIdx = H5Gget_num_objs( rootIndx, &numbObjs );
if ( errorIdx < 0 )
{
vtkGenericWarningMacro( "Failed to get the number of objects " <<
"in the root group" << endl );
return;
}
hsize_t objIndex;
vtkstd::string sObjName = "processor number";
char namefromfile[17];
for ( objIndex = 0; objIndex < numbObjs; objIndex ++ )
{
ssize_t objsize = H5Gget_objname_by_idx( rootIndx, objIndex, NULL, 0 );
if ( objsize == 16 )
{
H5Gget_objname_by_idx( rootIndx, objIndex, namefromfile, 17 );
vtkstd::string tempstr = namefromfile;
if ( tempstr == sObjName ) // if this file contains processor numbers
{
this->HaveProcessorsInfo = 1;
}
}
}
H5Gclose( rootIndx );
if ( this->HaveProcessorsInfo )
{
// Read the processor number description for the blocks
hid_t procnumId = H5Dopen( this->FileIndex, "processor number" );
if ( procnumId < 0 )
{
vtkGenericWarningMacro( "Processor Id information not found." << endl );
}
hid_t procnumSpaceId = H5Dget_space( procnumId );
hsize_t procnum_dims[1];
hsize_t procnum_ndims = H5Sget_simple_extent_dims
( procnumSpaceId, procnum_dims, NULL );
if ( static_cast<int> ( procnum_ndims ) != 1 ||
static_cast<int> ( procnum_dims[0] ) != this->NumberOfBlocks )
{
vtkGenericWarningMacro( "Error with getting the number of " <<
"processor Ids." << endl );
}
hid_t procnum_raw_data_type = H5Dget_type( procnumId );
hid_t procnum_data_type = H5Tget_native_type
( procnum_raw_data_type, H5T_DIR_ASCEND );
int * procnum_array = new int [ this->NumberOfBlocks ];
H5Dread( procnumId, procnum_data_type, H5S_ALL,
H5S_ALL, H5P_DEFAULT, procnum_array );
int highProcessor = -1;
for (int b = 0; b < this->NumberOfBlocks; b ++ )
{
int pnum = procnum_array[b];
if ( pnum > highProcessor )
{
highProcessor = pnum;
this->NumberOfProcessors ++;
}
this->Blocks[b].ProcessorId = pnum;
}
H5Tclose( procnum_data_type );
H5Tclose( procnum_raw_data_type );
H5Sclose( procnumSpaceId );
H5Dclose( procnumId );
delete[] procnum_array;
procnum_array = NULL;
}
else
{
this->NumberOfProcessors = 1;
for ( int b = 0; b < this->NumberOfBlocks; b ++ )
{
this->Blocks[b].ProcessorId = 0;
}
}
}
//-----------------------------------------------------------------------------
void vtkFlashReaderInternal::ReadDoubleScalars( hid_t fileIndx )
{
// Should only be used for FLASH3 files
if ( this->FileFormatVersion < FLASH_READER_FLASH3_FFV8 )
{
vtkGenericWarningMacro( "Error with the format version." << endl );
return;
}
hid_t realScalarsId = H5Dopen( fileIndx, "real scalars" );
//
// Read the real scalars
//
if ( realScalarsId < 0 )
{
vtkGenericWarningMacro( "Real scalars not found in FLASH3." << endl );
return;
}
hid_t spaceId = H5Dget_space( realScalarsId );
if ( spaceId < 0 )
{
vtkGenericWarningMacro( "Failed to get the real scalars space." << endl );
return;
}
hsize_t scalarDims[10];
H5Sget_simple_extent_dims( spaceId, scalarDims, NULL );
int nScalars = scalarDims[0];
hid_t datatype = H5Tcreate
( H5T_COMPOUND, sizeof( FlashReaderDoubleScalar ) );
hid_t string20 = H5Tcopy( H5T_C_S1 );
H5Tset_size( string20, 20 );
H5Tinsert( datatype, "name",
HOFFSET( FlashReaderDoubleScalar, Name ), string20 );
H5Tinsert( datatype, "value",
HOFFSET( FlashReaderDoubleScalar, Value ), H5T_NATIVE_DOUBLE );
FlashReaderDoubleScalar * rs = new FlashReaderDoubleScalar[ nScalars ];
H5Dread(realScalarsId, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, rs);
for ( int i = 0; i < nScalars; i ++ )
{
if ( strncmp( rs[i].Name, "time", 4 ) == 0 )
{
this->SimulationParameters.Time = rs[i].Value;
}
}
delete [] rs;
rs = NULL;
H5Tclose( string20 );
H5Tclose( datatype );
H5Sclose( spaceId );
H5Dclose( realScalarsId );
}
//-----------------------------------------------------------------------------
void vtkFlashReaderInternal::ReadIntegerScalars( hid_t fileIndx )
{
// Should only be used for FLASH3 files
if ( this->FileFormatVersion < FLASH_READER_FLASH3_FFV8 )
{
vtkGenericWarningMacro( "Error with the format version." << endl );
return;
}
hid_t intScalarsId = H5Dopen( fileIndx, "integer scalars" );
// Read the integer scalars
if ( intScalarsId < 0 )
{