1 //------------------------------------------------------------------------- 2 // Filename : ReadNC.hpp 3 // 4 // Purpose : Climate NC file reader 5 // 6 // Creator : Tim Tautges 7 //------------------------------------------------------------------------- 8 9 #ifndef READNC_HPP 10 #define READNC_HPP 11 12 #ifndef IS_BUILDING_MB 13 #error "ReadNC.hpp isn't supposed to be included into an application" 14 #endif 15 16 #include <vector> 17 #include <map> 18 #include <set> 19 #include <string> 20 21 #include "moab/ReaderIface.hpp" 22 #include "moab/ScdInterface.hpp" 23 #include "DebugOutput.hpp" 24 25 #ifdef MOAB_HAVE_MPI 26 #include "moab_mpi.h" 27 #include "moab/ParallelComm.hpp" 28 #endif 29 30 #ifdef MOAB_HAVE_PNETCDF 31 #include "pnetcdf.h" 32 #define NCFUNC(func) ncmpi_ ## func 33 34 //! Collective I/O mode get 35 #define NCFUNCAG(func) ncmpi_get ## func ## _all 36 37 //! Independent I/O mode get 38 #define NCFUNCG(func) ncmpi_get ## func 39 40 //! Nonblocking get (request aggregation), used so far only for ucd mesh 41 #define NCFUNCREQG(func) ncmpi_iget ## func 42 43 #define NCDF_SIZE MPI_Offset 44 #define NCDF_DIFF MPI_Offset 45 #else 46 #include "netcdf.h" 47 #define NCFUNC(func) nc_ ## func 48 #define NCFUNCAG(func) nc_get ## func 49 #define NCFUNCG(func) nc_get ## func 50 #define NCDF_SIZE size_t 51 #define NCDF_DIFF ptrdiff_t 52 #endif 53 54 namespace moab { 55 56 class ReadUtilIface; 57 class ScdInterface; 58 class NCHelper; 59 60 //! Output Exodus File for VERDE 61 class ReadNC : public ReaderIface 62 { 63 friend class NCHelper; 64 friend class ScdNCHelper; 65 friend class UcdNCHelper; 66 friend class NCHelperEuler; 67 friend class NCHelperFV; 68 friend class NCHelperHOMME; 69 friend class NCHelperMPAS; 70 friend class NCHelperGCRM; 71 72 public: 73 74 static ReaderIface* factory(Interface*); 75 76 //! Load an NC file 77 ErrorCode load_file(const char* file_name, 78 const EntityHandle* file_set, 79 const FileOptions& opts, 80 const SubsetList* subset_list = 0, 81 const Tag* file_id_tag = 0); 82 83 //! Constructor 84 ReadNC(Interface* impl = NULL); 85 86 //! Destructor 87 virtual ~ReadNC(); 88 89 virtual ErrorCode read_tag_values(const char* file_name, 90 const char* tag_name, 91 const FileOptions& opts, 92 std::vector<int>& tag_values_out, 93 const SubsetList* subset_list = 0); 94 95 //! ENTLOCNSEDGE for north/south edge 96 //! ENTLOCWEEDGE for west/east edge 97 enum EntityLocation {ENTLOCVERT = 0, ENTLOCNSEDGE, ENTLOCEWEDGE, ENTLOCFACE, ENTLOCSET, ENTLOCEDGE, ENTLOCREGION}; 98 99 private: 100 101 class AttData 102 { 103 public: AttData()104 AttData() : attId(-1), attLen(0), attVarId(-2) {} 105 int attId; 106 NCDF_SIZE attLen; 107 int attVarId; 108 nc_type attDataType; 109 std::string attName; 110 }; 111 112 class VarData 113 { 114 public: VarData()115 VarData() : varId(-1), numAtts(-1), entLoc(ENTLOCSET), numLev(0), sz(0), has_tsteps(false) {} 116 int varId; 117 int numAtts; 118 nc_type varDataType; 119 std::vector<int> varDims; // The dimension indices making up this multi-dimensional variable 120 std::map<std::string, AttData> varAtts; 121 std::string varName; 122 std::vector<Tag> varTags; // Tags created for this variable, e.g. one tag per timestep 123 std::vector<void*> varDatas; 124 std::vector<NCDF_SIZE> readStarts; // Starting index for reading data values along each dimension 125 std::vector<NCDF_SIZE> readCounts; // Number of data values to be read along each dimension 126 int entLoc; 127 int numLev; 128 int sz; 129 bool has_tsteps; // Indicate whether timestep numbers are appended to tag names 130 }; 131 132 ReadUtilIface* readMeshIface; 133 134 //! Read the header information 135 ErrorCode read_header(); 136 137 //! Get all global attributes in the file 138 ErrorCode get_attributes(int var_id, int num_atts, std::map<std::string, AttData>& atts, 139 const char* prefix = ""); 140 141 //! Get all dimensions in the file 142 ErrorCode get_dimensions(int file_id, std::vector<std::string>& dim_names, std::vector<int>& dim_lens); 143 144 //! Get the variable names and other info defined for this file 145 ErrorCode get_variables(); 146 147 ErrorCode parse_options(const FileOptions& opts, 148 std::vector<std::string>& var_names, 149 std::vector<int>& tstep_nums, 150 std::vector<double>& tstep_vals); 151 152 //------------member variables ------------// 153 154 //! Interface instance 155 Interface* mbImpl; 156 157 //! File name 158 std::string fileName; 159 160 //! File numbers assigned by netcdf 161 int fileId; 162 163 //! Dimension names 164 std::vector<std::string> dimNames; 165 166 //! Dimension lengths 167 std::vector<int> dimLens; 168 169 //! Global attribs 170 std::map<std::string, AttData> globalAtts; 171 172 //! Variable info 173 std::map<std::string, VarData> varInfo; 174 175 //! Cached tags for reading. Note that all these tags are defined when the 176 //! core is initialized. 177 Tag mGlobalIdTag; 178 179 //! This is a pointer to the file id tag that is passed from ReadParallel 180 //! it gets deleted at the end of resolve sharing, but it will have same data 181 //! as the global id tag 182 //! global id tag is preserved, and is needed later on. 183 const Tag* mpFileIdTag; 184 185 //! Debug stuff 186 DebugOutput dbgOut; 187 188 //! Are we reading in parallel? 189 bool isParallel; 190 191 //! Partitioning method 192 int partMethod; 193 194 //! Scd interface 195 ScdInterface* scdi; 196 197 //! Parallel data object, to be cached with ScdBox 198 ScdParData parData; 199 200 #ifdef MOAB_HAVE_MPI 201 ParallelComm* myPcomm; 202 #endif 203 204 //! Read options 205 bool noMesh; 206 bool noVars; 207 bool spectralMesh; 208 bool noMixedElements; 209 bool noEdges; 210 int gatherSetRank; 211 int tStepBase; 212 int trivialPartitionShift; 213 214 //! Helper class instance 215 NCHelper* myHelper; 216 }; 217 218 } // namespace moab 219 220 #endif 221