Updating convertIO
This commit is contained in:
parent
6d59317919
commit
89704cbb10
|
@ -57,8 +57,6 @@ inline std::vector<std::string> splitList( const char *line, const char token )
|
|||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
}; // namespace IO
|
||||
|
||||
#endif
|
||||
|
||||
|
|
111
IO/Mesh.cpp
111
IO/Mesh.cpp
|
@ -21,12 +21,8 @@ inline Point nullPoint()
|
|||
/****************************************************
|
||||
* Mesh *
|
||||
****************************************************/
|
||||
Mesh::Mesh( )
|
||||
{
|
||||
}
|
||||
Mesh::~Mesh( )
|
||||
{
|
||||
}
|
||||
Mesh::Mesh() {}
|
||||
Mesh::~Mesh() {}
|
||||
|
||||
|
||||
/****************************************************
|
||||
|
@ -34,22 +30,22 @@ Mesh::~Mesh( )
|
|||
****************************************************/
|
||||
bool MeshDataStruct::check() const
|
||||
{
|
||||
enum VariableType { NodeVariable=1, EdgeVariable=2, SurfaceVariable=2, VolumeVariable=3, NullVariable=0 };
|
||||
bool pass = mesh != nullptr;
|
||||
for ( const auto &var : vars ) {
|
||||
pass = pass && static_cast<int>( var->type ) >= 1 && static_cast<int>( var->type ) <= 3;
|
||||
pass = pass && !var->data.empty();
|
||||
}
|
||||
if ( !pass )
|
||||
if ( !pass ) {
|
||||
std::cerr << "Invalid variable detected\n";
|
||||
return false;
|
||||
}
|
||||
const std::string &meshClass = mesh->className();
|
||||
if ( meshClass == "PointList" ) {
|
||||
const auto mesh2 = dynamic_cast<IO::PointList*>( mesh.get() );
|
||||
if ( mesh2 == nullptr )
|
||||
return false;
|
||||
auto mesh2 = dynamic_cast<IO::PointList *>( mesh.get() );
|
||||
ASSERT( mesh2 );
|
||||
for ( const auto &var : vars ) {
|
||||
if ( var->type == IO::VariableType::NodeVariable ) {
|
||||
pass = pass && var->data.size(0)==mesh2->points.size() && var->data.size(1)==var->dim;
|
||||
pass = pass && var->data.size() == ArraySize( mesh2->points.size(), var->dim );
|
||||
} else if ( var->type == IO::VariableType::EdgeVariable ) {
|
||||
ERROR( "Invalid type for PointList" );
|
||||
} else if ( var->type == IO::VariableType::SurfaceVariable ) {
|
||||
|
@ -61,40 +57,42 @@ bool MeshDataStruct::check() const
|
|||
}
|
||||
}
|
||||
} else if ( meshClass == "TriMesh" || meshClass == "TriList" ) {
|
||||
const auto mesh2 = getTriMesh( mesh );
|
||||
if ( mesh2 == nullptr )
|
||||
return false;
|
||||
auto mesh2 = getTriMesh( mesh );
|
||||
ASSERT( mesh2 );
|
||||
for ( const auto &var : vars ) {
|
||||
if ( var->type == IO::VariableType::NodeVariable ) {
|
||||
pass = pass && var->data.size(0)==mesh2->vertices->points.size() && var->data.size(1)==var->dim;
|
||||
pass = pass &&
|
||||
var->data.size() == ArraySize( mesh2->vertices->points.size(), var->dim );
|
||||
} else if ( var->type == IO::VariableType::EdgeVariable ) {
|
||||
ERROR( "Not finished" );
|
||||
} else if ( var->type == IO::VariableType::SurfaceVariable ) {
|
||||
ERROR( "Not finished" );
|
||||
} else if ( var->type == IO::VariableType::VolumeVariable ) {
|
||||
pass = pass && var->data.size(0)==mesh2->A.size() && var->data.size(1)==var->dim;
|
||||
pass = pass && var->data.size( 0 ) == mesh2->A.size() &&
|
||||
var->data.size( 1 ) == var->dim;
|
||||
} else {
|
||||
ERROR( "Invalid variable type" );
|
||||
}
|
||||
}
|
||||
} else if ( meshClass == "DomainMesh" ) {
|
||||
const auto mesh2 = dynamic_cast<IO::DomainMesh*>( mesh.get() );
|
||||
if ( mesh2 == nullptr )
|
||||
return false;
|
||||
auto mesh2 = dynamic_cast<IO::DomainMesh *>( mesh.get() );
|
||||
ASSERT( mesh2 );
|
||||
for ( const auto &var : vars ) {
|
||||
ArraySize varSize;
|
||||
if ( var->type == IO::VariableType::NodeVariable ) {
|
||||
pass = pass && (int) var->data.size(0)==(mesh2->nx+1) && (int) var->data.size(1)==(mesh2->ny+1)
|
||||
&& (int) var->data.size(2)==(mesh2->nz+1) && var->data.size(3)==var->dim;
|
||||
varSize = ArraySize( mesh2->nx + 1, mesh2->ny + 1, mesh2->nz + 1, var->dim );
|
||||
} else if ( var->type == IO::VariableType::EdgeVariable ) {
|
||||
ERROR( "Not finished" );
|
||||
} else if ( var->type == IO::VariableType::SurfaceVariable ) {
|
||||
ERROR( "Not finished" );
|
||||
} else if ( var->type == IO::VariableType::VolumeVariable ) {
|
||||
pass = pass && (int) var->data.size(0)==mesh2->nx && (int) var->data.size(1)==mesh2->ny
|
||||
&& (int) var->data.size(2)==mesh2->nz && var->data.size(3)==var->dim;
|
||||
varSize = ArraySize( mesh2->nx, mesh2->ny, mesh2->nz, var->dim );
|
||||
} else {
|
||||
ERROR( "Invalid variable type" );
|
||||
}
|
||||
if ( var->data.size() == ArraySize( varSize[0] * varSize[1] * varSize[2], varSize[3] ) )
|
||||
var->data.resize( varSize );
|
||||
pass = pass && var->data.size() == varSize;
|
||||
}
|
||||
} else {
|
||||
ERROR( "Unknown mesh class: " + mesh->className() );
|
||||
|
@ -106,17 +104,13 @@ bool MeshDataStruct::check() const
|
|||
/****************************************************
|
||||
* PointList *
|
||||
****************************************************/
|
||||
PointList::PointList( )
|
||||
{
|
||||
}
|
||||
PointList::PointList() {}
|
||||
PointList::PointList( size_t N )
|
||||
{
|
||||
Point tmp = nullPoint();
|
||||
points.resize( N, tmp );
|
||||
}
|
||||
PointList::~PointList( )
|
||||
{
|
||||
}
|
||||
PointList::~PointList() {}
|
||||
size_t PointList::numberPointsVar( VariableType type ) const
|
||||
{
|
||||
size_t N = 0;
|
||||
|
@ -165,9 +159,7 @@ void PointList::unpack( const std::pair<size_t,void*>& data_in )
|
|||
/****************************************************
|
||||
* TriList *
|
||||
****************************************************/
|
||||
TriList::TriList( )
|
||||
{
|
||||
}
|
||||
TriList::TriList() {}
|
||||
TriList::TriList( size_t N_tri )
|
||||
{
|
||||
Point tmp = nullPoint();
|
||||
|
@ -190,9 +182,7 @@ TriList::TriList( const TriMesh& mesh )
|
|||
for ( size_t i = 0; i < C.size(); i++ )
|
||||
C[i] = P[mesh.C[i]];
|
||||
}
|
||||
TriList::~TriList( )
|
||||
{
|
||||
}
|
||||
TriList::~TriList() {}
|
||||
size_t TriList::numberPointsVar( VariableType type ) const
|
||||
{
|
||||
size_t N = 0;
|
||||
|
@ -257,9 +247,7 @@ void TriList::unpack( const std::pair<size_t,void*>& data_in )
|
|||
/****************************************************
|
||||
* TriMesh *
|
||||
****************************************************/
|
||||
TriMesh::TriMesh( )
|
||||
{
|
||||
}
|
||||
TriMesh::TriMesh() {}
|
||||
TriMesh::TriMesh( size_t N_tri, size_t N_point )
|
||||
{
|
||||
vertices.reset( new PointList( N_point ) );
|
||||
|
@ -312,8 +300,10 @@ 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.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;
|
||||
|
@ -368,22 +358,34 @@ void TriMesh::unpack( const std::pair<size_t,void*>& data_in )
|
|||
/****************************************************
|
||||
* Domain mesh *
|
||||
****************************************************/
|
||||
DomainMesh::DomainMesh():
|
||||
nprocx(0), nprocy(0), nprocz(0), rank(0),
|
||||
nx(0), ny(0), nz(0),
|
||||
Lx(0), Ly(0), Lz(0)
|
||||
DomainMesh::DomainMesh()
|
||||
: nprocx( 0 ),
|
||||
nprocy( 0 ),
|
||||
nprocz( 0 ),
|
||||
rank( 0 ),
|
||||
nx( 0 ),
|
||||
ny( 0 ),
|
||||
nz( 0 ),
|
||||
Lx( 0 ),
|
||||
Ly( 0 ),
|
||||
Lz( 0 )
|
||||
{
|
||||
}
|
||||
DomainMesh::DomainMesh( RankInfoStruct data,
|
||||
int nx2, int ny2, int nz2, double Lx2, double Ly2, double Lz2 ):
|
||||
nprocx(data.nx), nprocy(data.ny), nprocz(data.nz), rank(data.rank[1][1][1]),
|
||||
nx(nx2), ny(ny2), nz(nz2),
|
||||
Lx(Lx2), Ly(Ly2), Lz(Lz2)
|
||||
{
|
||||
}
|
||||
DomainMesh::~DomainMesh()
|
||||
DomainMesh::DomainMesh(
|
||||
RankInfoStruct data, int nx2, int ny2, int nz2, double Lx2, double Ly2, double Lz2 )
|
||||
: nprocx( data.nx ),
|
||||
nprocy( data.ny ),
|
||||
nprocz( data.nz ),
|
||||
rank( data.rank[1][1][1] ),
|
||||
nx( nx2 ),
|
||||
ny( ny2 ),
|
||||
nz( nz2 ),
|
||||
Lx( Lx2 ),
|
||||
Ly( Ly2 ),
|
||||
Lz( Lz2 )
|
||||
{
|
||||
}
|
||||
DomainMesh::~DomainMesh() {}
|
||||
size_t DomainMesh::numberPointsVar( VariableType type ) const
|
||||
{
|
||||
size_t N = 0;
|
||||
|
@ -477,5 +479,4 @@ std::shared_ptr<const TriList> getTriList( std::shared_ptr<const Mesh> mesh )
|
|||
}
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
||||
} // namespace IO
|
||||
|
|
40
IO/Mesh.h
40
IO/Mesh.h
|
@ -6,16 +6,22 @@
|
|||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include "analysis/PointList.h"
|
||||
#include "common/Array.h"
|
||||
#include "common/Communication.h"
|
||||
#include "analysis/PointList.h"
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
//! Possible variable types
|
||||
enum class VariableType: unsigned char { NodeVariable=1, EdgeVariable=2, SurfaceVariable=2, VolumeVariable=3, NullVariable=0 };
|
||||
enum class VariableType : unsigned char {
|
||||
NodeVariable = 1,
|
||||
EdgeVariable = 2,
|
||||
SurfaceVariable = 3,
|
||||
VolumeVariable = 4,
|
||||
NullVariable = 0
|
||||
};
|
||||
enum class DataType : unsigned char { Double = 1, Float = 2, Int = 2, Null = 0 };
|
||||
|
||||
|
||||
|
@ -35,6 +41,7 @@ public:
|
|||
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();
|
||||
|
@ -65,6 +72,7 @@ public:
|
|||
virtual void unpack( const std::pair<size_t, void *> &data );
|
||||
//! Access the points
|
||||
const std::vector<Point> &getPoints() const { return points; }
|
||||
|
||||
public:
|
||||
std::vector<Point> points; //!< List of points vertex
|
||||
};
|
||||
|
@ -93,6 +101,7 @@ public:
|
|||
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
|
||||
|
@ -101,7 +110,8 @@ public:
|
|||
|
||||
|
||||
/*! \class TriMesh
|
||||
\brief A class used to hold a list of trianges specified by their vertex number and list of coordiantes
|
||||
\brief A class used to hold a list of trianges specified by their vertex number and list of
|
||||
coordiantes
|
||||
*/
|
||||
class TriMesh : public Mesh
|
||||
{
|
||||
|
@ -124,6 +134,7 @@ public:
|
|||
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
|
||||
|
@ -152,6 +163,7 @@ public:
|
|||
virtual std::pair<size_t, void *> pack( int level ) const;
|
||||
//! Unpack the data
|
||||
virtual void unpack( const std::pair<size_t, void *> &data );
|
||||
|
||||
public:
|
||||
int nprocx, nprocy, nprocz, rank;
|
||||
int nx, ny, nz;
|
||||
|
@ -159,12 +171,10 @@ public:
|
|||
};
|
||||
|
||||
|
||||
|
||||
/*! \class Variable
|
||||
\brief A base class for variables
|
||||
*/
|
||||
struct Variable
|
||||
{
|
||||
struct Variable {
|
||||
public:
|
||||
// Internal variables
|
||||
unsigned char dim; //!< Number of points per grid point (1: scalar, 3: vector, ...)
|
||||
|
@ -175,13 +185,19 @@ public:
|
|||
//! Empty constructor
|
||||
Variable() : dim( 0 ), type( VariableType::NullVariable ), precision( DataType::Double ) {}
|
||||
//! Constructor
|
||||
Variable( int dim_, IO::VariableType type_, const std::string& name_ ):
|
||||
dim(dim_), type(type_), precision(DataType::Double), name(name_) {}
|
||||
Variable( int dim_, IO::VariableType type_, const std::string &name_ )
|
||||
: dim( dim_ ), type( type_ ), precision( DataType::Double ), name( name_ )
|
||||
{
|
||||
}
|
||||
//! Constructor
|
||||
Variable( int dim_, IO::VariableType type_, const std::string& name_, const Array<double>& data_ ):
|
||||
dim(dim_), type(type_), precision(DataType::Double), name(name_), data(data_) {}
|
||||
Variable(
|
||||
int dim_, IO::VariableType type_, const std::string &name_, const Array<double> &data_ )
|
||||
: dim( dim_ ), type( type_ ), precision( DataType::Double ), name( name_ ), data( data_ )
|
||||
{
|
||||
}
|
||||
//! Destructor
|
||||
virtual ~Variable() {}
|
||||
|
||||
protected:
|
||||
//! Empty constructor
|
||||
Variable( const Variable & );
|
||||
|
@ -189,7 +205,6 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
|
||||
/*! \class MeshDataStruct
|
||||
\brief A class used to hold database info for saving a mesh
|
||||
*/
|
||||
|
@ -214,7 +229,6 @@ std::shared_ptr<const TriMesh> getTriMesh( std::shared_ptr<const Mesh> mesh );
|
|||
std::shared_ptr<const TriList> getTriList( std::shared_ptr<const Mesh> mesh );
|
||||
|
||||
|
||||
} // IO namespace
|
||||
} // namespace IO
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "IO/Mesh.h"
|
||||
#include "IO/PackData.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#include <ProfilerApp.h>
|
||||
|
||||
|
||||
|
||||
// MeshType
|
||||
template<>
|
||||
size_t packsize<IO::MeshType>( const IO::MeshType &rhs )
|
||||
|
@ -56,17 +55,23 @@ template<>
|
|||
void pack<IO::DatabaseEntry>( const IO::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);
|
||||
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<IO::DatabaseEntry>( IO::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);
|
||||
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 );
|
||||
}
|
||||
// VariableDatabase
|
||||
template<>
|
||||
|
@ -78,53 +83,69 @@ template<>
|
|||
void pack<IO::VariableDatabase>( const IO::VariableDatabase &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.dim,&buffer[i]); i+=packsize(rhs.dim);
|
||||
pack( rhs.name, &buffer[i] );
|
||||
i += packsize( rhs.name );
|
||||
pack( rhs.type, &buffer[i] );
|
||||
i += packsize( rhs.type );
|
||||
pack( rhs.dim, &buffer[i] );
|
||||
i += packsize( rhs.dim );
|
||||
}
|
||||
template<>
|
||||
void unpack<IO::VariableDatabase>( IO::VariableDatabase &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.dim,&buffer[i]); i+=packsize(data.dim);
|
||||
unpack( data.name, &buffer[i] );
|
||||
i += packsize( data.name );
|
||||
unpack( data.type, &buffer[i] );
|
||||
i += packsize( data.type );
|
||||
unpack( data.dim, &buffer[i] );
|
||||
i += packsize( data.dim );
|
||||
}
|
||||
// MeshDatabase
|
||||
template<>
|
||||
size_t packsize<IO::MeshDatabase>( const IO::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);
|
||||
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<IO::MeshDatabase>( const IO::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);
|
||||
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<IO::MeshDatabase>( IO::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);
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -146,10 +167,7 @@ bool VariableDatabase::operator>=(const VariableDatabase& rhs ) const
|
|||
{
|
||||
return operator>( rhs ) || operator==( rhs );
|
||||
}
|
||||
bool VariableDatabase::operator<=(const VariableDatabase& rhs ) const
|
||||
{
|
||||
return !operator>(rhs);
|
||||
}
|
||||
bool VariableDatabase::operator<=( const VariableDatabase &rhs ) const { return !operator>( rhs ); }
|
||||
bool VariableDatabase::operator>( const VariableDatabase &rhs ) const
|
||||
{
|
||||
if ( name > rhs.name )
|
||||
|
@ -175,12 +193,8 @@ bool VariableDatabase::operator<(const VariableDatabase& rhs ) const
|
|||
/****************************************************
|
||||
* MeshDatabase *
|
||||
****************************************************/
|
||||
MeshDatabase::MeshDatabase()
|
||||
{
|
||||
}
|
||||
MeshDatabase::~MeshDatabase()
|
||||
{
|
||||
}
|
||||
MeshDatabase::MeshDatabase() {}
|
||||
MeshDatabase::~MeshDatabase() {}
|
||||
MeshDatabase::MeshDatabase( const MeshDatabase &rhs )
|
||||
{
|
||||
name = rhs.name;
|
||||
|
@ -223,21 +237,21 @@ std::string DatabaseEntry::write( ) const
|
|||
}
|
||||
DatabaseEntry::DatabaseEntry( const char *line )
|
||||
{
|
||||
std::vector<std::string> list = splitList(line,';');
|
||||
auto 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,';');
|
||||
auto 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(),';');
|
||||
auto list = splitList( line.c_str(), ';' );
|
||||
name = list[0];
|
||||
file = list[1];
|
||||
offset = atol( list[2].c_str() );
|
||||
|
@ -246,7 +260,8 @@ void DatabaseEntry::read( const std::string& line )
|
|||
|
||||
// Gather the mesh databases from all processors
|
||||
inline int tod( int N ) { return ( N + 7 ) / sizeof( double ); }
|
||||
std::vector<MeshDatabase> gatherAll( const std::vector<MeshDatabase>& meshes, const Utilities::MPI& comm )
|
||||
std::vector<MeshDatabase> gatherAll(
|
||||
const std::vector<MeshDatabase> &meshes, const Utilities::MPI &comm )
|
||||
{
|
||||
if ( comm.getSize() == 1 )
|
||||
return meshes;
|
||||
|
@ -301,7 +316,8 @@ std::vector<MeshDatabase> gatherAll( const std::vector<MeshDatabase>& meshes, co
|
|||
}
|
||||
for ( auto it = data.begin(); it != data.end(); ++it ) {
|
||||
// Get the unique variables
|
||||
std::set<VariableDatabase> data2(it->second.variables.begin(),it->second.variables.end());
|
||||
std::set<VariableDatabase> data2(
|
||||
it->second.variables.begin(), it->second.variables.end() );
|
||||
it->second.variables = std::vector<VariableDatabase>( data2.begin(), data2.end() );
|
||||
}
|
||||
// Free temporary memory
|
||||
|
@ -311,7 +327,8 @@ std::vector<MeshDatabase> gatherAll( const std::vector<MeshDatabase>& meshes, co
|
|||
// Return the results
|
||||
std::vector<MeshDatabase> data2( data.size() );
|
||||
size_t i = 0;
|
||||
for (std::map<std::string,MeshDatabase>::iterator it=data.begin(); it!=data.end(); ++it, ++i)
|
||||
for ( std::map<std::string, MeshDatabase>::iterator it = data.begin(); it != data.end();
|
||||
++it, ++i )
|
||||
data2[i] = it->second;
|
||||
PROFILE_STOP( "gatherAll-unpack", 2 );
|
||||
PROFILE_STOP( "gatherAll" );
|
||||
|
@ -341,7 +358,8 @@ void write( const std::vector<MeshDatabase>& meshes, const std::string& filename
|
|||
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());
|
||||
fprintf(
|
||||
fid, " variable(%s,%s): %s\n", domain, variable, it->second.write().c_str() );
|
||||
}
|
||||
}
|
||||
fclose( fid );
|
||||
|
@ -410,14 +428,14 @@ std::vector<MeshDatabase> read( const std::string& filename )
|
|||
// Return the mesh type
|
||||
IO::MeshType meshType( const IO::Mesh &mesh )
|
||||
{
|
||||
IO::MeshType type = IO::Unknown;
|
||||
IO::MeshType type = IO::MeshType::Unknown;
|
||||
const std::string meshClass = mesh.className();
|
||||
if ( meshClass == "PointList" ) {
|
||||
type = IO::PointMesh;
|
||||
type = IO::MeshType::PointMesh;
|
||||
} else if ( meshClass == "TriList" || meshClass == "TriMesh" ) {
|
||||
type = IO::SurfaceMesh;
|
||||
type = IO::MeshType::SurfaceMesh;
|
||||
} else if ( meshClass == "DomainMesh" ) {
|
||||
type = IO::VolumeMesh;
|
||||
type = IO::MeshType::VolumeMesh;
|
||||
} else {
|
||||
ERROR( "Unknown mesh" );
|
||||
}
|
||||
|
@ -425,5 +443,4 @@ IO::MeshType meshType( const IO::Mesh& mesh )
|
|||
}
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
||||
} // namespace IO
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#include "common/MPI.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
@ -18,7 +18,7 @@ class Mesh;
|
|||
|
||||
//! Enum to identify mesh type
|
||||
// enum class MeshType : char { PointMesh=1, SurfaceMesh=2, VolumeMesh=3, Unknown=-1 };
|
||||
enum MeshType { PointMesh=1, SurfaceMesh=2, VolumeMesh=3, Unknown=-1 };
|
||||
enum class MeshType { PointMesh = 1, SurfaceMesh = 2, VolumeMesh = 3, Unknown = -1 };
|
||||
|
||||
|
||||
//! Helper struct for containing offsets for the mesh info
|
||||
|
@ -61,6 +61,7 @@ struct MeshDatabase {
|
|||
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();
|
||||
|
@ -70,7 +71,8 @@ public:
|
|||
|
||||
|
||||
//! Gather the mesh databases from all processors
|
||||
std::vector<MeshDatabase> gatherAll( const std::vector<MeshDatabase>& meshes, const Utilities::MPI& comm );
|
||||
std::vector<MeshDatabase> gatherAll(
|
||||
const std::vector<MeshDatabase> &meshes, const Utilities::MPI &comm );
|
||||
|
||||
|
||||
//! Write the mesh databases to a file
|
||||
|
@ -85,6 +87,6 @@ std::vector<MeshDatabase> read( const std::string& filename );
|
|||
IO::MeshType meshType( const IO::Mesh &mesh );
|
||||
|
||||
|
||||
} // IO namespace
|
||||
} // namespace IO
|
||||
|
||||
#endif
|
||||
|
|
35
IO/PIO.cpp
35
IO/PIO.cpp
|
@ -1,10 +1,10 @@
|
|||
#include "IO/PIO.h"
|
||||
#include "common/Utilities.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
@ -20,7 +20,6 @@ std::ostream perr(&perr_buffer);
|
|||
std::ostream plog( &plog_buffer );
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Functions to control logging *
|
||||
****************************************************************************/
|
||||
|
@ -95,18 +94,12 @@ void Utilities::stopLogging( )
|
|||
/****************************************************************************
|
||||
* ParallelStreamBuffer class *
|
||||
****************************************************************************/
|
||||
ParallelStreamBuffer::ParallelStreamBuffer( ):
|
||||
d_rank(0), d_size(0), d_buffer_size(0), d_buffer(NULL)
|
||||
ParallelStreamBuffer::ParallelStreamBuffer()
|
||||
: d_rank( 0 ), d_size( 0 ), d_buffer_size( 0 ), d_buffer( NULL )
|
||||
{
|
||||
}
|
||||
ParallelStreamBuffer:: ~ParallelStreamBuffer()
|
||||
{
|
||||
delete [] d_buffer;
|
||||
}
|
||||
void ParallelStreamBuffer::setOutputStream( std::ostream *stream )
|
||||
{
|
||||
d_stream.push_back( stream );
|
||||
}
|
||||
ParallelStreamBuffer::~ParallelStreamBuffer() { delete[] d_buffer; }
|
||||
void ParallelStreamBuffer::setOutputStream( std::ostream *stream ) { d_stream.push_back( stream ); }
|
||||
int ParallelStreamBuffer::sync()
|
||||
{
|
||||
for ( size_t i = 0; i < d_stream.size(); i++ ) {
|
||||
|
@ -140,7 +133,9 @@ std::streamsize ParallelStreamBuffer::xsputn( const char* text, std::streamsize
|
|||
reserve( d_size + n );
|
||||
memcpy( &d_buffer[d_size], text, n );
|
||||
d_size += n;
|
||||
if ( text[n-1]==0 || text[n-1]==10 ) { sync(); }
|
||||
if ( text[n - 1] == 0 || text[n - 1] == 10 ) {
|
||||
sync();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
int ParallelStreamBuffer::overflow( int ch )
|
||||
|
@ -148,13 +143,12 @@ int ParallelStreamBuffer::overflow(int ch)
|
|||
reserve( d_size + 1 );
|
||||
d_buffer[d_size] = ch;
|
||||
d_size++;
|
||||
if ( ch==0 || ch==10 ) { sync(); }
|
||||
if ( ch == 0 || ch == 10 ) {
|
||||
sync();
|
||||
}
|
||||
return std::char_traits<char>::to_int_type( ch );
|
||||
}
|
||||
int ParallelStreamBuffer::underflow()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ParallelStreamBuffer::underflow() { return -1; }
|
||||
void ParallelStreamBuffer::reset()
|
||||
{
|
||||
sync();
|
||||
|
@ -165,5 +159,4 @@ void ParallelStreamBuffer::reset()
|
|||
}
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
||||
} // namespace IO
|
||||
|
|
1
IO/PIO.h
1
IO/PIO.h
|
@ -45,7 +45,6 @@ inline int printp( const char *format, ... );
|
|||
class ParallelStreamBuffer : public std::streambuf
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Create a parallel buffer class. The object will require further
|
||||
* initialization to set up the I/O streams and prefix string.
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
#include "IO/PIO.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
@ -24,6 +24,6 @@ inline int printp( const char *format, ... )
|
|||
}
|
||||
|
||||
|
||||
} // IO namespace
|
||||
} // namespace IO
|
||||
|
||||
#endif
|
||||
|
|
|
@ -102,4 +102,3 @@ void unpack<std::string>( std::string& data, const char *buffer )
|
|||
{
|
||||
data = std::string( buffer );
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#ifndef included_PackData
|
||||
#define included_PackData
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
|
||||
//! Template function to return the buffer size required to pack a class
|
||||
|
@ -75,4 +75,3 @@ void unpack( std::set<TYPE>& data, const char *buffer );
|
|||
#include "IO/PackData.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -4,11 +4,10 @@
|
|||
|
||||
#include "IO/PackData.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
|
||||
|
||||
/********************************************************
|
||||
|
@ -92,8 +91,10 @@ void pack( const std::map<TYPE1,TYPE2>& rhs, char *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);
|
||||
pack( it->first, &buffer[pos] );
|
||||
pos += packsize( it->first );
|
||||
pack( it->second, &buffer[pos] );
|
||||
pos += packsize( it->second );
|
||||
}
|
||||
}
|
||||
template<class TYPE1, class TYPE2>
|
||||
|
@ -105,8 +106,10 @@ void unpack( std::map<TYPE1,TYPE2>& data, const char *buffer )
|
|||
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);
|
||||
unpack( tmp.first, &buffer[pos] );
|
||||
pos += packsize( tmp.first );
|
||||
unpack( tmp.second, &buffer[pos] );
|
||||
pos += packsize( tmp.second );
|
||||
data.insert( tmp );
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +136,8 @@ void pack( const std::set<TYPE>& rhs, char *buffer )
|
|||
size_t pos = sizeof( size_t );
|
||||
typename std::set<TYPE>::const_iterator it;
|
||||
for ( it = rhs.begin(); it != rhs.end(); ++it ) {
|
||||
pack(*it); pos+=packsize(*it);
|
||||
pack( *it );
|
||||
pos += packsize( *it );
|
||||
}
|
||||
}
|
||||
template<class TYPE>
|
||||
|
@ -145,11 +149,11 @@ void unpack( std::set<TYPE>& data, const char *buffer )
|
|||
data.clear();
|
||||
for ( size_t i = 0; i < N; i++ ) {
|
||||
TYPE tmp;
|
||||
unpack(tmp,&buffer[pos]); pos+=packsize(tmp);
|
||||
unpack( tmp, &buffer[pos] );
|
||||
pos += packsize( tmp );
|
||||
data.insert( tmp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
102
IO/Reader.cpp
102
IO/Reader.cpp
|
@ -1,7 +1,7 @@
|
|||
#include "IO/Reader.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "IO/Mesh.h"
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#ifdef USE_SILO
|
||||
|
@ -10,18 +10,30 @@
|
|||
|
||||
|
||||
#include <ProfilerApp.h>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
// Inline function to read line without a return argument
|
||||
static inline void fgetl( char *str, int num, FILE *stream )
|
||||
{
|
||||
char *ptr = fgets( str, num, stream );
|
||||
if ( 0 ) {char *temp = (char *)&ptr; temp++;}
|
||||
if ( 0 ) {
|
||||
char *temp = (char *) &ptr;
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if the file exists
|
||||
bool fileExists( const std::string &filename )
|
||||
{
|
||||
std::ifstream ifile( filename.c_str() );
|
||||
return ifile.good();
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,8 +43,12 @@ std::string IO::getPath( const std::string& filename )
|
|||
std::string file( filename );
|
||||
size_t k1 = file.rfind( 47 );
|
||||
size_t k2 = file.rfind( 92 );
|
||||
if ( k1==std::string::npos ) { k1=0; }
|
||||
if ( k2==std::string::npos ) { k2=0; }
|
||||
if ( k1 == std::string::npos ) {
|
||||
k1 = 0;
|
||||
}
|
||||
if ( k2 == std::string::npos ) {
|
||||
k2 = 0;
|
||||
}
|
||||
return file.substr( 0, std::max( k1, k2 ) );
|
||||
}
|
||||
|
||||
|
@ -42,12 +58,25 @@ std::vector<std::string> IO::readTimesteps( const std::string& path, const std::
|
|||
{
|
||||
// Get the name of the summary filename
|
||||
std::string filename = path + "/";
|
||||
if ( format=="old" || format=="new" )
|
||||
if ( format == "old" || format == "new" ) {
|
||||
filename += "summary.LBM";
|
||||
else if ( format=="silo" )
|
||||
} else if ( format == "silo" ) {
|
||||
filename += "LBM.visit";
|
||||
else
|
||||
} else if ( format == "auto" ) {
|
||||
bool test_old = fileExists( path + "/summary.LBM" );
|
||||
bool test_silo = fileExists( path + "/LBM.visit" );
|
||||
if ( test_old && test_silo ) {
|
||||
ERROR( "Unable to determine format (both summary.LBM and LBM.visit exist)" );
|
||||
} else if ( test_old ) {
|
||||
filename += "summary.LBM";
|
||||
} else if ( test_silo ) {
|
||||
filename += "LBM.visit";
|
||||
} else {
|
||||
ERROR( "Unable to determine format (neither summary.LBM or LBM.visit exist)" );
|
||||
}
|
||||
} else {
|
||||
ERROR( "Unknown format: " + format );
|
||||
}
|
||||
PROFILE_START( "readTimesteps" );
|
||||
// Read the data
|
||||
FILE *fid = fopen( filename.c_str(), "rb" );
|
||||
|
@ -72,30 +101,48 @@ std::vector<std::string> IO::readTimesteps( const std::string& path, const std::
|
|||
}
|
||||
|
||||
|
||||
// Get the maximum number of domains
|
||||
int IO::maxDomains( const std::string &path, const std::string &format, const Utilities::MPI &comm )
|
||||
{
|
||||
int rank = comm.getRank();
|
||||
int n_domains = 0;
|
||||
if ( rank == 0 ) {
|
||||
// Get the timesteps
|
||||
auto timesteps = IO::readTimesteps( path, format );
|
||||
ASSERT( !timesteps.empty() );
|
||||
// Get the database for the first domain
|
||||
auto db = IO::getMeshList( path, timesteps[0] );
|
||||
for ( size_t i = 0; i < db.size(); i++ )
|
||||
n_domains = std::max<int>( n_domains, db[i].domains.size() );
|
||||
}
|
||||
return comm.bcast( n_domains, 0 );
|
||||
}
|
||||
|
||||
|
||||
// Read the data for the given timestep
|
||||
std::vector<IO::MeshDataStruct> IO::readData( const std::string& path, const std::string& timestep, const Utilities::MPI &comm )
|
||||
std::vector<IO::MeshDataStruct> IO::readData(
|
||||
const std::string &path, const std::string ×tep, int rank )
|
||||
{
|
||||
// Get the mesh databases
|
||||
auto db = IO::getMeshList( path, timestep );
|
||||
// Create the data
|
||||
std::vector<IO::MeshDataStruct> data( db.size() );
|
||||
for ( size_t i = 0; i < data.size(); i++ ) {
|
||||
ASSERT( (int) db [i].domains.size() == comm.getSize() );
|
||||
int domain = comm.getRank();
|
||||
data[i].precision = IO::DataType::Double;
|
||||
data[i].meshName = db[i].name;
|
||||
data[i].mesh = getMesh( path, timestep, db [i], domain );
|
||||
data[i].mesh = getMesh( path, timestep, db[i], rank );
|
||||
data[i].vars.resize( db[i].variables.size() );
|
||||
for ( size_t j = 0; j < db[i].variables.size(); j++ )
|
||||
data[i].vars[j] = getVariable( path, timestep, db[i], domain, db[i].variables[j].name );
|
||||
data[i].check();
|
||||
data[i].vars[j] = getVariable( path, timestep, db[i], rank, db[i].variables[j].name );
|
||||
INSIST( data[i].check(), "Failed check of " + data[i].meshName );
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
// Read the list of variables for the given timestep
|
||||
std::vector<IO::MeshDatabase> IO::getMeshList( const std::string& path, const std::string& timestep )
|
||||
std::vector<IO::MeshDatabase> IO::getMeshList(
|
||||
const std::string &path, const std::string ×tep )
|
||||
{
|
||||
std::string filename = path + "/" + timestep + "/LBM.summary";
|
||||
return IO::read( filename );
|
||||
|
@ -122,7 +169,7 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
|
|||
fclose( fid );
|
||||
if ( count % 3 != 0 )
|
||||
ERROR( "Error reading file" );
|
||||
if ( meshDatabase.type==IO::PointMesh ) {
|
||||
if ( meshDatabase.type == IO::MeshType::PointMesh ) {
|
||||
size_t N = count / 3;
|
||||
std::shared_ptr<PointList> pointlist( new PointList( N ) );
|
||||
std::vector<Point> &P = pointlist->points;
|
||||
|
@ -132,7 +179,7 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
|
|||
P[i].z = data[3 * i + 2];
|
||||
}
|
||||
mesh = pointlist;
|
||||
} else if ( meshDatabase.type==IO::SurfaceMesh ) {
|
||||
} else if ( meshDatabase.type == IO::MeshType::SurfaceMesh ) {
|
||||
if ( count % 9 != 0 )
|
||||
ERROR( "Error reading file (2)" );
|
||||
size_t N_tri = count / 9;
|
||||
|
@ -152,7 +199,7 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
|
|||
C[i].z = data[9 * i + 8];
|
||||
}
|
||||
mesh = trilist;
|
||||
} else if ( meshDatabase.type==IO::VolumeMesh ) {
|
||||
} else if ( meshDatabase.type == IO::MeshType::VolumeMesh ) {
|
||||
// this was never supported in the old format
|
||||
mesh = std::shared_ptr<DomainMesh>( new DomainMesh() );
|
||||
} else {
|
||||
|
@ -232,7 +279,8 @@ std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::strin
|
|||
silo::readUniformMesh( fid, database.name, range, N );
|
||||
auto rankinfo = silo::read<int>( fid, database.name + "_rankinfo" );
|
||||
RankInfoStruct rank_data( rankinfo[0], rankinfo[1], rankinfo[2], rankinfo[3] );
|
||||
mesh.reset( new IO::DomainMesh( rank_data, N[0], N[1], N[2], range[1]-range[0], range[3]-range[2], range[5]-range[4] ) );
|
||||
mesh.reset( new IO::DomainMesh( rank_data, N[0], N[1], N[2], range[1] - range[0],
|
||||
range[3] - range[2], range[5] - range[4] ) );
|
||||
} else {
|
||||
ERROR( "Unknown mesh class" );
|
||||
}
|
||||
|
@ -278,7 +326,7 @@ std::shared_ptr<IO::Variable> IO::getVariable( const std::string& path, const st
|
|||
var->dim = dim;
|
||||
var->type = static_cast<IO::VariableType>( type );
|
||||
var->name = variable;
|
||||
var->data.resize(N*dim);
|
||||
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 );
|
||||
|
@ -323,9 +371,12 @@ 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 == VariableType::NodeVariable ) {
|
||||
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 } );
|
||||
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 == VariableType::EdgeVariable ) {
|
||||
ERROR( "Not finished" );
|
||||
} else if ( var.type == VariableType::SurfaceVariable ) {
|
||||
|
@ -367,6 +418,3 @@ void IO::reformatVariable( const IO::Mesh& mesh, IO::Variable& var )
|
|||
ERROR( "Unknown mesh type" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
28
IO/Reader.h
28
IO/Reader.h
|
@ -17,6 +17,23 @@ namespace IO {
|
|||
std::string getPath( const std::string &filename );
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Get the maximum number of domains written
|
||||
* @details This function reads the summary files to determine the maximum
|
||||
* number of domains in the output.
|
||||
* @param[in] path The path to use for reading
|
||||
* @param[in] format The data format to use:
|
||||
* old - Old mesh format (provided for backward compatibility)
|
||||
* new - New format, 1 file/process
|
||||
* silo - Silo
|
||||
* auto - Auto-determin the format
|
||||
* @param[in] comm Optional comm to use to reduce IO load by
|
||||
* reading on rank 0 and then communicating the result
|
||||
*/
|
||||
int maxDomains( const std::string &path, const std::string &format = "auto",
|
||||
const Utilities::MPI &comm = MPI_COMM_SELF );
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Read the timestep list
|
||||
* @details This function reads the timestep list from the summary file.
|
||||
|
@ -25,19 +42,22 @@ std::string getPath( const std::string& filename );
|
|||
* old - Old mesh format (provided for backward compatibility)
|
||||
* new - New format, 1 file/process
|
||||
* silo - Silo
|
||||
* auto - Auto-determin the format
|
||||
* @return append Append any existing data (default is false)
|
||||
*/
|
||||
std::vector<std::string> readTimesteps( const std::string& path, const std::string& format );
|
||||
std::vector<std::string> readTimesteps(
|
||||
const std::string &path, const std::string &format = "auto" );
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Read the data for the timestep
|
||||
* @details This function reads the mesh and variable data provided for the given timestep.
|
||||
* Note: this function requires that the number of ranks of the comm match the number of ranks in the meshes
|
||||
* @param[in] path The path to use for reading
|
||||
* @param[in] timestep The timestep iteration
|
||||
* @param[in] domain The desired domain to read
|
||||
*/
|
||||
std::vector<IO::MeshDataStruct> readData( const std::string& path, const std::string& timestep, const Utilities::MPI &comm = MPI_COMM_WORLD );
|
||||
std::vector<IO::MeshDataStruct> readData(
|
||||
const std::string &path, const std::string ×tep, int domain );
|
||||
|
||||
|
||||
//! Read the list of mesh databases for the given timestep
|
||||
|
@ -72,6 +92,6 @@ std::shared_ptr<IO::Variable> getVariable( const std::string& path, const std::s
|
|||
void reformatVariable( const IO::Mesh &mesh, IO::Variable &var );
|
||||
|
||||
|
||||
} // IO namespace
|
||||
} // namespace IO
|
||||
|
||||
#endif
|
||||
|
|
160
IO/Writer.cpp
160
IO/Writer.cpp
|
@ -1,21 +1,62 @@
|
|||
#include "IO/Writer.h"
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/silo.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
#include <set>
|
||||
#include <sys/stat.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
enum class Format { OLD, NEW, SILO, UNKNOWN };
|
||||
|
||||
|
||||
/****************************************************
|
||||
* Recursively create the subdirectory *
|
||||
****************************************************/
|
||||
static void recursiveMkdir( const std::string &path, mode_t mode )
|
||||
{
|
||||
// Iterate through the root directories until we create the desired path
|
||||
for ( size_t pos = 0; pos < path.size(); ) {
|
||||
// slide backwards in string until next slash found
|
||||
pos++;
|
||||
for ( ; pos < path.size(); pos++ ) {
|
||||
if ( path[pos] == '/' || path[pos] == 92 )
|
||||
break;
|
||||
}
|
||||
// Create the temporary path
|
||||
auto path2 = path.substr( 0, pos );
|
||||
// Check if the temporary path exists
|
||||
struct stat status;
|
||||
int result = stat( path2.data(), &status );
|
||||
if ( result == 0 ) {
|
||||
// if there is a part of the path that already exists make sure it is really a directory
|
||||
if ( !S_ISDIR( status.st_mode ) ) {
|
||||
ERROR(
|
||||
"Error in recursiveMkdir...\n"
|
||||
" Cannot create directories in path = " +
|
||||
path +
|
||||
"\n because some intermediate item in path exists and is NOT a directory" );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Create the directory and test the result
|
||||
result = mkdir( path2.data(), mode );
|
||||
if ( result != 0 ) {
|
||||
// Maybe another rank created the directory, check
|
||||
int result = stat( path2.data(), &status );
|
||||
if ( result != 0 && !S_ISDIR( status.st_mode ) )
|
||||
ERROR( "Error in Utilities::recursiveMkdir...\n"
|
||||
" Cannot create directory = " +
|
||||
path2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* Initialize the writer *
|
||||
|
@ -38,7 +79,7 @@ void IO::initialize( const std::string& path, const std::string& format, bool ap
|
|||
ERROR( "Unknown format" );
|
||||
int rank = Utilities::MPI( MPI_COMM_WORLD ).getRank();
|
||||
if ( !append && rank == 0 ) {
|
||||
mkdir(path.c_str(),S_IRWXU|S_IRGRP);
|
||||
recursiveMkdir( path, S_IRWXU | S_IRGRP );
|
||||
std::string filename;
|
||||
if ( global_IO_format == Format::OLD || global_IO_format == Format::NEW )
|
||||
filename = global_IO_path + "/summary.LBM";
|
||||
|
@ -53,9 +94,9 @@ void IO::initialize( const std::string& path, const std::string& format, bool ap
|
|||
|
||||
|
||||
// Write the mesh data in the original format
|
||||
static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO::MeshDataStruct>& meshData, const std::string& path )
|
||||
static std::vector<IO::MeshDatabase> writeMeshesOrigFormat(
|
||||
const std::vector<IO::MeshDataStruct> &meshData, const std::string &path, int rank )
|
||||
{
|
||||
int rank = Utilities::MPI(MPI_COMM_WORLD).getRank();
|
||||
std::vector<IO::MeshDatabase> meshes_written;
|
||||
for ( size_t i = 0; i < meshData.size(); i++ ) {
|
||||
char domainname[100], filename[100], fullpath[200];
|
||||
|
@ -83,11 +124,14 @@ static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO
|
|||
const std::string meshClass = mesh->className();
|
||||
if ( meshClass == "PointList" ) {
|
||||
// List of points
|
||||
std::shared_ptr<IO::PointList> pointlist = std::dynamic_pointer_cast<IO::PointList>(mesh);
|
||||
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++ ) {
|
||||
double x[3];
|
||||
x[0] = P[i].x; x[1] = P[i].y; x[2] = P[i].z;
|
||||
x[0] = P[i].x;
|
||||
x[1] = P[i].y;
|
||||
x[2] = P[i].z;
|
||||
fwrite( x, sizeof( double ), 3, fid );
|
||||
}
|
||||
} else if ( meshClass == "TriList" || meshClass == "TriMesh" ) {
|
||||
|
@ -98,9 +142,15 @@ static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO
|
|||
const std::vector<Point> &C = trilist->C;
|
||||
for ( size_t i = 0; i < A.size(); i++ ) {
|
||||
double tri[9];
|
||||
tri[0] = A[i].x; tri[1] = A[i].y; tri[2] = A[i].z;
|
||||
tri[3] = B[i].x; tri[4] = B[i].y; tri[5] = B[i].z;
|
||||
tri[6] = C[i].x; tri[7] = C[i].y; tri[8] = C[i].z;
|
||||
tri[0] = A[i].x;
|
||||
tri[1] = A[i].y;
|
||||
tri[2] = A[i].z;
|
||||
tri[3] = B[i].x;
|
||||
tri[4] = B[i].y;
|
||||
tri[5] = B[i].z;
|
||||
tri[6] = C[i].x;
|
||||
tri[7] = C[i].y;
|
||||
tri[8] = C[i].z;
|
||||
fwrite( tri, sizeof( double ), 9, fid );
|
||||
}
|
||||
} else if ( meshClass == "DomainMesh" ) {
|
||||
|
@ -110,7 +160,9 @@ static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO
|
|||
}
|
||||
fclose( fid );
|
||||
std::sort( mesh_entry.variables.begin(), mesh_entry.variables.end() );
|
||||
mesh_entry.variables.erase( std::unique( mesh_entry.variables.begin(), mesh_entry.variables.end() ), mesh_entry.variables.end() );
|
||||
mesh_entry.variables.erase(
|
||||
std::unique( mesh_entry.variables.begin(), mesh_entry.variables.end() ),
|
||||
mesh_entry.variables.end() );
|
||||
meshes_written.push_back( mesh_entry );
|
||||
}
|
||||
return meshes_written;
|
||||
|
@ -118,9 +170,9 @@ static std::vector<IO::MeshDatabase> writeMeshesOrigFormat( const std::vector<IO
|
|||
|
||||
|
||||
// Create the database entry for the mesh data
|
||||
static IO::MeshDatabase getDatabase( const std::string& filename, const IO::MeshDataStruct& mesh, int format )
|
||||
static IO::MeshDatabase getDatabase(
|
||||
const std::string &filename, const IO::MeshDataStruct &mesh, int format, int rank )
|
||||
{
|
||||
int rank = Utilities::MPI(MPI_COMM_WORLD).getRank();
|
||||
char domainname[100];
|
||||
sprintf( domainname, "%s_%05i", mesh.meshName.c_str(), rank );
|
||||
// Create the MeshDatabase
|
||||
|
@ -157,13 +209,12 @@ static IO::MeshDatabase getDatabase( const std::string& filename, const IO::Mesh
|
|||
|
||||
|
||||
// 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 )
|
||||
static IO::MeshDatabase write_domain(
|
||||
FILE *fid, const std::string &filename, const IO::MeshDataStruct &mesh, int format, int rank )
|
||||
{
|
||||
const int level = 0;
|
||||
int rank = Utilities::MPI(MPI_COMM_WORLD).getRank();
|
||||
// Create the MeshDatabase
|
||||
IO::MeshDatabase database = getDatabase( filename, mesh, format );
|
||||
IO::MeshDatabase database = getDatabase( filename, mesh, format, rank );
|
||||
// Write the mesh
|
||||
IO::DatabaseEntry &domain = database.domains[0];
|
||||
domain.offset = ftell( fid );
|
||||
|
@ -185,9 +236,8 @@ static IO::MeshDatabase write_domain( FILE *fid, const std::string& filename,
|
|||
}
|
||||
size_t N_mesh = mesh.mesh->numberPointsVar( mesh.vars[i]->type );
|
||||
ASSERT( N == dim * N_mesh );
|
||||
fprintf(fid,"Var: %s-%05i-%s: %i, %i, %lu, %lu, double\n",
|
||||
database.name.c_str(), rank, variable.name.c_str(),
|
||||
dim, type, N_mesh, 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_mesh, N * sizeof( double ) );
|
||||
fwrite( mesh.vars[i]->data.data(), sizeof( double ), N, fid );
|
||||
fprintf( fid, "\n" );
|
||||
}
|
||||
|
@ -198,7 +248,8 @@ static IO::MeshDatabase write_domain( FILE *fid, const std::string& filename,
|
|||
#ifdef USE_SILO
|
||||
// Write a PointList mesh (and variables) to a file
|
||||
template<class TYPE>
|
||||
static void writeSiloPointMesh( DBfile *fid, const IO::PointList& mesh, const std::string& meshname )
|
||||
static void writeSiloPointMesh(
|
||||
DBfile *fid, const IO::PointList &mesh, const std::string &meshname )
|
||||
{
|
||||
const auto &points = mesh.getPoints();
|
||||
std::vector<TYPE> x( points.size() ), y( points.size() ), z( points.size() );
|
||||
|
@ -210,7 +261,8 @@ static void writeSiloPointMesh( DBfile *fid, const IO::PointList& mesh, const st
|
|||
const TYPE *coords[] = { x.data(), y.data(), z.data() };
|
||||
silo::writePointMesh<TYPE>( fid, meshname, 3, points.size(), coords );
|
||||
}
|
||||
static void writeSiloPointList( DBfile *fid, const IO::MeshDataStruct& meshData, IO::MeshDatabase database )
|
||||
static void writeSiloPointList(
|
||||
DBfile *fid, const IO::MeshDataStruct &meshData, IO::MeshDatabase database )
|
||||
{
|
||||
const IO::PointList &mesh = dynamic_cast<IO::PointList &>( *meshData.mesh );
|
||||
const std::string meshname = database.domains[0].name;
|
||||
|
@ -291,28 +343,33 @@ static void writeSiloTriMesh2( DBfile *fid, const IO::MeshDataStruct& meshData,
|
|||
}
|
||||
}
|
||||
}
|
||||
static void writeSiloTriMesh( DBfile *fid, const IO::MeshDataStruct& meshData, IO::MeshDatabase database )
|
||||
static void writeSiloTriMesh(
|
||||
DBfile *fid, const IO::MeshDataStruct &meshData, IO::MeshDatabase database )
|
||||
{
|
||||
const IO::TriMesh &mesh = dynamic_cast<IO::TriMesh &>( *meshData.mesh );
|
||||
writeSiloTriMesh2( fid, meshData, mesh, database );
|
||||
}
|
||||
static void writeSiloTriList( DBfile *fid, const IO::MeshDataStruct& meshData, IO::MeshDatabase database )
|
||||
static void writeSiloTriList(
|
||||
DBfile *fid, const IO::MeshDataStruct &meshData, IO::MeshDatabase database )
|
||||
{
|
||||
auto mesh = getTriMesh( meshData.mesh );
|
||||
writeSiloTriMesh2( fid, meshData, *mesh, database );
|
||||
}
|
||||
// Write a DomainMesh mesh (and variables) to a file
|
||||
static void writeSiloDomainMesh( DBfile *fid, const IO::MeshDataStruct& meshData, IO::MeshDatabase database )
|
||||
static void writeSiloDomainMesh(
|
||||
DBfile *fid, const IO::MeshDataStruct &meshData, IO::MeshDatabase database )
|
||||
{
|
||||
const IO::DomainMesh &mesh = dynamic_cast<IO::DomainMesh &>( *meshData.mesh );
|
||||
RankInfoStruct info( mesh.rank, mesh.nprocx, mesh.nprocy, mesh.nprocz );
|
||||
std::array<double,6> range = { info.ix*mesh.Lx/info.nx, (info.ix+1)*mesh.Lx/info.nx,
|
||||
info.jy*mesh.Ly/info.ny, (info.jy+1)*mesh.Ly/info.ny,
|
||||
info.kz*mesh.Lz/info.nz, (info.kz+1)*mesh.Lz/info.nz };
|
||||
std::array<double, 6> range = { info.ix * mesh.Lx / info.nx,
|
||||
( info.ix + 1 ) * mesh.Lx / info.nx, info.jy * mesh.Ly / info.ny,
|
||||
( info.jy + 1 ) * mesh.Ly / info.ny, info.kz * mesh.Lz / info.nz,
|
||||
( info.kz + 1 ) * mesh.Lz / info.nz };
|
||||
std::array<int, 3> N = { mesh.nx, mesh.ny, mesh.nz };
|
||||
auto meshname = database.domains[0].name;
|
||||
silo::writeUniformMesh<3>( fid, meshname, range, N );
|
||||
silo::write<int>( fid, meshname+"_rankinfo", { mesh.rank, mesh.nprocx, mesh.nprocy, mesh.nprocz } );
|
||||
silo::write<int>(
|
||||
fid, meshname + "_rankinfo", { mesh.rank, mesh.nprocx, mesh.nprocy, mesh.nprocz } );
|
||||
for ( size_t i = 0; i < meshData.vars.size(); i++ ) {
|
||||
const auto &var = *meshData.vars[i];
|
||||
auto type = static_cast<silo::VariableType>( var.type );
|
||||
|
@ -332,11 +389,11 @@ static void writeSiloDomainMesh( DBfile *fid, const IO::MeshDataStruct& meshData
|
|||
}
|
||||
}
|
||||
// Write a mesh (and variables) to a file
|
||||
static IO::MeshDatabase write_domain_silo( DBfile *fid, const std::string& filename,
|
||||
const IO::MeshDataStruct& mesh, int format )
|
||||
static IO::MeshDatabase write_domain_silo(
|
||||
DBfile *fid, const std::string &filename, const IO::MeshDataStruct &mesh, int format, int rank )
|
||||
{
|
||||
// Create the MeshDatabase
|
||||
auto database = getDatabase( filename, mesh, format );
|
||||
auto database = getDatabase( filename, mesh, format, rank );
|
||||
if ( database.meshClass == "PointList" ) {
|
||||
writeSiloPointList( fid, mesh, database );
|
||||
} else if ( database.meshClass == "TriMesh" ) {
|
||||
|
@ -372,7 +429,8 @@ std::pair<int,int> getSiloMeshType( const std::string& meshClass )
|
|||
}
|
||||
return std::make_pair( meshType, varType );
|
||||
}
|
||||
void writeSiloSummary( const std::vector<IO::MeshDatabase>& meshes_written, const std::string& filename )
|
||||
void writeSiloSummary(
|
||||
const std::vector<IO::MeshDatabase> &meshes_written, const std::string &filename )
|
||||
{
|
||||
auto fid = silo::open( filename, silo::CREATE );
|
||||
for ( const auto &data : meshes_written ) {
|
||||
|
@ -397,9 +455,8 @@ void writeSiloSummary( const std::vector<IO::MeshDatabase>& meshes_written, cons
|
|||
|
||||
// Write the mesh data in the new format
|
||||
static std::vector<IO::MeshDatabase> writeMeshesNewFormat(
|
||||
const std::vector<IO::MeshDataStruct>& meshData, const std::string& path, int format )
|
||||
const std::vector<IO::MeshDataStruct> &meshData, const std::string &path, int format, int rank )
|
||||
{
|
||||
int rank = Utilities::MPI(MPI_COMM_WORLD).getRank();
|
||||
std::vector<IO::MeshDatabase> meshes_written;
|
||||
char filename[100], fullpath[200];
|
||||
sprintf( filename, "%05i", rank );
|
||||
|
@ -407,7 +464,7 @@ static std::vector<IO::MeshDatabase> writeMeshesNewFormat(
|
|||
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) );
|
||||
meshes_written.push_back( write_domain( fid, filename, meshData[i], format, rank ) );
|
||||
}
|
||||
fclose( fid );
|
||||
return meshes_written;
|
||||
|
@ -416,10 +473,9 @@ static std::vector<IO::MeshDatabase> writeMeshesNewFormat(
|
|||
|
||||
// Write the mesh data to silo
|
||||
static std::vector<IO::MeshDatabase> writeMeshesSilo(
|
||||
const std::vector<IO::MeshDataStruct>& meshData, const std::string& path, int format )
|
||||
const std::vector<IO::MeshDataStruct> &meshData, const std::string &path, int format, int rank )
|
||||
{
|
||||
#ifdef USE_SILO
|
||||
int rank = Utilities::MPI(MPI_COMM_WORLD).getRank();
|
||||
std::vector<IO::MeshDatabase> meshes_written;
|
||||
char filename[100], fullpath[200];
|
||||
sprintf( filename, "%05i.silo", rank );
|
||||
|
@ -427,11 +483,15 @@ static std::vector<IO::MeshDatabase> writeMeshesSilo(
|
|||
auto fid = silo::open( fullpath, silo::CREATE );
|
||||
for ( size_t i = 0; i < meshData.size(); i++ ) {
|
||||
auto mesh = meshData[i].mesh;
|
||||
meshes_written.push_back( write_domain_silo(fid,filename,meshData[i],format) );
|
||||
meshes_written.push_back( write_domain_silo( fid, filename, meshData[i], format, rank ) );
|
||||
}
|
||||
silo::close( fid );
|
||||
return meshes_written;
|
||||
#else
|
||||
NULL_USE( meshData );
|
||||
NULL_USE( path );
|
||||
NULL_USE( format );
|
||||
NULL_USE( rank );
|
||||
ERROR( "Application built without silo support" );
|
||||
return std::vector<IO::MeshDatabase>();
|
||||
#endif
|
||||
|
@ -441,7 +501,8 @@ static std::vector<IO::MeshDatabase> writeMeshesSilo(
|
|||
/****************************************************
|
||||
* Write the mesh data *
|
||||
****************************************************/
|
||||
void IO::writeData( const std::string& subdir, const std::vector<IO::MeshDataStruct>& meshData, const Utilities::MPI& comm )
|
||||
void IO::writeData( const std::string &subdir, const std::vector<IO::MeshDataStruct> &meshData,
|
||||
const Utilities::MPI &comm )
|
||||
{
|
||||
if ( global_IO_path.empty() )
|
||||
IO::initialize();
|
||||
|
@ -454,21 +515,18 @@ void IO::writeData( const std::string& subdir, const std::vector<IO::MeshDataStr
|
|||
}
|
||||
// Create the output directory
|
||||
std::string path = global_IO_path + "/" + subdir;
|
||||
if ( rank == 0 ) {
|
||||
mkdir(path.c_str(),S_IRWXU|S_IRGRP);
|
||||
}
|
||||
comm.barrier();
|
||||
recursiveMkdir( path, S_IRWXU | S_IRGRP );
|
||||
// Write the mesh files
|
||||
std::vector<IO::MeshDatabase> meshes_written;
|
||||
if ( global_IO_format == Format::OLD ) {
|
||||
// Write the original triangle format
|
||||
meshes_written = writeMeshesOrigFormat( meshData, path );
|
||||
meshes_written = writeMeshesOrigFormat( meshData, path, rank );
|
||||
} else if ( global_IO_format == Format::NEW ) {
|
||||
// Write the new format (double precision)
|
||||
meshes_written = writeMeshesNewFormat( meshData, path, 2 );
|
||||
meshes_written = writeMeshesNewFormat( meshData, path, 2, rank );
|
||||
} else if ( global_IO_format == Format::SILO ) {
|
||||
// Write silo
|
||||
meshes_written = writeMeshesSilo( meshData, path, 4 );
|
||||
meshes_written = writeMeshesSilo( meshData, path, 4, rank );
|
||||
} else {
|
||||
ERROR( "Unknown format" );
|
||||
}
|
||||
|
@ -504,5 +562,3 @@ void IO::writeData( const std::string& subdir, const std::vector<IO::MeshDataStr
|
|||
}
|
||||
PROFILE_STOP( "writeData" );
|
||||
}
|
||||
|
||||
|
||||
|
|
23
IO/Writer.h
23
IO/Writer.h
|
@ -14,17 +14,18 @@ namespace IO {
|
|||
|
||||
/*!
|
||||
* @brief Initialize the writer
|
||||
* @details This function initializes the writer to the given path. All subsequent
|
||||
* writes will occur in this directory. If this is not called, then it will default
|
||||
* to the current path.
|
||||
* @details This function initializes the writer to the given path.
|
||||
* All subsequent writes will occur in this directory.
|
||||
* If this is not called, then it will default to the current path.
|
||||
* @param[in] path The path to use for writes
|
||||
* @param[in] format The data format to use:
|
||||
* old - Old mesh format (provided for backward compatibility, cannot write variables)
|
||||
* new - New format, 1 file/process
|
||||
* silo - Silo
|
||||
* old - Old mesh format
|
||||
* (provided for backward compatibility, cannot write variables)
|
||||
* new - New format, 1 file/process silo - Silo
|
||||
* @param[in] append Append any existing data (default is false)
|
||||
*/
|
||||
void initialize( const std::string& path="", const std::string& format="silo", bool append=false );
|
||||
void initialize(
|
||||
const std::string &path = "", const std::string &format = "silo", bool append = false );
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -34,7 +35,8 @@ void initialize( const std::string& path="", const std::string& format="silo", b
|
|||
* @param[in] meshData The data to write
|
||||
* @param[in] comm The comm to use for writing (usually MPI_COMM_WORLD or a dup thereof)
|
||||
*/
|
||||
void writeData( const std::string& subdir, const std::vector<IO::MeshDataStruct>& meshData, const Utilities::MPI& comm );
|
||||
void writeData( const std::string &subdir, const std::vector<IO::MeshDataStruct> &meshData,
|
||||
const Utilities::MPI &comm );
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -44,7 +46,8 @@ void writeData( const std::string& subdir, const std::vector<IO::MeshDataStruct>
|
|||
* @param[in] meshData The data to write
|
||||
* @param[in] comm The comm to use for writing (usually MPI_COMM_WORLD or a dup thereof)
|
||||
*/
|
||||
inline void writeData( int timestep, const std::vector<IO::MeshDataStruct>& meshData, const Utilities::MPI& comm )
|
||||
inline void writeData(
|
||||
int timestep, const std::vector<IO::MeshDataStruct> &meshData, const Utilities::MPI &comm )
|
||||
{
|
||||
char subdir[100];
|
||||
sprintf( subdir, "vis%03i", timestep );
|
||||
|
@ -52,6 +55,6 @@ inline void writeData( int timestep, const std::vector<IO::MeshDataStruct>& mesh
|
|||
}
|
||||
|
||||
|
||||
} // IO namespace
|
||||
} // namespace IO
|
||||
|
||||
#endif
|
||||
|
|
111
IO/netcdf.cpp
111
IO/netcdf.cpp
|
@ -1,6 +1,6 @@
|
|||
#include "IO/netcdf.h"
|
||||
#include "common/Utilities.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include "ProfilerApp.h"
|
||||
|
||||
|
@ -56,12 +56,33 @@ static inline VariableType convertType( nc_type type )
|
|||
|
||||
|
||||
// Get nc_type from the template
|
||||
template<class T> inline nc_type getType();
|
||||
template<> inline nc_type getType<char>() { return NC_CHAR; }
|
||||
template<> inline nc_type getType<short>() { return NC_SHORT; }
|
||||
template<> inline nc_type getType<int>() { return NC_INT; }
|
||||
template<> inline nc_type getType<float>() { return NC_FLOAT; }
|
||||
template<> inline nc_type getType<double>() { return NC_DOUBLE; }
|
||||
template<class T>
|
||||
inline nc_type getType();
|
||||
template<>
|
||||
inline nc_type getType<char>()
|
||||
{
|
||||
return NC_CHAR;
|
||||
}
|
||||
template<>
|
||||
inline nc_type getType<short>()
|
||||
{
|
||||
return NC_SHORT;
|
||||
}
|
||||
template<>
|
||||
inline nc_type getType<int>()
|
||||
{
|
||||
return NC_INT;
|
||||
}
|
||||
template<>
|
||||
inline nc_type getType<float>()
|
||||
{
|
||||
return NC_FLOAT;
|
||||
}
|
||||
template<>
|
||||
inline nc_type getType<double>()
|
||||
{
|
||||
return NC_DOUBLE;
|
||||
}
|
||||
|
||||
|
||||
// Function to reverse an array
|
||||
|
@ -134,13 +155,16 @@ int open( const std::string& filename, FileMode mode, const Utilities::MPI& comm
|
|||
}
|
||||
} else {
|
||||
if ( mode == READ ) {
|
||||
int err = nc_open_par( filename.c_str(), NC_MPIPOSIX, comm.getCommunicator(), MPI_INFO_NULL, &fid );
|
||||
int err = nc_open_par(
|
||||
filename.c_str(), NC_MPIPOSIX, comm.getCommunicator(), MPI_INFO_NULL, &fid );
|
||||
CHECK_NC_ERR( err );
|
||||
} else if ( mode == WRITE ) {
|
||||
int err = nc_open_par( filename.c_str(), NC_WRITE|NC_MPIPOSIX, comm.getCommunicator(), MPI_INFO_NULL, &fid );
|
||||
int err = nc_open_par( filename.c_str(), NC_WRITE | NC_MPIPOSIX, comm.getCommunicator(),
|
||||
MPI_INFO_NULL, &fid );
|
||||
CHECK_NC_ERR( err );
|
||||
} else if ( mode == CREATE ) {
|
||||
int err = nc_create_par( filename.c_str(), NC_NETCDF4|NC_MPIIO, comm.getCommunicator(), MPI_INFO_NULL, &fid );
|
||||
int err = nc_create_par( filename.c_str(), NC_NETCDF4 | NC_MPIIO,
|
||||
comm.getCommunicator(), MPI_INFO_NULL, &fid );
|
||||
CHECK_NC_ERR( err );
|
||||
} else {
|
||||
ERROR( "Unknown file mode" );
|
||||
|
@ -239,7 +263,6 @@ VariableType getAttType( int fid, const std::string& att )
|
|||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
* Read a variable *
|
||||
****************************************************/
|
||||
|
@ -329,9 +352,8 @@ Array<std::string> getVar<std::string>( int fid, const std::string& var )
|
|||
PROFILE_STOP( "getVar<std::string>" );
|
||||
return text;
|
||||
}
|
||||
static inline void get_stride_args( const std::vector<int>& start,
|
||||
const std::vector<int>& count, const std::vector<int>& stride,
|
||||
size_t *startp, size_t *countp, ptrdiff_t *stridep )
|
||||
static inline void get_stride_args( const std::vector<int> &start, const std::vector<int> &count,
|
||||
const std::vector<int> &stride, size_t *startp, size_t *countp, ptrdiff_t *stridep )
|
||||
{
|
||||
for ( size_t i = 0; i < start.size(); i++ )
|
||||
startp[i] = start[i];
|
||||
|
@ -341,29 +363,29 @@ static inline void get_stride_args( const std::vector<int>& start,
|
|||
stridep[i] = stride[i];
|
||||
}
|
||||
template<class TYPE>
|
||||
int nc_get_vars_TYPE( int fid, int varid, const size_t start[],
|
||||
const size_t count[], const ptrdiff_t stride[], TYPE *ptr );
|
||||
int nc_get_vars_TYPE( int fid, int varid, const size_t start[], const size_t count[],
|
||||
const ptrdiff_t stride[], TYPE *ptr );
|
||||
template<>
|
||||
int nc_get_vars_TYPE<short>( int fid, int varid, const size_t start[],
|
||||
const size_t count[], const ptrdiff_t stride[], short *ptr )
|
||||
int nc_get_vars_TYPE<short>( int fid, int varid, const size_t start[], const size_t count[],
|
||||
const ptrdiff_t stride[], short *ptr )
|
||||
{
|
||||
return nc_get_vars_short( fid, varid, start, count, stride, ptr );
|
||||
}
|
||||
template<>
|
||||
int nc_get_vars_TYPE<int>( int fid, int varid, const size_t start[],
|
||||
const size_t count[], const ptrdiff_t stride[], int *ptr )
|
||||
int nc_get_vars_TYPE<int>( int fid, int varid, const size_t start[], const size_t count[],
|
||||
const ptrdiff_t stride[], int *ptr )
|
||||
{
|
||||
return nc_get_vars_int( fid, varid, start, count, stride, ptr );
|
||||
}
|
||||
template<>
|
||||
int nc_get_vars_TYPE<float>( int fid, int varid, const size_t start[],
|
||||
const size_t count[], const ptrdiff_t stride[], float *ptr )
|
||||
int nc_get_vars_TYPE<float>( int fid, int varid, const size_t start[], const size_t count[],
|
||||
const ptrdiff_t stride[], float *ptr )
|
||||
{
|
||||
return nc_get_vars_float( fid, varid, start, count, stride, ptr );
|
||||
}
|
||||
template<>
|
||||
int nc_get_vars_TYPE<double>( int fid, int varid, const size_t start[],
|
||||
const size_t count[], const ptrdiff_t stride[], double *ptr )
|
||||
int nc_get_vars_TYPE<double>( int fid, int varid, const size_t start[], const size_t count[],
|
||||
const ptrdiff_t stride[], double *ptr )
|
||||
{
|
||||
return nc_get_vars_double( fid, varid, start, count, stride, ptr );
|
||||
}
|
||||
|
@ -377,7 +399,8 @@ Array<TYPE> getVar( int fid, const std::string& var, const std::vector<int>& sta
|
|||
if ( start[d] < 0 || start[d] + stride[d] * ( count[d] - 1 ) > (int) var_size[d] ) {
|
||||
int rank = Utilities::MPI( MPI_COMM_WORLD ).getRank();
|
||||
char tmp[1000];
|
||||
sprintf(tmp,"%i: Range exceeded array dimension:\n"
|
||||
sprintf( tmp,
|
||||
"%i: Range exceeded array dimension:\n"
|
||||
" start[%i]=%i, count[%i]=%i, stride[%i]=%i, var_size[%i]=%i",
|
||||
rank, d, start[d], d, count[d], d, stride[d], d, (int) var_size[d] );
|
||||
ERROR( tmp );
|
||||
|
@ -387,15 +410,20 @@ Array<TYPE> getVar( int fid, const std::string& var, const std::vector<int>& sta
|
|||
size_t startp[10], countp[10];
|
||||
ptrdiff_t stridep[10];
|
||||
get_stride_args( start, count, stride, startp, countp, stridep );
|
||||
int err = nc_get_vars_TYPE<TYPE>( fid, getVarID(fid,var), startp, countp, stridep, x.data() );
|
||||
int err =
|
||||
nc_get_vars_TYPE<TYPE>( fid, getVarID( fid, var ), startp, countp, stridep, x.data() );
|
||||
CHECK_NC_ERR( err );
|
||||
PROFILE_STOP( "getVar<> (strided)" );
|
||||
return x.reverseDim();
|
||||
}
|
||||
template Array<short> getVar<short>( int, const std::string&, const std::vector<int>&, const std::vector<int>&, const std::vector<int>& );
|
||||
template Array<int> getVar<int>( int, const std::string&, const std::vector<int>&, const std::vector<int>&, const std::vector<int>& );
|
||||
template Array<float> getVar<float>( int, const std::string&, const std::vector<int>&, const std::vector<int>&, const std::vector<int>& );
|
||||
template Array<double> getVar<double>( int, const std::string&, const std::vector<int>&, const std::vector<int>&, const std::vector<int>& );
|
||||
template Array<short> getVar<short>( int, const std::string &, const std::vector<int> &,
|
||||
const std::vector<int> &, const std::vector<int> & );
|
||||
template Array<int> getVar<int>( int, const std::string &, const std::vector<int> &,
|
||||
const std::vector<int> &, const std::vector<int> & );
|
||||
template Array<float> getVar<float>( int, const std::string &, const std::vector<int> &,
|
||||
const std::vector<int> &, const std::vector<int> & );
|
||||
template Array<double> getVar<double>( int, const std::string &, const std::vector<int> &,
|
||||
const std::vector<int> &, const std::vector<int> & );
|
||||
|
||||
|
||||
/****************************************************
|
||||
|
@ -427,7 +455,8 @@ Array<std::string> getAtt<std::string>( int fid, const std::string& att )
|
|||
/****************************************************
|
||||
* Write an array to a file *
|
||||
****************************************************/
|
||||
std::vector<int> defDim( int fid, const std::vector<std::string>& names, const std::vector<int>& dims )
|
||||
std::vector<int> defDim(
|
||||
int fid, const std::vector<std::string> &names, const std::vector<int> &dims )
|
||||
{
|
||||
std::vector<int> dimid( names.size(), 0 );
|
||||
for ( size_t i = 0; i < names.size(); i++ ) {
|
||||
|
@ -453,20 +482,22 @@ void write( int fid, const std::string& var, const std::vector<int>& dimids,
|
|||
// parallel write: each process writes its subarray to the file
|
||||
auto x = data.reverseDim();
|
||||
std::vector<size_t> count = { data.size( 0 ), data.size( 1 ), data.size( 2 ) };
|
||||
std::vector<size_t> start = { info.ix*data.size(0), info.jy*data.size(1), info.kz*data.size(2) };
|
||||
std::vector<size_t> start = { info.ix * data.size( 0 ), info.jy * data.size( 1 ),
|
||||
info.kz * data.size( 2 ) };
|
||||
nc_put_vara( fid, varid, start.data(), count.data(), x.data() );
|
||||
}
|
||||
template void write<short>( int fid, const std::string& var, const std::vector<int>& dimids, const Array<short>& data, const RankInfoStruct& info );
|
||||
template void write<int>( int fid, const std::string& var, const std::vector<int>& dimids, const Array<int>& data, const RankInfoStruct& info );
|
||||
template void write<float>( int fid, const std::string& var, const std::vector<int>& dimids, const Array<float>& data, const RankInfoStruct& info );
|
||||
template void write<double>( int fid, const std::string& var, const std::vector<int>& dimids, const Array<double>& data, const RankInfoStruct& info );
|
||||
template void write<short>( int fid, const std::string &var, const std::vector<int> &dimids,
|
||||
const Array<short> &data, const RankInfoStruct &info );
|
||||
template void write<int>( int fid, const std::string &var, const std::vector<int> &dimids,
|
||||
const Array<int> &data, const RankInfoStruct &info );
|
||||
template void write<float>( int fid, const std::string &var, const std::vector<int> &dimids,
|
||||
const Array<float> &data, const RankInfoStruct &info );
|
||||
template void write<double>( int fid, const std::string &var, const std::vector<int> &dimids,
|
||||
const Array<double> &data, const RankInfoStruct &info );
|
||||
|
||||
|
||||
|
||||
}; // netcdf namespace
|
||||
}; // namespace netcdf
|
||||
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
11
IO/netcdf.h
11
IO/netcdf.h
|
@ -5,9 +5,8 @@
|
|||
#include <vector>
|
||||
|
||||
#include "common/Array.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Communication.h"
|
||||
|
||||
#include "common/MPI.h"
|
||||
|
||||
|
||||
namespace netcdf {
|
||||
|
@ -125,7 +124,8 @@ Array<TYPE> getAtt( int fid, const std::string& att );
|
|||
* @details This function writes the grid dimensions to netcdf.
|
||||
* @param fid Handle to the open file
|
||||
*/
|
||||
std::vector<int> defDim( int fid, const std::vector<std::string>& names, const std::vector<int>& dims );
|
||||
std::vector<int> defDim(
|
||||
int fid, const std::vector<std::string> &names, const std::vector<int> &dims );
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -134,8 +134,9 @@ std::vector<int> defDim( int fid, const std::vector<std::string>& names, const s
|
|||
* @param fid Handle to the open file
|
||||
*/
|
||||
template<class TYPE>
|
||||
void write( int fid, const std::string& var, const std::vector<int>& dimids, const Array<TYPE>& data, const RankInfoStruct& rank_info );
|
||||
void write( int fid, const std::string &var, const std::vector<int> &dimids,
|
||||
const Array<TYPE> &data, const RankInfoStruct &rank_info );
|
||||
|
||||
|
||||
}; // netcdf namespace
|
||||
}; // namespace netcdf
|
||||
#endif
|
||||
|
|
27
IO/silo.cpp
27
IO/silo.cpp
|
@ -1,6 +1,6 @@
|
|||
#include "IO/silo.h"
|
||||
#include "common/Utilities.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include "ProfilerApp.h"
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
|||
#include <silo.h>
|
||||
|
||||
|
||||
|
||||
namespace silo {
|
||||
|
||||
|
||||
|
@ -29,10 +28,7 @@ DBfile* open( const std::string& filename, FileMode mode )
|
|||
}
|
||||
return fid;
|
||||
}
|
||||
void close( DBfile* fid )
|
||||
{
|
||||
DBClose( fid );
|
||||
}
|
||||
void close( DBfile *fid ) { DBClose( fid ); }
|
||||
|
||||
|
||||
/****************************************************
|
||||
|
@ -55,8 +51,8 @@ VariableDataType varDataType( DBfile *fid, const std::string& name )
|
|||
/****************************************************
|
||||
* Write/read a uniform mesh to silo *
|
||||
****************************************************/
|
||||
void readUniformMesh( DBfile* fid, const std::string& meshname,
|
||||
std::vector<double>& range, std::vector<int>& N )
|
||||
void readUniformMesh(
|
||||
DBfile *fid, const std::string &meshname, std::vector<double> &range, std::vector<int> &N )
|
||||
{
|
||||
DBquadmesh *mesh = DBGetQuadmesh( fid, meshname.c_str() );
|
||||
int ndim = mesh->ndims;
|
||||
|
@ -75,8 +71,7 @@ void readUniformMesh( DBfile* fid, const std::string& meshname,
|
|||
* Write a multimesh *
|
||||
****************************************************/
|
||||
void writeMultiMesh( DBfile *fid, const std::string &meshname,
|
||||
const std::vector<std::string>& meshNames,
|
||||
const std::vector<int>& meshTypes )
|
||||
const std::vector<std::string> &meshNames, const std::vector<int> &meshTypes )
|
||||
{
|
||||
std::vector<char *> meshnames( meshNames.size() );
|
||||
for ( size_t i = 0; i < meshNames.size(); ++i )
|
||||
|
@ -84,7 +79,8 @@ void writeMultiMesh( DBfile* fid, const std::string& meshname,
|
|||
std::string tree_name = meshname + "_tree";
|
||||
DBoptlist *optList = DBMakeOptlist( 1 );
|
||||
DBAddOption( optList, DBOPT_MRGTREE_NAME, (char *) tree_name.c_str() );
|
||||
DBPutMultimesh( fid, meshname.c_str(), meshNames.size(), meshnames.data(), (int*) meshTypes.data(), nullptr );
|
||||
DBPutMultimesh( fid, meshname.c_str(), meshNames.size(), meshnames.data(),
|
||||
(int *) meshTypes.data(), nullptr );
|
||||
DBFreeOptlist( optList );
|
||||
}
|
||||
|
||||
|
@ -93,18 +89,17 @@ void writeMultiMesh( DBfile* fid, const std::string& meshname,
|
|||
* Write a multivariable *
|
||||
****************************************************/
|
||||
void writeMultiVar( DBfile *fid, const std::string &varname,
|
||||
const std::vector<std::string>& varNames,
|
||||
const std::vector<int>& varTypes )
|
||||
const std::vector<std::string> &varNames, const std::vector<int> &varTypes )
|
||||
{
|
||||
std::vector<char *> varnames( varNames.size(), nullptr );
|
||||
for ( size_t j = 0; j < varNames.size(); j++ )
|
||||
varnames[j] = const_cast<char *>( varNames[j].c_str() );
|
||||
DBPutMultivar( fid, varname.c_str(), varNames.size(), varnames.data(), (int*) varTypes.data(), nullptr );
|
||||
DBPutMultivar(
|
||||
fid, varname.c_str(), varNames.size(), varnames.data(), (int *) varTypes.data(), nullptr );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}; // silo namespace
|
||||
}; // namespace silo
|
||||
|
||||
|
||||
#else
|
||||
|
|
43
IO/silo.h
43
IO/silo.h
|
@ -1,13 +1,13 @@
|
|||
#ifndef SILO_INTERFACE
|
||||
#define SILO_INTERFACE
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
#include "common/Array.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Communication.h"
|
||||
#include "common/MPI.h"
|
||||
|
||||
|
||||
#ifdef USE_SILO
|
||||
|
@ -17,13 +17,18 @@
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
namespace silo {
|
||||
|
||||
|
||||
enum FileMode { READ, WRITE, CREATE };
|
||||
|
||||
enum class VariableType : int { NodeVariable=1, EdgeVariable=2, SurfaceVariable=2, VolumeVariable=3, NullVariable=0 };
|
||||
enum class VariableType : int {
|
||||
NodeVariable = 1,
|
||||
EdgeVariable = 2,
|
||||
SurfaceVariable = 2,
|
||||
VolumeVariable = 3,
|
||||
NullVariable = 0
|
||||
};
|
||||
|
||||
enum class VariableDataType { DOUBLE, FLOAT, INT, UNKNOWN };
|
||||
|
||||
|
@ -98,8 +103,8 @@ void writeUniformMesh( DBfile* fid, const std::string& meshname,
|
|||
* @param[out] range Range of mesh { xmin, xmax, ymin, ymax, zmin, zmax }
|
||||
* @param[out] N Number of cells in each direction
|
||||
*/
|
||||
void readUniformMesh( DBfile* fid, const std::string& meshname,
|
||||
std::vector<double>& range, std::vector<int>& N );
|
||||
void readUniformMesh(
|
||||
DBfile *fid, const std::string &meshname, std::vector<double> &range, std::vector<int> &N );
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -113,8 +118,9 @@ void readUniformMesh( DBfile* fid, const std::string& meshname,
|
|||
* @param[in] type Variable type
|
||||
*/
|
||||
template<int NDIM, class TYPE>
|
||||
void writeUniformMeshVariable( DBfile* fid, const std::string& meshname, const std::array<int,NDIM>& N,
|
||||
const std::string& varname, const Array<TYPE>& data, VariableType type );
|
||||
void writeUniformMeshVariable( DBfile *fid, const std::string &meshname,
|
||||
const std::array<int, NDIM> &N, const std::string &varname, const Array<TYPE> &data,
|
||||
VariableType type );
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -138,8 +144,8 @@ Array<TYPE> readUniformMeshVariable( DBfile* fid, const std::string& varname );
|
|||
* @param[in] coords Coordinates of the points
|
||||
*/
|
||||
template<class TYPE>
|
||||
void writePointMesh( DBfile* fid, const std::string& meshname,
|
||||
int ndim, int N, const TYPE *coords[] );
|
||||
void writePointMesh(
|
||||
DBfile *fid, const std::string &meshname, int ndim, int N, const TYPE *coords[] );
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -162,8 +168,8 @@ Array<TYPE> readPointMesh( DBfile* fid, const std::string& meshname );
|
|||
* @param[in] data Variable data
|
||||
*/
|
||||
template<class TYPE>
|
||||
void writePointMeshVariable( DBfile* fid, const std::string& meshname,
|
||||
const std::string& varname, const Array<TYPE>& data );
|
||||
void writePointMeshVariable(
|
||||
DBfile *fid, const std::string &meshname, const std::string &varname, const Array<TYPE> &data );
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -190,8 +196,8 @@ Array<TYPE> readPointMeshVariable( DBfile* fid, const std::string& varname );
|
|||
* @param[in] tri Coordinates of the points
|
||||
*/
|
||||
template<class TYPE>
|
||||
void writeTriMesh( DBfile* fid, const std::string& meshname,
|
||||
int ndim, int ndim_tri, int N, const TYPE *coords[], int N_tri, const int *tri[] );
|
||||
void writeTriMesh( DBfile *fid, const std::string &meshname, int ndim, int ndim_tri, int N,
|
||||
const TYPE *coords[], int N_tri, const int *tri[] );
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -241,8 +247,7 @@ Array<TYPE> readTriMeshVariable( DBfile* fid, const std::string& varname );
|
|||
* @param[in] subMeshTypes Type of each submesh
|
||||
*/
|
||||
void writeMultiMesh( DBfile *fid, const std::string &meshname,
|
||||
const std::vector<std::string>& subMeshNames,
|
||||
const std::vector<int>& subMeshTypes );
|
||||
const std::vector<std::string> &subMeshNames, const std::vector<int> &subMeshTypes );
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -257,12 +262,10 @@ void writeMultiMesh( DBfile* fid, const std::string& meshname,
|
|||
* @param[in] nvar Number of subvariables (used to determine suffix)
|
||||
*/
|
||||
void writeMultiVar( DBfile *fid, const std::string &varname,
|
||||
const std::vector<std::string>& subVarNames,
|
||||
const std::vector<int>& subVarTypes );
|
||||
const std::vector<std::string> &subVarNames, const std::vector<int> &subVarTypes );
|
||||
|
||||
|
||||
}; // silo namespace
|
||||
}; // namespace silo
|
||||
#endif
|
||||
|
||||
#include "IO/silo.hpp"
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ ADD_LBPM_EXECUTABLE( GenerateSphereTest )
|
|||
#ADD_LBPM_EXECUTABLE( BlobAnalysis )
|
||||
#ADD_LBPM_EXECUTABLE( BlobIdentify )
|
||||
#ADD_LBPM_EXECUTABLE( BlobIdentifyParallel )
|
||||
#ADD_LBPM_EXECUTABLE( convertIO )
|
||||
ADD_LBPM_EXECUTABLE( convertIO )
|
||||
#ADD_LBPM_EXECUTABLE( DataAggregator )
|
||||
#ADD_LBPM_EXECUTABLE( BlobAnalyzeParallel )(
|
||||
ADD_LBPM_EXECUTABLE( lbpm_minkowski_scalar )
|
||||
|
|
|
@ -159,7 +159,7 @@ void testWriter( const std::string& format, std::vector<IO::MeshDataStruct>& mes
|
|||
// Test the simple read interface
|
||||
bool pass = true;
|
||||
for ( const auto& timestep : timesteps ) {
|
||||
auto data = IO::readData( path, timestep );
|
||||
auto data = IO::readData( path, timestep, comm.getRank() );
|
||||
pass = pass && data.size() == meshData.size();
|
||||
for ( size_t i=0; i<data.size(); i++ ) {
|
||||
pass = pass && checkMesh( meshData, format, data[i].mesh );
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
|
||||
#include "common/MPI_Helpers.h"
|
||||
#include "common/Communication.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
#include "IO/Mesh.h"
|
||||
#include "IO/Reader.h"
|
||||
|
@ -18,71 +17,53 @@ int main(int argc, char **argv)
|
|||
{
|
||||
// Initialize MPI
|
||||
Utilities::startup( argc, argv );
|
||||
Utilities::MPI comm( MPI_COMM_WORLD );
|
||||
int rank = comm.getRank();
|
||||
int nprocs = comm.getSize();
|
||||
Utilities::setErrorHandlers();
|
||||
PROFILE_ENABLE(2);
|
||||
PROFILE_ENABLE_TRACE();
|
||||
PROFILE_START("Main");
|
||||
|
||||
{ // Limit scope
|
||||
|
||||
Utilities::MPI comm( MPI_COMM_WORLD );
|
||||
// Get inputs
|
||||
if ( argc != 3 ) {
|
||||
if ( argc != 5 ) {
|
||||
std::cerr << "Error calling convertIO:\n";
|
||||
std::cerr << " convertIO input_file format\n";
|
||||
std::cerr << " convertIO <input_path> <input_format> <output_path> <output_format>\n";
|
||||
return -1;
|
||||
}
|
||||
std::string filename = argv[1];
|
||||
std::string format = argv[2];
|
||||
std::string path = IO::getPath( filename );
|
||||
std::string path_in = argv[1];
|
||||
std::string format_in = argv[2];
|
||||
std::string path_out = argv[3];
|
||||
std::string format_out = argv[4];
|
||||
|
||||
// Check that we have enough ranks to load and write the data
|
||||
// This is really only a bottleneck for the writer
|
||||
int N_domains = IO::maxDomains( path_in, format_in, comm );
|
||||
ASSERT( comm.getSize() == N_domains );
|
||||
|
||||
// Read the timesteps
|
||||
auto timesteps = IO::readTimesteps( filename, "old" );
|
||||
auto timesteps = IO::readTimesteps( path_in, format_in );
|
||||
|
||||
// Loop through the timesteps, reading/writing the data
|
||||
IO::initialize( "", format, false );
|
||||
IO::initialize( path_out, format_out, false );
|
||||
for ( auto timestep : timesteps ) {
|
||||
|
||||
// Read the list of MeshDatabase
|
||||
auto databases = IO::getMeshList( path, timestep );
|
||||
// Set the domain to read (needs to be the current rank for the writer to be valid)
|
||||
int domain = comm.getRank();
|
||||
|
||||
// Build the MeshDataStruct
|
||||
std::vector<IO::MeshDataStruct> meshData(databases.size());
|
||||
|
||||
// Loop through the database
|
||||
int i = 0;
|
||||
PROFILE_START("Read");
|
||||
for ( const auto& database : databases ) {
|
||||
|
||||
// Read the appropriate mesh domain
|
||||
ASSERT( (int) database.domains.size() == nprocs );
|
||||
meshData[i].meshName = database.name;
|
||||
meshData[i].mesh = IO::getMesh( path, timestep, database, rank );
|
||||
|
||||
// Read the variables
|
||||
for ( auto var : database.variables ) {
|
||||
auto varData = IO::getVariable( path, timestep, database, rank, var.name );
|
||||
IO::reformatVariable( *meshData[i].mesh, *varData );
|
||||
meshData[i].vars.push_back( varData );
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
MPI_Barrier(comm);
|
||||
PROFILE_STOP("Read");
|
||||
// Get the maximum number of domains for the
|
||||
auto data = IO::readData( path_in, timestep, domain );
|
||||
|
||||
// Save the mesh data to a new file
|
||||
PROFILE_START("Write");
|
||||
IO::writeData( timestep, meshData, MPI_COMM_WORLD );
|
||||
MPI_Barrier(comm);
|
||||
PROFILE_STOP("Write");
|
||||
IO::writeData( timestep, data, comm );
|
||||
|
||||
}
|
||||
|
||||
} // Limit scope
|
||||
|
||||
// shutdown
|
||||
PROFILE_STOP("Main");
|
||||
PROFILE_SAVE("convertData",true);
|
||||
comm.barrier();
|
||||
Utilities::shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user