Finishing Writing/Loading variables

This commit is contained in:
Mark Berrill 2014-11-05 16:54:18 -05:00
parent bc2f191537
commit 7f925e0389
7 changed files with 166 additions and 100 deletions

64
IO/IOHelpers.h Normal file
View File

@ -0,0 +1,64 @@
#ifndef IO_HELPERS_INC
#define IO_HELPERS_INC
#include <string.h>
#include <vector>
namespace IO {
// Find a character in a line
inline size_t find( const char *line, char token )
{
size_t i=0;
while ( 1 ) {
if ( line[i]==token || line[i]<32 || line[i]==0 )
break;
++i;
}
return i;
}
// Remove preceeding/trailing whitespace
inline std::string deblank( const std::string& str )
{
size_t i1 = str.size();
size_t i2 = 0;
for (size_t i=0; i<str.size(); i++) {
if ( str[i]!=' ' && str[i]>=32 ) {
i1 = std::min(i1,i);
i2 = std::max(i2,i);
}
}
return str.substr(i1,i2-i1+1);
}
// Split a list by the given token
inline std::vector<std::string> splitList( const char *line, const char token )
{
std::vector<std::string> list;
size_t i1 = 0;
size_t i2 = 0;
while ( 1 ) {
if ( line[i2]==token || line[i2]<32 ) {
std::string tmp(&line[i1],i2-i1);
tmp = deblank(tmp);
if ( !tmp.empty() )
list.push_back(tmp);
i1 = i2+1;
}
if ( line[i2]==0 )
break;
i2++;
}
return list;
}
};
#endif

View File

@ -122,12 +122,14 @@ public:
struct Variable
{
public:
//! Internal variables
int dim;
std::string name;
std::vector<double> data;
enum class VariableType : unsigned char { NodeVariable=1, EdgeVariable=2, SurfaceVariable=2, VolumeVariable=3, Null=0 };
// Internal variables
unsigned int dim; //!< Number of points per grid point (1: scalar, 3: vector, ...)
VariableType type; //!< Variable type
std::string name; //!< Variable name
std::vector<double> data; //!< Variable data
//! Empty constructor
Variable() {}
Variable(): type(VariableType::Null) {}
//! Destructor
virtual ~Variable() {}
protected:

View File

@ -1,5 +1,6 @@
#include "IO/MeshDatabase.h"
#include "IO/Mesh.h"
#include "IO/IOHelpers.h"
#include "common/Utilities.h"
#include <vector>
@ -11,21 +12,6 @@
namespace IO {
// Remove preceeding/trailing whitespace
inline std::string deblank( const std::string& str )
{
size_t i1 = str.size();
size_t i2 = 0;
for (size_t i=0; i<str.size(); i++) {
if ( str[i]!=' ' && str[i]>=32 ) {
i1 = std::min(i1,i);
i2 = std::max(i2,i);
}
}
return str.substr(i1,i2-i1+1);
}
/****************************************************
* Pack/unpack data from a buffer *
@ -281,40 +267,6 @@ MeshDatabase& MeshDatabase::operator=(const MeshDatabase& rhs)
}
/****************************************************
* Split a line into pieces *
****************************************************/
static inline size_t find( const char *line, char key )
{
size_t i=0;
while ( 1 ) {
if ( line[i]==key || line[i]<32 || line[i]==0 )
break;
++i;
}
return i;
}
static inline std::vector<std::string> splitList( const char *line )
{
std::vector<std::string> list;
size_t i1 = 0;
size_t i2 = 0;
while ( 1 ) {
if ( line[i2]==';' || line[i2]<32 ) {
std::string tmp(&line[i1],i2-i1);
tmp = deblank(tmp);
if ( !tmp.empty() )
list.push_back(tmp);
i1 = i2+1;
}
if ( line[i2]==0 )
break;
i2++;
}
return list;
}
/****************************************************
* DatabaseEntry *
****************************************************/
@ -326,21 +278,21 @@ std::string DatabaseEntry::write( ) const
}
DatabaseEntry::DatabaseEntry( const char* line )
{
std::vector<std::string> list = splitList(line);
std::vector<std::string> list = splitList(line,';');
name = list[0];
file = list[1];
offset = atol(list[2].c_str());
}
void DatabaseEntry::read( const char* line )
{
std::vector<std::string> list = splitList(line);
std::vector<std::string> list = splitList(line,';');
name = list[0];
file = list[1];
offset = atol(list[2].c_str());
}
void DatabaseEntry::read( const std::string& line )
{
std::vector<std::string> list = splitList(line.c_str());
std::vector<std::string> list = splitList(line.c_str(),';');
name = list[0];
file = list[1];
offset = atol(list[2].c_str());
@ -454,8 +406,8 @@ std::vector<MeshDatabase> read( const std::string& filename )
FILE *fid = fopen(filename.c_str(),"rb");
if ( fid==NULL )
ERROR("Error opening file");
char *line = new char[0x100000];
while ( std::fgets(line,0x100000,fid) != NULL ) {
char *line = new char[10000];
while ( std::fgets(line,1000,fid) != NULL ) {
if ( line[0]<32 ) {
// Empty line
continue;
@ -474,12 +426,12 @@ std::vector<MeshDatabase> read( const std::string& filename )
DatabaseEntry data(&line[10]);
meshes.back().domains.push_back(data);
} else if ( strncmp(line," variables:",13)==0 ) {
meshes.back().variables = splitList(&line[13]);
meshes.back().variables = splitList(&line[13],';');
} else if ( strncmp(line," variable(",12)==0 ) {
size_t i1 = find(line,',');
size_t i2 = find(line,':');
std::string domain = deblank(std::string(line,13,i1-13));
std::string variable = deblank(std::string(line,i1+1,i2-i1));
std::string domain = deblank(std::string(line,12,i1-12));
std::string variable = deblank(std::string(line,i1+1,i2-i1-2));
std::pair<std::string,std::string> key(domain,variable);
DatabaseEntry data(&line[i2+1]);
meshes.back().variable_data.insert(

View File

@ -1,6 +1,7 @@
#include "IO/Reader.h"
#include "IO/Mesh.h"
#include "IO/MeshDatabase.h"
#include "IO/IOHelpers.h"
#include "common/Utilities.h"
#include <ProfilerApp.h>
@ -8,34 +9,7 @@
#include <string.h>
#include <memory>
#include <vector>
// Helper function
static inline size_t find( const char *line, char key )
{
size_t i=0;
while ( 1 ) {
if ( line[i]==key || line[i]<32 || line[i]==0 )
break;
++i;
}
return i;
}
// Remove preceeding/trailing whitespace
inline std::string deblank( const std::string& str )
{
size_t i1 = str.size();
size_t i2 = 0;
for (size_t i=0; i<str.size(); i++) {
if ( str[i]!=' ' && str[i]>=32 ) {
i1 = std::min(i1,i);
i2 = std::max(i2,i);
}
}
return str.substr(i1,i2-i1+1);
}
#include <map>
@ -129,13 +103,14 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
FILE *fid = fopen(filename.c_str(),"rb");
fseek(fid,database.offset,SEEK_SET);
char line[1000];
std::fgets(line,0x100000,fid);
std::fgets(line,1000,fid);
size_t i1 = find(line,':');
size_t i2 = find(&line[i1+1],':')+i1+1;
size_t bytes = atol(&line[i2+1]);
char *data = new char[bytes];
size_t count = fread(data,1,bytes,fid);
fclose(fid);
ASSERT(count==bytes);
if ( meshDatabase.meshClass=="PointList" ) {
mesh.reset( new IO::PointList() );
} else if ( meshDatabase.meshClass=="TriMesh" ) {
@ -159,7 +134,43 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
std::shared_ptr<IO::Variable> IO::getVariable( const std::string& path, const std::string& timestep,
const MeshDatabase& meshDatabase, int domain, const std::string& variable )
{
return std::shared_ptr<IO::Variable>();
std::pair<std::string,std::string> key(meshDatabase.domains[domain].name,variable);
std::map<std::pair<std::string,std::string>,DatabaseEntry>::const_iterator it;
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];
std::fgets(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];
char *data = new char[bytes];
size_t count = fread(data,1,bytes,fid);
fclose(fid);
ASSERT(count==bytes);
std::shared_ptr<IO::Variable> var( new IO::Variable() );
var->dim = dim;
var->type = static_cast<IO::Variable::VariableType>(type);
var->name = variable;
var->data.resize(N);
double *var_data = var->data.data();
if ( precision=="double" ) {
memcpy(var_data,data,bytes);
} else {
ERROR("Format not implimented");
}
delete [] data;
return var;
}

View File

@ -1,5 +1,6 @@
#include "IO/Writer.h"
#include "IO/MeshDatabase.h"
#include "IO/IOHelpers.h"
#include "common/Utilities.h"
#include "mpi.h"
@ -37,8 +38,8 @@ static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO
mesh_entry.domains.push_back(domain);
if ( !meshData[i].vars.empty() ) {
printf("Warning: variables are not supported with this format\n");
for (size_t j=0; j<meshData[i].vars.size(); j++)
mesh_entry.variables.push_back( meshData[i].vars[j]->name );
//for (size_t j=0; j<meshData[i].vars.size(); j++)
// mesh_entry.variables.push_back( meshData[i].vars[j]->name );
}
if ( std::dynamic_pointer_cast<IO::PointList>(mesh)!=NULL ) {
// List of points
@ -110,10 +111,12 @@ static IO::MeshDatabase write_domain( FILE *fid, const std::string& filename,
database.variable_data.insert(
std::pair<std::pair<std::string,std::string>,IO::DatabaseEntry>(key,variable) );
int dim = mesh.vars[i]->dim;
int type = static_cast<int>(mesh.vars[i]->type);
size_t N = mesh.vars[i]->data.size();
const void* data = N==0 ? 0:&mesh.vars[i]->data[0];
fprintf(fid,"Var: %s-%05i-%s: %i, %lu, %lu, double\n",
database.name.c_str(),rank,variable.name.c_str(),dim,N,dim*N*sizeof(double));
fprintf(fid,"Var: %s-%05i-%s: %i, %i, %lu, %lu, double\n",
database.name.c_str(), rank, variable.name.c_str(),
dim, type, N, dim*N*sizeof(double) );
fwrite(data,sizeof(double),dim*N,fid);
fprintf(fid,"\n");
}

View File

@ -16,9 +16,13 @@
inline bool approx_equal( const Point& A, const Point& B )
{
double tol = 1e-8*(A.x*A.x+A.y*A.y+A.z*A.z);
double tol = 1e-8*sqrt(A.x*A.x+A.y*A.y+A.z*A.z);
return fabs(A.x-B.x)<=tol && fabs(A.y-B.y)<=tol && fabs(A.z-B.z)<=tol;
}
inline bool approx_equal( const double& A, const double& B )
{
return fabs(A-B)<=1e-8*fabs(A+B);
}
inline double distance( const Point& p )
@ -83,6 +87,8 @@ int main(int argc, char **argv)
dist_trimesh->dim = 1;
dist_set1->name = "Distance";
dist_trimesh->name = "Distance";
dist_set1->type = IO::Variable::VariableType::NodeVariable;
dist_trimesh->type = IO::Variable::VariableType::NodeVariable;
dist_set1->data.resize( N_points );
for (int i=0; i<N_points; i++)
dist_set1->data[i] = distance(set1->points[i]);
@ -196,10 +202,36 @@ int main(int argc, char **argv)
continue;
}
// For each domain, load the variables and check their data
if ( i==0 )
continue; // Format 1 does not support variables
for (size_t j=0; j<list.size(); j++) {
for (size_t k=0; k<list[i].domains.size(); k++) {
for (size_t v=0; v<list[i].variables.size(); v++) {
std::shared_ptr<IO::Variable> var = IO::getVariable(".",timesteps[i],list[j],k,list[i].variables[v]);
const IO::MeshDataStruct* mesh0 = NULL;
for (size_t k=0; k<meshData.size(); k++) {
if ( meshData[k].meshName == list[j].name ) {
mesh0 = &meshData[k];
break;
}
}
for (size_t v=0; v<list[i].variables.size(); v++) {
for (size_t k=0; k<list[i].domains.size(); k++) {
std::shared_ptr<const IO::Variable> variable =
IO::getVariable(".",timesteps[i],list[j],k,list[j].variables[v]);
const IO::Variable& var1 = *mesh0->vars[v];
const IO::Variable& var2 = *variable;
pass = var1.name == var2.name;
pass = pass && var1.dim == var2.dim;
pass = pass && var1.type == var2.type;
pass = pass && var1.data.size() == var2.data.size();
if ( pass ) {
for (size_t m=0; m<var1.data.size(); m++)
pass = pass && approx_equal(var1.data[m],var2.data[m]);
}
if ( pass ) {
ut.passes("Variables match");
} else {
ut.failure("Variables did not match");
break;
}
}
}
}

View File

@ -222,6 +222,8 @@ avtLBMFileFormat::PopulateDatabaseMetaData(avtDatabaseMetaData *md, int timeStat
expr.SetDefinition(expdef);
md->AddExpression(&expr);
}
// Add the variables
}
DebugStream::Stream1() << " Finished" << std::endl;