Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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 // An object to hold vertex coordinates, and an operator 00051 // for storing them in a STL tree-based container. use a tolerance saved somewhere as 1.e-12 00052 class Node3D 00053 { 00054 public: 00055 double coords[3]; 00056 bool operator<( const Node3D& ) const; 00057 Node3D( double x, double y, double z ) 00058 { 00059 coords[0] = x; 00060 coords[1] = y; 00061 coords[2] = z; 00062 } 00063 }; 00064 00065 protected: 00066 //! Separate set and non-set variables (common to scd mesh and ucd mesh) 00067 ErrorCode read_variables_setup( std::vector< std::string >& var_names, 00068 std::vector< int >& tstep_nums, 00069 std::vector< ReadNC::VarData >& vdatas, 00070 std::vector< ReadNC::VarData >& vsetdatas ); 00071 00072 //! Read set variables (common to scd mesh and ucd mesh) 00073 ErrorCode read_variables_to_set( std::vector< ReadNC::VarData >& vdatas, std::vector< int >& tstep_nums ); 00074 00075 ErrorCode read_coordinate( const char* var_name, int lmin, int lmax, std::vector< double >& cvals ); 00076 00077 ErrorCode get_tag_to_set( ReadNC::VarData& var_data, int tstep_num, Tag& tagh ); 00078 00079 ErrorCode get_tag_to_nonset( ReadNC::VarData& var_data, int tstep_num, Tag& tagh, int num_lev ); 00080 00081 //! Create a character string attString of attMap. with '\0' 00082 //! terminating each attribute name, ';' separating the data type 00083 //! and value, and ';' separating one name/data type/value from 00084 //! the next'. attLen stores the end position for each name/data 00085 //! type/ value. 00086 ErrorCode create_attrib_string( const std::map< std::string, ReadNC::AttData >& attMap, 00087 std::string& attString, 00088 std::vector< int >& attLen ); 00089 00090 //! For a dimension that does not have a corresponding coordinate variable (e.g. ncol for 00091 //! HOMME), create a dummy variable with a sparse tag to store the dimension length 00092 ErrorCode create_dummy_variables(); 00093 00094 private: 00095 //! Used by read_variables_to_set() 00096 ErrorCode read_variables_to_set_allocate( std::vector< ReadNC::VarData >& vdatas, std::vector< int >& tstep_nums ); 00097 00098 protected: 00099 //! Allow NCHelper to directly access members of ReadNC 00100 ReadNC* _readNC; 00101 00102 //! Cache some information from ReadNC 00103 int _fileId; 00104 const FileOptions& _opts; 00105 EntityHandle _fileSet; 00106 00107 //! Dimensions of time and level 00108 int nTimeSteps, nLevels; 00109 00110 //! Values for time and level 00111 std::vector< double > tVals, levVals; 00112 00113 //! Dimension numbers for time and level 00114 int tDim, levDim; 00115 00116 //! Ignored variables 00117 std::set< std::string > ignoredVarNames; 00118 00119 //! Dummy variables 00120 std::set< std::string > dummyVarNames; 00121 }; 00122 00123 //! Child helper class for scd mesh, e.g. CAM_EL or CAM_FV 00124 class ScdNCHelper : public NCHelper 00125 { 00126 public: 00127 ScdNCHelper( ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet ) 00128 : NCHelper( readNC, fileId, opts, fileSet ), iDim( -1 ), jDim( -1 ), iCDim( -1 ), jCDim( -1 ) 00129 { 00130 for( unsigned int i = 0; i < 6; i++ ) 00131 { 00132 gDims[i] = -1; 00133 lDims[i] = -1; 00134 gCDims[i] = -1; 00135 lCDims[i] = -1; 00136 } 00137 00138 locallyPeriodic[0] = locallyPeriodic[1] = locallyPeriodic[2] = 0; 00139 globallyPeriodic[0] = globallyPeriodic[1] = globallyPeriodic[2] = 0; 00140 } 00141 virtual ~ScdNCHelper() {} 00142 00143 private: 00144 //! Implementation of NCHelper::check_existing_mesh() 00145 virtual ErrorCode check_existing_mesh(); 00146 //! Implementation of NCHelper::create_mesh() 00147 virtual ErrorCode create_mesh( Range& faces ); 00148 //! Implementation of NCHelper::read_variables() 00149 virtual ErrorCode read_variables( std::vector< std::string >& var_names, std::vector< int >& tstep_nums ); 00150 00151 //! Read non-set variables for scd mesh 00152 ErrorCode read_scd_variables_to_nonset_allocate( std::vector< ReadNC::VarData >& vdatas, 00153 std::vector< int >& tstep_nums ); 00154 ErrorCode read_scd_variables_to_nonset( std::vector< ReadNC::VarData >& vdatas, std::vector< int >& tstep_nums ); 00155 00156 //! Create COORDS tag for quads coordinate 00157 ErrorCode create_quad_coordinate_tag(); 00158 00159 template < typename T > 00160 void kji_to_jik( size_t ni, size_t nj, size_t nk, void* dest, T* source ) 00161 { 00162 size_t nik = ni * nk, nij = ni * nj; 00163 T* tmp_data = reinterpret_cast< T* >( dest ); 00164 for( std::size_t j = 0; j != nj; j++ ) 00165 for( std::size_t i = 0; i != ni; i++ ) 00166 for( std::size_t k = 0; k != nk; k++ ) 00167 tmp_data[j * nik + i * nk + k] = source[k * nij + j * ni + i]; 00168 } 00169 00170 protected: 00171 //! Dimensions of global grid in file 00172 int gDims[6]; 00173 00174 //! Dimensions of my local part of grid 00175 int lDims[6]; 00176 00177 //! Center dimensions of global grid in file 00178 int gCDims[6]; 00179 00180 //! Center dimensions of my local part of grid 00181 int lCDims[6]; 00182 00183 //! Values for i/j 00184 std::vector< double > ilVals, jlVals; 00185 00186 //! Center values for i/j 00187 std::vector< double > ilCVals, jlCVals; 00188 00189 //! Dimension numbers for i/j 00190 int iDim, jDim; 00191 00192 //! Center dimension numbers for i/j 00193 int iCDim, jCDim; 00194 00195 //! Whether mesh is locally periodic in i or j or k 00196 int locallyPeriodic[3]; 00197 00198 //! Whether mesh is globally periodic in i or j or k 00199 int globallyPeriodic[3]; 00200 }; 00201 00202 //! Child helper class for ucd mesh, e.g. CAM_SE (HOMME) or MPAS 00203 class UcdNCHelper : public NCHelper 00204 { 00205 public: 00206 UcdNCHelper( ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet ) 00207 : NCHelper( readNC, fileId, opts, fileSet ), nCells( 0 ), nEdges( 0 ), nVertices( 0 ), nLocalCells( 0 ), 00208 nLocalEdges( 0 ), nLocalVertices( 0 ), cDim( -1 ), eDim( -1 ), vDim( -1 ) 00209 { 00210 } 00211 virtual ~UcdNCHelper() {} 00212 00213 private: 00214 //! Implementation of NCHelper::read_variables() 00215 virtual ErrorCode read_variables( std::vector< std::string >& var_names, std::vector< int >& tstep_nums ); 00216 00217 //! Read non-set variables for ucd mesh (implemented differently in child classes) 00218 virtual ErrorCode read_ucd_variables_to_nonset_allocate( std::vector< ReadNC::VarData >& vdatas, 00219 std::vector< int >& tstep_nums ) = 0; 00220 #ifdef MOAB_HAVE_PNETCDF 00221 virtual ErrorCode read_ucd_variables_to_nonset_async( std::vector< ReadNC::VarData >& vdatas, 00222 std::vector< int >& tstep_nums ) = 0; 00223 #else 00224 virtual ErrorCode read_ucd_variables_to_nonset( std::vector< ReadNC::VarData >& vdatas, 00225 std::vector< int >& tstep_nums ) = 0; 00226 #endif 00227 00228 protected: 00229 //! This version takes as input the moab range, from which we actually need just the 00230 //! size of each sequence, for a proper transpose of the data 00231 template < typename T > 00232 void kji_to_jik_stride( size_t, size_t nj, size_t nk, void* dest, T* source, Range& localGid ) 00233 { 00234 std::size_t idxInSource = 0; // Position of the start of the stride 00235 // For each subrange, we will transpose a matrix of size 00236 // subrange*nj*nk (subrange takes the role of ni) 00237 T* tmp_data = reinterpret_cast< T* >( dest ); 00238 for( Range::pair_iterator pair_iter = localGid.pair_begin(); pair_iter != localGid.pair_end(); ++pair_iter ) 00239 { 00240 std::size_t size_range = pair_iter->second - pair_iter->first + 1; 00241 std::size_t nik = size_range * nk, nij = size_range * nj; 00242 for( std::size_t j = 0; j != nj; j++ ) 00243 for( std::size_t i = 0; i != size_range; i++ ) 00244 for( std::size_t k = 0; k != nk; k++ ) 00245 tmp_data[idxInSource + j * nik + i * nk + k] = 00246 source[idxInSource + k * nij + j * size_range + i]; 00247 idxInSource += ( size_range * nj * nk ); 00248 } 00249 } 00250 00251 //! Dimensions of global grid in file 00252 int nCells; 00253 int nEdges; 00254 int nVertices; 00255 00256 //! Dimensions of my local part of grid 00257 int nLocalCells; 00258 int nLocalEdges; 00259 int nLocalVertices; 00260 00261 //! Coordinate values for vertices 00262 std::vector< double > xVertVals, yVertVals, zVertVals; 00263 00264 //! Dimension numbers for nCells, nEdges and nVertices 00265 int cDim, eDim, vDim; 00266 00267 //! Local global ID for cells, edges and vertices 00268 Range localGidCells, localGidEdges, localGidVerts; 00269 }; 00270 00271 } // namespace moab 00272 00273 #endif