#include "IO/MeshDatabase.h" #include "IO/Mesh.h" #include "IO/IOHelpers.h" #include "common/MPI_Helpers.h" #include "common/Utilities.h" #include #include #include #include #include /**************************************************** ****************************************************/ // MeshType template<> size_t packsize( const IO::MeshType& rhs ) { return sizeof(IO::MeshType); } template<> void pack( const IO::MeshType& rhs, char *buffer ) { memcpy(buffer,&rhs,sizeof(IO::MeshType)); } template<> void unpack( IO::MeshType& data, const char *buffer ) { memcpy(&data,buffer,sizeof(IO::MeshType)); } // Variable::VariableType template<> size_t packsize( const IO::VariableType& rhs ) { return sizeof(IO::VariableType); } template<> void pack( const IO::VariableType& rhs, char *buffer ) { memcpy(buffer,&rhs,sizeof(IO::VariableType)); } template<> void unpack( IO::VariableType& data, const char *buffer ) { memcpy(&data,buffer,sizeof(IO::VariableType)); } // DatabaseEntry template<> size_t packsize( const IO::DatabaseEntry& rhs ) { return packsize(rhs.name)+packsize(rhs.file)+packsize(rhs.offset); } template<> void pack( 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& 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( const IO::VariableDatabase& rhs ) { return packsize(rhs.name)+packsize(rhs.type)+packsize(rhs.dim); } template<> void pack( 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& 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( 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( 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& 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 ( namerhs.type ) return true; else if ( typerhs.dim ) return true; else if ( dim(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; } VariableDatabase MeshDatabase::getVariableDatabase( const std::string& varname ) const { for (size_t i=0; i list = splitList(line,';'); name = list[0]; file = list[1]; offset = atol(list[2].c_str()); } void DatabaseEntry::read( const char* line ) { std::vector list = splitList(line,';'); name = list[0]; file = list[1]; offset = atol(list[2].c_str()); } void DatabaseEntry::read( const std::string& line ) { std::vector list = splitList(line.c_str(),';'); name = list[0]; file = list[1]; offset = atol(list[2].c_str()); } // Gather the mesh databases from all processors inline int tod( int N ) { return (N+7)/sizeof(double); } std::vector gatherAll( const std::vector& meshes, MPI_Comm comm ) { #ifdef USE_MPI PROFILE_START("gatherAll"); PROFILE_START("gatherAll-pack",2); int size = MPI_WORLD_SIZE(); // First pack the mesh data to local buffers int localsize = 0; for (size_t i=0; i data; pos = 0; while ( pos < globalsize ) { MeshDatabase tmp; unpack(tmp,(char*)&globalbuf[pos]); pos += tod(packsize(tmp)); std::map::iterator it = data.find(tmp.name); if ( it==data.end() ) { data[tmp.name] = tmp; } else { for (size_t i=0; isecond.domains.push_back(tmp.domains[i]); for (size_t i=0; isecond.variables.push_back(tmp.variables[i]); it->second.variable_data.insert(tmp.variable_data.begin(),tmp.variable_data.end()); } } for (std::map::iterator it=data.begin(); it!=data.end(); ++it) { // Get the unique variables std::set data2(it->second.variables.begin(),it->second.variables.end()); it->second.variables = std::vector(data2.begin(),data2.end()); } // Free temporary memory delete [] localbuf; delete [] recvsize; delete [] disp; delete [] globalbuf; // Return the results std::vector data2(data.size()); size_t i=0; for (std::map::iterator it=data.begin(); it!=data.end(); ++it, ++i) data2[i] = it->second; PROFILE_STOP("gatherAll-unpack",2); PROFILE_STOP("gatherAll"); return data2; #else return meshes; #endif } //! Write the mesh databases to a file void write( const std::vector& meshes, const std::string& filename ) { PROFILE_START("write"); FILE *fid = fopen(filename.c_str(),"wb"); for (size_t i=0; i(meshes[i].type)); fprintf(fid," meshClass: %s\n",meshes[i].meshClass.c_str()); fprintf(fid," format: %i\n",static_cast(meshes[i].format)); for (size_t j=0; j(var.type),var.dim); } fprintf(fid,"\n"); std::map,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 read( const std::string& filename ) { std::vector 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(atoi(&line[10])); } else if ( strncmp(line," type:",8)==0 ) { meshes.back().type = static_cast(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 variables = splitList(&line[13],';'); mesh.variables.resize(variables.size()); for (size_t i=0; i tmp = splitList(variables[i].c_str(),'|'); ASSERT(tmp.size()==3); mesh.variables[i].name = tmp[0]; mesh.variables[i].type = static_cast(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 key(domain,variable); DatabaseEntry data(&line[i2+1]); meshes.back().variable_data.insert( std::pair,DatabaseEntry>(key,data) ); } else { ERROR("Error reading line"); } } fclose(fid); delete [] line; PROFILE_STOP("read"); return meshes; } // Return the mesh type IO::MeshType meshType( const IO::Mesh& mesh ) { IO::MeshType type = IO::Unknown; const std::string meshClass = mesh.className(); if ( meshClass=="PointList" ) { type = IO::PointMesh; } else if ( meshClass=="TriList" || meshClass=="TriMesh" ) { type = IO::SurfaceMesh; } else if ( meshClass=="DomainMesh" ) { type = IO::VolumeMesh; } else { ERROR("Unknown mesh"); } return type; } } // IO namespace