#include "Mesh.h" #include "common/Utilities.h" #include "shared_ptr.h" #include #include namespace IO { inline Point nullPoint() { Point tmp; tmp.x = std::numeric_limits::quiet_NaN(); tmp.y = std::numeric_limits::quiet_NaN(); tmp.z = std::numeric_limits::quiet_NaN(); return tmp; } /**************************************************** * Mesh * ****************************************************/ Mesh::Mesh( ) { } Mesh::~Mesh( ) { } /**************************************************** * MeshDataStruct * ****************************************************/ bool MeshDataStruct::check() const { enum VariableType { NodeVariable=1, EdgeVariable=2, SurfaceVariable=2, VolumeVariable=3, NullVariable=0 }; bool pass = mesh != nullptr; for ( const auto& var : vars ) { pass = pass && static_cast(var->type)>=1 && static_cast(var->type)<=3; pass = pass && !var->data.empty(); } if ( !pass ) return false; const std::string& meshClass = mesh->className(); if ( meshClass == "PointList" ) { const auto mesh2 = dynamic_cast( mesh.get() ); if ( mesh2 == nullptr ) return false; for ( const auto& var : vars ) { if ( var->type == IO::VariableType::NodeVariable ) { pass = pass && var->data.size(0)==mesh2->points.size() && var->data.size(1)==var->dim; } else if ( var->type == IO::VariableType::EdgeVariable ) { ERROR("Invalid type for PointList"); } else if ( var->type == IO::VariableType::SurfaceVariable ) { ERROR("Invalid type for PointList"); } else if ( var->type == IO::VariableType::VolumeVariable ) { ERROR("Invalid type for PointList"); } else { ERROR("Invalid variable type"); } } } else if ( meshClass == "TriMesh" || meshClass == "TriList" ) { const auto mesh2 = getTriMesh( mesh ); if ( mesh2 == nullptr ) return false; for ( const auto& var : vars ) { if ( var->type == IO::VariableType::NodeVariable ) { pass = pass && var->data.size(0)==mesh2->vertices->points.size() && var->data.size(1)==var->dim; } else if ( var->type == IO::VariableType::EdgeVariable ) { ERROR("Not finished"); } else if ( var->type == IO::VariableType::SurfaceVariable ) { ERROR("Not finished"); } else if ( var->type == IO::VariableType::VolumeVariable ) { pass = pass && var->data.size(0)==mesh2->A.size() && var->data.size(1)==var->dim; } else { ERROR("Invalid variable type"); } } } else if ( meshClass == "DomainMesh" ) { const auto mesh2 = dynamic_cast( mesh.get() ); if ( mesh2 == nullptr ) return false; for ( const auto& var : vars ) { if ( var->type == IO::VariableType::NodeVariable ) { pass = pass && (int) var->data.size(0)==(mesh2->nx+1) && (int) var->data.size(1)==(mesh2->ny+1) && (int) var->data.size(2)==(mesh2->nz+1) && var->data.size(3)==var->dim; } else if ( var->type == IO::VariableType::EdgeVariable ) { ERROR("Not finished"); } else if ( var->type == IO::VariableType::SurfaceVariable ) { ERROR("Not finished"); } else if ( var->type == IO::VariableType::VolumeVariable ) { pass = pass && (int) var->data.size(0)==mesh2->nx && (int) var->data.size(1)==mesh2->ny && (int) var->data.size(2)==mesh2->nz && var->data.size(3)==var->dim; } else { ERROR("Invalid variable type"); } } } else { ERROR("Unknown mesh class: "+mesh->className()); } return pass; } /**************************************************** * 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 PointList::pack( int level ) const { std::pair 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(data_ptr); data_int[0] = level; data_int[1] = points.size(); double *data = &data_ptr[2]; for (size_t i=0; i& data_in ) { uint64_t *data_int = reinterpret_cast(data_in.second); const double *data = reinterpret_cast(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& P = mesh.vertices->points; for (size_t i=0; i TriList::pack( int level ) const { std::pair 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(data_ptr); data_int[0] = level; data_int[1] = A.size(); double *data = &data_ptr[2]; for (size_t i=0; i& data_in ) { uint64_t *data_int = reinterpret_cast(data_in.second); const double *data = reinterpret_cast(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 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; ipoints[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 TriMesh::pack( int level ) const { std::pair data_out(0,NULL); if ( level==0 ) { const std::vector& 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(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(&data[3*points.size()]); for (size_t i=0; i& data_in ) { uint64_t *data_int64 = reinterpret_cast(data_in.second); const double *data = reinterpret_cast(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& points = vertices->points; for (size_t i=0; i(&data[3*N_P]); A.resize(N_A); B.resize(N_A); C.resize(N_A); for (size_t i=0; i DomainMesh::pack( int level ) const { std::pair data(0,NULL); data.first = 7*sizeof(double); data.second = new double[7]; memset(data.second,0,7*sizeof(double)); int *data_int = reinterpret_cast(data.second); double *data_double = &reinterpret_cast(data.second)[4]; data_int[0] = nprocx; data_int[1] = nprocy; data_int[2] = nprocz; data_int[3] = rank; data_int[4] = nx; data_int[5] = ny; data_int[6] = nz; data_double[0] = Lx; data_double[1] = Ly; data_double[2] = Lz; return data; } void DomainMesh::unpack( const std::pair& data ) { const int *data_int = reinterpret_cast(data.second); const double *data_double = &reinterpret_cast(data.second)[4]; nprocx = data_int[0]; nprocy = data_int[1]; nprocz = data_int[2]; rank = data_int[3]; nx = data_int[4]; ny = data_int[5]; nz = data_int[6]; Lx = data_double[0]; Ly = data_double[1]; Lz = data_double[2]; } /**************************************************** * Converters * ****************************************************/ std::shared_ptr getPointList( std::shared_ptr mesh ) { return std::dynamic_pointer_cast(mesh); } std::shared_ptr getTriMesh( std::shared_ptr mesh ) { std::shared_ptr mesh2; if ( std::dynamic_pointer_cast(mesh).get() != NULL ) { mesh2 = std::dynamic_pointer_cast(mesh); } else if ( std::dynamic_pointer_cast(mesh).get() != NULL ) { std::shared_ptr trilist = std::dynamic_pointer_cast(mesh); ASSERT(trilist.get()!=NULL); mesh2.reset( new TriMesh(*trilist) ); } return mesh2; } std::shared_ptr getTriList( std::shared_ptr mesh ) { std::shared_ptr mesh2; if ( std::dynamic_pointer_cast(mesh).get() != NULL ) { mesh2 = std::dynamic_pointer_cast(mesh); } else if ( std::dynamic_pointer_cast(mesh).get() != NULL ) { std::shared_ptr trimesh = std::dynamic_pointer_cast(mesh); ASSERT(trimesh.get()!=NULL); mesh2.reset( new TriList(*trimesh) ); } return mesh2; } std::shared_ptr getPointList( std::shared_ptr mesh ) { return getPointList( std::const_pointer_cast(mesh) ); } std::shared_ptr getTriMesh( std::shared_ptr mesh ) { return getTriMesh( std::const_pointer_cast(mesh) ); } std::shared_ptr getTriList( std::shared_ptr mesh ) { return getTriList( std::const_pointer_cast(mesh) ); } } // IO namespace