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