Working on IO classes
This commit is contained in:
parent
f8f09ae999
commit
bc2f191537
143
IO/Mesh.cpp
143
IO/Mesh.cpp
@ -42,6 +42,42 @@ PointList::PointList( size_t N )
|
||||
PointList::~PointList( )
|
||||
{
|
||||
}
|
||||
std::pair<size_t,void*> PointList::pack( int level ) const
|
||||
{
|
||||
std::pair<size_t,void*> data_out(0,NULL);
|
||||
if ( level==0 ) {
|
||||
data_out.first = (2+3*points.size())*sizeof(double);
|
||||
double *data_ptr = new double[2+3*points.size()];
|
||||
data_out.second = data_ptr;
|
||||
uint64_t *data_int = reinterpret_cast<uint64_t*>(data_ptr);
|
||||
data_int[0] = level;
|
||||
data_int[1] = points.size();
|
||||
double *data = &data_ptr[2];
|
||||
for (size_t i=0; i<points.size(); i++) {
|
||||
data[3*i+0] = points[i].x;
|
||||
data[3*i+1] = points[i].y;
|
||||
data[3*i+2] = points[i].z;
|
||||
}
|
||||
}
|
||||
return data_out;
|
||||
}
|
||||
void PointList::unpack( const std::pair<size_t,void*>& data_in )
|
||||
{
|
||||
uint64_t *data_int = reinterpret_cast<uint64_t*>(data_in.second);
|
||||
const double *data = reinterpret_cast<const double*>(data_in.second);
|
||||
int level = data_int[0];
|
||||
uint64_t N = data_int[1];
|
||||
data = &data[2];
|
||||
if ( level==0 ) {
|
||||
ASSERT((2+3*N)*sizeof(double)==data_in.first);
|
||||
points.resize(N);
|
||||
for (size_t i=0; i<points.size(); i++) {
|
||||
points[i].x = data[3*i+0];
|
||||
points[i].y = data[3*i+1];
|
||||
points[i].z = data[3*i+2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
@ -63,6 +99,7 @@ TriList::TriList( const TriMesh& mesh )
|
||||
A.resize(mesh.A.size(),tmp);
|
||||
B.resize(mesh.B.size(),tmp);
|
||||
C.resize(mesh.C.size(),tmp);
|
||||
ASSERT(mesh.vertices.get()!=NULL);
|
||||
const std::vector<Point>& P = mesh.vertices->points;
|
||||
for (size_t i=0; i<A.size(); i++)
|
||||
A[i] = P[mesh.A[i]];
|
||||
@ -74,6 +111,56 @@ TriList::TriList( const TriMesh& mesh )
|
||||
TriList::~TriList( )
|
||||
{
|
||||
}
|
||||
std::pair<size_t,void*> TriList::pack( int level ) const
|
||||
{
|
||||
std::pair<size_t,void*> data_out(0,NULL);
|
||||
if ( level==0 ) {
|
||||
data_out.first = (2+9*A.size())*sizeof(double);
|
||||
double *data_ptr = new double[2+9*A.size()];
|
||||
data_out.second = data_ptr;
|
||||
uint64_t *data_int = reinterpret_cast<uint64_t*>(data_ptr);
|
||||
data_int[0] = level;
|
||||
data_int[1] = A.size();
|
||||
double *data = &data_ptr[2];
|
||||
for (size_t i=0; i<A.size(); i++) {
|
||||
data[9*i+0] = A[i].x;
|
||||
data[9*i+1] = A[i].y;
|
||||
data[9*i+2] = A[i].z;
|
||||
data[9*i+3] = B[i].x;
|
||||
data[9*i+4] = B[i].y;
|
||||
data[9*i+5] = B[i].z;
|
||||
data[9*i+6] = C[i].x;
|
||||
data[9*i+7] = C[i].y;
|
||||
data[9*i+8] = C[i].z;
|
||||
}
|
||||
}
|
||||
return data_out;
|
||||
}
|
||||
void TriList::unpack( const std::pair<size_t,void*>& data_in )
|
||||
{
|
||||
uint64_t *data_int = reinterpret_cast<uint64_t*>(data_in.second);
|
||||
const double *data = reinterpret_cast<const double*>(data_in.second);
|
||||
int level = data_int[0];
|
||||
uint64_t N = data_int[1];
|
||||
data = &data[2];
|
||||
if ( level==0 ) {
|
||||
ASSERT((2+9*N)*sizeof(double)==data_in.first);
|
||||
A.resize(N);
|
||||
B.resize(N);
|
||||
C.resize(N);
|
||||
for (size_t i=0; i<A.size(); i++) {
|
||||
A[i].x = data[9*i+0];
|
||||
A[i].y = data[9*i+1];
|
||||
A[i].z = data[9*i+2];
|
||||
B[i].x = data[9*i+3];
|
||||
B[i].y = data[9*i+4];
|
||||
B[i].z = data[9*i+5];
|
||||
C[i].x = data[9*i+6];
|
||||
C[i].y = data[9*i+7];
|
||||
C[i].z = data[9*i+8];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
@ -120,6 +207,62 @@ TriMesh::~TriMesh( )
|
||||
B.clear();
|
||||
C.clear();
|
||||
}
|
||||
std::pair<size_t,void*> TriMesh::pack( int level ) const
|
||||
{
|
||||
std::pair<size_t,void*> data_out(0,NULL);
|
||||
if ( level==0 ) {
|
||||
const std::vector<Point>& points = vertices->points;
|
||||
data_out.first = (3+3*points.size())*sizeof(double) + 3*A.size()*sizeof(int);
|
||||
double *data_ptr = new double[4+3*points.size()+(3*A.size()*sizeof(int))/sizeof(double)];
|
||||
data_out.second = data_ptr;
|
||||
uint64_t *data_int64 = reinterpret_cast<uint64_t*>(data_ptr);
|
||||
data_int64[0] = level;
|
||||
data_int64[1] = points.size();
|
||||
data_int64[2] = A.size();
|
||||
double *data = &data_ptr[3];
|
||||
for (size_t i=0; i<points.size(); i++) {
|
||||
data[3*i+0] = points[i].x;
|
||||
data[3*i+1] = points[i].y;
|
||||
data[3*i+2] = points[i].z;
|
||||
}
|
||||
int *data_int = reinterpret_cast<int*>(&data[3*points.size()]);
|
||||
for (size_t i=0; i<A.size(); i++) {
|
||||
data_int[3*i+0] = A[i];
|
||||
data_int[3*i+1] = B[i];
|
||||
data_int[3*i+2] = C[i];
|
||||
}
|
||||
}
|
||||
return data_out;
|
||||
}
|
||||
void TriMesh::unpack( const std::pair<size_t,void*>& data_in )
|
||||
{
|
||||
uint64_t *data_int64 = reinterpret_cast<uint64_t*>(data_in.second);
|
||||
const double *data = reinterpret_cast<const double*>(data_in.second);
|
||||
int level = data_int64[0];
|
||||
uint64_t N_P = data_int64[1];
|
||||
uint64_t N_A = data_int64[2];
|
||||
data = &data[3];
|
||||
if ( level==0 ) {
|
||||
size_t size = (3+3*N_P)*sizeof(double)+3*N_A*sizeof(int);
|
||||
ASSERT(size==data_in.first);
|
||||
vertices.reset( new PointList(N_P) );
|
||||
std::vector<Point>& points = vertices->points;
|
||||
for (size_t i=0; i<points.size(); i++) {
|
||||
points[i].x = data[3*i+0];
|
||||
points[i].y = data[3*i+1];
|
||||
points[i].z = data[3*i+2];
|
||||
}
|
||||
const int *data_int = reinterpret_cast<const int*>(&data[3*N_P]);
|
||||
A.resize(N_A);
|
||||
B.resize(N_A);
|
||||
C.resize(N_A);
|
||||
for (size_t i=0; i<A.size(); i++) {
|
||||
A[i] = data_int[3*i+0];
|
||||
B[i] = data_int[3*i+1];
|
||||
C[i] = data_int[3*i+2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
|
50
IO/Mesh.h
50
IO/Mesh.h
@ -20,6 +20,12 @@ class Mesh
|
||||
public:
|
||||
//! Destructor
|
||||
virtual ~Mesh();
|
||||
//! Mesh class name (eg. PointList)
|
||||
virtual std::string className() const = 0;
|
||||
//! Pack the data
|
||||
virtual std::pair<size_t,void*> pack( int level ) const = 0;
|
||||
//! Unpack the data
|
||||
virtual void unpack( const std::pair<size_t,void*>& data ) = 0;
|
||||
protected:
|
||||
//! Empty constructor
|
||||
Mesh();
|
||||
@ -40,6 +46,12 @@ public:
|
||||
PointList( size_t N );
|
||||
//! Destructor
|
||||
virtual ~PointList();
|
||||
//! Mesh class name
|
||||
virtual std::string className() const { return "PointList"; }
|
||||
//! Pack the data
|
||||
virtual std::pair<size_t,void*> pack( int level ) const;
|
||||
//! Unpack the data
|
||||
virtual void unpack( const std::pair<size_t,void*>& data );
|
||||
public:
|
||||
std::vector<Point> points; //!< List of points vertex
|
||||
};
|
||||
@ -62,6 +74,12 @@ public:
|
||||
TriMesh( const TriList& );
|
||||
//! Destructor
|
||||
virtual ~TriMesh();
|
||||
//! Mesh class name
|
||||
virtual std::string className() const { return "TriMesh"; }
|
||||
//! Pack the data
|
||||
virtual std::pair<size_t,void*> pack( int level ) const;
|
||||
//! Unpack the data
|
||||
virtual void unpack( const std::pair<size_t,void*>& data );
|
||||
public:
|
||||
std::shared_ptr<PointList> vertices; //!< List of verticies
|
||||
std::vector<int> A; //!< First vertex
|
||||
@ -84,6 +102,12 @@ public:
|
||||
TriList( const TriMesh& );
|
||||
//! Destructor
|
||||
virtual ~TriList();
|
||||
//! Mesh class name
|
||||
virtual std::string className() const { return "TriList"; }
|
||||
//! Pack the data
|
||||
virtual std::pair<size_t,void*> pack( int level ) const;
|
||||
//! Unpack the data
|
||||
virtual void unpack( const std::pair<size_t,void*>& data );
|
||||
public:
|
||||
std::vector<Point> A; //!< First vertex
|
||||
std::vector<Point> B; //!< Second vertex
|
||||
@ -92,15 +116,35 @@ public:
|
||||
|
||||
|
||||
|
||||
/*! \class Variable
|
||||
\brief A base class fore variables
|
||||
*/
|
||||
struct Variable
|
||||
{
|
||||
public:
|
||||
//! Internal variables
|
||||
int dim;
|
||||
std::string name;
|
||||
std::vector<double> data;
|
||||
//! Empty constructor
|
||||
Variable() {}
|
||||
//! Destructor
|
||||
virtual ~Variable() {}
|
||||
protected:
|
||||
//! Empty constructor
|
||||
Variable(const Variable&);
|
||||
Variable& operator=(const Variable&);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*! \class MeshDataStruct
|
||||
\brief A class used to hold database info for saving a mesh
|
||||
*/
|
||||
struct MeshDataStruct {
|
||||
std::string meshName;
|
||||
std::shared_ptr<Mesh> mesh;
|
||||
//std::vector<std::string> dataName;
|
||||
//std::vector<int> dataType;
|
||||
//std::vector<double*> data;
|
||||
std::vector<std::shared_ptr<Variable> > vars;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/Mesh.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <vector>
|
||||
@ -25,7 +26,232 @@ inline std::string deblank( const std::string& str )
|
||||
}
|
||||
|
||||
|
||||
// MeshDatabase::MeshDatabase
|
||||
|
||||
/****************************************************
|
||||
* Pack/unpack data from a buffer *
|
||||
****************************************************/
|
||||
template<class TYPE>
|
||||
size_t packsize( const TYPE& rhs );
|
||||
template<class TYPE>
|
||||
void pack( const TYPE& rhs, char *buffer );
|
||||
template<class TYPE>
|
||||
void unpack( TYPE& data, const char *buffer );
|
||||
// std::vector
|
||||
template<class TYPE>
|
||||
size_t packsize( const std::vector<TYPE>& rhs )
|
||||
{
|
||||
size_t bytes = sizeof(size_t);
|
||||
for (size_t i=0; i<rhs.size(); i++)
|
||||
bytes += packsize(rhs[i]);
|
||||
return bytes;
|
||||
}
|
||||
template<class TYPE>
|
||||
void pack( const std::vector<TYPE>& rhs, char *buffer )
|
||||
{
|
||||
size_t size = rhs.size();
|
||||
memcpy(buffer,&size,sizeof(size_t));
|
||||
size_t pos = sizeof(size_t);
|
||||
for (int i=0; i<rhs.size(); i++) {
|
||||
pack(rhs[i],&buffer[pos]);
|
||||
pos += packsize(rhs[i]);
|
||||
}
|
||||
}
|
||||
template<class TYPE>
|
||||
void unpack( std::vector<TYPE>& data, const char *buffer )
|
||||
{
|
||||
size_t size;
|
||||
memcpy(&size,buffer,sizeof(size_t));
|
||||
data.clear();
|
||||
data.resize(size);
|
||||
size_t pos = sizeof(size_t);
|
||||
for (int i=0; i<data.size(); i++) {
|
||||
unpack(data[i],&buffer[pos]);
|
||||
pos += packsize(data[i]);
|
||||
}
|
||||
}
|
||||
// std::pair
|
||||
template<class TYPE1, class TYPE2>
|
||||
size_t packsize( const std::pair<TYPE1,TYPE2>& rhs )
|
||||
{
|
||||
return packsize(rhs.first)+packsize(rhs.second);
|
||||
}
|
||||
template<class TYPE1, class TYPE2>
|
||||
void pack( const std::pair<TYPE1,TYPE2>& rhs, char *buffer )
|
||||
{
|
||||
pack(rhs.first,buffer);
|
||||
pack(rhs.second,&buffer[packsize(rhs.first)]);
|
||||
}
|
||||
template<class TYPE1, class TYPE2>
|
||||
void unpack( std::pair<TYPE1,TYPE2>& data, const char *buffer )
|
||||
{
|
||||
unpack(data.first,buffer);
|
||||
unpack(data.second,&buffer[packsize(data.first)]);
|
||||
}
|
||||
// std::map
|
||||
template<class TYPE1, class TYPE2>
|
||||
size_t packsize( const std::map<TYPE1,TYPE2>& rhs )
|
||||
{
|
||||
size_t bytes = sizeof(size_t);
|
||||
typename std::map<TYPE1,TYPE2>::const_iterator it;
|
||||
for (it=rhs.begin(); it!=rhs.end(); ++it) {
|
||||
bytes += packsize(it->first);
|
||||
bytes += packsize(it->second);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
template<class TYPE1, class TYPE2>
|
||||
void pack( const std::map<TYPE1,TYPE2>& rhs, char *buffer )
|
||||
{
|
||||
size_t N = rhs.size();
|
||||
pack(N,buffer);
|
||||
size_t pos = sizeof(size_t);
|
||||
typename std::map<TYPE1,TYPE2>::const_iterator it;
|
||||
for (it=rhs.begin(); it!=rhs.end(); ++it) {
|
||||
pack(it->first,&buffer[pos]); pos+=packsize(it->first);
|
||||
pack(it->second,&buffer[pos]); pos+=packsize(it->second);
|
||||
}
|
||||
}
|
||||
template<class TYPE1, class TYPE2>
|
||||
void unpack( std::map<TYPE1,TYPE2>& data, const char *buffer )
|
||||
{
|
||||
size_t N = 0;
|
||||
unpack(N,buffer);
|
||||
size_t pos = sizeof(size_t);
|
||||
data.clear();
|
||||
for (size_t i=0; i<N; i++) {
|
||||
std::pair<TYPE1,TYPE2> tmp;
|
||||
unpack(tmp.first,&buffer[pos]); pos+=packsize(tmp.first);
|
||||
unpack(tmp.second,&buffer[pos]); pos+=packsize(tmp.second);
|
||||
data.insert(tmp);
|
||||
}
|
||||
}
|
||||
// size_t
|
||||
template<>
|
||||
size_t packsize<size_t>( const size_t& rhs )
|
||||
{
|
||||
return sizeof(size_t);
|
||||
}
|
||||
template<>
|
||||
void pack<size_t>( const size_t& rhs, char *buffer )
|
||||
{
|
||||
memcpy(buffer,&rhs,sizeof(size_t));
|
||||
}
|
||||
template<>
|
||||
void unpack<size_t>( size_t& data, const char *buffer )
|
||||
{
|
||||
memcpy(&data,buffer,sizeof(size_t));
|
||||
}
|
||||
// unsigned char
|
||||
template<>
|
||||
size_t packsize<unsigned char>( const unsigned char& rhs )
|
||||
{
|
||||
return sizeof(unsigned char);
|
||||
}
|
||||
template<>
|
||||
void pack<unsigned char>( const unsigned char& rhs, char *buffer )
|
||||
{
|
||||
memcpy(buffer,&rhs,sizeof(unsigned char));
|
||||
}
|
||||
template<>
|
||||
void unpack<unsigned char>( unsigned char& data, const char *buffer )
|
||||
{
|
||||
memcpy(&data,buffer,sizeof(unsigned char));
|
||||
}
|
||||
// std::string
|
||||
template<>
|
||||
size_t packsize<std::string>( const std::string& rhs )
|
||||
{
|
||||
return rhs.size()+1;
|
||||
}
|
||||
template<>
|
||||
void pack<std::string>( const std::string& rhs, char *buffer )
|
||||
{
|
||||
memcpy(buffer,rhs.c_str(),rhs.size()+1);
|
||||
}
|
||||
template<>
|
||||
void unpack<std::string>( std::string& data, const char *buffer )
|
||||
{
|
||||
data = std::string(buffer);
|
||||
}
|
||||
// MeshType
|
||||
template<>
|
||||
size_t packsize<MeshType>( const MeshType& rhs )
|
||||
{
|
||||
return sizeof(MeshType);
|
||||
}
|
||||
template<>
|
||||
void pack<MeshType>( const MeshType& rhs, char *buffer )
|
||||
{
|
||||
memcpy(buffer,&rhs,sizeof(MeshType));
|
||||
}
|
||||
template<>
|
||||
void unpack<MeshType>( MeshType& data, const char *buffer )
|
||||
{
|
||||
memcpy(&data,buffer,sizeof(MeshType));
|
||||
}
|
||||
// DatabaseEntry
|
||||
template<>
|
||||
size_t packsize<DatabaseEntry>( const DatabaseEntry& rhs )
|
||||
{
|
||||
return packsize(rhs.name)+packsize(rhs.file)+packsize(rhs.offset);
|
||||
}
|
||||
template<>
|
||||
void pack<DatabaseEntry>( const DatabaseEntry& rhs, char *buffer )
|
||||
{
|
||||
size_t i=0;
|
||||
pack(rhs.name,&buffer[i]); i+=packsize(rhs.name);
|
||||
pack(rhs.file,&buffer[i]); i+=packsize(rhs.file);
|
||||
pack(rhs.offset,&buffer[i]); i+=packsize(rhs.offset);
|
||||
}
|
||||
template<>
|
||||
void unpack<DatabaseEntry>( DatabaseEntry& data, const char *buffer )
|
||||
{
|
||||
size_t i=0;
|
||||
unpack(data.name,&buffer[i]); i+=packsize(data.name);
|
||||
unpack(data.file,&buffer[i]); i+=packsize(data.file);
|
||||
unpack(data.offset,&buffer[i]); i+=packsize(data.offset);
|
||||
}
|
||||
// MeshDatabase
|
||||
template<>
|
||||
size_t packsize<MeshDatabase>( const MeshDatabase& data )
|
||||
{
|
||||
return packsize(data.name)
|
||||
+ packsize(data.type)
|
||||
+ packsize(data.meshClass)
|
||||
+ packsize(data.format)
|
||||
+ packsize(data.domains)
|
||||
+ packsize(data.variables)
|
||||
+ packsize(data.variable_data);
|
||||
}
|
||||
template<>
|
||||
void pack<MeshDatabase>( const MeshDatabase& rhs, char *buffer )
|
||||
{
|
||||
size_t i = 0;
|
||||
pack(rhs.name,&buffer[i]); i+=packsize(rhs.name);
|
||||
pack(rhs.type,&buffer[i]); i+=packsize(rhs.type);
|
||||
pack(rhs.meshClass,&buffer[i]); i+=packsize(rhs.meshClass);
|
||||
pack(rhs.format,&buffer[i]); i+=packsize(rhs.format);
|
||||
pack(rhs.domains,&buffer[i]); i+=packsize(rhs.domains);
|
||||
pack(rhs.variables,&buffer[i]); i+=packsize(rhs.variables);
|
||||
pack(rhs.variable_data,&buffer[i]); i+=packsize(rhs.variable_data);
|
||||
}
|
||||
template<>
|
||||
void unpack<MeshDatabase>( MeshDatabase& data, const char *buffer )
|
||||
{
|
||||
size_t i=0;
|
||||
unpack(data.name,&buffer[i]); i+=packsize(data.name);
|
||||
unpack(data.type,&buffer[i]); i+=packsize(data.type);
|
||||
unpack(data.meshClass,&buffer[i]); i+=packsize(data.meshClass);
|
||||
unpack(data.format,&buffer[i]); i+=packsize(data.format);
|
||||
unpack(data.domains,&buffer[i]); i+=packsize(data.domains);
|
||||
unpack(data.variables,&buffer[i]); i+=packsize(data.variables);
|
||||
unpack(data.variable_data,&buffer[i]); i+=packsize(data.variable_data);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* MeshDatabase *
|
||||
****************************************************/
|
||||
MeshDatabase::MeshDatabase()
|
||||
{
|
||||
}
|
||||
@ -36,94 +262,88 @@ MeshDatabase::MeshDatabase(const MeshDatabase& rhs)
|
||||
{
|
||||
name = rhs.name;
|
||||
type = rhs.type;
|
||||
meshClass = rhs.meshClass;
|
||||
format = rhs.format;
|
||||
domains = rhs.domains;
|
||||
file = rhs.file;
|
||||
variables = rhs.variables;
|
||||
variable_data = rhs.variable_data;
|
||||
}
|
||||
MeshDatabase& MeshDatabase::operator=(const MeshDatabase& rhs)
|
||||
{
|
||||
this->name = rhs.name;
|
||||
this->type = rhs.type;
|
||||
this->meshClass = rhs.meshClass;
|
||||
this->format = rhs.format;
|
||||
this->domains = rhs.domains;
|
||||
this->file = rhs.file;
|
||||
this->variables = rhs.variables;
|
||||
this->variable_data = rhs.variable_data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Pack/Unpack the MeshDatabase to/from buffer
|
||||
static size_t MeshDatabaseSize( const MeshDatabase& data )
|
||||
/****************************************************
|
||||
* Split a line into pieces *
|
||||
****************************************************/
|
||||
static inline size_t find( const char *line, char key )
|
||||
{
|
||||
size_t bytes = 2;
|
||||
bytes += data.name.size()+1;
|
||||
bytes += sizeof(int);
|
||||
for (size_t i=0; i<data.domains.size(); i++)
|
||||
bytes += data.domains[i].size()+1;
|
||||
bytes += sizeof(int);
|
||||
for (size_t i=0; i<data.file.size(); i++)
|
||||
bytes += data.file[i].size()+1;
|
||||
bytes += sizeof(int);
|
||||
for (size_t i=0; i<data.variables.size(); i++)
|
||||
bytes += data.variables[i].size()+1;
|
||||
return bytes;
|
||||
size_t i=0;
|
||||
while ( 1 ) {
|
||||
if ( line[i]==key || line[i]<32 || line[i]==0 )
|
||||
break;
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
static void pack( const MeshDatabase& data, char *buffer )
|
||||
static inline std::vector<std::string> splitList( const char *line )
|
||||
{
|
||||
buffer[0] = static_cast<char>(data.type);
|
||||
buffer[1] = data.format;
|
||||
size_t pos = 2;
|
||||
memcpy(&buffer[pos],data.name.c_str(),data.name.size()+1);
|
||||
pos += data.name.size()+1;
|
||||
*reinterpret_cast<int*>(&buffer[pos]) = data.domains.size();
|
||||
pos += sizeof(int);
|
||||
for (size_t i=0; i<data.domains.size(); i++) {
|
||||
memcpy(&buffer[pos],data.domains[i].c_str(),data.domains[i].size()+1);
|
||||
pos += data.domains[i].size()+1;
|
||||
}
|
||||
*reinterpret_cast<int*>(&buffer[pos]) = data.file.size();
|
||||
pos += sizeof(int);
|
||||
for (size_t i=0; i<data.file.size(); i++) {
|
||||
memcpy(&buffer[pos],data.file[i].c_str(),data.file[i].size()+1);
|
||||
pos += data.file[i].size()+1;
|
||||
}
|
||||
*reinterpret_cast<int*>(&buffer[pos]) = data.variables.size();
|
||||
pos += sizeof(int);
|
||||
for (size_t i=0; i<data.variables.size(); i++) {
|
||||
memcpy(&buffer[pos],data.variables[i].c_str(),data.variables[i].size()+1);
|
||||
pos += data.variables[i].size()+1;
|
||||
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;
|
||||
}
|
||||
static MeshDatabase unpack( const char *buffer )
|
||||
|
||||
|
||||
/****************************************************
|
||||
* DatabaseEntry *
|
||||
****************************************************/
|
||||
std::string DatabaseEntry::write( ) const
|
||||
{
|
||||
MeshDatabase data;
|
||||
data.type = static_cast<MeshType>(buffer[0]);
|
||||
data.format = buffer[1];
|
||||
size_t pos = 2;
|
||||
data.name = std::string(&buffer[pos]);
|
||||
pos += data.name.size()+1;
|
||||
int N_domains = *reinterpret_cast<const int*>(&buffer[pos]);
|
||||
pos += sizeof(int);
|
||||
data.domains.resize(N_domains);
|
||||
for (size_t i=0; i<data.domains.size(); i++) {
|
||||
data.domains[i] = std::string(&buffer[pos]);
|
||||
pos += data.domains[i].size()+1;
|
||||
}
|
||||
int N_file = *reinterpret_cast<const int*>(&buffer[pos]);
|
||||
pos += sizeof(int);
|
||||
data.file.resize(N_file);
|
||||
for (size_t i=0; i<data.file.size(); i++) {
|
||||
data.file[i] = std::string(&buffer[pos]);
|
||||
pos += data.file[i].size()+1;
|
||||
}
|
||||
int N_variables = *reinterpret_cast<const int*>(&buffer[pos]);
|
||||
pos += sizeof(int);
|
||||
data.variables.resize(N_variables);
|
||||
for (size_t i=0; i<data.variables.size(); i++) {
|
||||
data.variables[i] = std::string(&buffer[pos]);
|
||||
pos += data.variables[i].size()+1;
|
||||
}
|
||||
return data;
|
||||
char tmp[1000];
|
||||
sprintf(tmp,"%s; %s; %lu",name.c_str(),file.c_str(),offset);
|
||||
return std::string(tmp);
|
||||
}
|
||||
DatabaseEntry::DatabaseEntry( const char* 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);
|
||||
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());
|
||||
name = list[0];
|
||||
file = list[1];
|
||||
offset = atol(list[2].c_str());
|
||||
}
|
||||
|
||||
|
||||
@ -138,12 +358,12 @@ std::vector<MeshDatabase> gatherAll( const std::vector<MeshDatabase>& meshes, MP
|
||||
// First pack the mesh data to local buffers
|
||||
size_t localsize = 0;
|
||||
for (size_t i=0; i<meshes.size(); i++)
|
||||
localsize += MeshDatabaseSize(meshes[i]);
|
||||
localsize += packsize(meshes[i]);
|
||||
char *localbuf = new char[localsize];
|
||||
size_t pos = 0;
|
||||
for (size_t i=0; i<meshes.size(); i++) {
|
||||
pack( meshes[i], &localbuf[pos] );
|
||||
pos += MeshDatabaseSize(meshes[i]);
|
||||
pos += packsize(meshes[i]);
|
||||
}
|
||||
// Get the number of bytes each processor will be sending/recieving
|
||||
int sendsize = static_cast<int>(localsize);
|
||||
@ -151,8 +371,8 @@ std::vector<MeshDatabase> gatherAll( const std::vector<MeshDatabase>& meshes, MP
|
||||
MPI_Allgather(&sendsize,1,MPI_INT,recvsize,1,MPI_INT,comm);
|
||||
size_t globalsize = recvsize[0];
|
||||
int *disp = new int[size];
|
||||
disp[0] = 0;
|
||||
for (size_t i=1; i<size; i++) {
|
||||
disp[0] = 0;
|
||||
for (int i=1; i<size; i++) {
|
||||
disp[i] = disp[i-1] + recvsize[i];
|
||||
globalsize += recvsize[i];
|
||||
}
|
||||
@ -163,18 +383,18 @@ std::vector<MeshDatabase> gatherAll( const std::vector<MeshDatabase>& meshes, MP
|
||||
std::map<std::string,MeshDatabase> data;
|
||||
pos = 0;
|
||||
while ( pos < globalsize ) {
|
||||
MeshDatabase tmp = unpack(&globalbuf[pos]);
|
||||
pos += MeshDatabaseSize(tmp);
|
||||
MeshDatabase tmp;
|
||||
unpack(tmp,&globalbuf[pos]);
|
||||
pos += packsize(tmp);
|
||||
std::map<std::string,MeshDatabase>::iterator it = data.find(tmp.name);
|
||||
if ( it==data.end() ) {
|
||||
data[tmp.name] = tmp;
|
||||
} else {
|
||||
for (size_t i=0; i<tmp.domains.size(); i++)
|
||||
it->second.domains.push_back(tmp.domains[i]);
|
||||
for (size_t i=0; i<tmp.domains.size(); i++)
|
||||
it->second.file.push_back(tmp.file[i]);
|
||||
for (size_t i=0; i<tmp.variables.size(); i++)
|
||||
it->second.variables.push_back(tmp.variables[i]);
|
||||
it->second.variable_data.insert(tmp.variable_data.begin(),tmp.variable_data.end());
|
||||
}
|
||||
}
|
||||
for (std::map<std::string,MeshDatabase>::iterator it=data.begin(); it!=data.end(); ++it) {
|
||||
@ -204,51 +424,28 @@ void write( const std::vector<MeshDatabase>& meshes, const std::string& filename
|
||||
FILE *fid = fopen(filename.c_str(),"wb");
|
||||
for (size_t i=0; i<meshes.size(); i++) {
|
||||
fprintf(fid,"%s\n",meshes[i].name.c_str());
|
||||
fprintf(fid," format: %i\n",static_cast<int>(meshes[i].format));
|
||||
fprintf(fid," type: %i\n",static_cast<int>(meshes[i].type));
|
||||
fprintf(fid," domains: ");
|
||||
for (size_t j=0; j<meshes[i].domains.size(); j++) {
|
||||
fprintf(fid,"%s; ",meshes[i].domains[j].c_str());
|
||||
}
|
||||
fprintf(fid,"\n");
|
||||
fprintf(fid," file: ");
|
||||
for (size_t j=0; j<meshes[i].file.size(); j++) {
|
||||
fprintf(fid,"%s; ",meshes[i].file[j].c_str());
|
||||
}
|
||||
fprintf(fid,"\n");
|
||||
fprintf(fid," meshClass: %s\n",meshes[i].meshClass.c_str());
|
||||
fprintf(fid," format: %i\n",static_cast<int>(meshes[i].format));
|
||||
for (size_t j=0; j<meshes[i].domains.size(); j++)
|
||||
fprintf(fid," domain: %s\n",meshes[i].domains[j].write().c_str());
|
||||
fprintf(fid," variables: ");
|
||||
for (size_t j=0; j<meshes[i].variables.size(); j++) {
|
||||
fprintf(fid,"%s; ",meshes[i].variables[j].c_str());
|
||||
}
|
||||
fprintf(fid,"\n");
|
||||
std::map<std::pair<std::string,std::string>,DatabaseEntry>::const_iterator it;
|
||||
for (it=meshes[i].variable_data.begin(); it!=meshes[i].variable_data.end(); ++it) {
|
||||
const char* domain = it->first.first.c_str();
|
||||
const char* variable = it->first.second.c_str();
|
||||
fprintf(fid," variable(%s,%s): %s\n",domain,variable,it->second.write().c_str());
|
||||
}
|
||||
}
|
||||
fclose(fid);
|
||||
PROFILE_STOP("write");
|
||||
}
|
||||
|
||||
|
||||
// Helper function to split a line into the sub variables
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//! Read the mesh databases from a file
|
||||
std::vector<MeshDatabase> read( const std::string& filename )
|
||||
{
|
||||
@ -271,12 +468,22 @@ std::vector<MeshDatabase> read( const std::string& filename )
|
||||
meshes.back().format = static_cast<unsigned char>(atoi(&line[10]));
|
||||
} else if ( strncmp(line," type:",8)==0 ) {
|
||||
meshes.back().type = static_cast<MeshType>(atoi(&line[8]));
|
||||
} else if ( strncmp(line," domains:",11)==0 ) {
|
||||
meshes.back().domains = splitList(&line[11]);
|
||||
} else if ( strncmp(line," file:",8)==0 ) {
|
||||
meshes.back().file = splitList(&line[8]);
|
||||
} else if ( strncmp(line," meshClass:",13)==0 ) {
|
||||
meshes.back().meshClass = deblank(std::string(&line[13]));
|
||||
} else if ( strncmp(line," domain:",10)==0 ) {
|
||||
DatabaseEntry data(&line[10]);
|
||||
meshes.back().domains.push_back(data);
|
||||
} else if ( strncmp(line," variables:",13)==0 ) {
|
||||
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::pair<std::string,std::string> key(domain,variable);
|
||||
DatabaseEntry data(&line[i2+1]);
|
||||
meshes.back().variable_data.insert(
|
||||
std::pair<std::pair<std::string,std::string>,DatabaseEntry>(key,data) );
|
||||
} else {
|
||||
ERROR("Error reading line");
|
||||
}
|
||||
@ -288,6 +495,20 @@ std::vector<MeshDatabase> read( const std::string& filename )
|
||||
}
|
||||
|
||||
|
||||
// Return the mesh type
|
||||
IO::MeshType meshType( std::shared_ptr<IO::Mesh> mesh )
|
||||
{
|
||||
IO::MeshType type = IO::MeshType::Unknown;
|
||||
if ( std::dynamic_pointer_cast<IO::PointList>(mesh)!=NULL ) {
|
||||
type = IO::MeshType::PointMesh;
|
||||
} else if ( std::dynamic_pointer_cast<IO::TriList>(mesh)!=NULL || std::dynamic_pointer_cast<IO::TriMesh>(mesh)!=NULL ) {
|
||||
type = IO::MeshType::SurfaceMesh;
|
||||
} else {
|
||||
ERROR("Unknown mesh");
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#ifdef USE_MPI
|
||||
#include "mpi.h"
|
||||
@ -12,21 +13,39 @@
|
||||
typedef int MPI_Comm;
|
||||
#endif
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
class Mesh;
|
||||
|
||||
|
||||
//! Enum to identify mesh type
|
||||
enum class MeshType : char { PointMesh=1, SurfaceMesh=2, VolumeMesh=3 };
|
||||
enum class MeshType : char { PointMesh=1, SurfaceMesh=2, VolumeMesh=3, Unknown=-1 };
|
||||
|
||||
|
||||
//! Helper struct for containing offsets for the mesh info
|
||||
struct DatabaseEntry {
|
||||
std::string name; //!< Name of the entry
|
||||
std::string file; //!< Name of the file containing the entry
|
||||
size_t offset; //!< Offset in the file to start reading
|
||||
std::string write( ) const; //!< Convert the data to a string
|
||||
void read( const char* line ); //!< Convert the string to data
|
||||
void read( const std::string& line ); //!< Convert the string to data
|
||||
DatabaseEntry( ) {} //!< Empty constructor
|
||||
DatabaseEntry( const char* line ); //!< Convert the string to data
|
||||
~DatabaseEntry() {} //!< Destructor
|
||||
};
|
||||
|
||||
|
||||
//! Structure to hold the info about the meshes
|
||||
struct MeshDatabase {
|
||||
std::string name; //!< Name of the mesh
|
||||
MeshType type; //!< Mesh type
|
||||
std::string meshClass; //!< Mesh class
|
||||
unsigned char format; //!< Data format
|
||||
std::vector<std::string> domains; //!< List of the domains
|
||||
std::vector<std::string> file; //!< File containing the mesh data for the given domain
|
||||
std::vector<DatabaseEntry> domains; //!< List of the domains
|
||||
std::vector<std::string> variables; //!< List of the variables
|
||||
std::map<std::pair<std::string,std::string>,DatabaseEntry> variable_data; //!< Data for the variables
|
||||
public:
|
||||
MeshDatabase();
|
||||
~MeshDatabase();
|
||||
@ -47,6 +66,10 @@ void write( const std::vector<MeshDatabase>& meshes, const std::string& filename
|
||||
std::vector<MeshDatabase> read( const std::string& filename );
|
||||
|
||||
|
||||
//! Return the mesh type
|
||||
IO::MeshType meshType( std::shared_ptr<IO::Mesh> mesh );
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "IO/Reader.h"
|
||||
#include "IO/Mesh.h"
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
@ -9,6 +10,35 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// List the timesteps in the given directors (dumps.LBPM)
|
||||
std::vector<std::string> IO::readTimesteps( const std::string& filename )
|
||||
{
|
||||
@ -47,7 +77,7 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
|
||||
std::shared_ptr<IO::Mesh> mesh;
|
||||
if ( meshDatabase.format==1 ) {
|
||||
// Old format (binary doubles)
|
||||
std::string filename = path + "/" + timestep + "/" + meshDatabase.file[domain];
|
||||
std::string filename = path + "/" + timestep + "/" + meshDatabase.domains[domain].file;
|
||||
FILE *fid = fopen(filename.c_str(),"rb");
|
||||
INSIST(fid!=NULL,"Error opening file");
|
||||
fseek( fid, 0, SEEK_END );
|
||||
@ -93,6 +123,30 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
|
||||
ERROR("Unknown mesh type");
|
||||
}
|
||||
delete [] data;
|
||||
} else if ( meshDatabase.format==2 ) {
|
||||
const DatabaseEntry& database = meshDatabase.domains[domain];
|
||||
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,0x100000,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);
|
||||
if ( meshDatabase.meshClass=="PointList" ) {
|
||||
mesh.reset( new IO::PointList() );
|
||||
} else if ( meshDatabase.meshClass=="TriMesh" ) {
|
||||
mesh.reset( new IO::TriMesh() );
|
||||
} else if ( meshDatabase.meshClass=="TriList" ) {
|
||||
mesh.reset( new IO::TriList() );
|
||||
} else {
|
||||
ERROR("Unknown mesh class");
|
||||
}
|
||||
mesh->unpack( std::pair<size_t,void*>(bytes,data) );
|
||||
delete [] data;
|
||||
} else {
|
||||
ERROR("Unknown format");
|
||||
}
|
||||
@ -101,3 +155,12 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
|
||||
}
|
||||
|
||||
|
||||
// Read the given variable for the given mesh domain
|
||||
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>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -23,7 +23,12 @@ std::vector<IO::MeshDatabase> getMeshList( const std::string& path, const std::s
|
||||
|
||||
//! Read the given mesh domain
|
||||
std::shared_ptr<IO::Mesh> getMesh( const std::string& path, const std::string& timestep,
|
||||
const MeshDatabase& mesh, int domain );
|
||||
const MeshDatabase& meshDatabase, int domain );
|
||||
|
||||
|
||||
//! Read the given mesh domain
|
||||
std::shared_ptr<IO::Variable> getVariable( const std::string& path, const std::string& timestep,
|
||||
const MeshDatabase& meshDatabase, int domain, const std::string& variable );
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
static bool global_summary_created = false;
|
||||
|
||||
|
||||
// Write the mesh data in the original format
|
||||
static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO::MeshDataStruct>& meshData, const char* path )
|
||||
{
|
||||
@ -18,20 +19,29 @@ static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
|
||||
std::vector<IO::MeshDatabase> meshes_written;
|
||||
for (size_t i=0; i<meshData.size(); i++) {
|
||||
char domain[100], filename[100], fullpath[200];
|
||||
sprintf(domain,"%05i",rank);
|
||||
char domainname[100], filename[100], fullpath[200];
|
||||
sprintf(domainname,"%05i",rank);
|
||||
sprintf(filename,"%s.%05i",meshData[i].meshName.c_str(),rank);
|
||||
sprintf(fullpath,"%s/%s",path,filename);
|
||||
FILE *fid = fopen(fullpath,"wb");
|
||||
std::shared_ptr<IO::Mesh> mesh = meshData[i].mesh;
|
||||
IO::MeshDatabase mesh_entry;
|
||||
mesh_entry.name = meshData[i].meshName;
|
||||
mesh_entry.type = meshType(mesh);
|
||||
mesh_entry.meshClass = meshData[i].mesh->className();
|
||||
mesh_entry.format = 1;
|
||||
IO::DatabaseEntry domain;
|
||||
domain.name = domainname;
|
||||
domain.file = filename;
|
||||
domain.offset = 0;
|
||||
mesh_entry.domains.push_back(domain);
|
||||
mesh_entry.file.push_back(filename);
|
||||
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 );
|
||||
}
|
||||
if ( std::dynamic_pointer_cast<IO::PointList>(mesh)!=NULL ) {
|
||||
// List of points
|
||||
mesh_entry.type = IO::MeshType::PointMesh;
|
||||
std::shared_ptr<IO::PointList> pointlist = std::dynamic_pointer_cast<IO::PointList>(mesh);
|
||||
const std::vector<Point>& P = pointlist->points;
|
||||
for (size_t i=0; i<P.size(); i++) {
|
||||
@ -41,7 +51,6 @@ static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO
|
||||
}
|
||||
} else if ( std::dynamic_pointer_cast<IO::TriList>(mesh)!=NULL || std::dynamic_pointer_cast<IO::TriMesh>(mesh)!=NULL ) {
|
||||
// Triangle mesh
|
||||
mesh_entry.type = IO::MeshType::SurfaceMesh;
|
||||
std::shared_ptr<IO::TriList> trilist = IO::getTriList(mesh);
|
||||
const std::vector<Point>& A = trilist->A;
|
||||
const std::vector<Point>& B = trilist->B;
|
||||
@ -57,16 +66,84 @@ static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO
|
||||
ERROR("Unknown mesh");
|
||||
}
|
||||
fclose(fid);
|
||||
std::unique(mesh_entry.variables.begin(),mesh_entry.variables.end());
|
||||
meshes_written.push_back(mesh_entry);
|
||||
}
|
||||
return meshes_written;
|
||||
}
|
||||
|
||||
|
||||
// Write the mesh data
|
||||
void IO::writeData( int timestep, const std::vector<IO::MeshDataStruct>& meshData )
|
||||
// Write a mesh (and variables) to a file
|
||||
static IO::MeshDatabase write_domain( FILE *fid, const std::string& filename,
|
||||
const IO::MeshDataStruct& mesh, int format )
|
||||
{
|
||||
int rank = -1;
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
|
||||
char domainname[10];
|
||||
sprintf(domainname,"%05i",rank);
|
||||
int level = 0;
|
||||
// Create the MeshDatabase
|
||||
IO::MeshDatabase database;
|
||||
database.name = mesh.meshName;
|
||||
database.type = meshType(mesh.mesh);
|
||||
database.meshClass = mesh.mesh->className();
|
||||
database.format = format;
|
||||
// Write the mesh
|
||||
IO::DatabaseEntry domain;
|
||||
domain.name = domainname;
|
||||
domain.file = filename;
|
||||
domain.offset = ftell(fid);
|
||||
database.domains.push_back(domain);
|
||||
std::pair<size_t,void*> data = mesh.mesh->pack(level);
|
||||
fprintf(fid,"Mesh: %s-%05i: %lu\n",mesh.meshName.c_str(),rank,data.first);
|
||||
fwrite(data.second,1,data.first,fid);
|
||||
fprintf(fid,"\n");
|
||||
delete [] (char*) data.second;
|
||||
// Write the variables
|
||||
for (size_t i=0; i<mesh.vars.size(); i++) {
|
||||
IO::DatabaseEntry variable;
|
||||
variable.name = mesh.vars[i]->name;
|
||||
variable.file = filename;
|
||||
variable.offset = ftell(fid);
|
||||
std::pair<std::string,std::string> key(domainname,variable.name);
|
||||
database.variables.push_back(variable.name);
|
||||
database.variable_data.insert(
|
||||
std::pair<std::pair<std::string,std::string>,IO::DatabaseEntry>(key,variable) );
|
||||
int dim = mesh.vars[i]->dim;
|
||||
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));
|
||||
fwrite(data,sizeof(double),dim*N,fid);
|
||||
fprintf(fid,"\n");
|
||||
}
|
||||
return database;
|
||||
}
|
||||
|
||||
|
||||
// Write the mesh data in the new format
|
||||
static std::vector<IO::MeshDatabase> writeMeshesNewFormat(
|
||||
const std::vector<IO::MeshDataStruct>& meshData, const char* path, int format )
|
||||
{
|
||||
int rank = -1;
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
|
||||
std::vector<IO::MeshDatabase> meshes_written;
|
||||
char filename[100], fullpath[200];
|
||||
sprintf(filename,"%05i",rank);
|
||||
sprintf(fullpath,"%s/%s",path,filename);
|
||||
FILE *fid = fopen(fullpath,"wb");
|
||||
for (size_t i=0; i<meshData.size(); i++) {
|
||||
std::shared_ptr<IO::Mesh> mesh = meshData[i].mesh;
|
||||
meshes_written.push_back( write_domain(fid,filename,meshData[i],format) );
|
||||
}
|
||||
fclose(fid);
|
||||
return meshes_written;
|
||||
}
|
||||
|
||||
|
||||
// Write the mesh data
|
||||
void IO::writeData( int timestep, const std::vector<IO::MeshDataStruct>& meshData, int format )
|
||||
{
|
||||
const int format = 1;
|
||||
int rank = -1;
|
||||
int size = 0;
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
|
||||
@ -81,6 +158,9 @@ void IO::writeData( int timestep, const std::vector<IO::MeshDataStruct>& meshDat
|
||||
if ( format == 1 ) {
|
||||
// Write the original triangle format
|
||||
meshes_written = writeMeshesOrigFormat( meshData, path );
|
||||
} else if ( format == 2 ) {
|
||||
// Write the new format
|
||||
meshes_written = writeMeshesNewFormat( meshData, path, format );
|
||||
} else {
|
||||
ERROR("Unknown format");
|
||||
}
|
||||
|
12
IO/Writer.h
12
IO/Writer.h
@ -13,7 +13,17 @@
|
||||
namespace IO {
|
||||
|
||||
|
||||
void writeData( int timestep, const std::vector<IO::MeshDataStruct>& meshData );
|
||||
/*!
|
||||
* @brief Write the data for the timestep
|
||||
* @details This function writes the mesh and variable data provided for the current timestep
|
||||
* @param[in] timestep The timestep iteration
|
||||
* @param[in] meshData The data to write
|
||||
* @param[in] format The data format to use:
|
||||
* 1 - Old mesh format (provided for backward compatibility, cannot write variables)
|
||||
* 2 - New format, 1 file/process, double precision
|
||||
* 3 - New format, 1 file/process, single precision (not finished)
|
||||
*/
|
||||
void writeData( int timestep, const std::vector<IO::MeshDataStruct>& meshData, int format );
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
@ -39,7 +39,8 @@ MACRO( VISIT_PLUGIN SRC_DIR TARGET )
|
||||
ADD_CUSTOM_TARGET(copy-${SRC_DIR})
|
||||
FOREACH( ConfigFile ${ConfigFiles} )
|
||||
ADD_CUSTOM_COMMAND(TARGET copy-${SRC_DIR} PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_DIR}/${ConfigFile}" "${CMAKE_CURRENT_BINARY_DIR}/${SRC_DIR}/${ConfigFile}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_DIR}/${ConfigFile}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${SRC_DIR}/${ConfigFile}"
|
||||
)
|
||||
ENDFOREACH()
|
||||
ADD_CUSTOM_TARGET(
|
||||
|
@ -177,10 +177,10 @@ ENDMACRO()
|
||||
# Macro to set the proper warnings
|
||||
MACRO ( SET_WARNINGS )
|
||||
IF ( USING_GCC )
|
||||
## Add gcc specific compiler options
|
||||
## -Wno-reorder: warning: "" will be initialized after "" when initialized here
|
||||
#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall ")
|
||||
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall ")
|
||||
# Add gcc specific compiler options
|
||||
# -Wno-reorder: warning: "" will be initialized after "" when initialized here
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-char-subscripts -Wno-comment -Wno-unused-variable -Wno-unused-but-set-variable")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-char-subscripts -Wno-comment -Wno-unused-variable -Wno-unused-but-set-variable")
|
||||
ELSEIF ( USING_MICROSOFT )
|
||||
# Add Microsoft specifc compiler options
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _SCL_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_WARNINGS /D _ITERATOR_DEBUG_LEVEL=0" )
|
||||
|
@ -3,14 +3,15 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
struct Point {
|
||||
Point() : x(0.0), y(0.0), z(0.0) {}
|
||||
Point(double xv,double yv,double zv) : x(xv), y(yv), z(zv) {}
|
||||
Point(const Point& rhs): x(rhs.x), y(rhs.y), z(rhs.z) {}
|
||||
Point& operator=(const Point& rhs) { this->x=rhs.x; this->y=rhs.y; this->z=rhs.z; }
|
||||
~Point() {}
|
||||
struct LBPM_Point {
|
||||
LBPM_Point() : x(0.0), y(0.0), z(0.0) {}
|
||||
LBPM_Point(double xv,double yv,double zv) : x(xv), y(yv), z(zv) {}
|
||||
LBPM_Point(const LBPM_Point& rhs): x(rhs.x), y(rhs.y), z(rhs.z) {}
|
||||
//Point& operator=(const Point& rhs) { this->x=rhs.x; this->y=rhs.y; this->z=rhs.z; return *this; }
|
||||
//~Point() {}
|
||||
double x,y,z;
|
||||
};
|
||||
typedef LBPM_Point Point;
|
||||
|
||||
inline Point operator+(const Point &A,const Point &B) {return Point(A.x+B.x,A.y+B.y,A.z+B.z);}
|
||||
inline Point operator-(const Point &A,const Point &B) {return Point(A.x-B.x,A.y-B.y,A.z-B.z);}
|
||||
|
@ -324,7 +324,7 @@ int main(int argc, char **argv)
|
||||
int sum = 0;
|
||||
double sum_local;
|
||||
double iVol_global = 1.0/(1.0*Nx*Ny*Nz*nprocs);
|
||||
double porosity;
|
||||
double porosity = 0;
|
||||
|
||||
DoubleArray SignDist(Nx,Ny,Nz);
|
||||
//.......................................................................
|
||||
@ -2165,7 +2165,22 @@ int main(int argc, char **argv)
|
||||
std::vector<IO::MeshDataStruct> meshData(1);
|
||||
meshData[0].meshName = "wn-tris";
|
||||
meshData[0].mesh = mesh;
|
||||
IO::writeData( bubbleCount, meshData );
|
||||
for (size_t k=0; k<meshData.size(); k++) {
|
||||
std::shared_ptr<IO::Variable> dist( new IO::Variable() );
|
||||
dist->name = "distance";
|
||||
dist->dim = 1;
|
||||
dist->data.resize(3*mesh->A.size());
|
||||
for (size_t i=0; i<mesh->A.size(); i++) {
|
||||
const Point& a = mesh->A[i];
|
||||
const Point& b = mesh->B[i];
|
||||
const Point& c = mesh->C[i];
|
||||
dist->data[3*i+0] = sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
|
||||
dist->data[3*i+1] = sqrt(b.x*b.x+b.y*b.y+b.z*b.z);
|
||||
dist->data[3*i+2] = sqrt(c.x*c.x+c.y*c.y+c.z*c.z);
|
||||
}
|
||||
meshData[k].vars.push_back(dist);
|
||||
}
|
||||
IO::writeData( bubbleCount, meshData, 2 );
|
||||
#else
|
||||
fclose(WN_TRIS);
|
||||
#endif
|
||||
|
@ -13,12 +13,21 @@
|
||||
#include "IO/Reader.h"
|
||||
#include "IO/Writer.h"
|
||||
|
||||
|
||||
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);
|
||||
return fabs(A.x-B.x)<=tol && fabs(A.y-B.y)<=tol && fabs(A.z-B.z)<=tol;
|
||||
}
|
||||
|
||||
|
||||
inline double distance( const Point& p )
|
||||
{
|
||||
return sqrt(p.x*p.x+p.y*p.y+p.z*p.z);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rank,nprocs;
|
||||
@ -66,16 +75,39 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
// Write the data
|
||||
// Create the variables
|
||||
std::shared_ptr<IO::Variable> dist_set1( new IO::Variable() );
|
||||
std::shared_ptr<IO::Variable> dist_trimesh( new IO::Variable() );
|
||||
std::shared_ptr<IO::Variable> dist_list( new IO::Variable() );
|
||||
dist_set1->dim = 1;
|
||||
dist_trimesh->dim = 1;
|
||||
dist_set1->name = "Distance";
|
||||
dist_trimesh->name = "Distance";
|
||||
dist_set1->data.resize( N_points );
|
||||
for (int i=0; i<N_points; i++)
|
||||
dist_set1->data[i] = distance(set1->points[i]);
|
||||
dist_trimesh->data.resize( 3*N_tri );
|
||||
for (int i=0; i<N_tri; i++) {
|
||||
dist_trimesh->data[3*i+0] = trimesh->A[i];
|
||||
dist_trimesh->data[3*i+1] = trimesh->B[i];
|
||||
dist_trimesh->data[3*i+2] = trimesh->C[i];
|
||||
}
|
||||
|
||||
// Create the MeshDataStruct
|
||||
std::vector<IO::MeshDataStruct> meshData(3);
|
||||
meshData[0].meshName = "pointmesh";
|
||||
meshData[0].mesh = set1;
|
||||
meshData[0].vars.push_back(dist_set1);
|
||||
meshData[1].meshName = "trimesh";
|
||||
meshData[1].mesh = trimesh;
|
||||
meshData[1].vars.push_back(dist_trimesh);
|
||||
meshData[2].meshName = "trilist";
|
||||
meshData[2].mesh = trilist;
|
||||
IO::writeData( 0, meshData );
|
||||
IO::writeData( 3, meshData );
|
||||
meshData[2].vars.push_back(dist_set1);
|
||||
|
||||
// Write the data
|
||||
IO::writeData( 0, meshData, 1 );
|
||||
IO::writeData( 3, meshData, 2 );
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
|
||||
// Get a list of the timesteps
|
||||
@ -96,7 +128,7 @@ int main(int argc, char **argv)
|
||||
// Check the number of domains for each mesh
|
||||
bool pass = true;
|
||||
for (size_t j=0; j<list.size(); j++)
|
||||
pass = pass && list[j].domains.size()==nprocs;
|
||||
pass = pass && (int)list[j].domains.size()==nprocs;
|
||||
if ( pass ) {
|
||||
ut.passes("Corrent number of domains for mesh");
|
||||
} else {
|
||||
@ -163,6 +195,14 @@ int main(int argc, char **argv)
|
||||
ut.failure("Meshes did not load correctly");
|
||||
continue;
|
||||
}
|
||||
// For each domain, load the variables and check their data
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finished
|
||||
|
@ -207,7 +207,9 @@ avtLBMFileFormat::PopulateDatabaseMetaData(avtDatabaseMetaData *md, int timeStat
|
||||
if ( mmd->meshType==AVT_SURFACE_MESH )
|
||||
mmd->topologicalDimension = 2;
|
||||
mmd->numBlocks = database[i].domains.size();
|
||||
mmd->blockNames = database[i].domains;
|
||||
mmd->blockNames.resize( mmd->numBlocks );
|
||||
for (int j=0; j<mmd->numBlocks; j++)
|
||||
mmd->blockNames[j] = database[i].domains[j].name;
|
||||
md->Add(mmd);
|
||||
// Add expressions for the coordinates
|
||||
const char *xyz[3] = {"x","y","z"};
|
||||
@ -452,7 +454,7 @@ avtLBMFileFormat::GetVar(int timestate, int domain, const char *varname)
|
||||
// ****************************************************************************
|
||||
|
||||
vtkDataArray *
|
||||
avtLBMFileFormat::GetVectorVar(int timestate, int domain,const char *varname)
|
||||
avtLBMFileFormat::GetVectorVar(int timestate, int domain, const char *varname)
|
||||
{
|
||||
DebugStream::Stream1() << "avtLBMFileFormat::GetVectorVar" << std::endl;
|
||||
EXCEPTION1(InvalidVariableException, varname);
|
||||
|
Loading…
Reference in New Issue
Block a user