Finishing silo writer/reader

This commit is contained in:
Mark Berrill
2017-02-03 11:26:08 -05:00
parent 31c815144e
commit 578382f0b5
7 changed files with 305 additions and 76 deletions

View File

@@ -203,6 +203,14 @@ MeshDatabase& MeshDatabase::operator=(const MeshDatabase& rhs)
this->variable_data = rhs.variable_data;
return *this;
}
VariableDatabase MeshDatabase::getVariableDatabase( const std::string& varname ) const
{
for (size_t i=0; i<variables.size(); i++) {
if ( variables[i].name == varname )
return variables[i];
}
return VariableDatabase();
}
/****************************************************

View File

@@ -60,6 +60,7 @@ struct MeshDatabase {
std::vector<DatabaseEntry> domains; //!< List of the domains
std::vector<VariableDatabase> variables; //!< List of the variables
std::map<variable_id,DatabaseEntry> variable_data; //!< Data for the variables
VariableDatabase getVariableDatabase( const std::string& varname ) const;
public:
MeshDatabase();
~MeshDatabase();

View File

@@ -44,6 +44,10 @@ std::vector<std::string> IO::readTimesteps( const std::string& filename )
FILE *fid= fopen(filename.c_str(),"rb");
if ( fid==NULL )
ERROR("Error opening file");
auto pos = std::min(filename.find_last_of(47),filename.find_last_of(90));
std::string path = getPath( filename );
if ( !path.empty() )
path += "/";
std::vector<std::string> timesteps;
char buf[1000];
while (fgets(buf,sizeof(buf),fid) != NULL) {
@@ -54,7 +58,7 @@ std::vector<std::string> IO::readTimesteps( const std::string& filename )
line.resize(pos);
if ( line.empty() )
continue;
timesteps.push_back(line);
timesteps.push_back(path+line);
}
fclose(fid);
PROFILE_STOP("readTimesteps");
@@ -162,14 +166,39 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
int rank = std::stoi(database.file.substr(0,database.file.find(".silo")).c_str());
auto fid = silo::open( filename, silo::READ );
if ( meshDatabase.meshClass=="PointList" ) {
mesh.reset( new IO::PointList() );
ERROR("Not finished");
} else if ( meshDatabase.meshClass=="TriMesh" ) {
mesh.reset( new IO::TriMesh() );
ERROR("Not finished");
} else if ( meshDatabase.meshClass=="TriList" ) {
mesh.reset( new IO::TriList() );
ERROR("Not finished");
Array<double> coords = silo::readPointMesh( fid, database.name );
ASSERT(coords.size(1)==3);
std::shared_ptr<IO::PointList> mesh2( new IO::PointList( coords.size(0) ) );
for (size_t i=0; i<coords.size(1); i++) {
mesh2->points[i].x = coords(i,0);
mesh2->points[i].y = coords(i,1);
mesh2->points[i].z = coords(i,2);
}
mesh = mesh2;
} else if ( meshDatabase.meshClass=="TriMesh" || meshDatabase.meshClass=="TriList" ) {
Array<double> coords;
Array<int> tri;
silo::readTriMesh( fid, database.name, coords, tri );
ASSERT( tri.size(1)==3 && coords.size(1)==3 );
int N_tri = tri.size(0);
int N_point = coords.size(0);
std::shared_ptr<IO::TriMesh> mesh2( new IO::TriMesh( N_tri, N_point ) );
for (int i=0; i<N_point; i++) {
mesh2->vertices->points[i].x = coords(i,0);
mesh2->vertices->points[i].y = coords(i,1);
mesh2->vertices->points[i].z = coords(i,2);
}
for (int i=0; i<N_tri; i++) {
mesh2->A[i] = tri(i,0);
mesh2->B[i] = tri(i,1);
mesh2->C[i] = tri(i,2);
}
if ( meshDatabase.meshClass=="TriMesh" ) {
mesh = mesh2;
} else if ( meshDatabase.meshClass=="TriList" ) {
auto trilist = IO::getTriList( std::dynamic_pointer_cast<IO::Mesh>( mesh2 ) );
mesh = trilist;
}
} else if ( meshDatabase.meshClass=="DomainMesh" ) {
std::vector<double> range;
std::vector<int> N;
@@ -201,33 +230,61 @@ std::shared_ptr<IO::Variable> IO::getVariable( const std::string& path, const st
it = meshDatabase.variable_data.find(key);
if ( it==meshDatabase.variable_data.end() )
return std::shared_ptr<IO::Variable>();
const DatabaseEntry& database = it->second;
std::string filename = path + "/" + timestep + "/" + database.file;
FILE *fid = fopen(filename.c_str(),"rb");
fseek(fid,database.offset,SEEK_SET);
char line[1000];
fgetl(line,1000,fid);
size_t i1 = find(line,':');
size_t i2 = find(&line[i1+1],':')+i1+1;
std::vector<std::string> values = splitList(&line[i2+1],',');
ASSERT(values.size()==5);
int dim = atoi(values[0].c_str());
int type = atoi(values[1].c_str());
size_t N = atol(values[2].c_str());
size_t bytes = atol(values[3].c_str());
std::string precision = values[4];
std::shared_ptr<IO::Variable> var( new IO::Variable() );
var->dim = dim;
var->type = static_cast<IO::VariableType>(type);
var->name = variable;
var->data.resize(N*dim);
if ( precision=="double" ) {
size_t count = fread(var->data.data(),sizeof(double),N*dim,fid);
ASSERT(count*sizeof(double)==bytes);
std::shared_ptr<IO::Variable> var;
if ( meshDatabase.format == 2 ) {
const DatabaseEntry& database = it->second;
std::string filename = path + "/" + timestep + "/" + database.file;
FILE *fid = fopen(filename.c_str(),"rb");
fseek(fid,database.offset,SEEK_SET);
char line[1000];
fgetl(line,1000,fid);
size_t i1 = find(line,':');
size_t i2 = find(&line[i1+1],':')+i1+1;
std::vector<std::string> values = splitList(&line[i2+1],',');
ASSERT(values.size()==5);
int dim = atoi(values[0].c_str());
int type = atoi(values[1].c_str());
size_t N = atol(values[2].c_str());
size_t bytes = atol(values[3].c_str());
std::string precision = values[4];
var = std::shared_ptr<IO::Variable>( new IO::Variable() );
var->dim = dim;
var->type = static_cast<IO::VariableType>(type);
var->name = variable;
var->data.resize(N*dim);
if ( precision=="double" ) {
size_t count = fread(var->data.data(),sizeof(double),N*dim,fid);
ASSERT(count*sizeof(double)==bytes);
} else {
ERROR("Format not implimented");
}
fclose(fid);
} else if ( meshDatabase.format == 4 ) {
// Reading a silo file
#ifdef USE_SILO
const auto& database = meshDatabase.domains[domain];
auto variableDatabase = meshDatabase.getVariableDatabase( variable );
std::string filename = path + "/" + timestep + "/" + database.file;
int rank = std::stoi(database.file.substr(0,database.file.find(".silo")).c_str());
auto fid = silo::open( filename, silo::READ );
var.reset( new Variable( variableDatabase.dim, variableDatabase.type, variable ) );
if ( meshDatabase.meshClass=="PointList" ) {
var->data = silo::readPointMeshVariable( fid, variable );
} else if ( meshDatabase.meshClass=="TriMesh" || meshDatabase.meshClass=="TriList" ) {
var->data = silo::readTriMeshVariable( fid, variable );
} else if ( meshDatabase.meshClass=="DomainMesh" ) {
var->data = silo::readUniformMeshVariable( fid, variable );
} else {
ERROR("Unknown mesh class");
}
silo::close( fid );
#else
ERROR("Build without silo support");
#endif
} else {
ERROR("Format not implimented");
ERROR("Unknown format");
}
fclose(fid);
return var;
}
@@ -240,7 +297,9 @@ void IO::reformatVariable( const IO::Mesh& mesh, IO::Variable& var )
if ( mesh.className() == "DomainMesh" ) {
const IO::DomainMesh& mesh2 = dynamic_cast<const IO::DomainMesh&>( mesh );
if ( var.type == NodeVariable ) {
ERROR("Not finished");
size_t N2 = var.data.length() / ((mesh2.nx+1)*(mesh2.ny+1)*(mesh2.nz+1));
ASSERT( (mesh2.nx+1)*(mesh2.ny+1)*(mesh2.nz+1)*N2 == var.data.length() );
var.data.reshape( { (size_t) mesh2.nx+1, (size_t) mesh2.ny+1, (size_t) mesh2.nz+1, N2 } );
} else if ( var.type == EdgeVariable ) {
ERROR("Not finished");
} else if ( var.type == SurfaceVariable ) {
@@ -253,9 +312,31 @@ void IO::reformatVariable( const IO::Mesh& mesh, IO::Variable& var )
ERROR("Invalid variable type");
}
} else if ( mesh.className() == "PointList" ) {
ERROR("Not finished");
} else if ( mesh.className() == "TriMesh" ) {
ERROR("Not finished");
const IO::PointList& mesh2 = dynamic_cast<const IO::PointList&>( mesh );
size_t N = mesh2.points.size();
size_t N_var = var.data.length()/N;
ASSERT( N*N_var == var.data.length() );
var.data.reshape( { N, N_var } );
} else if ( mesh.className()=="TriMesh" || mesh.className() == "TriList" ) {
std::shared_ptr<Mesh> mesh_ptr( const_cast<Mesh*>(&mesh), []( void* ) {} );
std::shared_ptr<TriMesh> mesh2 = getTriMesh( mesh_ptr );
if ( var.type == NodeVariable ) {
size_t N = mesh2->vertices->points.size();
size_t N_var = var.data.length()/N;
ASSERT( N*N_var == var.data.length() );
var.data.reshape( { N, N_var } );
} else if ( var.type == EdgeVariable ) {
ERROR("Not finished");
} else if ( var.type == SurfaceVariable ) {
ERROR("Not finished");
} else if ( var.type == VolumeVariable ) {
size_t N = mesh2->A.size();
size_t N_var = var.data.length()/N;
ASSERT( N*N_var == var.data.length() );
var.data.reshape( { N, N_var } );
} else {
ERROR("Invalid variable type");
}
} else {
ERROR("Unknown mesh type");
}

View File

@@ -234,7 +234,6 @@ static void writeSiloTriMesh2( DBfile *fid, const IO::MeshDataStruct& meshData,
const IO::Variable& var = *meshData.vars[i];
auto type = static_cast<silo::VariableType>( var.type );
silo::writeTriMeshVariable( fid, 3, meshname, var.name, var.data, type );
printf("%s-%s: %i %i %i\n",meshname.c_str(),var.name.c_str(),points.size(),var.data.size(0),var.data.size(1));
}
}
static void writeSiloTriMesh( DBfile *fid, const IO::MeshDataStruct& meshData, IO::MeshDatabase database )
@@ -428,7 +427,7 @@ void IO::writeData( const std::string& subdir, const std::vector<IO::MeshDataStr
if ( global_IO_format == Format::OLD || global_IO_format == Format::NEW ) {
auto filename = global_IO_path+"/summary.LBM";
FILE *fid = fopen(filename.c_str(),"ab");
fprintf(fid,"%s/\n",path.c_str());
fprintf(fid,"%s/\n",subdir.c_str());
fclose(fid);
} else if ( global_IO_format == Format::SILO ) {
auto filename = global_IO_path+"/LBM.visit";

View File

@@ -151,11 +151,11 @@ void readUniformMesh( DBfile* fid, const std::string& meshname,
range.resize(2*ndim);
N.resize(ndim);
for (int d=0; d<ndim; d++) {
N[d] = mesh->dims[d];
N[d] = mesh->dims[d]-1;
range[2*d+0] = mesh->min_extents[d];
range[2*d+1] = mesh->max_extents[d];
}
delete mesh;
DBFreeQuadmesh( mesh );
}
@@ -211,10 +211,28 @@ void writeUniformMeshVariable( DBfile* fid, const std::string& meshname, const s
ASSERT( err == 0 );
PROFILE_STOP("writeUniformMeshVariable",2);
}
Array<double> readUniformMeshVariable( DBfile* fid, const std::string& varname )
{
auto var = DBGetQuadvar( fid, varname.c_str() );
ASSERT( var != nullptr );
Array<double> data( var->nels, var->nvals );
if ( var->datatype == DB_DOUBLE ) {
for (int i=0; i<var->nvals; i++)
memcpy( &data(0,i), var->vals[i], var->nels*sizeof(double) );
} else {
ERROR("Unsupported format");
}
DBFreeQuadvar( var );
std::vector<size_t> dims( var->ndims+1, var->nvals );
for (int d=0; d<var->ndims; d++)
dims[d] = var->dims[d];
data.reshape( dims );
return data;
}
/****************************************************
* Write a point mesh/variable to silo *
* Read/write a point mesh/variable to silo *
****************************************************/
void writePointMesh( DBfile* fid, const std::string& meshname,
int ndim, int N, const double *coords[] )
@@ -222,6 +240,21 @@ void writePointMesh( DBfile* fid, const std::string& meshname,
int err = DBPutPointmesh( fid, meshname.c_str(), ndim, coords, N, DB_DOUBLE, nullptr );
ASSERT( err == 0 );
}
Array<double> readPointMesh( DBfile* fid, const std::string& meshname )
{
auto mesh = DBGetPointmesh( fid, meshname.c_str() );
int N = mesh->nels;
int ndim = mesh->ndims;
Array<double> coords(N,ndim);
if ( mesh->datatype == DB_DOUBLE ) {
for (int d=0; d<ndim; d++)
memcpy(&coords(0,d),mesh->coords[d],N*sizeof(double));
} else {
ERROR("Unsupported format");
}
DBFreePointmesh( mesh );
return coords;
}
void writePointMeshVariable( DBfile* fid, const std::string& meshname,
const std::string& varname, const Array<double>& data )
{
@@ -233,10 +266,24 @@ void writePointMeshVariable( DBfile* fid, const std::string& meshname,
int err = DBPutPointvar( fid, varname.c_str(), meshname.c_str(), nvars, vars.data(), N, DB_DOUBLE, nullptr );
ASSERT( err == 0 );
}
Array<double> readPointMeshVariable( DBfile* fid, const std::string& varname )
{
auto var = DBGetPointvar( fid, varname.c_str() );
ASSERT( var != nullptr );
Array<double> data( var->nels, var->nvals );
if ( var->datatype == DB_DOUBLE ) {
for (int i=0; i<var->nvals; i++)
memcpy( &data(0,i), var->vals[i], var->nels*sizeof(double) );
} else {
ERROR("Unsupported format");
}
DBFreeMeshvar( var );
return data;
}
/****************************************************
* Write a triangle mesh *
* Read/write a triangle mesh *
****************************************************/
void writeTriMesh( DBfile* fid, const std::string& meshName,
int ndim, int ndim_tri, int N, const double *coords[], int N_tri, const int *tri[] )
@@ -263,6 +310,31 @@ void writeTriMesh( DBfile* fid, const std::string& meshName,
DBPutUcdmesh( fid, meshName.c_str(), ndim, nullptr, coords, N,
nodelist.size(), zoneName.c_str(), nullptr, DB_DOUBLE, nullptr );
}
void readTriMesh( DBfile* fid, const std::string& meshname, Array<double>& coords, Array<int>& tri )
{
auto mesh = DBGetUcdmesh( fid, meshname.c_str() );
int ndim = mesh->ndims;
int N_nodes = mesh->nnodes;
coords.resize(N_nodes,ndim);
if ( mesh->datatype == DB_DOUBLE ) {
for (int d=0; d<ndim; d++)
memcpy(&coords(0,d),mesh->coords[d],N_nodes*sizeof(double));
} else {
ERROR("Unsupported format");
}
auto zones = mesh->zones;
int N_zones = zones->nzones;
int ndim_zones = zones->ndims;
ASSERT( zones->nshapes==1 );
int type = zones->shapetype[0];
int shapesize = zones->shapesize[0];
tri.resize(N_zones,shapesize);
for (int i=0; i<N_zones; i++) {
for (int j=0; j<shapesize; j++)
tri(i,j) = zones->nodelist[i*shapesize+j];
}
DBFreeUcdmesh( mesh );
}
void writeTriMeshVariable( DBfile* fid, int ndim, const std::string& meshname,
const std::string& varname, const Array<double>& data, VariableType type )
{
@@ -296,6 +368,20 @@ void writeTriMeshVariable( DBfile* fid, int ndim, const std::string& meshname,
DBPutUcdvar( fid, varname.c_str(), meshname.c_str(), nvars,
varnames.data(), vars, data.size(0), nullptr, 0, DB_DOUBLE, vartype, nullptr );
}
Array<double> readTriMeshVariable( DBfile* fid, const std::string& varname )
{
auto var = DBGetUcdvar( fid, varname.c_str() );
ASSERT( var != nullptr );
Array<double> data( var->nels, var->nvals );
if ( var->datatype == DB_DOUBLE ) {
for (int i=0; i<var->nvals; i++)
memcpy( &data(0,i), var->vals[i], var->nels*sizeof(double) );
} else {
ERROR("Unsupported format");
}
DBFreeUcdvar( var );
return data;
}
/****************************************************

View File

@@ -106,6 +106,16 @@ void writeUniformMeshVariable( DBfile* fid, const std::string& meshname, const s
const std::string& varname, const Array<double>& data, VariableType type );
/*!
* @brief Read a uniform mesh grid variable
* @detailed This function read a uniform mesh variable to silo
* @param[in] fid Handle to the open file
* @param[in] varname Variable name
* @return Variable data
*/
Array<double> readUniformMeshVariable( DBfile* fid, const std::string& varname );
/*!
* @brief Write a pointmesh
* @detailed This function writes a pointmesh to silo
@@ -119,6 +129,16 @@ void writePointMesh( DBfile* fid, const std::string& meshname,
int ndim, int N, const double *coords[] );
/*!
* @brief Read a pointmesh
* @detailed This function reads a pointmesh from silo
* @param[in] fid Handle to the open file
* @param[in] meshname Mesh name
* @return Returns the coordinates as a N x ndim array
*/
Array<double> readPointMesh( DBfile* fid, const std::string& meshname );
/*!
* @brief Write a pointmesh grid variable
* @detailed This function writes a pointmesh variable to silo
@@ -131,6 +151,16 @@ void writePointMeshVariable( DBfile* fid, const std::string& meshname,
const std::string& varname, const Array<double>& data );
/*!
* @brief Read a pointmesh grid variable
* @detailed This function reads a pointmesh variable from silo
* @param[in] fid Handle to the open file
* @param[in] varname Variable name
* @return Variable data
*/
Array<double> readPointMeshVariable( DBfile* fid, const std::string& varname );
/*!
* @brief Write a triangle mesh
* @detailed This function writes a triangle (or simplex) based mesh to silo
@@ -148,8 +178,19 @@ void writeTriMesh( DBfile* fid, const std::string& meshname,
/*!
* @brief Write a pointmesh grid variable
* @detailed This function writes a pointmesh variable to silo
* @brief Read a triangle mesh
* @detailed This function reads a triangle (or simplex) based mesh to silo
* @param[in] fid Handle to the open file
* @param[in] meshname Mesh name
* @param[in] coords Coordinates of the points
* @param[in] tri Coordinates of the points
*/
void readTriMesh( DBfile* fid, const std::string& meshname, Array<double>& coords, Array<int>& tri );
/*!
* @brief Write a triangle mesh grid variable
* @detailed This function writes a triangle mesh variable to silo
* @param[in] fid Handle to the open file
* @param[in] meshname Mesh name
* @param[in] varname Variable name
@@ -158,6 +199,17 @@ void writeTriMesh( DBfile* fid, const std::string& meshname,
void writeTriMeshVariable( DBfile* fid, int ndim, const std::string& meshname,
const std::string& varname, const Array<double>& data, VariableType type );
/*!
* @brief Read a triangle mesh grid variable
* @detailed This function read a triangle mesh variable to silo
* @param[in] fid Handle to the open file
* @param[in] varname Variable name
* @return Variable data
*/
Array<double> readTriMeshVariable( DBfile* fid, const std::string& varname );
/*!
* @brief Write a multimesh
* @detailed This function writes a multimesh to silo