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