![]() |
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