Fixed merge conflicts to use new writers / visualization
This commit is contained in:
@@ -55,7 +55,7 @@ ENDIF()
|
||||
|
||||
|
||||
# Add some directories to include
|
||||
INCLUDE_DIRECTORIES( ${LBPM_INSTALL_DIR}/include )
|
||||
INCLUDE_DIRECTORIES( "${LBPM_INSTALL_DIR}/include" )
|
||||
|
||||
|
||||
# Set doxygen info
|
||||
@@ -89,6 +89,7 @@ IF ( NOT ONLY_BUILD_DOCS )
|
||||
CONFIGURE_CUDA()
|
||||
CONFIGURE_MIC()
|
||||
CONFIGURE_LBPM()
|
||||
CONFIGURE_TIMER()
|
||||
CONFIGURE_LINE_COVERAGE()
|
||||
ENDIF()
|
||||
|
||||
@@ -101,6 +102,7 @@ SET( LBPM_LIBS lbpm-wia )
|
||||
IF ( NOT ONLY_BUILD_DOCS )
|
||||
BEGIN_PACKAGE_CONFIG( lbpm-wia )
|
||||
ADD_PACKAGE_SUBDIRECTORY( common )
|
||||
ADD_PACKAGE_SUBDIRECTORY( IO )
|
||||
IF ( USE_CUDA )
|
||||
ADD_PACKAGE_SUBDIRECTORY( gpu )
|
||||
ELSE()
|
||||
@@ -112,3 +114,10 @@ IF ( NOT ONLY_BUILD_DOCS )
|
||||
ENDIF()
|
||||
|
||||
|
||||
# Create the visit plugin
|
||||
IF ( USE_VISIT )
|
||||
INCLUDE( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindVisIt.cmake )
|
||||
VISIT_PLUGIN( visit LBM )
|
||||
ENDIF()
|
||||
|
||||
|
||||
|
||||
64
IO/IOHelpers.h
Normal file
64
IO/IOHelpers.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef IO_HELPERS_INC
|
||||
#define IO_HELPERS_INC
|
||||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
// Find a character in a line
|
||||
inline size_t find( const char *line, char token )
|
||||
{
|
||||
size_t i=0;
|
||||
while ( 1 ) {
|
||||
if ( line[i]==token || line[i]<32 || line[i]==0 )
|
||||
break;
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
// Remove preceeding/trailing whitespace
|
||||
inline std::string deblank( const std::string& str )
|
||||
{
|
||||
size_t i1 = str.size();
|
||||
size_t i2 = 0;
|
||||
for (size_t i=0; i<str.size(); i++) {
|
||||
if ( str[i]!=' ' && str[i]>=32 ) {
|
||||
i1 = std::min(i1,i);
|
||||
i2 = std::max(i2,i);
|
||||
}
|
||||
}
|
||||
return str.substr(i1,i2-i1+1);
|
||||
}
|
||||
|
||||
|
||||
// Split a list by the given token
|
||||
inline std::vector<std::string> splitList( const char *line, const char token )
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
size_t i1 = 0;
|
||||
size_t i2 = 0;
|
||||
while ( 1 ) {
|
||||
if ( line[i2]==token || line[i2]<32 ) {
|
||||
std::string tmp(&line[i1],i2-i1);
|
||||
tmp = deblank(tmp);
|
||||
if ( !tmp.empty() )
|
||||
list.push_back(tmp);
|
||||
i1 = i2+1;
|
||||
}
|
||||
if ( line[i2]==0 )
|
||||
break;
|
||||
i2++;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
339
IO/Mesh.cpp
Normal file
339
IO/Mesh.cpp
Normal file
@@ -0,0 +1,339 @@
|
||||
#include "Mesh.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
inline Point nullPoint()
|
||||
{
|
||||
Point tmp;
|
||||
tmp.x = std::numeric_limits<double>::quiet_NaN();
|
||||
tmp.y = std::numeric_limits<double>::quiet_NaN();
|
||||
tmp.z = std::numeric_limits<double>::quiet_NaN();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* Mesh *
|
||||
****************************************************/
|
||||
Mesh::Mesh( )
|
||||
{
|
||||
}
|
||||
Mesh::~Mesh( )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* PointList *
|
||||
****************************************************/
|
||||
PointList::PointList( )
|
||||
{
|
||||
}
|
||||
PointList::PointList( size_t N )
|
||||
{
|
||||
Point tmp = nullPoint();
|
||||
points.resize(N,tmp);
|
||||
}
|
||||
PointList::~PointList( )
|
||||
{
|
||||
}
|
||||
size_t PointList::numberPointsVar( VariableType type ) const
|
||||
{
|
||||
size_t N = 0;
|
||||
if ( type == VariableType::NodeVariable )
|
||||
N = points.size();
|
||||
return N;
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* TriList *
|
||||
****************************************************/
|
||||
TriList::TriList( )
|
||||
{
|
||||
}
|
||||
TriList::TriList( size_t N_tri )
|
||||
{
|
||||
Point tmp = nullPoint();
|
||||
A.resize(N_tri,tmp);
|
||||
B.resize(N_tri,tmp);
|
||||
C.resize(N_tri,tmp);
|
||||
}
|
||||
TriList::TriList( const TriMesh& mesh )
|
||||
{
|
||||
Point tmp = nullPoint();
|
||||
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]];
|
||||
for (size_t i=0; i<B.size(); i++)
|
||||
B[i] = P[mesh.B[i]];
|
||||
for (size_t i=0; i<C.size(); i++)
|
||||
C[i] = P[mesh.C[i]];
|
||||
}
|
||||
TriList::~TriList( )
|
||||
{
|
||||
}
|
||||
size_t TriList::numberPointsVar( VariableType type ) const
|
||||
{
|
||||
size_t N = 0;
|
||||
if ( type==VariableType::NodeVariable )
|
||||
N = 3*A.size();
|
||||
else if ( type==VariableType::SurfaceVariable || type==VariableType::VolumeVariable )
|
||||
N = A.size();
|
||||
return N;
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* TriMesh *
|
||||
****************************************************/
|
||||
TriMesh::TriMesh( )
|
||||
{
|
||||
}
|
||||
TriMesh::TriMesh( size_t N_tri, size_t N_point )
|
||||
{
|
||||
vertices.reset( new PointList(N_point) );
|
||||
A.resize(N_tri,-1);
|
||||
B.resize(N_tri,-1);
|
||||
C.resize(N_tri,-1);
|
||||
}
|
||||
TriMesh::TriMesh( size_t N_tri, std::shared_ptr<PointList> points )
|
||||
{
|
||||
vertices = points;
|
||||
A.resize(N_tri,-1);
|
||||
B.resize(N_tri,-1);
|
||||
C.resize(N_tri,-1);
|
||||
}
|
||||
TriMesh::TriMesh( const TriList& mesh )
|
||||
{
|
||||
// For simlicity we will just create a mesh with ~3x the verticies for now
|
||||
ASSERT(mesh.A.size()==mesh.B.size()&&mesh.A.size()==mesh.C.size());
|
||||
A.resize(mesh.A.size());
|
||||
B.resize(mesh.B.size());
|
||||
C.resize(mesh.C.size());
|
||||
vertices.reset( new PointList(3*mesh.A.size()) );
|
||||
for (size_t i=0; i<A.size(); i++) {
|
||||
A[i] = 3*i+0;
|
||||
B[i] = 3*i+1;
|
||||
C[i] = 3*i+2;
|
||||
vertices->points[A[i]] = mesh.A[i];
|
||||
vertices->points[B[i]] = mesh.B[i];
|
||||
vertices->points[C[i]] = mesh.C[i];
|
||||
}
|
||||
}
|
||||
TriMesh::~TriMesh( )
|
||||
{
|
||||
vertices.reset();
|
||||
A.clear();
|
||||
B.clear();
|
||||
C.clear();
|
||||
}
|
||||
size_t TriMesh::numberPointsVar( VariableType type ) const
|
||||
{
|
||||
size_t N = 0;
|
||||
if ( type==VariableType::NodeVariable )
|
||||
N = vertices->points.size();
|
||||
else if ( type==VariableType::SurfaceVariable || type==VariableType::VolumeVariable )
|
||||
N = A.size();
|
||||
return N;
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* Converters *
|
||||
****************************************************/
|
||||
std::shared_ptr<PointList> getPointList( std::shared_ptr<Mesh> mesh )
|
||||
{
|
||||
return std::dynamic_pointer_cast<PointList>(mesh);
|
||||
}
|
||||
std::shared_ptr<TriMesh> getTriMesh( std::shared_ptr<Mesh> mesh )
|
||||
{
|
||||
std::shared_ptr<TriMesh> mesh2;
|
||||
if ( std::dynamic_pointer_cast<TriMesh>(mesh) != NULL ) {
|
||||
mesh2 = std::dynamic_pointer_cast<TriMesh>(mesh);
|
||||
} else if ( std::dynamic_pointer_cast<TriList>(mesh) != NULL ) {
|
||||
std::shared_ptr<TriList> trilist = std::dynamic_pointer_cast<TriList>(mesh);
|
||||
ASSERT(trilist!=NULL);
|
||||
mesh2.reset( new TriMesh(*trilist) );
|
||||
}
|
||||
return mesh2;
|
||||
}
|
||||
std::shared_ptr<TriList> getTriList( std::shared_ptr<Mesh> mesh )
|
||||
{
|
||||
std::shared_ptr<TriList> mesh2;
|
||||
if ( std::dynamic_pointer_cast<TriList>(mesh) != NULL ) {
|
||||
mesh2 = std::dynamic_pointer_cast<TriList>(mesh);
|
||||
} else if ( std::dynamic_pointer_cast<TriMesh>(mesh) != NULL ) {
|
||||
std::shared_ptr<TriMesh> trimesh = std::dynamic_pointer_cast<TriMesh>(mesh);
|
||||
ASSERT(trimesh!=NULL);
|
||||
mesh2.reset( new TriList(*trimesh) );
|
||||
}
|
||||
return mesh2;
|
||||
}
|
||||
std::shared_ptr<const PointList> getPointList( std::shared_ptr<const Mesh> mesh )
|
||||
{
|
||||
return getPointList( std::const_pointer_cast<Mesh>(mesh) );
|
||||
}
|
||||
std::shared_ptr<const TriMesh> getTriMesh( std::shared_ptr<const Mesh> mesh )
|
||||
{
|
||||
return getTriMesh( std::const_pointer_cast<Mesh>(mesh) );
|
||||
}
|
||||
std::shared_ptr<const TriList> getTriList( std::shared_ptr<const Mesh> mesh )
|
||||
{
|
||||
return getTriList( std::const_pointer_cast<Mesh>(mesh) );
|
||||
}
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
||||
176
IO/Mesh.h
Normal file
176
IO/Mesh.h
Normal file
@@ -0,0 +1,176 @@
|
||||
#ifndef MESH_INC
|
||||
#define MESH_INC
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "common/PointList.h"
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
//! Possible variable types
|
||||
enum class VariableType : unsigned char { NodeVariable=1, EdgeVariable=2, SurfaceVariable=2, VolumeVariable=3, Null=0 };
|
||||
|
||||
|
||||
/*! \class Mesh
|
||||
\brief A base class for meshes
|
||||
*/
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
//! Destructor
|
||||
virtual ~Mesh();
|
||||
//! Mesh class name (eg. PointList)
|
||||
virtual std::string className() const = 0;
|
||||
//! Number of points for the given variable type
|
||||
virtual size_t numberPointsVar( VariableType type ) 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();
|
||||
Mesh(const Mesh&);
|
||||
Mesh& operator=(const Mesh&);
|
||||
};
|
||||
|
||||
|
||||
/*! \class PointList
|
||||
\brief A class used to hold a list of verticies
|
||||
*/
|
||||
class PointList: public Mesh
|
||||
{
|
||||
public:
|
||||
//! Empty constructor
|
||||
PointList();
|
||||
//! Constructor for N points
|
||||
PointList( size_t N );
|
||||
//! Destructor
|
||||
virtual ~PointList();
|
||||
//! Mesh class name
|
||||
virtual std::string className() const { return "PointList"; }
|
||||
//! Number of points for the given variable type
|
||||
virtual size_t numberPointsVar( VariableType type ) const;
|
||||
//! 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
|
||||
};
|
||||
|
||||
|
||||
/*! \class TriMesh
|
||||
\brief A class used to hold a list of trianges specified by their vertex number and list of coordiantes
|
||||
*/
|
||||
class TriList;
|
||||
class TriMesh: public Mesh
|
||||
{
|
||||
public:
|
||||
//! TriMesh constructor
|
||||
TriMesh();
|
||||
//! Constructor for Nt triangles and Np points
|
||||
TriMesh( size_t N_tri, size_t N_point );
|
||||
//! Constructor for Nt triangles and the given points
|
||||
TriMesh( size_t N_tri, std::shared_ptr<PointList> points );
|
||||
//! Constructor from TriList
|
||||
TriMesh( const TriList& );
|
||||
//! Destructor
|
||||
virtual ~TriMesh();
|
||||
//! Mesh class name
|
||||
virtual std::string className() const { return "TriMesh"; }
|
||||
//! Number of points for the given variable type
|
||||
virtual size_t numberPointsVar( VariableType type ) const;
|
||||
//! 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
|
||||
std::vector<int> B; //!< Second vertex
|
||||
std::vector<int> C; //!< Third vertex
|
||||
};
|
||||
|
||||
|
||||
/*! \class TriList
|
||||
\brief A class used to hold a list of triangles specified by their vertex coordinates
|
||||
*/
|
||||
class TriList: public Mesh
|
||||
{
|
||||
public:
|
||||
//! Empty constructor
|
||||
TriList();
|
||||
//! Constructor for N triangles
|
||||
TriList( size_t N_tri );
|
||||
//! Constructor from TriMesh
|
||||
TriList( const TriMesh& );
|
||||
//! Destructor
|
||||
virtual ~TriList();
|
||||
//! Mesh class name
|
||||
virtual std::string className() const { return "TriList"; }
|
||||
//! Number of points for the given variable type
|
||||
virtual size_t numberPointsVar( VariableType type ) const;
|
||||
//! 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
|
||||
std::vector<Point> C; //!< Third vertex
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*! \class Variable
|
||||
\brief A base class fore variables
|
||||
*/
|
||||
struct Variable
|
||||
{
|
||||
public:
|
||||
// Internal variables
|
||||
unsigned int dim; //!< Number of points per grid point (1: scalar, 3: vector, ...)
|
||||
VariableType type; //!< Variable type
|
||||
std::string name; //!< Variable name
|
||||
std::vector<double> data; //!< Variable data
|
||||
//! Empty constructor
|
||||
Variable(): type(VariableType::Null) {}
|
||||
//! 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::shared_ptr<Variable> > vars;
|
||||
};
|
||||
|
||||
|
||||
//! Convert the mesh to a TriMesh (will return NULL if this is invalid)
|
||||
std::shared_ptr<PointList> getPointList( std::shared_ptr<Mesh> mesh );
|
||||
std::shared_ptr<TriMesh> getTriMesh( std::shared_ptr<Mesh> mesh );
|
||||
std::shared_ptr<TriList> getTriList( std::shared_ptr<Mesh> mesh );
|
||||
std::shared_ptr<const PointList> getPointList( std::shared_ptr<const Mesh> mesh );
|
||||
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
|
||||
|
||||
#endif
|
||||
|
||||
415
IO/MeshDatabase.cpp
Normal file
415
IO/MeshDatabase.cpp
Normal file
@@ -0,0 +1,415 @@
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/Mesh.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <ProfilerApp.h>
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
* Pack/unpack data from a buffer *
|
||||
****************************************************/
|
||||
// MeshType
|
||||
template<>
|
||||
size_t packsize<IO::MeshType>( const IO::MeshType& rhs )
|
||||
{
|
||||
return sizeof(IO::MeshType);
|
||||
}
|
||||
template<>
|
||||
void pack<IO::MeshType>( const IO::MeshType& rhs, char *buffer )
|
||||
{
|
||||
memcpy(buffer,&rhs,sizeof(IO::MeshType));
|
||||
}
|
||||
template<>
|
||||
void unpack<IO::MeshType>( IO::MeshType& data, const char *buffer )
|
||||
{
|
||||
memcpy(&data,buffer,sizeof(IO::MeshType));
|
||||
}
|
||||
// Variable::VariableType
|
||||
template<>
|
||||
size_t packsize<IO::VariableType>( const IO::VariableType& rhs )
|
||||
{
|
||||
return sizeof(IO::VariableType);
|
||||
}
|
||||
template<>
|
||||
void pack<IO::VariableType>( const IO::VariableType& rhs, char *buffer )
|
||||
{
|
||||
memcpy(buffer,&rhs,sizeof(IO::VariableType));
|
||||
}
|
||||
template<>
|
||||
void unpack<IO::VariableType>( IO::VariableType& data, const char *buffer )
|
||||
{
|
||||
memcpy(&data,buffer,sizeof(IO::VariableType));
|
||||
}
|
||||
// DatabaseEntry
|
||||
template<>
|
||||
size_t packsize<IO::DatabaseEntry>( const IO::DatabaseEntry& rhs )
|
||||
{
|
||||
return packsize(rhs.name)+packsize(rhs.file)+packsize(rhs.offset);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
// VariableDatabase
|
||||
template<>
|
||||
size_t packsize<IO::VariableDatabase>( const IO::VariableDatabase& rhs )
|
||||
{
|
||||
return packsize(rhs.name)+packsize(rhs.type)+packsize(rhs.dim);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
/****************************************************
|
||||
* VariableDatabase *
|
||||
****************************************************/
|
||||
bool VariableDatabase::operator==(const VariableDatabase& rhs ) const
|
||||
{
|
||||
return type==rhs.type && dim==rhs.dim && name==rhs.name;
|
||||
}
|
||||
bool VariableDatabase::operator!=(const VariableDatabase& rhs ) const
|
||||
{
|
||||
return type!=rhs.type || dim!=rhs.dim || name!=rhs.name;
|
||||
}
|
||||
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
|
||||
{
|
||||
if ( name>rhs.name )
|
||||
return true;
|
||||
else if ( name<rhs.name )
|
||||
return false;
|
||||
if ( type>rhs.type )
|
||||
return true;
|
||||
else if ( type<rhs.type )
|
||||
return false;
|
||||
if ( dim>rhs.dim )
|
||||
return true;
|
||||
else if ( dim<rhs.dim )
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
bool VariableDatabase::operator<(const VariableDatabase& rhs ) const
|
||||
{
|
||||
return !operator>(rhs) && operator!=(rhs);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* MeshDatabase *
|
||||
****************************************************/
|
||||
MeshDatabase::MeshDatabase()
|
||||
{
|
||||
}
|
||||
MeshDatabase::~MeshDatabase()
|
||||
{
|
||||
}
|
||||
MeshDatabase::MeshDatabase(const MeshDatabase& rhs)
|
||||
{
|
||||
name = rhs.name;
|
||||
type = rhs.type;
|
||||
meshClass = rhs.meshClass;
|
||||
format = rhs.format;
|
||||
domains = rhs.domains;
|
||||
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->variables = rhs.variables;
|
||||
this->variable_data = rhs.variable_data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
* DatabaseEntry *
|
||||
****************************************************/
|
||||
std::string DatabaseEntry::write( ) const
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
// Gather the mesh databases from all processors
|
||||
std::vector<MeshDatabase> gatherAll( const std::vector<MeshDatabase>& meshes, MPI_Comm comm )
|
||||
{
|
||||
#ifdef USE_MPI
|
||||
PROFILE_START("gatherAll");
|
||||
int rank = MPI_WORLD_RANK();
|
||||
int size = MPI_WORLD_SIZE();
|
||||
// First pack the mesh data to local buffers
|
||||
size_t localsize = 0;
|
||||
for (size_t i=0; i<meshes.size(); 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 += packsize(meshes[i]);
|
||||
}
|
||||
// Get the number of bytes each processor will be sending/recieving
|
||||
int sendsize = static_cast<int>(localsize);
|
||||
int *recvsize = new int[size];
|
||||
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 (int i=1; i<size; i++) {
|
||||
disp[i] = disp[i-1] + recvsize[i];
|
||||
globalsize += recvsize[i];
|
||||
}
|
||||
// Send/recv the global data
|
||||
char *globalbuf = new char[globalsize];
|
||||
MPI_Allgatherv(localbuf,sendsize,MPI_CHAR,globalbuf,recvsize,disp,MPI_CHAR,comm);
|
||||
// Unpack the data
|
||||
std::map<std::string,MeshDatabase> data;
|
||||
pos = 0;
|
||||
while ( pos < globalsize ) {
|
||||
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.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) {
|
||||
// Get the unique variables
|
||||
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
|
||||
delete [] localbuf;
|
||||
delete [] recvsize;
|
||||
delete [] disp;
|
||||
delete [] globalbuf;
|
||||
// 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)
|
||||
data2[i] = it->second;
|
||||
PROFILE_STOP("gatherAll");
|
||||
return data2;
|
||||
#else
|
||||
return meshes;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//! Write the mesh databases to a file
|
||||
void write( const std::vector<MeshDatabase>& meshes, const std::string& filename )
|
||||
{
|
||||
PROFILE_START("write");
|
||||
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," type: %i\n",static_cast<int>(meshes[i].type));
|
||||
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++) {
|
||||
const VariableDatabase& var = meshes[i].variables[j];
|
||||
fprintf(fid,"%s|%i|%i; ",var.name.c_str(),static_cast<int>(var.type),var.dim);
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
//! Read the mesh databases from a file
|
||||
std::vector<MeshDatabase> read( const std::string& filename )
|
||||
{
|
||||
std::vector<MeshDatabase> meshes;
|
||||
PROFILE_START("read");
|
||||
FILE *fid = fopen(filename.c_str(),"rb");
|
||||
if ( fid==NULL )
|
||||
ERROR("Error opening file");
|
||||
char *line = new char[10000];
|
||||
while ( std::fgets(line,1000,fid) != NULL ) {
|
||||
if ( line[0]<32 ) {
|
||||
// Empty line
|
||||
continue;
|
||||
} else if ( line[0] != ' ' ) {
|
||||
meshes.resize(meshes.size()+1);
|
||||
std::string name(line);
|
||||
name.resize(name.size()-1);
|
||||
meshes.back().name = name;
|
||||
} else if ( strncmp(line," format:",10)==0 ) {
|
||||
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," 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 ) {
|
||||
MeshDatabase& mesh = meshes.back();
|
||||
std::vector<std::string> variables = splitList(&line[13],';');
|
||||
mesh.variables.resize(variables.size());
|
||||
for (size_t i=0; i<variables.size(); i++) {
|
||||
std::vector<std::string> tmp = splitList(variables[i].c_str(),'|');
|
||||
ASSERT(tmp.size()==3);
|
||||
mesh.variables[i].name = tmp[0];
|
||||
mesh.variables[i].type = static_cast<VariableType>(atoi(tmp[1].c_str()));
|
||||
mesh.variables[i].dim = atoi(tmp[2].c_str());
|
||||
}
|
||||
} else if ( strncmp(line," variable(",12)==0 ) {
|
||||
size_t i1 = find(line,',');
|
||||
size_t i2 = find(line,':');
|
||||
std::string domain = deblank(std::string(line,12,i1-12));
|
||||
std::string variable = deblank(std::string(line,i1+1,i2-i1-2));
|
||||
std::pair<std::string,std::string> key(domain,variable);
|
||||
DatabaseEntry data(&line[i2+1]);
|
||||
meshes.back().variable_data.insert(
|
||||
std::pair<std::pair<std::string,std::string>,DatabaseEntry>(key,data) );
|
||||
} else {
|
||||
ERROR("Error reading line");
|
||||
}
|
||||
}
|
||||
fclose(fid);
|
||||
delete [] line;
|
||||
PROFILE_STOP("read");
|
||||
return meshes;
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
88
IO/MeshDatabase.h
Normal file
88
IO/MeshDatabase.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#ifndef MeshDatabase_INC
|
||||
#define MeshDatabase_INC
|
||||
|
||||
#include "IO/Mesh.h"
|
||||
#include "common/MPI.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
class Mesh;
|
||||
|
||||
|
||||
//! Enum to identify mesh type
|
||||
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 variables
|
||||
struct VariableDatabase {
|
||||
std::string name; //!< Name of the variable
|
||||
IO::VariableType type; //!< Variable
|
||||
unsigned int dim; //!< Number of points per grid point (1: scalar, 3: vector, ...)
|
||||
// Overload key operators
|
||||
bool operator==(const VariableDatabase& rhs ) const;
|
||||
bool operator!=(const VariableDatabase& rhs ) const;
|
||||
bool operator>=(const VariableDatabase& rhs ) const;
|
||||
bool operator<=(const VariableDatabase& rhs ) const;
|
||||
bool operator> (const VariableDatabase& rhs ) const;
|
||||
bool operator< (const VariableDatabase& rhs ) const;
|
||||
};
|
||||
|
||||
|
||||
//! Structure to hold the info about the meshes
|
||||
struct MeshDatabase {
|
||||
typedef std::pair<std::string,std::string> variable_id;
|
||||
std::string name; //!< Name of the mesh
|
||||
MeshType type; //!< Mesh type
|
||||
std::string meshClass; //!< Mesh class
|
||||
unsigned char format; //!< Data format
|
||||
std::vector<DatabaseEntry> domains; //!< List of the domains
|
||||
std::vector<VariableDatabase> variables; //!< List of the variables
|
||||
std::map<variable_id,DatabaseEntry> variable_data; //!< Data for the variables
|
||||
public:
|
||||
MeshDatabase();
|
||||
~MeshDatabase();
|
||||
MeshDatabase(const MeshDatabase&);
|
||||
MeshDatabase& operator=(const MeshDatabase&);
|
||||
};
|
||||
|
||||
|
||||
//! Gather the mesh databases from all processors
|
||||
std::vector<MeshDatabase> gatherAll( const std::vector<MeshDatabase>& meshes, MPI_Comm comm );
|
||||
|
||||
|
||||
//! Write the mesh databases to a file
|
||||
void write( const std::vector<MeshDatabase>& meshes, const std::string& filename );
|
||||
|
||||
|
||||
//! Read the mesh databases from a file
|
||||
std::vector<MeshDatabase> read( const std::string& filename );
|
||||
|
||||
|
||||
//! Return the mesh type
|
||||
IO::MeshType meshType( std::shared_ptr<IO::Mesh> mesh );
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
||||
#endif
|
||||
172
IO/PIO.cpp
Normal file
172
IO/PIO.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
#include "IO/PIO.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
#ifdef USE_MPI
|
||||
#include "mpi.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
static ParallelStreamBuffer pout_buffer;
|
||||
static ParallelStreamBuffer perr_buffer;
|
||||
static ParallelStreamBuffer plog_buffer;
|
||||
|
||||
|
||||
std::ostream pout(&pout_buffer);
|
||||
std::ostream perr(&perr_buffer);
|
||||
std::ostream plog(&plog_buffer);
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Functions to control logging *
|
||||
****************************************************************************/
|
||||
std::ofstream *global_filestream=NULL;
|
||||
static void shutdownFilestream( )
|
||||
{
|
||||
if ( global_filestream!=NULL ) {
|
||||
global_filestream->flush();
|
||||
global_filestream->close();
|
||||
delete global_filestream;
|
||||
global_filestream = NULL;
|
||||
}
|
||||
}
|
||||
void Utilities::logOnlyNodeZero( const std::string &filename )
|
||||
{
|
||||
int rank = 0;
|
||||
#ifdef USE_MPI
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
|
||||
#endif
|
||||
if ( rank == 0 )
|
||||
logAllNodes(filename,true);
|
||||
}
|
||||
void Utilities::logAllNodes( const std::string &filename, bool singleStream )
|
||||
{
|
||||
if ( singleStream )
|
||||
ERROR("Not implimented yet");
|
||||
|
||||
// If the filestream was open, then close it and reset streams
|
||||
shutdownFilestream();
|
||||
|
||||
// Open the log stream and redirect output
|
||||
std::string full_filename = filename;
|
||||
if ( !singleStream ) {
|
||||
int rank = 0;
|
||||
#ifdef USE_MPI
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
|
||||
#endif
|
||||
char tmp[100];
|
||||
sprintf(tmp,".%04i",rank);
|
||||
full_filename += std::string(tmp);
|
||||
}
|
||||
global_filestream = new std::ofstream(full_filename.c_str());
|
||||
|
||||
if ( !(*global_filestream) ) {
|
||||
delete global_filestream;
|
||||
global_filestream = NULL;
|
||||
perr << "PIO: Could not open log file ``" << full_filename << "''\n";
|
||||
} else {
|
||||
pout_buffer.setOutputStream(global_filestream);
|
||||
pout_buffer.setOutputStream(&std::cout);
|
||||
perr_buffer.setOutputStream(global_filestream);
|
||||
perr_buffer.setOutputStream(&std::cerr);
|
||||
plog_buffer.setOutputStream(global_filestream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* ParallelStreamBuffer class *
|
||||
****************************************************************************/
|
||||
void Utilities::stopLogging( )
|
||||
{
|
||||
pout_buffer.reset();
|
||||
perr_buffer.reset();
|
||||
plog_buffer.reset();
|
||||
shutdownFilestream();
|
||||
delete global_filestream;
|
||||
global_filestream = NULL;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* ParallelStreamBuffer class *
|
||||
****************************************************************************/
|
||||
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 );
|
||||
}
|
||||
int ParallelStreamBuffer::sync()
|
||||
{
|
||||
for (size_t i=0; i<d_stream.size(); i++) {
|
||||
std::ostream& stream = *d_stream[i];
|
||||
stream << d_buffer;
|
||||
}
|
||||
d_size = 0;
|
||||
memset(d_buffer,0,d_buffer_size);
|
||||
return 0;
|
||||
}
|
||||
void ParallelStreamBuffer::reserve( size_t size )
|
||||
{
|
||||
if ( size > d_buffer_size ) {
|
||||
if ( d_buffer_size==0 ) {
|
||||
d_buffer_size = 1024;
|
||||
d_buffer = new char[d_buffer_size];
|
||||
memset(d_buffer,0,d_buffer_size);
|
||||
}
|
||||
while ( size > d_buffer_size ) {
|
||||
char *tmp = d_buffer;
|
||||
d_buffer_size *= 2;
|
||||
d_buffer = new char[d_buffer_size];
|
||||
memset(d_buffer,0,d_buffer_size);
|
||||
memcpy(d_buffer,tmp,d_size);
|
||||
delete [] tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::streamsize ParallelStreamBuffer::xsputn( const std::string &text, std::streamsize n )
|
||||
{
|
||||
reserve(d_size+n);
|
||||
memcpy(&d_buffer[d_size],text.c_str(),text.size());
|
||||
if ( text[n-1]==0 || text[n-1]==10 ) { sync(); }
|
||||
return n;
|
||||
}
|
||||
int ParallelStreamBuffer::overflow(int ch)
|
||||
{
|
||||
reserve(d_size+1);
|
||||
d_buffer[d_size] = ch;
|
||||
d_size++;
|
||||
if ( ch==0 || ch==10 ) { sync(); }
|
||||
return std::char_traits<char>::to_int_type(ch);
|
||||
}
|
||||
int ParallelStreamBuffer::underflow()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
void ParallelStreamBuffer::reset()
|
||||
{
|
||||
sync();
|
||||
d_stream.clear();
|
||||
delete [] d_buffer;
|
||||
d_buffer = NULL;
|
||||
d_buffer_size = 0;
|
||||
}
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
||||
135
IO/PIO.h
Normal file
135
IO/PIO.h
Normal file
@@ -0,0 +1,135 @@
|
||||
#ifndef included_PIO
|
||||
#define included_PIO
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
/*!
|
||||
* Parallel output stream pout writes to the standard output from node zero
|
||||
* only. Output from other nodes is ignored. If logging is enabled, then
|
||||
* output is mirrored to the log stream, as well.
|
||||
*/
|
||||
extern std::ostream pout;
|
||||
|
||||
/*!
|
||||
* Parallel output stream perr writes to the standard error from all nodes.
|
||||
* Output is prepended with the processor number.
|
||||
*/
|
||||
extern std::ostream perr;
|
||||
|
||||
/*!
|
||||
* Parallel output stream plog writes output to the log file. When logging
|
||||
* from multiple processors, the processor number is appended to the filename.
|
||||
*/
|
||||
extern std::ostream plog;
|
||||
|
||||
/*!
|
||||
* Parallel output printp pout writes to the standard output from node zero
|
||||
* only. Output from other nodes is ignored. If logging is enabled, then
|
||||
* output is mirrored to the log stream, as well.
|
||||
* The format matches the format for printf
|
||||
*/
|
||||
inline int printp( const char *format, ... );
|
||||
|
||||
|
||||
/*!
|
||||
* Class ParallelBuffer is a simple I/O stream utility that
|
||||
* intercepts output from an ostream and redirects the output as necessary
|
||||
* for parallel I/O. This class defines a stream buffer class for an
|
||||
* ostream class.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
ParallelStreamBuffer( );
|
||||
|
||||
/*!
|
||||
* Set the output file stream (multiple output streams are supported)
|
||||
* @param stream Output stream
|
||||
*/
|
||||
void setOutputStream( std::ostream *stream );
|
||||
|
||||
/*!
|
||||
* The destructor simply deallocates any internal data
|
||||
* buffers. It does not modify the output streams.
|
||||
*/
|
||||
virtual ~ParallelStreamBuffer();
|
||||
|
||||
/*!
|
||||
* Synchronize the parallel buffer (called from streambuf).
|
||||
*/
|
||||
virtual int sync();
|
||||
|
||||
/**
|
||||
* Write the specified number of characters into the output stream (called
|
||||
* from streambuf).
|
||||
*/
|
||||
virtual std::streamsize xsputn(const std::string &text, std::streamsize n);
|
||||
|
||||
/*!
|
||||
* Write an overflow character into the parallel buffer (called from
|
||||
* streambuf).
|
||||
*/
|
||||
virtual int overflow(int ch);
|
||||
|
||||
/*!
|
||||
* Read an overflow character from the parallel buffer (called from
|
||||
* streambuf). This is not implemented. It is needed by the
|
||||
* MSVC++ stream implementation.
|
||||
*/
|
||||
virtual int underflow();
|
||||
|
||||
/*!
|
||||
* Clear the internal buffer's memory
|
||||
*/
|
||||
virtual void reset();
|
||||
|
||||
private:
|
||||
int d_rank;
|
||||
size_t d_size;
|
||||
size_t d_buffer_size;
|
||||
char *d_buffer;
|
||||
std::vector<std::ostream*> d_stream;
|
||||
inline void reserve( size_t size );
|
||||
};
|
||||
|
||||
|
||||
namespace Utilities {
|
||||
|
||||
/*!
|
||||
* Log messages for node zero only to the specified filename. All output
|
||||
* to pout, perr, and plog on node zero will go to the log file.
|
||||
*/
|
||||
void logOnlyNodeZero( const std::string &filename );
|
||||
|
||||
/*!
|
||||
* Log messages from all nodes. The diagnostic data for processor XXXXX
|
||||
* will be sent to a file with the name filename.XXXXX, where filename is
|
||||
* the function argument.
|
||||
*/
|
||||
void logAllNodes( const std::string &filename, bool singleStream=false );
|
||||
|
||||
/*!
|
||||
* Stop logging messages, flush buffers, and reset memory.
|
||||
*/
|
||||
void stopLogging( );
|
||||
|
||||
|
||||
} // namespace Utilities
|
||||
|
||||
|
||||
} // namespace IO
|
||||
|
||||
|
||||
#include "IO/PIO.hpp"
|
||||
|
||||
#endif
|
||||
29
IO/PIO.hpp
Normal file
29
IO/PIO.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef included_PIO_hpp
|
||||
#define included_PIO_hpp
|
||||
|
||||
#include "IO/PIO.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
inline int printp( const char *format, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap,format);
|
||||
char tmp[1024];
|
||||
int n = vsprintf(tmp,format,ap);
|
||||
va_end(ap);
|
||||
pout << tmp;
|
||||
pout.flush();
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
} // IO namespace
|
||||
|
||||
#endif
|
||||
177
IO/Reader.cpp
Normal file
177
IO/Reader.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
#include "IO/Reader.h"
|
||||
#include "IO/Mesh.h"
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <ProfilerApp.h>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
|
||||
// List the timesteps in the given directors (dumps.LBPM)
|
||||
std::vector<std::string> IO::readTimesteps( const std::string& filename )
|
||||
{
|
||||
PROFILE_START("readTimesteps");
|
||||
FILE *fid= fopen(filename.c_str(),"rb");
|
||||
if ( fid==NULL )
|
||||
ERROR("Error opening file");
|
||||
std::vector<std::string> timesteps;
|
||||
char buf[1000];
|
||||
while (fgets(buf,sizeof(buf),fid) != NULL) {
|
||||
std::string line(buf);
|
||||
line.resize(line.size()-1);
|
||||
if ( line.empty() )
|
||||
continue;
|
||||
timesteps.push_back(line);
|
||||
}
|
||||
fclose(fid);
|
||||
PROFILE_STOP("readTimesteps");
|
||||
return timesteps;
|
||||
}
|
||||
|
||||
|
||||
// Read the list of variables for the given timestep
|
||||
std::vector<IO::MeshDatabase> IO::getMeshList( const std::string& path, const std::string& timestep )
|
||||
{
|
||||
std::string filename = path + "/" + timestep + "/LBM.summary";
|
||||
return IO::read( filename );
|
||||
}
|
||||
|
||||
|
||||
// Read the given mesh domain
|
||||
std::shared_ptr<IO::Mesh> IO::getMesh( const std::string& path, const std::string& timestep,
|
||||
const IO::MeshDatabase& meshDatabase, int domain )
|
||||
{
|
||||
PROFILE_START("getMesh");
|
||||
std::shared_ptr<IO::Mesh> mesh;
|
||||
if ( meshDatabase.format==1 ) {
|
||||
// Old format (binary doubles)
|
||||
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 );
|
||||
size_t bytes = ftell(fid);
|
||||
size_t N_max = bytes/sizeof(double)+1000;
|
||||
double *data = new double[N_max];
|
||||
fseek(fid,0,SEEK_SET);
|
||||
size_t count = fread(data,sizeof(double),N_max,fid);
|
||||
fclose(fid);
|
||||
if ( count%3 != 0 )
|
||||
ERROR("Error reading file");
|
||||
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;
|
||||
for (size_t i=0; i<N; i++) {
|
||||
P[i].x = data[3*i+0];
|
||||
P[i].y = data[3*i+1];
|
||||
P[i].z = data[3*i+2];
|
||||
}
|
||||
mesh = pointlist;
|
||||
} else if ( meshDatabase.type==IO::MeshType::SurfaceMesh ) {
|
||||
if ( count%9 != 0 )
|
||||
ERROR("Error reading file (2)");
|
||||
size_t N_tri = count/9;
|
||||
std::shared_ptr<TriList> trilist( new TriList(N_tri) );
|
||||
std::vector<Point>& A = trilist->A;
|
||||
std::vector<Point>& B = trilist->B;
|
||||
std::vector<Point>& C = trilist->C;
|
||||
for (size_t i=0; i<N_tri; 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];
|
||||
}
|
||||
mesh = trilist;
|
||||
} else {
|
||||
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,1000,fid);
|
||||
size_t i1 = find(line,':');
|
||||
size_t i2 = find(&line[i1+1],':')+i1+1;
|
||||
size_t bytes = atol(&line[i2+1]);
|
||||
char *data = new char[bytes];
|
||||
size_t count = fread(data,1,bytes,fid);
|
||||
fclose(fid);
|
||||
ASSERT(count==bytes);
|
||||
if ( meshDatabase.meshClass=="PointList" ) {
|
||||
mesh.reset( new IO::PointList() );
|
||||
} else if ( meshDatabase.meshClass=="TriMesh" ) {
|
||||
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");
|
||||
}
|
||||
PROFILE_STOP("getMesh");
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
||||
// 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 )
|
||||
{
|
||||
std::pair<std::string,std::string> key(meshDatabase.domains[domain].name,variable);
|
||||
std::map<std::pair<std::string,std::string>,DatabaseEntry>::const_iterator it;
|
||||
it = meshDatabase.variable_data.find(key);
|
||||
if ( it==meshDatabase.variable_data.end() )
|
||||
return std::shared_ptr<IO::Variable>();
|
||||
const DatabaseEntry& database = it->second;
|
||||
std::string filename = path + "/" + timestep + "/" + database.file;
|
||||
FILE *fid = fopen(filename.c_str(),"rb");
|
||||
fseek(fid,database.offset,SEEK_SET);
|
||||
char line[1000];
|
||||
std::fgets(line,1000,fid);
|
||||
size_t i1 = find(line,':');
|
||||
size_t i2 = find(&line[i1+1],':')+i1+1;
|
||||
std::vector<std::string> values = splitList(&line[i2+1],',');
|
||||
ASSERT(values.size()==5);
|
||||
int dim = atoi(values[0].c_str());
|
||||
int type = atoi(values[1].c_str());
|
||||
size_t N = atol(values[2].c_str());
|
||||
size_t bytes = atol(values[3].c_str());
|
||||
std::string precision = values[4];
|
||||
char *data = new char[bytes];
|
||||
size_t count = fread(data,1,bytes,fid);
|
||||
fclose(fid);
|
||||
ASSERT(count==bytes);
|
||||
std::shared_ptr<IO::Variable> var( new IO::Variable() );
|
||||
var->dim = dim;
|
||||
var->type = static_cast<IO::VariableType>(type);
|
||||
var->name = variable;
|
||||
var->data.resize(N);
|
||||
double *var_data = var->data.data();
|
||||
if ( precision=="double" ) {
|
||||
memcpy(var_data,data,bytes);
|
||||
} else {
|
||||
ERROR("Format not implimented");
|
||||
}
|
||||
delete [] data;
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
|
||||
36
IO/Reader.h
Normal file
36
IO/Reader.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef READER_INC
|
||||
#define READER_INC
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "IO/Mesh.h"
|
||||
#include "IO/MeshDatabase.h"
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
//! List the timesteps in the given directors (dumps.LBPM)
|
||||
std::vector<std::string> readTimesteps( const std::string& filename );
|
||||
|
||||
|
||||
//! Read the list of variables for the given timestep
|
||||
std::vector<IO::MeshDatabase> getMeshList( const std::string& path, const std::string& timestep );
|
||||
|
||||
|
||||
//! Read the given mesh domain
|
||||
std::shared_ptr<IO::Mesh> getMesh( const std::string& path, const std::string& timestep,
|
||||
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
|
||||
|
||||
#endif
|
||||
197
IO/Writer.cpp
Normal file
197
IO/Writer.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
#include "IO/Writer.h"
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
int rank = MPI_WORLD_RANK();
|
||||
std::vector<IO::MeshDatabase> meshes_written;
|
||||
for (size_t i=0; i<meshData.size(); i++) {
|
||||
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");
|
||||
INSIST(fid!=NULL,std::string("Error opening file: ")+fullpath);
|
||||
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);
|
||||
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
|
||||
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;
|
||||
fwrite(x,sizeof(double),3,fid);
|
||||
}
|
||||
} else if ( std::dynamic_pointer_cast<IO::TriList>(mesh)!=NULL || std::dynamic_pointer_cast<IO::TriMesh>(mesh)!=NULL ) {
|
||||
// Triangle mesh
|
||||
std::shared_ptr<IO::TriList> trilist = IO::getTriList(mesh);
|
||||
const std::vector<Point>& A = trilist->A;
|
||||
const std::vector<Point>& B = trilist->B;
|
||||
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;
|
||||
fwrite(tri,sizeof(double),9,fid);
|
||||
}
|
||||
} else {
|
||||
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 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 = MPI_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);
|
||||
IO::VariableDatabase info;
|
||||
info.name = variable.name;
|
||||
info.type = mesh.vars[i]->type;
|
||||
info.dim = mesh.vars[i]->dim;
|
||||
database.variables.push_back(info);
|
||||
std::pair<std::string,std::string> key(domainname,variable.name);
|
||||
database.variable_data.insert(
|
||||
std::pair<std::pair<std::string,std::string>,IO::DatabaseEntry>(key,variable) );
|
||||
int dim = mesh.vars[i]->dim;
|
||||
int type = static_cast<int>(mesh.vars[i]->type);
|
||||
size_t N = mesh.vars[i]->data.size();
|
||||
const void* data = N==0 ? 0:&mesh.vars[i]->data[0];
|
||||
if ( type == static_cast<int>(IO::VariableType::Null) ) {
|
||||
ERROR("Variable type not set");
|
||||
}
|
||||
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, 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 = MPI_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 )
|
||||
{
|
||||
int rank = MPI_WORLD_RANK();
|
||||
int size = MPI_WORLD_SIZE();
|
||||
// Create the output directory
|
||||
char path[100];
|
||||
sprintf(path,"vis%03i",timestep);
|
||||
if ( rank == 0 )
|
||||
mkdir(path,S_IRWXU|S_IRGRP);
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
// Write the mesh files
|
||||
std::vector<IO::MeshDatabase> meshes_written;
|
||||
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");
|
||||
}
|
||||
// Gather a complete list of files on rank 0
|
||||
meshes_written = gatherAll(meshes_written,MPI_COMM_WORLD);
|
||||
// Write the summary files
|
||||
if ( rank == 0 ) {
|
||||
// Write the summary file for the current timestep
|
||||
char filename[200];
|
||||
sprintf(filename,"%s/LBM.summary",path);
|
||||
write(meshes_written,filename);
|
||||
// Add the timestep to the global summary file
|
||||
FILE *fid = NULL;
|
||||
if ( !global_summary_created ) {
|
||||
fid = fopen("summary.LBM","wb");
|
||||
global_summary_created = true;
|
||||
} else {
|
||||
fid = fopen("summary.LBM","ab");
|
||||
}
|
||||
fprintf(fid,"%s\n",path);
|
||||
fclose(fid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
31
IO/Writer.h
Normal file
31
IO/Writer.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef WRITER_INC
|
||||
#define WRITER_INC
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "IO/Mesh.h"
|
||||
#include "IO/MeshDatabase.h"
|
||||
|
||||
|
||||
namespace IO {
|
||||
|
||||
|
||||
/*!
|
||||
* @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
|
||||
|
||||
#endif
|
||||
62
README.visit
Normal file
62
README.visit
Normal file
@@ -0,0 +1,62 @@
|
||||
To compile the visit plug-in and run in parallel on computational back-end:
|
||||
|
||||
Checkout code and create a cmake script to compile plug-in.
|
||||
Example commands for Rhea:
|
||||
|
||||
Load the proper modules
|
||||
module load visit
|
||||
module load cmake
|
||||
module load gcc/4.8.2
|
||||
|
||||
Configure cmake to build the plug-in
|
||||
cmake \
|
||||
-D CMAKE_BUILD_TYPE:STRING=Release \
|
||||
-D CMAKE_C_COMPILER:PATH=gcc \
|
||||
-D CMAKE_CXX_COMPILER:PATH=g++ \
|
||||
-D USE_MPI=false \
|
||||
-D USE_CUDA=false \
|
||||
-D USE_VISIT=true \
|
||||
-D VISIT_ROOT_DIR=/sw/rhea/visit \
|
||||
-D USE_TIMER=false \
|
||||
../../LBPM-WIA
|
||||
|
||||
|
||||
|
||||
Build the visit plug-in
|
||||
make visit
|
||||
|
||||
Check that the visit plug-in installed in ~/.visit/2.7.1/linux-x86_64/plugins/databases
|
||||
It should have created several shared libraries:
|
||||
libELBMDatabase_par.so libELBMDatabase_ser.so libILBMDatabase.so libMLBMDatabase.so
|
||||
|
||||
Install visit on local machine (2.7.3)
|
||||
|
||||
Start visit on local machine
|
||||
|
||||
First time:
|
||||
Go to: Options - Host profiles
|
||||
Click Remote Profiles - Update
|
||||
After list populates, drag host_ornl_rhea.xml to Hosts
|
||||
Select ORNL_Rhea from Hosts, click on Machines
|
||||
Set account username
|
||||
Click on Launch Profiles tab
|
||||
Change profile name and timeout if desired
|
||||
Click on Parallel tab
|
||||
Add Default Bank / Account with project number, set default nodes/processors if desired
|
||||
Click Apply, then close window
|
||||
Go to: Options - Save Settings
|
||||
|
||||
Open remote file / launch parallel job
|
||||
Click Open file
|
||||
Change Host to ORNL_Rhea, enter passcode when prompted
|
||||
Open visualization file
|
||||
/lustre/atlas/proj-shared/geo106/vis_test/dumps.LBM
|
||||
New window will open prompting for # of nodes, processors, Bank (project number) and time limit
|
||||
Rhea as 16 physical-cores/node and 64 GB/node
|
||||
for example file above I used 1 node, 16 cores
|
||||
Visit will call qsub and submit a parallel job that will start when ready
|
||||
|
||||
Visualize desired quantities
|
||||
|
||||
|
||||
|
||||
59
cmake/FindVisIt.cmake
Normal file
59
cmake/FindVisIt.cmake
Normal file
@@ -0,0 +1,59 @@
|
||||
# Tool for building visit plugins
|
||||
#
|
||||
# The script will prompt the user to specify VISIT_ROOT_DIR if the prefix
|
||||
# cannot be determined by the location of xml2cmake in the system path.
|
||||
# Users can set the environment variable VISIT_BIN_PATH before running cmake
|
||||
# (e.g. VISIT_BIN_PATH=/usr/local/bin instead of VISIT_ROOT_DIR)
|
||||
|
||||
|
||||
|
||||
# Find the xml2cmake executable and set VISIT_XML_CMAKE
|
||||
SET( VISIT_XML_CMAKE )
|
||||
FIND_PROGRAM( VISIT_XML_CMAKE
|
||||
NAMES xml2cmake
|
||||
PATHS
|
||||
"${VISIT_ROOT_DIR}"
|
||||
"${VISIT_BIN_PATH}"
|
||||
"$ENV{VISIT_ROOT_DIR}"
|
||||
"$ENV{VISIT_BIN_PATH}"
|
||||
PATH_SUFFIXES bin bin64
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
IF( NOT VISIT_XML_CMAKE )
|
||||
MESSAGE( FATAL_ERROR "xml2cmake not found in:\n"
|
||||
"${VISIT_ROOT_DIR}/bin\n"
|
||||
"${VISIT_BIN_PATH}\n"
|
||||
"$ENV{VISIT_ROOT_DIR}/bin\n"
|
||||
"$ENV{VISIT_BIN_PATH}\n"
|
||||
)
|
||||
ELSE()
|
||||
MESSAGE( "VISIT_XML_CMAKE=${VISIT_XML_CMAKE}" )
|
||||
ENDIF()
|
||||
|
||||
|
||||
# Install plugin
|
||||
MACRO( VISIT_PLUGIN SRC_DIR TARGET )
|
||||
CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_DIR}/${TARGET}.xml" "${CMAKE_CURRENT_BINARY_DIR}/${SRC_DIR}/${TARGET}.xml" )
|
||||
FILE( GLOB ConfigFiles RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_DIR}/*.C" "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_DIR}/*.h" )
|
||||
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}"
|
||||
)
|
||||
ENDFOREACH()
|
||||
ADD_CUSTOM_TARGET(
|
||||
${SRC_DIR}
|
||||
COMMAND ${VISIT_XML_CMAKE} ${TARGET}.xml
|
||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} .
|
||||
COMMAND make
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${SRC_DIR}"
|
||||
SOURCES ${SRC_DIR}
|
||||
DEPENDS lbpm-wia copy-${SRC_DIR}
|
||||
)
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
46
cmake/Find_TIMER.cmake
Normal file
46
cmake/Find_TIMER.cmake
Normal file
@@ -0,0 +1,46 @@
|
||||
# Macro to find and configure timer
|
||||
MACRO( CONFIGURE_TIMER )
|
||||
SET( NULL_TIMER_DIR "${LBPM_INSTALL_DIR}/include" )
|
||||
# Determine if we want to use the timer utility
|
||||
CHECK_ENABLE_FLAG( USE_TIMER 1 )
|
||||
IF ( USE_TIMER )
|
||||
# Check if we specified the timer directory
|
||||
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E remove -f "${NULL_TIMER_DIR}/ProfilerApp.h" )
|
||||
IF ( TIMER_DIRECTORY )
|
||||
VERIFY_PATH ( ${TIMER_DIRECTORY} )
|
||||
VERIFY_PATH ( ${TIMER_DIRECTORY}/include )
|
||||
VERIFY_PATH ( ${TIMER_DIRECTORY}/lib )
|
||||
SET( TIMER_INCLUDE ${TIMER_DIRECTORY}/include )
|
||||
FIND_LIBRARY( TIMER_LIBS NAMES timerutility PATHS ${TIMER_DIRECTORY}/lib NO_DEFAULT_PATH )
|
||||
SET( TIMER_CXXFLAGS "-DUSE_TIMER -I${TIMER_DIRECTORY}/include" )
|
||||
SET( TIMER_LDFLAGS -L${TIMER_DIRECTORY}/lib )
|
||||
SET( TIMER_LDLIBS -ltimerutility )
|
||||
ELSE()
|
||||
MESSAGE( FATAL_ERROR "Default search for TIMER is not yet supported. Use -D TIMER_DIRECTORY=" )
|
||||
ENDIF()
|
||||
SET(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH} "${TIMER_DIRECTORY}/lib" )
|
||||
INCLUDE_DIRECTORIES( ${TIMER_INCLUDE} )
|
||||
ADD_DEFINITIONS( "-D USE_TIMER" )
|
||||
MESSAGE( "Using timer utility" )
|
||||
MESSAGE( " TIMER_LIBRARIES = ${TIMER_LIBS}" )
|
||||
ELSE()
|
||||
FILE(WRITE "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_START(...) do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_STOP(...) do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_START2(...) do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_STOP2(...) do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_SCOPED(...) do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_SYNCRONIZE() do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_SAVE(...) do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_STORE_TRACE(X) do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_ENABLE(...) do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_DISABLE() do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_ENABLE_TRACE() do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_DISABLE_TRACE() do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_ENABLE_MEMORY() do {} while(0)\n" )
|
||||
FILE(APPEND "${NULL_TIMER_DIR}/ProfilerApp.h" "#define PROFILE_DISABLE_MEMORY() do {} while(0)\n" )
|
||||
MESSAGE( "Disabling timer utility" )
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
MACRO ( CONFIGURE_LINE_COVERAGE )
|
||||
INCLUDE( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Find_TIMER.cmake" )
|
||||
|
||||
|
||||
MACRO( CONFIGURE_LINE_COVERAGE )
|
||||
SET ( COVERAGE_LIBS )
|
||||
IF ( ENABLE_GCOV )
|
||||
ADD_DEFINITIONS ( -fprofile-arcs -ftest-coverage )
|
||||
SET ( COVERAGE_LIBS -lgcov -fprofile-arcs )
|
||||
ENDIF ()
|
||||
ENDMACRO ()
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
# Macro to configure CUDA
|
||||
MACRO ( CONFIGURE_CUDA )
|
||||
MACRO( CONFIGURE_CUDA )
|
||||
CHECK_ENABLE_FLAG( USE_CUDA 0 )
|
||||
IF( USE_CUDA )
|
||||
SET( CUDA_FLAGS ${CUDA_NVCC_FLAGS} )
|
||||
@@ -41,14 +44,14 @@ ENDMACRO()
|
||||
|
||||
|
||||
# Macro to configure MIC
|
||||
MACRO ( CONFIGURE_MIC )
|
||||
MACRO( CONFIGURE_MIC )
|
||||
CHECK_ENABLE_FLAG( USE_MIC 0 )
|
||||
ADD_DEFINITIONS ( "-D USE_MIC" )
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
# Macro to find and configure the MPI libraries
|
||||
MACRO ( CONFIGURE_MPI )
|
||||
MACRO( CONFIGURE_MPI )
|
||||
# Determine if we want to use MPI
|
||||
CHECK_ENABLE_FLAG(USE_MPI 1 )
|
||||
IF ( USE_MPI )
|
||||
@@ -102,6 +105,7 @@ MACRO ( CONFIGURE_MPI )
|
||||
ENDIF()
|
||||
# Check if we need to use MPI for serial tests
|
||||
CHECK_ENABLE_FLAG( USE_MPI_FOR_SERIAL_TESTS 0 )
|
||||
SET( MPI_CXXFLAGS -DUSE_MPI -I${MPI_INCLUDE} )
|
||||
# Set the definitions
|
||||
ADD_DEFINITIONS ( "-D USE_MPI" )
|
||||
MESSAGE ( "Using MPI" )
|
||||
@@ -123,11 +127,17 @@ ENDMACRO ()
|
||||
|
||||
|
||||
# Macro to configure system-specific libraries and flags
|
||||
MACRO ( CONFIGURE_SYSTEM )
|
||||
MACRO( CONFIGURE_SYSTEM )
|
||||
# First check/set the compile mode
|
||||
IF( NOT CMAKE_BUILD_TYPE )
|
||||
MESSAGE(FATAL_ERROR "CMAKE_BUILD_TYPE is not set")
|
||||
ENDIF()
|
||||
# Disable gxx debug flags if we are building the visit plugin
|
||||
# This is necessary to prvent segfaults caused by inconsistent object sizes
|
||||
# caused by std::vector<std::string> in the avtMeshMetaData class
|
||||
IF ( USE_VISIT )
|
||||
SET( DISABLE_GXX_DEBUG 1 )
|
||||
ENDIF()
|
||||
# Remove extra library links
|
||||
# Get the compiler
|
||||
SET_COMPILER ()
|
||||
|
||||
@@ -149,18 +149,22 @@ MACRO( SET_COMPILER )
|
||||
# SET the C/C++ compiler
|
||||
IF( CMAKE_COMPILE_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||
SET( USING_GCC TRUE )
|
||||
ADD_DEFINITIONS( -D USING_GCC )
|
||||
MESSAGE("Using gcc")
|
||||
ELSEIF( MSVC OR MSVC_IDE OR MSVC60 OR MSVC70 OR MSVC71 OR MSVC80 OR CMAKE_COMPILER_2005 OR MSVC90 OR MSVC10 )
|
||||
IF( NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows" )
|
||||
MESSAGE( FATAL_ERROR "Using microsoft compilers on non-windows system?" )
|
||||
ENDIF()
|
||||
SET( USING_MICROSOFT TRUE )
|
||||
ADD_DEFINITIONS( -D USING_MICROSOFT )
|
||||
MESSAGE("Using Microsoft")
|
||||
ELSEIF( (${CMAKE_C_COMPILER_ID} MATCHES "Intel") OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Intel") )
|
||||
SET(USING_ICC TRUE)
|
||||
ADD_DEFINITIONS( -D USING_ICC )
|
||||
MESSAGE("Using icc")
|
||||
ELSEIF( ${CMAKE_C_COMPILER_ID} MATCHES "PGI")
|
||||
SET(USING_PGCC TRUE)
|
||||
ADD_DEFINITIONS( -D USING_ICCPGCC )
|
||||
MESSAGE("Using pgCC")
|
||||
ELSE()
|
||||
SET(USING_DEFAULT TRUE)
|
||||
@@ -170,13 +174,14 @@ MACRO( SET_COMPILER )
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
# Macro to set the proper warnings
|
||||
MACRO ( SET_WARNINGS )
|
||||
# Macro to set the compiler specific flags
|
||||
MACRO ( SET_COMPILER_FLAGS )
|
||||
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_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
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" )
|
||||
@@ -233,7 +238,7 @@ MACRO( SET_COMPILE_FLAGS )
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unknown build type: ${CMAKE_BUILD_TYPE}")
|
||||
ENDIF()
|
||||
SET_WARNINGS()
|
||||
SET_COMPILER_FLAGS()
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
@@ -252,6 +257,7 @@ MACRO( ADD_LBPM_EXE_DEP EXE )
|
||||
# Add the libraries
|
||||
TARGET_LINK_LIBRARIES( ${EXE} ${LBPM_LIBS} )
|
||||
# Add external libraries
|
||||
TARGET_LINK_LIBRARIES( ${EXE} ${TIMER_LIBS} )
|
||||
TARGET_LINK_LIBRARIES( ${EXE} ${EXTERNAL_LIBS} )
|
||||
IF ( USE_MPI )
|
||||
TARGET_LINK_LIBRARIES( ${EXE} ${MPI_LINK_FLAGS} ${MPI_LIBRARIES} )
|
||||
@@ -496,6 +502,8 @@ MACRO( ADD_DISTCLEAN )
|
||||
gpu
|
||||
example
|
||||
common
|
||||
visit
|
||||
IO
|
||||
)
|
||||
ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
|
||||
IF (UNIX)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef COMMUNICATION_H_INC
|
||||
#define COMMUNICATION_H_INC
|
||||
|
||||
#include "common/MPI.h"
|
||||
#include "Array.h"
|
||||
|
||||
// ********** COMMUNICTION **************************************
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
#include <time.h>
|
||||
#include <exception> // std::exception
|
||||
#include <stdexcept>
|
||||
#include <mpi.h>
|
||||
|
||||
#include "common/Utilities.h"
|
||||
#include "common/MPI.h"
|
||||
|
||||
|
||||
|
||||
int MAX_BLOB_COUNT=50;
|
||||
|
||||
|
||||
175
common/MPI.cpp
Normal file
175
common/MPI.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
#include "common/MPI.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Concrete implimentations for packing/unpacking *
|
||||
********************************************************/
|
||||
// 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));
|
||||
}
|
||||
// char
|
||||
template<>
|
||||
size_t packsize<char>( const char& rhs )
|
||||
{
|
||||
return sizeof(char);
|
||||
}
|
||||
template<>
|
||||
void pack<char>( const char& rhs, char *buffer )
|
||||
{
|
||||
memcpy(buffer,&rhs,sizeof(char));
|
||||
}
|
||||
template<>
|
||||
void unpack<char>( char& data, const char *buffer )
|
||||
{
|
||||
memcpy(&data,buffer,sizeof(char));
|
||||
}
|
||||
// int
|
||||
template<>
|
||||
size_t packsize<int>( const int& rhs )
|
||||
{
|
||||
return sizeof(int);
|
||||
}
|
||||
template<>
|
||||
void pack<int>( const int& rhs, char *buffer )
|
||||
{
|
||||
memcpy(buffer,&rhs,sizeof(int));
|
||||
}
|
||||
template<>
|
||||
void unpack<int>( int& data, const char *buffer )
|
||||
{
|
||||
memcpy(&data,buffer,sizeof(int));
|
||||
}
|
||||
// unsigned int
|
||||
template<>
|
||||
size_t packsize<unsigned int>( const unsigned int& rhs )
|
||||
{
|
||||
return sizeof(unsigned int);
|
||||
}
|
||||
template<>
|
||||
void pack<unsigned int>( const unsigned int& rhs, char *buffer )
|
||||
{
|
||||
memcpy(buffer,&rhs,sizeof(int));
|
||||
}
|
||||
template<>
|
||||
void unpack<unsigned int>( unsigned int& data, const char *buffer )
|
||||
{
|
||||
memcpy(&data,buffer,sizeof(int));
|
||||
}
|
||||
// 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));
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Fake MPI routines *
|
||||
********************************************************/
|
||||
#ifndef USE_MPI
|
||||
int MPI_Init(int*,char***)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int MPI_Finalize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int MPI_Comm_size( MPI_Comm, int *size )
|
||||
{
|
||||
*size = 1;
|
||||
return 0;
|
||||
}
|
||||
int MPI_Comm_rank( MPI_Comm, int *rank )
|
||||
{
|
||||
*rank = 0;
|
||||
return 0;
|
||||
}
|
||||
int MPI_Barrier( MPI_Comm )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int MPI_Waitall( int, MPI_Request[], MPI_Status[] )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int MPI_Bcast( void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm )
|
||||
{
|
||||
ERROR("Not implimented yet");
|
||||
return 0;
|
||||
}
|
||||
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag,
|
||||
MPI_Comm comm, MPI_Request *request)
|
||||
{
|
||||
ERROR("Not implimented yet");
|
||||
return 0;
|
||||
}
|
||||
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source,
|
||||
int tag, MPI_Comm comm, MPI_Request *request)
|
||||
{
|
||||
ERROR("Not implimented yet");
|
||||
return 0;
|
||||
}
|
||||
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count,
|
||||
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
|
||||
{
|
||||
ERROR("Not implimented yet");
|
||||
return 0;
|
||||
}
|
||||
int MPI_Sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
|
||||
int dest, int sendtag,
|
||||
void *recvbuf, int recvcount, MPI_Datatype recvtype,
|
||||
int source, int recvtag,
|
||||
MPI_Comm comm, MPI_Status *status)
|
||||
{
|
||||
ERROR("Not implimented yet");
|
||||
return 0;
|
||||
}
|
||||
double MPI_Wtime( void )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
132
common/MPI.h
Normal file
132
common/MPI.h
Normal file
@@ -0,0 +1,132 @@
|
||||
// This file contains wrappers for MPI routines and functions to pack/unpack data structures
|
||||
#ifndef MPI_WRAPPERS_INC
|
||||
#define MPI_WRAPPERS_INC
|
||||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#ifdef USE_MPI
|
||||
// Inlcude MPI
|
||||
#include "mpi.h"
|
||||
#else
|
||||
// Create fake MPI types
|
||||
typedef int MPI_Comm;
|
||||
typedef int MPI_Request;
|
||||
typedef int MPI_Status;
|
||||
#define MPI_COMM_WORLD 0
|
||||
#define MPI_COMM_SELF 0
|
||||
#define MPI_STATUS_IGNORE NULL
|
||||
enum MPI_Datatype { MPI_LOGICAL, MPI_CHAR, MPI_INT, MPI_DOUBLE };
|
||||
enum MPI_Op { MPI_SUM };
|
||||
// Fake MPI functions
|
||||
int MPI_Init(int*,char***);
|
||||
int MPI_Finalize();
|
||||
int MPI_Comm_size( MPI_Comm, int *size );
|
||||
int MPI_Comm_rank( MPI_Comm, int *rank );
|
||||
int MPI_Barrier(MPI_Comm);
|
||||
int MPI_Waitall(int,MPI_Request[],MPI_Status[]);
|
||||
int MPI_Bcast(void*,int,MPI_Datatype,int,MPI_Comm);
|
||||
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag,
|
||||
MPI_Comm comm, MPI_Request *request);
|
||||
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source,
|
||||
int tag, MPI_Comm comm, MPI_Request *request);
|
||||
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count,
|
||||
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
|
||||
int MPI_Sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
|
||||
int dest, int sendtag,
|
||||
void *recvbuf, int recvcount, MPI_Datatype recvtype,
|
||||
int source, int recvtag,
|
||||
MPI_Comm comm, MPI_Status *status);
|
||||
double MPI_Wtime( void );
|
||||
#endif
|
||||
|
||||
|
||||
//! Get the size of MPI_COMM_WORLD
|
||||
inline int MPI_WORLD_SIZE( ) {
|
||||
int size = 1;
|
||||
MPI_Comm_size( MPI_COMM_WORLD, &size );
|
||||
return size;
|
||||
}
|
||||
|
||||
//! Get the size of MPI_COMM_WORLD
|
||||
inline int MPI_WORLD_RANK( ) {
|
||||
int rank = 0;
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
|
||||
return rank;
|
||||
}
|
||||
|
||||
|
||||
//! Template function to return the buffer size required to pack a class
|
||||
template<class TYPE>
|
||||
size_t packsize( const TYPE& rhs );
|
||||
|
||||
//! Template function to pack a class to a buffer
|
||||
template<class TYPE>
|
||||
void pack( const TYPE& rhs, char *buffer );
|
||||
|
||||
//! Template function to unpack a class from a buffer
|
||||
template<class TYPE>
|
||||
void unpack( TYPE& data, const char *buffer );
|
||||
|
||||
|
||||
//! Template function to return the buffer size required to pack a std::vector
|
||||
template<class TYPE>
|
||||
size_t packsize( const std::vector<TYPE>& rhs );
|
||||
|
||||
//! Template function to pack a class to a buffer
|
||||
template<class TYPE>
|
||||
void pack( const std::vector<TYPE>& rhs, char *buffer );
|
||||
|
||||
//! Template function to pack a class to a buffer
|
||||
template<class TYPE>
|
||||
void unpack( std::vector<TYPE>& data, const char *buffer );
|
||||
|
||||
|
||||
//! Template function to return the buffer size required to pack a std::pair
|
||||
template<class TYPE1, class TYPE2>
|
||||
size_t packsize( const std::pair<TYPE1,TYPE2>& rhs );
|
||||
|
||||
//! Template function to pack a class to a buffer
|
||||
template<class TYPE1, class TYPE2>
|
||||
void pack( const std::pair<TYPE1,TYPE2>& rhs, char *buffer );
|
||||
|
||||
//! Template function to pack a class to a buffer
|
||||
template<class TYPE1, class TYPE2>
|
||||
void unpack( std::pair<TYPE1,TYPE2>& data, const char *buffer );
|
||||
|
||||
|
||||
//! Template function to return the buffer size required to pack a std::map
|
||||
template<class TYPE1, class TYPE2>
|
||||
size_t packsize( const std::map<TYPE1,TYPE2>& rhs );
|
||||
|
||||
//! Template function to pack a class to a buffer
|
||||
template<class TYPE1, class TYPE2>
|
||||
void pack( const std::map<TYPE1,TYPE2>& rhs, char *buffer );
|
||||
|
||||
//! Template function to pack a class to a buffer
|
||||
template<class TYPE1, class TYPE2>
|
||||
void unpack( std::map<TYPE1,TYPE2>& data, const char *buffer );
|
||||
|
||||
|
||||
//! Template function to return the buffer size required to pack a std::set
|
||||
template<class TYPE>
|
||||
size_t packsize( const std::set<TYPE>& rhs );
|
||||
|
||||
//! Template function to pack a class to a buffer
|
||||
template<class TYPE>
|
||||
void pack( const std::set<TYPE>& rhs, char *buffer );
|
||||
|
||||
//! Template function to pack a class to a buffer
|
||||
template<class TYPE>
|
||||
void unpack( std::set<TYPE>& data, const char *buffer );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "common/MPI.hpp"
|
||||
|
||||
|
||||
155
common/MPI.hpp
Normal file
155
common/MPI.hpp
Normal file
@@ -0,0 +1,155 @@
|
||||
// This file contains wrappers for MPI routines and functions to pack/unpack data structures
|
||||
#ifndef MPI_WRAPPERS_HPP
|
||||
#define MPI_WRAPPERS_HPP
|
||||
|
||||
#include "common/MPI.h"
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Default instantiations for 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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Default instantiations for 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)]);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Default instantiations for 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************
|
||||
* Default instantiations for std::set *
|
||||
********************************************************/
|
||||
template<class TYPE>
|
||||
size_t packsize( const std::set<TYPE>& rhs )
|
||||
{
|
||||
size_t bytes = sizeof(size_t);
|
||||
typename std::set<TYPE>::const_iterator it;
|
||||
for (it=rhs.begin(); it!=rhs.end(); ++it) {
|
||||
bytes += packsize(*it);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
template<class TYPE>
|
||||
void pack( const std::set<TYPE>& rhs, char *buffer )
|
||||
{
|
||||
size_t N = rhs.size();
|
||||
pack(N,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);
|
||||
}
|
||||
}
|
||||
template<class TYPE>
|
||||
void unpack( std::set<TYPE>& 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++) {
|
||||
TYPE tmp;
|
||||
unpack(tmp,&buffer[pos]); pos+=packsize(tmp);
|
||||
data.insert(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
#ifndef PointList_INC
|
||||
#define PointList_INC
|
||||
|
||||
#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) {}
|
||||
|
||||
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);}
|
||||
@@ -179,3 +184,6 @@ template <class T> DTMutableList<T> IncreaseSize(const DTList<T> &A,size_t addLe
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
* \param MSG Error message to print
|
||||
*/
|
||||
#define ERROR(MSG) do { \
|
||||
Utilities::abort(MSG,__FILE__,__LINE__); \
|
||||
::Utilities::abort(MSG,__FILE__,__LINE__); \
|
||||
}while(0)
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
if ( !(EXP) ) { \
|
||||
std::stringstream tboxos; \
|
||||
tboxos << "Failed assertion: " << #EXP << std::ends; \
|
||||
Utilities::abort(tboxos.str(), __FILE__, __LINE__); \
|
||||
::Utilities::abort(tboxos.str(), __FILE__, __LINE__); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
std::stringstream tboxos; \
|
||||
tboxos << "Failed insist: " << #EXP << std::endl; \
|
||||
tboxos << "Message: " << MSG << std::ends; \
|
||||
Utilities::abort(tboxos.str(), __FILE__, __LINE__); \
|
||||
::Utilities::abort(tboxos.str(), __FILE__, __LINE__); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ INSTALL_LBPM_EXE( BlobAnalysis )
|
||||
|
||||
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/cylindertest ${CMAKE_CURRENT_BINARY_DIR}/cylindertest COPYONLY )
|
||||
|
||||
|
||||
# Add the tests
|
||||
ADD_LBPM_TEST( pmmc_cylinder )
|
||||
ADD_LBPM_TEST( TestBubble )
|
||||
@@ -18,12 +17,15 @@ ADD_LBPM_TEST( TestInterfaceSpeed )
|
||||
ADD_LBPM_TEST( TestSphereCurvature )
|
||||
ADD_LBPM_TEST_1_2_4( testCommunication )
|
||||
ADD_LBPM_TEST_1_2_4( testUtilities )
|
||||
ADD_LBPM_TEST( TestWriter )
|
||||
|
||||
# Sample test that will run with 1, 2, and 4 processors, failing with 4 or more procs
|
||||
ADD_LBPM_TEST_1_2_4( hello_world )
|
||||
SET_TESTS_PROPERTIES( hello_world PROPERTIES ENVIRONMENT "MPICH_RDMA_ENABLED_CUDA=0")
|
||||
SET_TESTS_PROPERTIES( hello_world_2procs PROPERTIES ENVIRONMENT "MPICH_RDMA_ENABLED_CUDA=0")
|
||||
SET_TESTS_PROPERTIES( hello_world_4procs PROPERTIES ENVIRONMENT "MPICH_RDMA_ENABLED_CUDA=0")
|
||||
IF ( USE_MPI )
|
||||
SET_TESTS_PROPERTIES( hello_world_2procs PROPERTIES ENVIRONMENT "MPICH_RDMA_ENABLED_CUDA=0")
|
||||
SET_TESTS_PROPERTIES( hello_world_4procs PROPERTIES ENVIRONMENT "MPICH_RDMA_ENABLED_CUDA=0")
|
||||
ENDIF()
|
||||
|
||||
|
||||
# Add CPU/GPU specific test
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
#include <mpi.h>
|
||||
|
||||
#include "pmmc.h"
|
||||
#include "Domain.h"
|
||||
@@ -12,9 +11,14 @@
|
||||
#include "D3Q19.h"
|
||||
#include "D3Q7.h"
|
||||
#include "Color.h"
|
||||
#include "common/MPI.h"
|
||||
#include "Communication.h"
|
||||
#include "IO/Mesh.h"
|
||||
#include "IO/Writer.h"
|
||||
#include "ProfilerApp.h"
|
||||
|
||||
#define CBUB
|
||||
#define USE_NEW_WRITER
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -101,6 +105,8 @@ int main(int argc, char **argv)
|
||||
MPI_Init(&argc,&argv);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
|
||||
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
|
||||
Utilities::setAbortBehavior(true,true,false);
|
||||
PROFILE_ENABLE(0);
|
||||
// parallel domain size (# of sub-domains)
|
||||
int nprocx,nprocy,nprocz;
|
||||
int iproc,jproc,kproc;
|
||||
@@ -318,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);
|
||||
//.......................................................................
|
||||
@@ -2089,11 +2095,17 @@ int main(int argc, char **argv)
|
||||
Gwn_global(0),Gwn_global(1),Gwn_global(2),Gwn_global(3),Gwn_global(4),Gwn_global(5)); // orientation of wn interface
|
||||
}
|
||||
|
||||
|
||||
FILE *WN_TRIS;
|
||||
sprintf(LocalRankFilename,"%s%s","wn-tris.",LocalRankString);
|
||||
WN_TRIS = fopen(LocalRankFilename,"wb");
|
||||
|
||||
#ifdef USE_NEW_WRITER
|
||||
std::shared_ptr<IO::TriList> mesh( new IO::TriList() );
|
||||
mesh->A.reserve(8*ncubes);
|
||||
mesh->B.reserve(8*ncubes);
|
||||
mesh->C.reserve(8*ncubes);
|
||||
#else
|
||||
FILE *WN_TRIS;
|
||||
sprintf(LocalRankFilename,"%s%s","wn-tris.",LocalRankString);
|
||||
WN_TRIS = fopen(LocalRankFilename,"wb");
|
||||
#endif
|
||||
for (c=0;c<ncubes;c++){
|
||||
// Get cube from the list
|
||||
i = cubeList(0,c);
|
||||
@@ -2131,20 +2143,49 @@ int main(int argc, char **argv)
|
||||
A = C;
|
||||
C = P;
|
||||
}
|
||||
//fprintf(WN_TRIS,"%f %f %f %f %f %f %f %f %f \n",A.x,A.y,A.z,B.x,B.y,B.z,C.x,C.y,C.z);
|
||||
fwrite(&A.x,sizeof(A.x),1,WN_TRIS);
|
||||
fwrite(&A.y,sizeof(A.y),1,WN_TRIS);
|
||||
fwrite(&A.z,sizeof(A.z),1,WN_TRIS);
|
||||
fwrite(&B.x,sizeof(B.x),1,WN_TRIS);
|
||||
fwrite(&B.y,sizeof(B.y),1,WN_TRIS);
|
||||
fwrite(&B.z,sizeof(B.z),1,WN_TRIS);
|
||||
fwrite(&C.x,sizeof(C.x),1,WN_TRIS);
|
||||
fwrite(&C.y,sizeof(C.y),1,WN_TRIS);
|
||||
fwrite(&C.z,sizeof(C.z),1,WN_TRIS);
|
||||
#ifdef USE_NEW_WRITER
|
||||
mesh->A.push_back(A);
|
||||
mesh->B.push_back(B);
|
||||
mesh->C.push_back(C);
|
||||
#else
|
||||
//fprintf(WN_TRIS,"%f %f %f %f %f %f %f %f %f \n",A.x,A.y,A.z,B.x,B.y,B.z,C.x,C.y,C.z);
|
||||
fwrite(&A.x,sizeof(A.x),1,WN_TRIS);
|
||||
fwrite(&A.y,sizeof(A.y),1,WN_TRIS);
|
||||
fwrite(&A.z,sizeof(A.z),1,WN_TRIS);
|
||||
fwrite(&B.x,sizeof(B.x),1,WN_TRIS);
|
||||
fwrite(&B.y,sizeof(B.y),1,WN_TRIS);
|
||||
fwrite(&B.z,sizeof(B.z),1,WN_TRIS);
|
||||
fwrite(&C.x,sizeof(C.x),1,WN_TRIS);
|
||||
fwrite(&C.y,sizeof(C.y),1,WN_TRIS);
|
||||
fwrite(&C.z,sizeof(C.z),1,WN_TRIS);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
fclose(WN_TRIS);
|
||||
|
||||
#ifdef USE_NEW_WRITER
|
||||
std::vector<IO::MeshDataStruct> meshData(1);
|
||||
meshData[0].meshName = "wn-tris";
|
||||
meshData[0].mesh = mesh;
|
||||
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->type = IO::VariableType::NodeVariable;
|
||||
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
|
||||
|
||||
}
|
||||
//************************************************************************/
|
||||
DeviceBarrier();
|
||||
@@ -2184,7 +2225,7 @@ int main(int argc, char **argv)
|
||||
fwrite(DensityValues,8,2*N,PHASE);
|
||||
fclose(PHASE);
|
||||
*/ //************************************************************************/
|
||||
|
||||
PROFILE_SAVE("TestBubble");
|
||||
return 0;
|
||||
|
||||
// ****************************************************
|
||||
|
||||
247
tests/TestWriter.cpp
Normal file
247
tests/TestWriter.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
#include "common/UnitTest.h"
|
||||
#include "common/Utilities.h"
|
||||
#include "common/MPI.h"
|
||||
#include "IO/MeshDatabase.h"
|
||||
#include "IO/Reader.h"
|
||||
#include "IO/Writer.h"
|
||||
|
||||
|
||||
inline bool approx_equal( const Point& A, const Point& B )
|
||||
{
|
||||
double tol = 1e-8*sqrt(A.x*A.x+A.y*A.y+A.z*A.z);
|
||||
return fabs(A.x-B.x)<=tol && fabs(A.y-B.y)<=tol && fabs(A.z-B.z)<=tol;
|
||||
}
|
||||
inline bool approx_equal( const double& A, const double& B )
|
||||
{
|
||||
return fabs(A-B)<=1e-8*fabs(A+B);
|
||||
}
|
||||
|
||||
|
||||
inline double distance( const Point& p )
|
||||
{
|
||||
return sqrt(p.x*p.x+p.y*p.y+p.z*p.z);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rank,nprocs;
|
||||
MPI_Init(&argc,&argv);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
|
||||
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
|
||||
Utilities::setAbortBehavior(true,true,false);
|
||||
Utilities::setErrorHandlers();
|
||||
UnitTest ut;
|
||||
|
||||
// Create some points
|
||||
const int N_points = 8;
|
||||
const int N_tri = 12;
|
||||
double x[8] = { 0, 1, 0, 1, 0, 1, 0, 1 };
|
||||
double y[8] = { 0, 0, 1, 1, 0, 0, 1, 1 };
|
||||
double z[8] = { 0, 0, 0, 0, 1, 1, 1, 1 };
|
||||
int tri[N_tri][3] = {
|
||||
{0,1,3}, {0,3,2}, {4,5,7}, {4,7,6}, // z faces
|
||||
{0,1,4}, {1,4,5}, {2,3,6}, {3,6,7}, // y faces
|
||||
{0,2,4}, {2,4,6}, {1,3,5}, {3,5,7} // x faces
|
||||
};
|
||||
|
||||
// Create the meshes
|
||||
std::shared_ptr<IO::PointList> set1( new IO::PointList(N_points) );
|
||||
for (int i=0; i<N_points; i++) {
|
||||
set1->points[i].x = x[i];
|
||||
set1->points[i].y = y[i];
|
||||
set1->points[i].z = z[i];
|
||||
}
|
||||
std::shared_ptr<IO::TriMesh> trimesh( new IO::TriMesh(N_tri,set1) );
|
||||
for (int i=0; i<N_tri; i++) {
|
||||
trimesh->A[i] = tri[i][0];
|
||||
trimesh->B[i] = tri[i][1];
|
||||
trimesh->C[i] = tri[i][2];
|
||||
}
|
||||
std::shared_ptr<IO::TriList> trilist( new IO::TriList(*trimesh) );
|
||||
for (int i=0; i<N_tri; i++) {
|
||||
Point A(x[tri[i][0]],y[tri[i][0]],z[tri[i][0]]);
|
||||
Point B(x[tri[i][1]],y[tri[i][1]],z[tri[i][1]]);
|
||||
Point C(x[tri[i][2]],y[tri[i][2]],z[tri[i][2]]);
|
||||
if ( !approx_equal(trilist->A[i],A) || !approx_equal(trilist->B[i],B) || !approx_equal(trilist->C[i],C) )
|
||||
{
|
||||
printf("Failed to create trilist\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the variables
|
||||
std::shared_ptr<IO::Variable> dist_set1( new IO::Variable() );
|
||||
std::shared_ptr<IO::Variable> dist_list( new IO::Variable() );
|
||||
dist_set1->dim = 1;
|
||||
dist_list->dim = 1;
|
||||
dist_set1->name = "Distance";
|
||||
dist_list->name = "Distance";
|
||||
dist_set1->type = IO::VariableType::NodeVariable;
|
||||
dist_list->type = IO::VariableType::NodeVariable;
|
||||
dist_set1->data.resize( N_points );
|
||||
for (int i=0; i<N_points; i++)
|
||||
dist_set1->data[i] = distance(set1->points[i]);
|
||||
dist_list->data.resize( 3*N_tri );
|
||||
for (int i=0; i<N_tri; i++) {
|
||||
dist_list->data[3*i+0] = distance(trilist->A[i]);
|
||||
dist_list->data[3*i+1] = distance(trilist->B[i]);
|
||||
dist_list->data[3*i+2] = distance(trilist->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_set1);
|
||||
meshData[2].meshName = "trilist";
|
||||
meshData[2].mesh = trilist;
|
||||
meshData[2].vars.push_back(dist_list);
|
||||
|
||||
// Write the data
|
||||
IO::writeData( 0, meshData, 1 );
|
||||
IO::writeData( 3, meshData, 2 );
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
|
||||
// Get a list of the timesteps
|
||||
std::vector<std::string> timesteps = IO::readTimesteps("summary.LBM");
|
||||
if ( timesteps.size()==2 )
|
||||
ut.passes("Corrent number of timesteps");
|
||||
else
|
||||
ut.failure("Incorrent number of timesteps");
|
||||
|
||||
// Check the mesh lists
|
||||
for (size_t i=0; i<timesteps.size(); i++) {
|
||||
// Load the list of meshes and check its size
|
||||
std::vector<IO::MeshDatabase> list = IO::getMeshList(".",timesteps[i]);
|
||||
if ( list.size()==meshData.size() )
|
||||
ut.passes("Corrent number of meshes found");
|
||||
else
|
||||
ut.failure("Incorrent number of meshes found");
|
||||
// Check the number of domains for each mesh
|
||||
bool pass = true;
|
||||
for (size_t j=0; j<list.size(); j++)
|
||||
pass = pass && (int)list[j].domains.size()==nprocs;
|
||||
if ( pass ) {
|
||||
ut.passes("Corrent number of domains for mesh");
|
||||
} else {
|
||||
ut.failure("Incorrent number of domains for mesh");
|
||||
continue;
|
||||
}
|
||||
// For each domain, load the mesh and check its data
|
||||
for (size_t j=0; j<list.size(); j++) {
|
||||
for (size_t k=0; k<list[i].domains.size(); k++) {
|
||||
std::shared_ptr<IO::Mesh> mesh = IO::getMesh(".",timesteps[i],list[j],k);
|
||||
if ( mesh==NULL ) {
|
||||
printf("Failed to load %s\n",meshData[i].meshName.c_str());
|
||||
pass = false;
|
||||
break;
|
||||
}
|
||||
if ( meshData[j].meshName=="pointmesh" ) {
|
||||
// Check the pointmesh
|
||||
std::shared_ptr<IO::PointList> pmesh = IO::getPointList(mesh);
|
||||
if ( pmesh==NULL ) {
|
||||
pass = false;
|
||||
break;
|
||||
}
|
||||
if ( pmesh->points.size()!=N_points ) {
|
||||
pass = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( meshData[j].meshName=="trimesh" || meshData[j].meshName=="trilist" ) {
|
||||
// Check the trimesh/trilist
|
||||
std::shared_ptr<IO::TriMesh> mesh1 = IO::getTriMesh(mesh);
|
||||
std::shared_ptr<IO::TriList> mesh2 = IO::getTriList(mesh);
|
||||
if ( mesh1==NULL || mesh2==NULL ) {
|
||||
pass = false;
|
||||
break;
|
||||
}
|
||||
if ( mesh1->A.size()!=N_tri || mesh1->B.size()!=N_tri || mesh1->C.size()!=N_tri ||
|
||||
mesh2->A.size()!=N_tri || mesh2->B.size()!=N_tri || mesh2->C.size()!=N_tri )
|
||||
{
|
||||
pass = false;
|
||||
break;
|
||||
}
|
||||
const std::vector<Point>& P1 = mesh1->vertices->points;
|
||||
const std::vector<int>& A1 = mesh1->A;
|
||||
const std::vector<int>& B1 = mesh1->B;
|
||||
const std::vector<int>& C1 = mesh1->C;
|
||||
const std::vector<Point>& A2 = mesh2->A;
|
||||
const std::vector<Point>& B2 = mesh2->B;
|
||||
const std::vector<Point>& C2 = mesh2->C;
|
||||
const std::vector<Point>& A = trilist->A;
|
||||
const std::vector<Point>& B = trilist->B;
|
||||
const std::vector<Point>& C = trilist->C;
|
||||
for (size_t i=0; i<N_tri; i++) {
|
||||
if ( !approx_equal(P1[A1[i]],A[i]) || !approx_equal(P1[B1[i]],B[i]) || !approx_equal(P1[C1[i]],C[i]) )
|
||||
pass = false;
|
||||
if ( !approx_equal(A2[i],A[i]) || !approx_equal(B2[i],B[i]) || !approx_equal(C2[i],C[i]) )
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( pass ) {
|
||||
ut.passes("Meshes loaded correctly");
|
||||
} else {
|
||||
ut.failure("Meshes did not load correctly");
|
||||
continue;
|
||||
}
|
||||
// For each domain, load the variables and check their data
|
||||
if ( i==0 )
|
||||
continue; // Format 1 does not support variables
|
||||
for (size_t j=0; j<list.size(); j++) {
|
||||
const IO::MeshDataStruct* mesh0 = NULL;
|
||||
for (size_t k=0; k<meshData.size(); k++) {
|
||||
if ( meshData[k].meshName == list[j].name ) {
|
||||
mesh0 = &meshData[k];
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (size_t v=0; v<list[i].variables.size(); v++) {
|
||||
for (size_t k=0; k<list[i].domains.size(); k++) {
|
||||
std::shared_ptr<const IO::Variable> variable =
|
||||
IO::getVariable(".",timesteps[i],list[j],k,list[j].variables[v].name);
|
||||
const IO::Variable& var1 = *mesh0->vars[v];
|
||||
const IO::Variable& var2 = *variable;
|
||||
pass = var1.name == var2.name;
|
||||
pass = pass && var1.dim == var2.dim;
|
||||
pass = pass && var1.type == var2.type;
|
||||
pass = pass && var1.data.size() == var2.data.size();
|
||||
if ( pass ) {
|
||||
for (size_t m=0; m<var1.data.size(); m++)
|
||||
pass = pass && approx_equal(var1.data[m],var2.data[m]);
|
||||
}
|
||||
if ( pass ) {
|
||||
ut.passes("Variables match");
|
||||
} else {
|
||||
ut.failure("Variables did not match");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finished
|
||||
ut.report();
|
||||
int N_errors = ut.NumFailGlobal();
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
MPI_Finalize();
|
||||
return N_errors;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "mpi.h"
|
||||
#include "common/MPI.h"
|
||||
|
||||
|
||||
int main (int argc, char **argv)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
#include <mpi.h>
|
||||
|
||||
#include "pmmc.h"
|
||||
#include "Domain.h"
|
||||
@@ -14,15 +13,16 @@
|
||||
#include "D3Q7.h"
|
||||
#include "Color.h"
|
||||
#include "Communication.h"
|
||||
#include "common/MPI.h"
|
||||
|
||||
#define CBUB
|
||||
//#define WRITE_SURFACES
|
||||
//#define USE_EXP_CONTACT_ANGLE
|
||||
//#define CBUB
|
||||
|
||||
/*
|
||||
* Simulator for two-phase flow in porous media
|
||||
* James E. McClure 2013-2014
|
||||
*/
|
||||
#define USE_EXP_CONTACT_ANGLE
|
||||
#define USE_NEW_WRITER
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -2452,28 +2452,47 @@ int main(int argc, char **argv)
|
||||
WriteCheckpoint(LocalRestartFile, cDen, cDistEven, cDistOdd, N);
|
||||
|
||||
#ifdef WRITE_SURFACES
|
||||
|
||||
sprintf(tmpstr,"vis%03d",logcount);
|
||||
if (rank==0){
|
||||
mkdir(tmpstr,0777);
|
||||
}
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
|
||||
FILE *WN_TRIS;
|
||||
sprintf(LocalRankFilename,"%s/%s%s",tmpstr,"wn-tris.",LocalRankString);
|
||||
WN_TRIS = fopen(LocalRankFilename,"wb");
|
||||
|
||||
FILE *NS_TRIS;
|
||||
sprintf(LocalRankFilename,"%s/%s%s",tmpstr,"ns-tris.",LocalRankString);
|
||||
NS_TRIS = fopen(LocalRankFilename,"wb");
|
||||
#ifdef USE_NEW_WRITER
|
||||
std::shared_ptr<TriList> wn_mesh( new TriList() );
|
||||
wn_mesh->A.reserve(8*ncubes);
|
||||
wn_mesh->B.reserve(8*ncubes);
|
||||
wn_mesh->C.reserve(8*ncubes);
|
||||
std::shared_ptr<TriList> ns_mesh( new TriList() );
|
||||
ns_mesh->A.reserve(8*ncubes);
|
||||
ns_mesh->B.reserve(8*ncubes);
|
||||
ns_mesh->C.reserve(8*ncubes);
|
||||
std::shared_ptr<TriList> ws_mesh( new TriList() );
|
||||
ws_mesh->A.reserve(8*ncubes);
|
||||
ws_mesh->B.reserve(8*ncubes);
|
||||
ws_mesh->C.reserve(8*ncubes);
|
||||
std::shared_ptr<TriList> wns_mesh( new TriList() );
|
||||
wns_mesh->A.reserve(8*ncubes);
|
||||
wns_mesh->B.reserve(8*ncubes);
|
||||
wns_mesh->C.reserve(8*ncubes);
|
||||
#else
|
||||
sprintf(tmpstr,"vis%03d",logcount);
|
||||
if (rank==0){
|
||||
mkdir(tmpstr,0777);
|
||||
}
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
|
||||
FILE *WS_TRIS;
|
||||
sprintf(LocalRankFilename,"%s/%s%s",tmpstr,"ws-tris.",LocalRankString);
|
||||
WS_TRIS = fopen(LocalRankFilename,"wb");
|
||||
FILE *WN_TRIS;
|
||||
sprintf(LocalRankFilename,"%s/%s%s",tmpstr,"wn-tris.",LocalRankString);
|
||||
WN_TRIS = fopen(LocalRankFilename,"wb");
|
||||
|
||||
FILE *WNS_PTS;
|
||||
sprintf(LocalRankFilename,"%s/%s%s",tmpstr,"wns-crv.",LocalRankString);
|
||||
WNS_PTS = fopen(LocalRankFilename,"wb");
|
||||
FILE *NS_TRIS;
|
||||
sprintf(LocalRankFilename,"%s/%s%s",tmpstr,"ns-tris.",LocalRankString);
|
||||
NS_TRIS = fopen(LocalRankFilename,"wb");
|
||||
|
||||
FILE *WS_TRIS;
|
||||
sprintf(LocalRankFilename,"%s/%s%s",tmpstr,"ws-tris.",LocalRankString);
|
||||
WS_TRIS = fopen(LocalRankFilename,"wb");
|
||||
|
||||
FILE *WNS_PTS;
|
||||
sprintf(LocalRankFilename,"%s/%s%s",tmpstr,"wns-crv.",LocalRankString);
|
||||
WNS_PTS = fopen(LocalRankFilename,"wb");
|
||||
#endif
|
||||
|
||||
for (c=0;c<ncubes;c++){
|
||||
// Get cube from the list
|
||||
@@ -2521,16 +2540,22 @@ int main(int argc, char **argv)
|
||||
C.x += 1.0*iproc*(Nx-2);
|
||||
C.y += 1.0*jproc*(Nx-2);
|
||||
C.z += 1.0*kproc*(Nx-2);
|
||||
// write the triangle
|
||||
fwrite(&A.x,sizeof(A.x),1,WN_TRIS);
|
||||
fwrite(&A.y,sizeof(A.y),1,WN_TRIS);
|
||||
fwrite(&A.z,sizeof(A.z),1,WN_TRIS);
|
||||
fwrite(&B.x,sizeof(B.x),1,WN_TRIS);
|
||||
fwrite(&B.y,sizeof(B.y),1,WN_TRIS);
|
||||
fwrite(&B.z,sizeof(B.z),1,WN_TRIS);
|
||||
fwrite(&C.x,sizeof(C.x),1,WN_TRIS);
|
||||
fwrite(&C.y,sizeof(C.y),1,WN_TRIS);
|
||||
fwrite(&C.z,sizeof(C.z),1,WN_TRIS);
|
||||
#ifdef USE_NEW_WRITER
|
||||
wn_mesh->A.push_back(A);
|
||||
wn_mesh->B.push_back(B);
|
||||
wn_mesh->C.push_back(C);
|
||||
#else
|
||||
// write the triangle
|
||||
fwrite(&A.x,sizeof(A.x),1,WN_TRIS);
|
||||
fwrite(&A.y,sizeof(A.y),1,WN_TRIS);
|
||||
fwrite(&A.z,sizeof(A.z),1,WN_TRIS);
|
||||
fwrite(&B.x,sizeof(B.x),1,WN_TRIS);
|
||||
fwrite(&B.y,sizeof(B.y),1,WN_TRIS);
|
||||
fwrite(&B.z,sizeof(B.z),1,WN_TRIS);
|
||||
fwrite(&C.x,sizeof(C.x),1,WN_TRIS);
|
||||
fwrite(&C.y,sizeof(C.y),1,WN_TRIS);
|
||||
fwrite(&C.z,sizeof(C.z),1,WN_TRIS);
|
||||
#endif
|
||||
}
|
||||
for (int r=0;r<n_ws_tris;r++){
|
||||
A = ws_pts(ws_tris(0,r));
|
||||
@@ -2546,16 +2571,22 @@ int main(int argc, char **argv)
|
||||
C.x += 1.0*iproc*(Nx-2);
|
||||
C.y += 1.0*jproc*(Nx-2);
|
||||
C.z += 1.0*kproc*(Nx-2);
|
||||
// write the triangle
|
||||
fwrite(&A.x,sizeof(A.x),1,WS_TRIS);
|
||||
fwrite(&A.y,sizeof(A.y),1,WS_TRIS);
|
||||
fwrite(&A.z,sizeof(A.z),1,WS_TRIS);
|
||||
fwrite(&B.x,sizeof(B.x),1,WS_TRIS);
|
||||
fwrite(&B.y,sizeof(B.y),1,WS_TRIS);
|
||||
fwrite(&B.z,sizeof(B.z),1,WS_TRIS);
|
||||
fwrite(&C.x,sizeof(C.x),1,WS_TRIS);
|
||||
fwrite(&C.y,sizeof(C.y),1,WS_TRIS);
|
||||
fwrite(&C.z,sizeof(C.z),1,WS_TRIS);
|
||||
#ifdef USE_NEW_WRITER
|
||||
ws_mesh->A.push_back(A);
|
||||
ws_mesh->B.push_back(B);
|
||||
ws_mesh->C.push_back(C);
|
||||
#else
|
||||
// write the triangle
|
||||
fwrite(&A.x,sizeof(A.x),1,WS_TRIS);
|
||||
fwrite(&A.y,sizeof(A.y),1,WS_TRIS);
|
||||
fwrite(&A.z,sizeof(A.z),1,WS_TRIS);
|
||||
fwrite(&B.x,sizeof(B.x),1,WS_TRIS);
|
||||
fwrite(&B.y,sizeof(B.y),1,WS_TRIS);
|
||||
fwrite(&B.z,sizeof(B.z),1,WS_TRIS);
|
||||
fwrite(&C.x,sizeof(C.x),1,WS_TRIS);
|
||||
fwrite(&C.y,sizeof(C.y),1,WS_TRIS);
|
||||
fwrite(&C.z,sizeof(C.z),1,WS_TRIS);
|
||||
#endif
|
||||
}
|
||||
for (int r=0;r<n_ns_tris;r++){
|
||||
A = ns_pts(ns_tris(0,r));
|
||||
@@ -2571,16 +2602,22 @@ int main(int argc, char **argv)
|
||||
C.x += 1.0*iproc*(Nx-2);
|
||||
C.y += 1.0*jproc*(Nx-2);
|
||||
C.z += 1.0*kproc*(Nx-2);
|
||||
// write the triangle
|
||||
fwrite(&A.x,sizeof(A.x),1,NS_TRIS);
|
||||
fwrite(&A.y,sizeof(A.y),1,NS_TRIS);
|
||||
fwrite(&A.z,sizeof(A.z),1,NS_TRIS);
|
||||
fwrite(&B.x,sizeof(B.x),1,NS_TRIS);
|
||||
fwrite(&B.y,sizeof(B.y),1,NS_TRIS);
|
||||
fwrite(&B.z,sizeof(B.z),1,NS_TRIS);
|
||||
fwrite(&C.x,sizeof(C.x),1,NS_TRIS);
|
||||
fwrite(&C.y,sizeof(C.y),1,NS_TRIS);
|
||||
fwrite(&C.z,sizeof(C.z),1,NS_TRIS);
|
||||
#ifdef USE_NEW_WRITER
|
||||
ns_mesh->A.push_back(A);
|
||||
ns_mesh->B.push_back(B);
|
||||
ns_mesh->C.push_back(C);
|
||||
#else
|
||||
// write the triangle
|
||||
fwrite(&A.x,sizeof(A.x),1,NS_TRIS);
|
||||
fwrite(&A.y,sizeof(A.y),1,NS_TRIS);
|
||||
fwrite(&A.z,sizeof(A.z),1,NS_TRIS);
|
||||
fwrite(&B.x,sizeof(B.x),1,NS_TRIS);
|
||||
fwrite(&B.y,sizeof(B.y),1,NS_TRIS);
|
||||
fwrite(&B.z,sizeof(B.z),1,NS_TRIS);
|
||||
fwrite(&C.x,sizeof(C.x),1,NS_TRIS);
|
||||
fwrite(&C.y,sizeof(C.y),1,NS_TRIS);
|
||||
fwrite(&C.z,sizeof(C.z),1,NS_TRIS);
|
||||
#endif
|
||||
}
|
||||
for (int p=0; p < n_nws_pts; p++){
|
||||
P = nws_pts(p);
|
||||
@@ -2590,10 +2627,23 @@ int main(int argc, char **argv)
|
||||
fwrite(&P.z,sizeof(P.z),1,WNS_PTS);
|
||||
}
|
||||
}
|
||||
fclose(WN_TRIS);
|
||||
fclose(NS_TRIS);
|
||||
fclose(WS_TRIS);
|
||||
fclose(WNS_PTS);
|
||||
#ifdef USE_NEW_WRITER
|
||||
std::vector<MeshDataStruct> meshData(4);
|
||||
meshData[0].meshName = "wn-tris";
|
||||
meshData[0].mesh = wn_mesh;
|
||||
meshData[1].meshName = "ws-tris";
|
||||
meshData[1].mesh = ws_mesh;
|
||||
meshData[2].meshName = "ns-tris";
|
||||
meshData[2].mesh = ns_mesh;
|
||||
meshData[3].meshName = "wns-tris";
|
||||
meshData[3].mesh = wns_mesh;
|
||||
writeData( logcount, meshData );
|
||||
#else
|
||||
fclose(WN_TRIS);
|
||||
fclose(NS_TRIS);
|
||||
fclose(WS_TRIS);
|
||||
fclose(WNS_PTS);
|
||||
#endif
|
||||
logcount++;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
#include <mpi.h>
|
||||
|
||||
#include "pmmc.h"
|
||||
#include "Domain.h"
|
||||
@@ -14,6 +13,8 @@
|
||||
#include "D3Q7.h"
|
||||
#include "Color.h"
|
||||
#include "Communication.h"
|
||||
#include "common/MPI.h"
|
||||
|
||||
|
||||
#define CBUB
|
||||
//#define WRITE_SURFACES
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
#include <mpi.h>
|
||||
|
||||
#include "Communication.h"
|
||||
#include "common/MPI.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
23
visit/LBM.xml
Normal file
23
visit/LBM.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0"?>
|
||||
<Plugin name="LBM" type="database" label="LBM" version="1.0" mdspecificcode="true" dbtype="MTMD">
|
||||
<FilePatterns>
|
||||
*.LBM
|
||||
</FilePatterns>
|
||||
<CXXFLAGS>
|
||||
-I${LBPM_INSTALL_DIR}/include
|
||||
${MPI_CXXFLAGS}
|
||||
${TIMER_CXXFLAGS}
|
||||
</CXXFLAGS>
|
||||
<LDFLAGS>
|
||||
-L${LBPM_INSTALL_DIR}/lib
|
||||
-L${CMAKE_CURRENT_BINARY_DIR}/..
|
||||
${TIMER_LDFLAGS}
|
||||
${MPI_LINK_FLAGS}
|
||||
</LDFLAGS>
|
||||
<LIBS>
|
||||
-llbpm-wia
|
||||
${TIMER_LDLIBS}
|
||||
${MPI_LIBRARIES}
|
||||
</LIBS>
|
||||
</Plugin>
|
||||
|
||||
92
visit/LBMCommonPluginInfo.C
Normal file
92
visit/LBMCommonPluginInfo.C
Normal file
@@ -0,0 +1,92 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
|
||||
* Produced at the Lawrence Livermore National Laboratory
|
||||
* LLNL-CODE-442911
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
|
||||
* full copyright notice is contained in the file COPYRIGHT located at the root
|
||||
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the disclaimer (as noted below) in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
|
||||
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <LBMPluginInfo.h>
|
||||
#include <avtLBMFileFormat.h>
|
||||
#include <avtMTMDFileFormatInterface.h>
|
||||
#include <avtGenericDatabase.h>
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: LBMCommonPluginInfo::GetDatabaseType
|
||||
//
|
||||
// Purpose:
|
||||
// Returns the type of a LBM database.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
DatabaseType
|
||||
LBMCommonPluginInfo::GetDatabaseType()
|
||||
{
|
||||
return DB_TYPE_MTMD;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: LBMCommonPluginInfo::SetupDatabase
|
||||
//
|
||||
// Purpose:
|
||||
// Sets up a LBM database.
|
||||
//
|
||||
// Arguments:
|
||||
// list A list of file names.
|
||||
// nList The number of timesteps in list.
|
||||
// nBlocks The number of blocks in the list.
|
||||
//
|
||||
// Returns: A LBM database from list.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
avtDatabase *
|
||||
LBMCommonPluginInfo::SetupDatabase(const char *const *list,
|
||||
int nList, int nBlock)
|
||||
{
|
||||
// ignore any nBlocks past 1
|
||||
int nTimestepGroups = nList / nBlock;
|
||||
avtMTMDFileFormat **ffl = new avtMTMDFileFormat*[nTimestepGroups];
|
||||
for (int i = 0 ; i < nTimestepGroups ; i++)
|
||||
{
|
||||
ffl[i] = new avtLBMFileFormat(list[i*nBlock]);
|
||||
}
|
||||
avtMTMDFileFormatInterface *inter
|
||||
= new avtMTMDFileFormatInterface(ffl, nTimestepGroups);
|
||||
return new avtGenericDatabase(inter);
|
||||
}
|
||||
|
||||
73
visit/LBMEnginePluginInfo.C
Normal file
73
visit/LBMEnginePluginInfo.C
Normal file
@@ -0,0 +1,73 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
|
||||
* Produced at the Lawrence Livermore National Laboratory
|
||||
* LLNL-CODE-442911
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
|
||||
* full copyright notice is contained in the file COPYRIGHT located at the root
|
||||
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the disclaimer (as noted below) in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
|
||||
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <LBMPluginInfo.h>
|
||||
|
||||
// ****************************************************************************
|
||||
// Function: GetEngineInfo
|
||||
//
|
||||
// Purpose:
|
||||
// Return a new EnginePluginInfo for the LBM database.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
extern "C" DBP_EXPORT EngineDatabasePluginInfo* LBM_GetEngineInfo()
|
||||
{
|
||||
return new LBMEnginePluginInfo;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: LBMEnginePluginInfo::GetWriter
|
||||
//
|
||||
// Purpose:
|
||||
// Sets up a LBM writer.
|
||||
//
|
||||
// Returns: A LBM writer.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
avtDatabaseWriter *
|
||||
LBMEnginePluginInfo::GetWriter(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
60
visit/LBMMDServerPluginInfo.C
Normal file
60
visit/LBMMDServerPluginInfo.C
Normal file
@@ -0,0 +1,60 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
|
||||
* Produced at the Lawrence Livermore National Laboratory
|
||||
* LLNL-CODE-442911
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
|
||||
* full copyright notice is contained in the file COPYRIGHT located at the root
|
||||
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the disclaimer (as noted below) in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
|
||||
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <LBMPluginInfo.h>
|
||||
|
||||
// ****************************************************************************
|
||||
// Function: GetMDServerInfo
|
||||
//
|
||||
// Purpose:
|
||||
// Return a new MDServerPluginInfo for the LBM database.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
extern "C" DBP_EXPORT MDServerDatabasePluginInfo* LBM_GetMDServerInfo()
|
||||
{
|
||||
return new LBMMDServerPluginInfo;
|
||||
}
|
||||
|
||||
// this makes compilers happy... remove if we ever have functions here
|
||||
void LBMMDServerPluginInfo::dummy()
|
||||
{
|
||||
}
|
||||
|
||||
206
visit/LBMPluginInfo.C
Normal file
206
visit/LBMPluginInfo.C
Normal file
@@ -0,0 +1,206 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
|
||||
* Produced at the Lawrence Livermore National Laboratory
|
||||
* LLNL-CODE-442911
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
|
||||
* full copyright notice is contained in the file COPYRIGHT located at the root
|
||||
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the disclaimer (as noted below) in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
|
||||
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// ************************************************************************* //
|
||||
// File: LBMPluginInfo.C
|
||||
// ************************************************************************* //
|
||||
|
||||
#include <LBMPluginInfo.h>
|
||||
|
||||
#include <visit-config.h>
|
||||
VISIT_PLUGIN_VERSION(LBM,DBP_EXPORT)
|
||||
|
||||
// ****************************************************************************
|
||||
// Function: GetGeneralInfo
|
||||
//
|
||||
// Purpose:
|
||||
// Return a new GeneralPluginInfo for the LBM database.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
extern "C" DBP_EXPORT GeneralDatabasePluginInfo* LBM_GetGeneralInfo()
|
||||
{
|
||||
return new LBMGeneralPluginInfo;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: LBMGeneralPluginInfo::GetName
|
||||
//
|
||||
// Purpose:
|
||||
// Return the name of the database plugin.
|
||||
//
|
||||
// Returns: A pointer to the name of the database plugin.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
const char *
|
||||
LBMGeneralPluginInfo::GetName() const
|
||||
{
|
||||
return "LBM";
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: LBMGeneralPluginInfo::GetVersion
|
||||
//
|
||||
// Purpose:
|
||||
// Return the version of the database plugin.
|
||||
//
|
||||
// Returns: A pointer to the version of the database plugin.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
const char *
|
||||
LBMGeneralPluginInfo::GetVersion() const
|
||||
{
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: LBMGeneralPluginInfo::GetID
|
||||
//
|
||||
// Purpose:
|
||||
// Return the id of the database plugin.
|
||||
//
|
||||
// Returns: A pointer to the id of the database plugin.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
const char *
|
||||
LBMGeneralPluginInfo::GetID() const
|
||||
{
|
||||
return "LBM_1.0";
|
||||
}
|
||||
// ****************************************************************************
|
||||
// Method: LBMGeneralPluginInfo::EnabledByDefault
|
||||
//
|
||||
// Purpose:
|
||||
// Return true if this plugin should be enabled by default; false otherwise.
|
||||
//
|
||||
// Returns: true/false
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
bool
|
||||
LBMGeneralPluginInfo::EnabledByDefault() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// ****************************************************************************
|
||||
// Method: LBMGeneralPluginInfo::HasWriter
|
||||
//
|
||||
// Purpose:
|
||||
// Return true if this plugin has a database writer.
|
||||
//
|
||||
// Returns: true/false
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
bool
|
||||
LBMGeneralPluginInfo::HasWriter() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// ****************************************************************************
|
||||
// Method: LBMGeneralPluginInfo::GetDefaultFilePatterns
|
||||
//
|
||||
// Purpose:
|
||||
// Returns the default patterns for a LBM database.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
std::vector<std::string>
|
||||
LBMGeneralPluginInfo::GetDefaultFilePatterns() const
|
||||
{
|
||||
std::vector<std::string> defaultPatterns;
|
||||
defaultPatterns.push_back("*.LBM");
|
||||
|
||||
return defaultPatterns;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: LBMGeneralPluginInfo::AreDefaultFilePatternsStrict
|
||||
//
|
||||
// Purpose:
|
||||
// Returns if the file patterns for a LBM database are
|
||||
// intended to be interpreted strictly by default.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
bool
|
||||
LBMGeneralPluginInfo::AreDefaultFilePatternsStrict() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: LBMGeneralPluginInfo::OpensWholeDirectory
|
||||
//
|
||||
// Purpose:
|
||||
// Returns if the LBM plugin opens a whole directory name
|
||||
// instead of a single file.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// ****************************************************************************
|
||||
bool
|
||||
LBMGeneralPluginInfo::OpensWholeDirectory() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
100
visit/LBMPluginInfo.h
Normal file
100
visit/LBMPluginInfo.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
|
||||
* Produced at the Lawrence Livermore National Laboratory
|
||||
* LLNL-CODE-442911
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
|
||||
* full copyright notice is contained in the file COPYRIGHT located at the root
|
||||
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the disclaimer (as noted below) in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
|
||||
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// ****************************************************************************
|
||||
// LBMPluginInfo.h
|
||||
// ****************************************************************************
|
||||
|
||||
#ifndef LBM_PLUGIN_INFO_H
|
||||
#define LBM_PLUGIN_INFO_H
|
||||
#include <DatabasePluginInfo.h>
|
||||
#include <database_plugin_exports.h>
|
||||
|
||||
class avtDatabase;
|
||||
class avtDatabaseWriter;
|
||||
|
||||
// ****************************************************************************
|
||||
// Class: LBMDatabasePluginInfo
|
||||
//
|
||||
// Purpose:
|
||||
// Classes that provide all the information about the LBM plugin.
|
||||
// Portions are separated into pieces relevant to the appropriate
|
||||
// components of VisIt.
|
||||
//
|
||||
// Programmer: generated by xml2info
|
||||
// Creation: omitted
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
class LBMGeneralPluginInfo : public virtual GeneralDatabasePluginInfo
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const;
|
||||
virtual const char *GetVersion() const;
|
||||
virtual const char *GetID() const;
|
||||
virtual bool EnabledByDefault() const;
|
||||
virtual bool HasWriter() const;
|
||||
virtual std::vector<std::string> GetDefaultFilePatterns() const;
|
||||
virtual bool AreDefaultFilePatternsStrict() const;
|
||||
virtual bool OpensWholeDirectory() const;
|
||||
};
|
||||
|
||||
class LBMCommonPluginInfo : public virtual CommonDatabasePluginInfo, public virtual LBMGeneralPluginInfo
|
||||
{
|
||||
public:
|
||||
virtual DatabaseType GetDatabaseType();
|
||||
virtual avtDatabase *SetupDatabase(const char * const *list,
|
||||
int nList, int nBlock);
|
||||
};
|
||||
|
||||
class LBMMDServerPluginInfo : public virtual MDServerDatabasePluginInfo, public virtual LBMCommonPluginInfo
|
||||
{
|
||||
public:
|
||||
// this makes compilers happy... remove if we ever have functions here
|
||||
virtual void dummy();
|
||||
};
|
||||
|
||||
class LBMEnginePluginInfo : public virtual EngineDatabasePluginInfo, public virtual LBMCommonPluginInfo
|
||||
{
|
||||
public:
|
||||
virtual avtDatabaseWriter *GetWriter(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
484
visit/avtLBMFileFormat.C
Normal file
484
visit/avtLBMFileFormat.C
Normal file
@@ -0,0 +1,484 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
|
||||
* Produced at the Lawrence Livermore National Laboratory
|
||||
* LLNL-CODE-442911
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
|
||||
* full copyright notice is contained in the file COPYRIGHT located at the root
|
||||
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the disclaimer (as noted below) in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
|
||||
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// ************************************************************************* //
|
||||
// avtLBMFileFormat.C //
|
||||
// ************************************************************************* //
|
||||
|
||||
#include <avtLBMFileFormat.h>
|
||||
#include <DebugStream.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
// LBPM headers
|
||||
#include "IO/Reader.h"
|
||||
#include "IO/IOHelpers.h"
|
||||
#include "IO/PIO.h"
|
||||
#include "common/Utilities.h"
|
||||
|
||||
// vtk headers
|
||||
#include <vtkFloatArray.h>
|
||||
#include <vtkRectilinearGrid.h>
|
||||
#include <vtkStructuredGrid.h>
|
||||
#include <vtkUnstructuredGrid.h>
|
||||
#include <vtkPointSet.h>
|
||||
#include <vtkCellType.h>
|
||||
#include <vtkPolyData.h>
|
||||
#include <vtkCellArray.h>
|
||||
|
||||
|
||||
#include <avtDatabaseMetaData.h>
|
||||
#include <vtkHelpers.h>
|
||||
|
||||
#include <DBOptionsAttributes.h>
|
||||
#include <Expression.h>
|
||||
|
||||
#include <InvalidVariableException.h>
|
||||
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
|
||||
#define USE_WINDOWS
|
||||
#elif defined(__APPLE__)
|
||||
#define USE_MAC
|
||||
#else
|
||||
#define USE_LINUX
|
||||
#endif
|
||||
#ifdef USE_WINDOWS
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#define TIME_TYPE LARGE_INTEGER
|
||||
#define get_time(x) QueryPerformanceCounter(x)
|
||||
#define get_frequency(f) QueryPerformanceFrequency(f)
|
||||
#define get_diff(start,end,f) \
|
||||
static_cast<double>(end.QuadPart-start.QuadPart)/static_cast<double>(f.QuadPart)
|
||||
#elif defined(USE_LINUX) || defined(USE_MAX)
|
||||
#include <sys/time.h>
|
||||
#define TIME_TYPE timeval
|
||||
#define get_time(x) gettimeofday(x,NULL);
|
||||
#define get_frequency(f) (*f=timeval())
|
||||
#define get_diff(start,end,f) 1e-6*static_cast<double>( \
|
||||
0xF4240*(static_cast<int64_t>(end.tv_sec)-static_cast<int64_t>(start.tv_sec)) + \
|
||||
(static_cast<int64_t>(end.tv_usec)-static_cast<int64_t>(start.tv_usec)) )
|
||||
#else
|
||||
#error Unknown OS
|
||||
#endif
|
||||
|
||||
|
||||
// Output streams
|
||||
static IO::ParallelStreamBuffer DebugStreamBuffer1;
|
||||
static IO::ParallelStreamBuffer DebugStreamBuffer2;
|
||||
std::ostream DebugStream1(&DebugStreamBuffer1);
|
||||
std::ostream DebugStream2(&DebugStreamBuffer2);
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: avtLBMFileFormat constructor
|
||||
//
|
||||
// Programmer: mbt -- generated by xml2avt
|
||||
// Creation: Wed Jul 9 10:59:08 PDT 2014
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
avtLBMFileFormat::avtLBMFileFormat(const char *filename)
|
||||
: avtMTMDFileFormat(filename)
|
||||
{
|
||||
// Set abort behavior
|
||||
Utilities::setAbortBehavior(true,true,true);
|
||||
Utilities::setErrorHandlers();
|
||||
// Set debug streams
|
||||
DebugStreamBuffer1.setOutputStream( &DebugStream::Stream1() );
|
||||
DebugStreamBuffer2.setOutputStream( &DebugStream::Stream2() );
|
||||
DebugStreamBuffer1.setOutputStream( &std::cout );
|
||||
// Get the path to the input file
|
||||
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; }
|
||||
d_path = file.substr(0,std::max(k1,k2));
|
||||
// Load the summary file
|
||||
DebugStream1 << "Loading " << filename << std::endl;
|
||||
d_timesteps = IO::readTimesteps(filename);
|
||||
// Read the mesh dabases
|
||||
d_database.clear();
|
||||
d_database.resize(d_timesteps.size());
|
||||
for (size_t i=0; i<d_timesteps.size(); i++)
|
||||
d_database[i] = IO::getMeshList(d_path,d_timesteps[i]);
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: avtEMSTDFileFormat::GetNTimesteps
|
||||
//
|
||||
// Purpose:
|
||||
// Tells the rest of the code how many timesteps there are in this file.
|
||||
//
|
||||
// Programmer: mbt -- generated by xml2avt
|
||||
// Creation: Wed Jul 9 10:59:08 PDT 2014
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
int
|
||||
avtLBMFileFormat::GetNTimesteps(void)
|
||||
{
|
||||
DebugStream2 << "avtLBMFileFormat::GetNTimesteps" << std::endl;
|
||||
return static_cast<int>(d_timesteps.size());
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: avtLBMFileFormat::FreeUpResources
|
||||
//
|
||||
// Purpose:
|
||||
// When VisIt is done focusing on a particular timestep, it asks that
|
||||
// timestep to free up any resources (memory, file descriptors) that
|
||||
// it has associated with it. This method is the mechanism for doing
|
||||
// that.
|
||||
//
|
||||
// Programmer: mbt -- generated by xml2avt
|
||||
// Creation: Wed Jul 9 10:59:08 PDT 2014
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
void
|
||||
avtLBMFileFormat::FreeUpResources(void)
|
||||
{
|
||||
DebugStream1 << "avtLBMFileFormat::FreeUpResources" << std::endl;
|
||||
std::map<std::string,vtkObjectBase*>::iterator it;
|
||||
for ( it=d_meshcache.begin(); it!=d_meshcache.end(); ++it ) {
|
||||
DebugStream2 << " deleting: " << it->first << std::endl;
|
||||
vtkObjectBase* obj = it->second;
|
||||
it->second = NULL;
|
||||
if ( obj!=NULL )
|
||||
obj->Delete();
|
||||
}
|
||||
DebugStream2 << " finished" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: avtLBMFileFormat::PopulateDatabaseMetaData
|
||||
//
|
||||
// Purpose:
|
||||
// This database meta-data object is like a table of contents for the
|
||||
// file. By populating it, you are telling the rest of VisIt what
|
||||
// information it can request from you.
|
||||
//
|
||||
// Programmer: mbt -- generated by xml2avt
|
||||
// Creation: Wed Jul 9 10:59:08 PDT 2014
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
void
|
||||
avtLBMFileFormat::PopulateDatabaseMetaData(avtDatabaseMetaData *md, int timestate)
|
||||
{
|
||||
DebugStream1 << "avtLBMFileFormat::PopulateDatabaseMetaData: " << timestate << std::endl;
|
||||
// Add the mesh domains to the meta data
|
||||
const std::vector<IO::MeshDatabase> database = d_database[timestate];
|
||||
for (size_t i=0; i<database.size(); i++) {
|
||||
DebugStream2 << " Adding " << database[i].name << std::endl;
|
||||
avtMeshMetaData *mmd = new avtMeshMetaData;
|
||||
mmd->name = database[i].name;
|
||||
mmd->meshType = vtkMeshType(database[i].type);
|
||||
mmd->spatialDimension = 3;
|
||||
mmd->topologicalDimension = -1;
|
||||
if ( mmd->meshType==AVT_SURFACE_MESH )
|
||||
mmd->topologicalDimension = 2;
|
||||
mmd->numBlocks = database[i].domains.size();
|
||||
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"};
|
||||
for(int j=0; j<3; j++) {
|
||||
Expression expr;
|
||||
char expdef[100], expname[100];
|
||||
sprintf(expdef,"coord(<%s>)[%i]",mmd->name.c_str(),j);
|
||||
sprintf(expname,"%s/%s",xyz[j],mmd->name.c_str());
|
||||
expr.SetName(expname);
|
||||
expr.SetDefinition(expdef);
|
||||
md->AddExpression(&expr);
|
||||
}
|
||||
// Add the variables
|
||||
for (size_t j=0; j<database[i].variables.size(); j++) {
|
||||
IO::VariableDatabase variable = database[i].variables[j];
|
||||
std::string varname = variable.name + "/" + mmd->name;
|
||||
avtCentering center = AVT_UNKNOWN_CENT;
|
||||
if ( variable.type==IO::VariableType::NodeVariable ) {
|
||||
center = AVT_NODECENT;
|
||||
} else if ( variable.type==IO::VariableType::SurfaceVariable ) {
|
||||
center = AVT_ZONECENT;
|
||||
} else if ( variable.type==IO::VariableType::VolumeVariable ) {
|
||||
center = AVT_ZONECENT;
|
||||
}
|
||||
if ( variable.dim==1 ) {
|
||||
AddScalarVarToMetaData( md, varname, mmd->name, center );
|
||||
} else if ( variable.dim==3 ) {
|
||||
AddVectorVarToMetaData( md, varname, mmd->name, center, variable.dim );
|
||||
} else if ( variable.dim==9 ) {
|
||||
AddTensorVarToMetaData( md, varname, mmd->name, center, variable.dim );
|
||||
}
|
||||
}
|
||||
}
|
||||
DebugStream2 << " Finished" << std::endl;
|
||||
|
||||
//
|
||||
// CODE TO ADD A MATERIAL
|
||||
//
|
||||
// string mesh_for_mat = meshname; // ??? -- could be multiple meshes
|
||||
// string matname = ...
|
||||
// int nmats = ...;
|
||||
// vector<string> mnames;
|
||||
// for (int i = 0 ; i < nmats ; i++)
|
||||
// {
|
||||
// char str[32];
|
||||
// sprintf(str, "mat%d", i);
|
||||
// -- or --
|
||||
// strcpy(str, "Aluminum");
|
||||
// mnames.push_back(str);
|
||||
// }
|
||||
//
|
||||
// Here's the call that tells the meta-data object that we have a mat:
|
||||
//
|
||||
// AddMaterialToMetaData(md, matname, mesh_for_mat, nmats, mnames);
|
||||
//
|
||||
//
|
||||
// Here's the way to add expressions:
|
||||
//Expression momentum_expr;
|
||||
//momentum_expr.SetName("momentum");
|
||||
//momentum_expr.SetDefinition("{u, v}");
|
||||
//momentum_expr.SetType(Expression::VectorMeshVar);
|
||||
//md->AddExpression(&momentum_expr);
|
||||
//Expression KineticEnergy_expr;
|
||||
//KineticEnergy_expr.SetName("KineticEnergy");
|
||||
//KineticEnergy_expr.SetDefinition("0.5*(momentum*momentum)/(rho*rho)");
|
||||
//KineticEnergy_expr.SetType(Expression::ScalarMeshVar);
|
||||
//md->AddExpression(&KineticEnergy_expr);
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: avtLBMFileFormat::GetMesh
|
||||
//
|
||||
// Purpose:
|
||||
// Gets the mesh associated with this file. The mesh is returned as a
|
||||
// derived type of vtkDataSet (ie vtkRectilinearGrid, vtkStructuredGrid,
|
||||
// vtkUnstructuredGrid, etc).
|
||||
//
|
||||
// Arguments:
|
||||
// timestate The index of the timestate. If GetNTimesteps returned
|
||||
// 'N' time steps, this is guaranteed to be between 0 and N-1.
|
||||
// domain The index of the domain. If there are NDomains, this
|
||||
// value is guaranteed to be between 0 and NDomains-1,
|
||||
// regardless of block origin.
|
||||
// meshname The name of the mesh of interest. This can be ignored if
|
||||
// there is only one mesh.
|
||||
//
|
||||
// Programmer: mbt -- generated by xml2avt
|
||||
// Creation: Wed Jul 9 10:59:08 PDT 2014
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
vtkDataSet *
|
||||
avtLBMFileFormat::GetMesh(int timestate, int domain, const char *meshname)
|
||||
{
|
||||
DebugStream1 << "avtLBMFileFormat::GetMesh - " << meshname
|
||||
<< "," << timestate << "," << domain << std::endl;
|
||||
TIME_TYPE start, stop, freq;
|
||||
get_frequency(&freq);
|
||||
get_time(&start);
|
||||
// Check if we have a cached copy of the mesh
|
||||
char cache_name[1000];
|
||||
sprintf(cache_name,"%i-%i-%s",timestate,domain,meshname);
|
||||
if ( d_meshcache.find(cache_name)!=d_meshcache.end() )
|
||||
return dynamic_cast<vtkDataSet*>(d_meshcache.find(cache_name)->second);
|
||||
// Read the mesh
|
||||
std::shared_ptr<IO::Mesh> mesh;
|
||||
const std::vector<IO::MeshDatabase> database = d_database[timestate];
|
||||
const std::string timestep = d_timesteps[timestate];
|
||||
for (size_t i=0; i<database.size(); i++) {
|
||||
if ( database[i].name==std::string(meshname) ) {
|
||||
DebugStream2 << " calling getMesh" << std::endl;
|
||||
try {
|
||||
mesh = IO::getMesh(d_path,timestep,database[i],domain);
|
||||
} catch (const std::exception &err) {
|
||||
DebugStream1 << " Caught errror calling getMesh:" << std::endl;
|
||||
DebugStream1 << err.what() << std::endl;
|
||||
} catch (...) {
|
||||
DebugStream1 << " Caught unknown errror calling getMesh" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( mesh==NULL ) {
|
||||
DebugStream1 << " Error loading mesh" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
// Create the mesh in vtk
|
||||
vtkDataSet* vtkMesh = meshToVTK(mesh);
|
||||
DebugStream2 << " mesh created:" << std::endl;
|
||||
ASSERT(vtkMesh!=NULL);
|
||||
DebugStream2 << " " << vtkMesh->GetNumberOfCells() << std::endl;
|
||||
vtkMesh->PrintSelf(DebugStream2,vtkIndent(6));
|
||||
// Cache the mesh and return
|
||||
// meshcache[cache_name] = mesh;
|
||||
get_time(&stop);
|
||||
DebugStream2 << " Time required: " << get_diff(start,stop,freq) << std::endl;
|
||||
return vtkMesh;
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: avtLBMFileFormat::GetVar
|
||||
//
|
||||
// Purpose:
|
||||
// Gets a scalar variable associated with this file. Although VTK has
|
||||
// support for many different types, the best bet is vtkFloatArray, since
|
||||
// that is supported everywhere through VisIt.
|
||||
//
|
||||
// Arguments:
|
||||
// timestate The index of the timestate. If GetNTimesteps returned
|
||||
// 'N' time steps, this is guaranteed to be between 0 and N-1.
|
||||
// domain The index of the domain. If there are NDomains, this
|
||||
// value is guaranteed to be between 0 and NDomains-1,
|
||||
// regardless of block origin.
|
||||
// varname The name of the variable requested.
|
||||
//
|
||||
// Programmer: mbt -- generated by xml2avt
|
||||
// Creation: Wed Jul 9 10:59:08 PDT 2014
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
vtkDataArray *
|
||||
avtLBMFileFormat::GetVar(int timestate, int domain, const char *meshvarname)
|
||||
{
|
||||
DebugStream1 << "avtLBMFileFormat::GetVar: " << meshvarname
|
||||
<< "," << timestate << "," << domain << std::endl;
|
||||
std::vector<std::string> tmp = IO::splitList(meshvarname,'/');
|
||||
ASSERT(tmp.size()==2);
|
||||
std::string varname = tmp[0];
|
||||
std::string meshname = tmp[1];
|
||||
const std::vector<IO::MeshDatabase> database = d_database[timestate];
|
||||
const std::string timestep = d_timesteps[timestate];
|
||||
std::shared_ptr<const IO::Variable> variable;
|
||||
for (size_t i=0; i<database.size(); i++) {
|
||||
if ( database[i].name==std::string(meshname) ) {
|
||||
DebugStream2 << " calling getVar" << std::endl;
|
||||
try {
|
||||
variable = IO::getVariable(d_path,timestep,database[i],domain,varname);
|
||||
} catch (const std::exception &err) {
|
||||
DebugStream1 << " Caught errror calling getVar:" << std::endl;
|
||||
DebugStream1 << err.what() << std::endl;
|
||||
} catch (...) {
|
||||
DebugStream1 << " Caught unknown errror calling getVar" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( variable == NULL )
|
||||
EXCEPTION1(InvalidVariableException, varname);
|
||||
vtkDataArray* vtkVar = varToVTK(variable);
|
||||
return vtkVar;
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Method: avtLBMFileFormat::GetVectorVar
|
||||
//
|
||||
// Purpose:
|
||||
// Gets a vector variable associated with this file. Although VTK has
|
||||
// support for many different types, the best bet is vtkFloatArray, since
|
||||
// that is supported everywhere through VisIt.
|
||||
//
|
||||
// Arguments:
|
||||
// timestate The index of the timestate. If GetNTimesteps returned
|
||||
// 'N' time steps, this is guaranteed to be between 0 and N-1.
|
||||
// domain The index of the domain. If there are NDomains, this
|
||||
// value is guaranteed to be between 0 and NDomains-1,
|
||||
// regardless of block origin.
|
||||
// varname The name of the variable requested.
|
||||
//
|
||||
// Programmer: mbt -- generated by xml2avt
|
||||
// Creation: Wed Jul 9 10:59:08 PDT 2014
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
vtkDataArray *
|
||||
avtLBMFileFormat::GetVectorVar(int timestate, int domain, const char *varname)
|
||||
{
|
||||
cerr << "avtLBMFileFormat::GetVectorVar - " << varname
|
||||
<< "," << timestate << "," << domain << std::endl;
|
||||
DebugStream1 << "avtLBMFileFormat::GetVectorVar" << std::endl;
|
||||
EXCEPTION1(InvalidVariableException, varname);
|
||||
return NULL;
|
||||
|
||||
//
|
||||
// If you have a file format where variables don't apply (for example a
|
||||
// strictly polygonal format like the STL (Stereo Lithography) format,
|
||||
// then uncomment the code below.
|
||||
//
|
||||
// EXCEPTION1(InvalidVariableException, varname);
|
||||
//
|
||||
|
||||
//
|
||||
// If you do have a vector variable, here is some code that may be helpful.
|
||||
//
|
||||
// int ncomps = YYY; // This is the rank of the vector - typically 2 or 3.
|
||||
// int ntuples = XXX; // this is the number of entries in the variable.
|
||||
// vtkFloatArray *rv = vtkFloatArray::New();
|
||||
// int ucomps = (ncomps == 2 ? 3 : ncomps);
|
||||
// rv->SetNumberOfComponents(ucomps);
|
||||
// rv->SetNumberOfTuples(ntuples);
|
||||
// float *one_entry = new float[ucomps];
|
||||
// for (int i = 0 ; i < ntuples ; i++)
|
||||
// {
|
||||
// int j;
|
||||
// for (j = 0 ; j < ncomps ; j++)
|
||||
// one_entry[j] = ...
|
||||
// for (j = ncomps ; j < ucomps ; j++)
|
||||
// one_entry[j] = 0.;
|
||||
// rv->SetTuple(i, one_entry);
|
||||
// }
|
||||
//
|
||||
// delete [] one_entry;
|
||||
// return rv;
|
||||
//
|
||||
}
|
||||
|
||||
115
visit/avtLBMFileFormat.h
Normal file
115
visit/avtLBMFileFormat.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
|
||||
* Produced at the Lawrence Livermore National Laboratory
|
||||
* LLNL-CODE-442911
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
|
||||
* full copyright notice is contained in the file COPYRIGHT located at the root
|
||||
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the disclaimer (as noted below) in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
|
||||
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// ************************************************************************* //
|
||||
// avtLBMFileFormat.h //
|
||||
// ************************************************************************* //
|
||||
|
||||
#ifndef AVT_LBM_FILE_FORMAT_H
|
||||
#define AVT_LBM_FILE_FORMAT_H
|
||||
|
||||
#include <vtkObjectBase.h>
|
||||
|
||||
#include <avtMTMDFileFormat.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "IO/MeshDatabase.h"
|
||||
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// Class: avtLBMFileFormat
|
||||
//
|
||||
// Purpose:
|
||||
// Reads in LBM files as a plugin to VisIt.
|
||||
//
|
||||
// Programmer: mbt -- generated by xml2avt
|
||||
// Creation: Wed Jul 9 10:59:08 PDT 2014
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
class avtLBMFileFormat : public avtMTMDFileFormat
|
||||
{
|
||||
public:
|
||||
avtLBMFileFormat(const char *);
|
||||
virtual ~avtLBMFileFormat() {;};
|
||||
|
||||
//
|
||||
// This is used to return unconvention data -- ranging from material
|
||||
// information to information about block connectivity.
|
||||
//
|
||||
// virtual void *GetAuxiliaryData(const char *var, int timestep,
|
||||
// int domain, const char *type, void *args,
|
||||
// DestructorFunction &);
|
||||
//
|
||||
|
||||
//
|
||||
// If you know the times and cycle numbers, overload this function.
|
||||
// Otherwise, VisIt will make up some reasonable ones for you.
|
||||
//
|
||||
// virtual void GetCycles(std::vector<int> &);
|
||||
// virtual void GetTimes(std::vector<double> &);
|
||||
//
|
||||
|
||||
virtual int GetNTimesteps(void);
|
||||
|
||||
virtual const char *GetType(void) { return "LBM"; };
|
||||
virtual void FreeUpResources(void);
|
||||
|
||||
virtual vtkDataSet *GetMesh(int, int, const char *);
|
||||
virtual vtkDataArray *GetVar(int, int, const char *);
|
||||
virtual vtkDataArray *GetVectorVar(int, int, const char *);
|
||||
|
||||
protected:
|
||||
|
||||
// Populate the databes
|
||||
virtual void PopulateDatabaseMetaData(avtDatabaseMetaData*, int);
|
||||
|
||||
// Helper typedefs
|
||||
typedef std::pair<std::string,int> mesh_key;
|
||||
|
||||
// DATA MEMBERS
|
||||
std::string d_path;
|
||||
std::vector<std::string> d_timesteps;
|
||||
std::vector<std::vector<IO::MeshDatabase> > d_database;
|
||||
std::map<std::string,vtkObjectBase*> d_meshcache;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
10
visit/testVisit.py
Normal file
10
visit/testVisit.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# visit -debug 1 -valgrind engine_ser -cli -s /projects/JamesClure/LBPM-WIA/visit/testVisit.py
|
||||
|
||||
|
||||
OpenDatabase("localhost:/projects/JamesClure/build/debug/tests/summary.LBM", 0)
|
||||
#AddPlot("Mesh", "pointmesh", 1, 1)
|
||||
AddPlot("Mesh", "trilist", 1, 1)
|
||||
DrawPlots()
|
||||
#quit()
|
||||
|
||||
|
||||
161
visit/vtkHelpers.h
Normal file
161
visit/vtkHelpers.h
Normal file
@@ -0,0 +1,161 @@
|
||||
// vtk headers
|
||||
#include <vtkFloatArray.h>
|
||||
#include <vtkRectilinearGrid.h>
|
||||
#include <vtkStructuredGrid.h>
|
||||
#include <vtkUnstructuredGrid.h>
|
||||
#include <vtkPointSet.h>
|
||||
#include <vtkCellType.h>
|
||||
#include <vtkPolyData.h>
|
||||
#include <vtkCellArray.h>
|
||||
|
||||
|
||||
// LBPM headers
|
||||
#include "IO/Mesh.h"
|
||||
|
||||
|
||||
// Convert a point array to vtkFloatArray
|
||||
inline vtkFloatArray* pointToVTK( const std::vector<Point>& points )
|
||||
{
|
||||
vtkFloatArray *coords = vtkFloatArray::New();
|
||||
coords->SetNumberOfComponents(3);
|
||||
coords->SetNumberOfTuples(points.size());
|
||||
for (size_t i=0; i<points.size(); i++)
|
||||
coords->SetTuple3(i,points[i].x,points[i].y,points[i].z);
|
||||
return coords;
|
||||
}
|
||||
|
||||
|
||||
// Return the mesh type
|
||||
inline avtMeshType vtkMeshType( IO::MeshType meshType )
|
||||
{
|
||||
avtMeshType vtkType = AVT_UNKNOWN_MESH;
|
||||
if ( meshType==IO::MeshType::PointMesh )
|
||||
vtkType = AVT_POINT_MESH;
|
||||
else if ( meshType==IO::MeshType::SurfaceMesh )
|
||||
vtkType = AVT_SURFACE_MESH;
|
||||
else if ( meshType==IO::MeshType::VolumeMesh )
|
||||
vtkType = AVT_UNSTRUCTURED_MESH;
|
||||
return vtkType;
|
||||
}
|
||||
|
||||
|
||||
// Convert a PointList to vtkDataSet
|
||||
inline vtkDataSet* PointListToVTK( std::shared_ptr<const IO::PointList> mesh )
|
||||
{
|
||||
vtkFloatArray *coords = pointToVTK(mesh->points);
|
||||
vtkPoints *points = vtkPoints::New(VTK_FLOAT);
|
||||
points->SetData(coords);
|
||||
points->ComputeBounds();
|
||||
size_t N = mesh->points.size();
|
||||
vtkPolyData *vtkMesh = vtkPolyData::New();
|
||||
vtkMesh->SetPoints(points);
|
||||
vtkMesh->Allocate(N);
|
||||
for (int i=0; i<(int)N; i++) {
|
||||
vtkIdType ids[1] = {i};
|
||||
vtkMesh->InsertNextCell(VTK_VERTEX,1,ids);
|
||||
}
|
||||
// vtkMesh->BuildCells();
|
||||
vtkMesh->ComputeBounds();
|
||||
points->Delete();
|
||||
coords->Delete();
|
||||
return vtkMesh;
|
||||
}
|
||||
|
||||
|
||||
// Convert a TriMesh to vtkDataSet
|
||||
inline vtkDataSet* TriMeshToVTK( std::shared_ptr<const IO::TriMesh> mesh )
|
||||
{
|
||||
vtkFloatArray *coords = pointToVTK(mesh->vertices->points);
|
||||
ASSERT(coords!=NULL);
|
||||
vtkPoints *points = vtkPoints::New(VTK_FLOAT);
|
||||
points->SetData(coords);
|
||||
points->ComputeBounds();
|
||||
const std::vector<int>& A = mesh->A;
|
||||
const std::vector<int>& B = mesh->B;
|
||||
const std::vector<int>& C = mesh->C;
|
||||
size_t N_tri = A.size();
|
||||
vtkPolyData *vtkMesh = vtkPolyData::New();
|
||||
vtkMesh->SetPoints(points);
|
||||
vtkMesh->Allocate(N_tri);
|
||||
for (size_t i=0; i<N_tri; i++) {
|
||||
vtkIdType ids[3] = {A[i],B[i],C[i]};
|
||||
vtkMesh->InsertNextCell(VTK_TRIANGLE,3,ids);
|
||||
}
|
||||
vtkMesh->BuildCells();
|
||||
vtkMesh->ComputeBounds();
|
||||
points->Delete();
|
||||
coords->Delete();
|
||||
return vtkMesh;
|
||||
}
|
||||
|
||||
|
||||
// Convert a TriList to vtkDataSet
|
||||
inline vtkDataSet* TriListToVTK( std::shared_ptr<const IO::TriList> mesh )
|
||||
{
|
||||
std::vector<LBPM_Point> point_set(3*mesh->A.size());
|
||||
for (size_t i=0; i<mesh->A.size(); i++) {
|
||||
point_set[3*i+0] = mesh->A[i];
|
||||
point_set[3*i+1] = mesh->B[i];
|
||||
point_set[3*i+2] = mesh->C[i];
|
||||
}
|
||||
vtkFloatArray *coords = pointToVTK(point_set);
|
||||
ASSERT(coords!=NULL);
|
||||
vtkPoints *points = vtkPoints::New(VTK_FLOAT);
|
||||
points->SetData(coords);
|
||||
points->ComputeBounds();
|
||||
size_t N_tri = mesh->A.size();
|
||||
vtkPolyData *vtkMesh = vtkPolyData::New();
|
||||
vtkMesh->SetPoints(points);
|
||||
vtkMesh->Allocate(N_tri);
|
||||
for (int i=0; i<(int)N_tri; i++) {
|
||||
vtkIdType ids[3] = {3*i+0,3*i+1,3*i+2};
|
||||
vtkMesh->InsertNextCell(VTK_TRIANGLE,3,ids);
|
||||
}
|
||||
vtkMesh->BuildCells();
|
||||
vtkMesh->ComputeBounds();
|
||||
points->Delete();
|
||||
coords->Delete();
|
||||
return vtkMesh;
|
||||
}
|
||||
|
||||
|
||||
// Convert a mesh to vtkDataSet
|
||||
inline vtkDataSet* meshToVTK( std::shared_ptr<const IO::Mesh> mesh )
|
||||
{
|
||||
vtkDataSet* mesh2 = NULL;
|
||||
if ( std::dynamic_pointer_cast<const IO::PointList>(mesh) != NULL ) {
|
||||
// We are dealing with a point mesh
|
||||
mesh2 = PointListToVTK( std::dynamic_pointer_cast<const IO::PointList>(mesh) );
|
||||
DebugStream::Stream1() << " Point mesh created" << std::endl;
|
||||
} else if ( std::dynamic_pointer_cast<const IO::TriMesh>(mesh) != NULL ) {
|
||||
mesh2 = TriMeshToVTK( std::dynamic_pointer_cast<const IO::TriMesh>(mesh) );
|
||||
DebugStream::Stream1() << " Surface mesh created" << std::endl;
|
||||
} else if ( std::dynamic_pointer_cast<const IO::TriList>(mesh) != NULL ) {
|
||||
mesh2 = TriListToVTK( std::dynamic_pointer_cast<const IO::TriList>(mesh) );
|
||||
DebugStream::Stream1() << " Surface mesh created" << std::endl;
|
||||
} else {
|
||||
DebugStream::Stream1() << " Error, unknown mesh type" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
return mesh2;
|
||||
}
|
||||
|
||||
|
||||
// Convert a variable to vtkDataSet
|
||||
inline vtkDataArray* varToVTK( std::shared_ptr<const IO::Variable> var )
|
||||
{
|
||||
vtkFloatArray* var2 = NULL;
|
||||
if ( var->dim==1 ) {
|
||||
// Scalar variable
|
||||
var2 = vtkFloatArray::New();
|
||||
var2->SetNumberOfTuples(var->data.size());
|
||||
for (size_t i=0; i<var->data.size(); i++)
|
||||
var2->SetTuple1(i,var->data[i]);
|
||||
} else {
|
||||
DebugStream::Stream1() << " Error, variable not yet supported" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
return var2;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user