MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 //------------------------------------------------------------------------- 00002 // Filename : NCHelper.hpp 00003 // 00004 // Purpose : Climate NC file helper 00005 // 00006 // Creator : Danqing Wu 00007 //------------------------------------------------------------------------- 00008 00009 #ifndef NCHELPER_HPP 00010 #define NCHELPER_HPP 00011 00012 #include "ReadNC.hpp" 00013 00014 #ifdef WIN32 00015 #ifdef size_t 00016 #undef size_t 00017 #endif 00018 #endif 00019 00020 namespace moab 00021 { 00022 00023 //! Helper class to isolate reading of several different nc file formats 00024 class NCHelper 00025 { 00026 public: 00027 NCHelper( ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet ) 00028 : _readNC( readNC ), _fileId( fileId ), _opts( opts ), _fileSet( fileSet ), nTimeSteps( 0 ), nLevels( 1 ), 00029 tDim( -1 ), levDim( -1 ) 00030 { 00031 } 00032 virtual ~NCHelper() {} 00033 00034 //! Get appropriate helper instance for ReadNC class 00035 static NCHelper* get_nc_helper( ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet ); 00036 00037 //! Interfaces to be implemented in child classes 00038 virtual ErrorCode init_mesh_vals() = 0; 00039 virtual ErrorCode check_existing_mesh() = 0; 00040 virtual ErrorCode create_mesh( Range& faces ) = 0; 00041 virtual ErrorCode read_variables( std::vector< std::string >& var_names, std::vector< int >& tstep_nums ) = 0; 00042 virtual std::string get_mesh_type_name() = 0; 00043 00044 //! Create NC conventional tags 00045 ErrorCode create_conventional_tags( const std::vector< int >& tstep_nums ); 00046 00047 //! Update time tag values if timesteps spread across files 00048 ErrorCode update_time_tag_vals(); 00049 00050 protected: 00051 //! Separate set and non-set variables (common to scd mesh and ucd mesh) 00052 ErrorCode read_variables_setup( std::vector< std::string >& var_names, std::vector< int >& tstep_nums, 00053 std::vector< ReadNC::VarData >& vdatas, std::vector< ReadNC::VarData >& vsetdatas ); 00054 00055 //! Read set variables (common to scd mesh and ucd mesh) 00056 ErrorCode read_variables_to_set( std::vector< ReadNC::VarData >& vdatas, std::vector< int >& tstep_nums ); 00057 00058 ErrorCode read_coordinate( const char* var_name, int lmin, int lmax, std::vector< double >& cvals ); 00059 00060 ErrorCode get_tag_to_set( ReadNC::VarData& var_data, int tstep_num, Tag& tagh ); 00061 00062 ErrorCode get_tag_to_nonset( ReadNC::VarData& var_data, int tstep_num, Tag& tagh, int num_lev ); 00063 00064 //! Create a character string attString of attMap. with '\0' 00065 //! terminating each attribute name, ';' separating the data type 00066 //! and value, and ';' separating one name/data type/value from 00067 //! the next'. attLen stores the end position for each name/data 00068 //! type/ value. 00069 ErrorCode create_attrib_string( const std::map< std::string, ReadNC::AttData >& attMap, std::string& attString, 00070 std::vector< int >& attLen ); 00071 00072 //! For a dimension that does not have a corresponding coordinate variable (e.g. ncol for 00073 //! HOMME), create a dummy variable with a sparse tag to store the dimension length 00074 ErrorCode create_dummy_variables(); 00075 00076 private: 00077 //! Used by read_variables_to_set() 00078 ErrorCode read_variables_to_set_allocate( std::vector< ReadNC::VarData >& vdatas, std::vector< int >& tstep_nums ); 00079 00080 protected: 00081 //! Allow NCHelper to directly access members of ReadNC 00082 ReadNC* _readNC; 00083 00084 //! Cache some information from ReadNC 00085 int _fileId; 00086 const FileOptions& _opts; 00087 EntityHandle _fileSet; 00088 00089 //! Dimensions of time and level 00090 int nTimeSteps, nLevels; 00091 00092 //! Values for time and level 00093 std::vector< double > tVals, levVals; 00094 00095 //! Dimension numbers for time and level 00096 int tDim, levDim; 00097 00098 //! Ignored variables 00099 std::set< std::string > ignoredVarNames; 00100 00101 //! Dummy variables 00102 std::set< std::string > dummyVarNames; 00103 }; 00104 00105 //! Child helper class for scd mesh, e.g. CAM_EL or CAM_FV 00106 class ScdNCHelper : public NCHelper 00107 { 00108 public: 00109 ScdNCHelper( ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet ) 00110 : NCHelper( readNC, fileId, opts, fileSet ), iDim( -1 ), jDim( -1 ), iCDim( -1 ), jCDim( -1 ) 00111 { 00112 for( unsigned int i = 0; i < 6; i++ ) 00113 { 00114 gDims[i] = -1; 00115 lDims[i] = -1; 00116 gCDims[i] = -1; 00117 lCDims[i] = -1; 00118 } 00119 00120 locallyPeriodic[0] = locallyPeriodic[1] = locallyPeriodic[2] = 0; 00121 globallyPeriodic[0] = globallyPeriodic[1] = globallyPeriodic[2] = 0; 00122 } 00123 virtual ~ScdNCHelper() {} 00124 00125 private: 00126 //! Implementation of NCHelper::check_existing_mesh() 00127 virtual ErrorCode check_existing_mesh(); 00128 //! Implementation of NCHelper::create_mesh() 00129 virtual ErrorCode create_mesh( Range& faces ); 00130 //! Implementation of NCHelper::read_variables() 00131 virtual ErrorCode read_variables( std::vector< std::string >& var_names, std::vector< int >& tstep_nums ); 00132 00133 //! Read non-set variables for scd mesh 00134 ErrorCode read_scd_variables_to_nonset_allocate( std::vector< ReadNC::VarData >& vdatas, 00135 std::vector< int >& tstep_nums ); 00136 ErrorCode read_scd_variables_to_nonset( std::vector< ReadNC::VarData >& vdatas, std::vector< int >& tstep_nums ); 00137 00138 //! Create COORDS tag for quads coordinate 00139 ErrorCode create_quad_coordinate_tag(); 00140 00141 template < typename T > 00142 void kji_to_jik( size_t ni, size_t nj, size_t nk, void* dest, T* source ) 00143 { 00144 size_t nik = ni * nk, nij = ni * nj; 00145 T* tmp_data = reinterpret_cast< T* >( dest ); 00146 for( std::size_t j = 0; j != nj; j++ ) 00147 for( std::size_t i = 0; i != ni; i++ ) 00148 for( std::size_t k = 0; k != nk; k++ ) 00149 tmp_data[j * nik + i * nk + k] = source[k * nij + j * ni + i]; 00150 } 00151 00152 protected: 00153 //! Dimensions of global grid in file 00154 int gDims[6]; 00155 00156 //! Dimensions of my local part of grid 00157 int lDims[6]; 00158 00159 //! Center dimensions of global grid in file 00160 int gCDims[6]; 00161 00162 //! Center dimensions of my local part of grid 00163 int lCDims[6]; 00164 00165 //! Values for i/j 00166 std::vector< double > ilVals, jlVals; 00167 00168 //! Center values for i/j 00169 std::vector< double > ilCVals, jlCVals; 00170 00171 //! Dimension numbers for i/j 00172 int iDim, jDim; 00173 00174 //! Center dimension numbers for i/j 00175 int iCDim, jCDim; 00176 00177 //! Whether mesh is locally periodic in i or j or k 00178 int locallyPeriodic[3]; 00179 00180 //! Whether mesh is globally periodic in i or j or k 00181 int globallyPeriodic[3]; 00182 }; 00183 00184 //! Child helper class for ucd mesh, e.g. CAM_SE (HOMME) or MPAS 00185 class UcdNCHelper : public NCHelper 00186 { 00187 public: 00188 UcdNCHelper( ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet ) 00189 : NCHelper( readNC, fileId, opts, fileSet ), nCells( 0 ), nEdges( 0 ), nVertices( 0 ), nLocalCells( 0 ), 00190 nLocalEdges( 0 ), nLocalVertices( 0 ), cDim( -1 ), eDim( -1 ), vDim( -1 ) 00191 { 00192 } 00193 virtual ~UcdNCHelper() {} 00194 00195 private: 00196 //! Implementation of NCHelper::read_variables() 00197 virtual ErrorCode read_variables( std::vector< std::string >& var_names, std::vector< int >& tstep_nums ); 00198 00199 //! Read non-set variables for ucd mesh (implemented differently in child classes) 00200 virtual ErrorCode read_ucd_variables_to_nonset_allocate( std::vector< ReadNC::VarData >& vdatas, 00201 std::vector< int >& tstep_nums ) = 0; 00202 #ifdef MOAB_HAVE_PNETCDF 00203 virtual ErrorCode read_ucd_variables_to_nonset_async( std::vector< ReadNC::VarData >& vdatas, 00204 std::vector< int >& tstep_nums ) = 0; 00205 #else 00206 virtual ErrorCode read_ucd_variables_to_nonset( std::vector< ReadNC::VarData >& vdatas, 00207 std::vector< int >& tstep_nums ) = 0; 00208 #endif 00209 00210 protected: 00211 //! This version takes as input the moab range, from which we actually need just the 00212 //! size of each sequence, for a proper transpose of the data 00213 template < typename T > 00214 void kji_to_jik_stride( size_t, size_t nj, size_t nk, void* dest, T* source, Range& localGid ) 00215 { 00216 std::size_t idxInSource = 0; // Position of the start of the stride 00217 // For each subrange, we will transpose a matrix of size 00218 // subrange*nj*nk (subrange takes the role of ni) 00219 T* tmp_data = reinterpret_cast< T* >( dest ); 00220 for( Range::pair_iterator pair_iter = localGid.pair_begin(); pair_iter != localGid.pair_end(); ++pair_iter ) 00221 { 00222 std::size_t size_range = pair_iter->second - pair_iter->first + 1; 00223 std::size_t nik = size_range * nk, nij = size_range * nj; 00224 for( std::size_t j = 0; j != nj; j++ ) 00225 for( std::size_t i = 0; i != size_range; i++ ) 00226 for( std::size_t k = 0; k != nk; k++ ) 00227 tmp_data[idxInSource + j * nik + i * nk + k] = 00228 source[idxInSource + k * nij + j * size_range + i]; 00229 idxInSource += ( size_range * nj * nk ); 00230 } 00231 } 00232 00233 //! Dimensions of global grid in file 00234 int nCells; 00235 int nEdges; 00236 int nVertices; 00237 00238 //! Dimensions of my local part of grid 00239 int nLocalCells; 00240 int nLocalEdges; 00241 int nLocalVertices; 00242 00243 //! Coordinate values for vertices 00244 std::vector< double > xVertVals, yVertVals, zVertVals; 00245 00246 //! Dimension numbers for nCells, nEdges and nVertices 00247 int cDim, eDim, vDim; 00248 00249 //! Local global ID for cells, edges and vertices 00250 Range localGidCells, localGidEdges, localGidVerts; 00251 }; 00252 00253 } // namespace moab 00254 00255 #endif