#ifndef SILO_INTERFACE_HPP #define SILO_INTERFACE_HPP #include "IO/silo.h" #include "common/Utilities.h" #include "common/MPI_Helpers.h" #include "ProfilerApp.h" #ifdef USE_SILO #include namespace silo { /**************************************************** * Helper functions * ****************************************************/ template static constexpr int getType(); template<> constexpr int getType() { return DB_DOUBLE; } template<> constexpr int getType() { return DB_FLOAT; } template<> constexpr int getType() { return DB_INT; } template inline void copyData( Array& data, int type, const void *src ) { if ( type == getType() ) memcpy( data.data(), src, data.length()*sizeof(TYPE) ); else if ( type == DB_DOUBLE ) data.copy( static_cast(src) ); else if ( type == DB_FLOAT ) data.copy( static_cast(src) ); else if ( type == DB_INT ) data.copy( static_cast(src) ); else ERROR("Unknown type"); } /**************************************************** * Write/read an arbitrary vector * ****************************************************/ template constexpr int getSiloType(); template<> constexpr int getSiloType() { return DB_INT; } template<> constexpr int getSiloType() { return DB_FLOAT; } template<> constexpr int getSiloType() { return DB_DOUBLE; } template void write( DBfile* fid, const std::string& varname, const std::vector& data ) { int dims = data.size(); int err = DBWrite( fid, varname.c_str(), (void*) data.data(), &dims, 1, getSiloType() ); ASSERT( err == 0 ); } template std::vector read( DBfile* fid, const std::string& varname ) { int N = DBGetVarLength( fid, varname.c_str() ); std::vector data(N); int err = DBReadVar( fid, varname.c_str(), data.data() ); ASSERT( err == 0 ); return data; } /**************************************************** * Helper function to get variable suffixes * ****************************************************/ inline std::vector getVarSuffix( int ndim, int nvars ) { std::vector suffix(nvars); if ( nvars == 1 ) { suffix[0] = ""; } else if ( nvars == ndim ) { if ( ndim==2 ) { suffix[0] = "_x"; suffix[1] = "_y"; } else if ( ndim==3 ) { suffix[0] = "_x"; suffix[1] = "_y"; suffix[2] = "_z"; } else { ERROR("Not finished"); } } else if ( nvars == ndim*ndim ) { if ( ndim==2 ) { suffix[0] = "_xx"; suffix[1] = "_xy"; suffix[2] = "_yx"; suffix[3] = "_yy"; } else if ( ndim==3 ) { suffix[0] = "_xx"; suffix[1] = "_xy"; suffix[2] = "_xz"; suffix[3] = "_yx"; suffix[4] = "_yy"; suffix[5] = "_yz"; suffix[6] = "_zx"; suffix[7] = "_zy"; suffix[8] = "_zz"; } else { ERROR("Not finished"); } } else { for (int i=0; i void writeUniformMesh( DBfile* fid, const std::string& meshname, const std::array& range, const std::array& N ) { PROFILE_START("writeUniformMesh",2); int dims[NDIM]; for (size_t d=0; d= 1 ) { x = new float[dims[0]]; for (int i=0; i= 2 ) { y = new float[dims[1]]; for (int i=0; i= 3 ) { z = new float[dims[2]]; for (int i=0; i void writeUniformMeshVariable( DBfile* fid, const std::string& meshname, const std::array& N, const std::string& varname, const Array& data, VariableType type ) { PROFILE_START("writeUniformMeshVariable",2); int nvars=1, dims[NDIM]={1}; const TYPE *vars[NDIM] = { nullptr }; int vartype = 0; if ( type == VariableType::NodeVariable ) { ASSERT( data.ndim()==NDIM || data.ndim()==NDIM+1 ); for (int d=0; d var_names(nvars); for (int i=0; i varnames(nvars,nullptr); for (int i=0; i(var_names[i].c_str()); int err = DBPutQuadvar( fid, varname.c_str(), meshname.c_str(), nvars, varnames.data(), vars, dims, NDIM, nullptr, 0, getType(), vartype, nullptr ); ASSERT( err == 0 ); PROFILE_STOP("writeUniformMeshVariable",2); } template Array readUniformMeshVariable( DBfile* fid, const std::string& varname ) { auto var = DBGetQuadvar( fid, varname.c_str() ); ASSERT( var != nullptr ); Array data( var->nels, var->nvals ); int type = var->datatype; for (int i=0; invals; i++) { Array data2( var->nels ); copyData( data2, type, var->vals[i] ); memcpy( &data(0,i), data2.data(), var->nels*sizeof(TYPE) ); } DBFreeQuadvar( var ); std::vector dims( var->ndims+1, var->nvals ); for (int d=0; dndims; d++) dims[d] = var->dims[d]; data.reshape( dims ); return data; } /**************************************************** * Read/write a point mesh/variable to silo * ****************************************************/ template void writePointMesh( DBfile* fid, const std::string& meshname, int ndim, int N, const TYPE *coords[] ) { int err = DBPutPointmesh( fid, meshname.c_str(), ndim, coords, N, getType(), nullptr ); ASSERT( err == 0 ); } template Array readPointMesh( DBfile* fid, const std::string& meshname ) { auto mesh = DBGetPointmesh( fid, meshname.c_str() ); int N = mesh->nels; int ndim = mesh->ndims; Array coords(N,ndim); int type = mesh->datatype; for (int d=0; d data2( N ); copyData( data2, type, mesh->coords[d] ); memcpy( &coords(0,d), data2.data(), N*sizeof(TYPE) ); } DBFreePointmesh( mesh ); return coords; } template void writePointMeshVariable( DBfile* fid, const std::string& meshname, const std::string& varname, const Array& data ) { int N = data.size(0); int nvars = data.size(1); std::vector vars(nvars); for (int i=0; i(), nullptr ); ASSERT( err == 0 ); } template Array readPointMeshVariable( DBfile* fid, const std::string& varname ) { auto var = DBGetPointvar( fid, varname.c_str() ); ASSERT( var != nullptr ); Array data( var->nels, var->nvals ); int type = var->datatype; for (int i=0; invals; i++) { Array data2( var->nels ); copyData( data2, type, var->vals[i] ); memcpy( &data(0,i), data2.data(), var->nels*sizeof(TYPE) ); } DBFreeMeshvar( var ); return data; } /**************************************************** * Read/write a triangle mesh * ****************************************************/ template void writeTriMesh( DBfile* fid, const std::string& meshName, int ndim, int ndim_tri, int N, const TYPE *coords[], int N_tri, const int *tri[] ) { auto zoneName = meshName + "_zones"; std::vector nodelist( (ndim_tri+1)*N_tri ); for (int i=0, j=0; i(), nullptr ); } template void readTriMesh( DBfile* fid, const std::string& meshname, Array& coords, Array& tri ) { auto mesh = DBGetUcdmesh( fid, meshname.c_str() ); int ndim = mesh->ndims; int N_nodes = mesh->nnodes; coords.resize(N_nodes,ndim); int mesh_type = mesh->datatype; for (int d=0; d data2( N_nodes ); copyData( data2, mesh_type, mesh->coords[d] ); memcpy( &coords(0,d), data2.data(), N_nodes*sizeof(TYPE) ); } auto zones = mesh->zones; int N_zones = zones->nzones; ASSERT( zones->nshapes==1 ); int shapesize = zones->shapesize[0]; tri.resize(N_zones,shapesize); for (int i=0; inodelist[i*shapesize+j]; } DBFreeUcdmesh( mesh ); } template void writeTriMeshVariable( DBfile* fid, int ndim, const std::string& meshname, const std::string& varname, const Array& data, VariableType type ) { int nvars = 0; int vartype = 0; const TYPE *vars[10] = { nullptr }; if ( type == VariableType::NodeVariable ) { vartype = DB_NODECENT; nvars = data.size(1); for (int i=0; i var_names(nvars); for (int i=0; i varnames(nvars,nullptr); for (int i=0; i(var_names[i].c_str()); DBPutUcdvar( fid, varname.c_str(), meshname.c_str(), nvars, varnames.data(), vars, data.size(0), nullptr, 0, getType(), vartype, nullptr ); } template Array readTriMeshVariable( DBfile* fid, const std::string& varname ) { auto var = DBGetUcdvar( fid, varname.c_str() ); ASSERT( var != nullptr ); Array data( var->nels, var->nvals ); int type = var->datatype; for (int i=0; invals; i++) { Array data2( var->nels ); copyData( data2, type, var->vals[i] ); memcpy( &data(0,i), data2.data(), var->nels*sizeof(TYPE) ); } DBFreeUcdvar( var ); return data; } }; // silo namespace #endif #endif