Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
WriteNC.hpp
Go to the documentation of this file.
1 /**
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation. Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7  * retains certain rights in this software.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  */
15 
16 #ifndef WRITENC_HPP_
17 #define WRITENC_HPP_
18 
19 #ifndef IS_BUILDING_MB
20 #error "WriteNC.hpp isn't supposed to be included into an application"
21 #endif
22 
23 #include <vector>
24 #include <map>
25 #include <set>
26 #include <string>
27 
28 #include "moab/WriterIface.hpp"
29 #include "moab/ScdInterface.hpp"
30 #include "DebugOutput.hpp"
31 
32 #ifdef MOAB_HAVE_MPI
33 #include "moab_mpi.h"
34 #include "moab/ParallelComm.hpp"
35 #endif
36 
37 #ifdef MOAB_HAVE_PNETCDF
38 #include "pnetcdf.h"
39 #define NCFUNC( func ) ncmpi_##func
40 
41 //! Collective I/O mode put
42 #define NCFUNCAP( func ) ncmpi_put##func##_all
43 
44 //! Independent I/O mode put
45 #define NCFUNCP( func ) ncmpi_put##func
46 
47 //! Nonblocking put (request aggregation)
48 #define NCFUNCREQP( func ) ncmpi_iput##func
49 
50 #define NCDF_SIZE MPI_Offset
51 #define NCDF_DIFF MPI_Offset
52 #else
53 #include "netcdf.h"
54 #define NCFUNC( func ) nc_##func
55 #define NCFUNCAP( func ) nc_put##func
56 #define NCFUNCP( func ) nc_put##func
57 #define NCDF_SIZE size_t
58 #define NCDF_DIFF ptrdiff_t
59 #endif
60 
61 namespace moab
62 {
63 
64 class WriteUtilIface;
65 class NCWriteHelper;
66 
67 /**
68  * \brief Export NC files.
69  */
70 class WriteNC : public WriterIface
71 {
72  friend class NCWriteHelper;
73  friend class ScdNCWriteHelper;
74  friend class UcdNCWriteHelper;
75  friend class NCWriteEuler;
76  friend class NCWriteFV;
77  friend class NCWriteHOMME;
78  friend class NCWriteMPAS;
79  friend class NCWriteGCRM;
80 
81  public:
82  //! Factory method
83  static WriterIface* factory( Interface* );
84 
85  //! Constructor
86  WriteNC( Interface* impl = NULL );
87 
88  //! Destructor
89  virtual ~WriteNC();
90 
91  //! Writes out a file
92  ErrorCode write_file( const char* file_name,
93  const bool overwrite,
94  const FileOptions& opts,
95  const EntityHandle* output_list,
96  const int num_sets,
97  const std::vector< std::string >& qa_list,
98  const Tag* tag_list = NULL,
99  int num_tags = 0,
100  int export_dimension = 3 );
101 
102  private:
103  //! ENTLOCNSEDGE for north/south edge
104  //! ENTLOCWEEDGE for west/east edge
106  {
114  };
115 
116  class AttData
117  {
118  public:
119  AttData() : attId( -1 ), attLen( 0 ), attVarId( -2 ), attDataType( NC_NAT ) {}
120  int attId;
122  int attVarId;
123  nc_type attDataType;
124  std::string attValue;
125  };
126 
127  class VarData
128  {
129  public:
130  VarData() : varId( -1 ), numAtts( -1 ), entLoc( ENTLOCSET ), numLev( 0 ), sz( 0 ), has_tsteps( false ) {}
131  int varId;
132  int numAtts;
133  nc_type varDataType;
134  std::vector< int > varDims; // The dimension indices making up this multi-dimensional variable
135  std::map< std::string, AttData > varAtts;
136  std::string varName;
137  std::vector< Tag > varTags; // Tags created for this variable, e.g. one tag per timestep
138  std::vector< void* > memoryHogs; // These will point to the real data; fill before writing the data
139  std::vector< NCDF_SIZE > writeStarts; // Starting index for writing data values along each dimension
140  std::vector< NCDF_SIZE > writeCounts; // Number of data values to be written along each dimension
141  int entLoc;
142  int numLev;
143  int sz;
144  bool has_tsteps; // Indicate whether timestep numbers are appended to tag names
145  };
146 
147  //! This info will be reconstructed from metadata stored on conventional fileSet tags
148  //! Dimension names
149  std::vector< std::string > dimNames;
150 
151  //! Dimension lengths
152  std::vector< int > dimLens;
153 
154  //! Will collect used dimensions (coordinate variables)
155  std::set< std::string > usedCoordinates;
156 
157  //! Dummy variables (for dimensions that have no corresponding coordinate variables)
158  std::set< std::string > dummyVarNames;
159 
160  //! Global attribs
161  std::map< std::string, AttData > globalAtts;
162 
163  //! Variable info
164  std::map< std::string, VarData > varInfo;
165 
166  ErrorCode parse_options( const FileOptions& opts,
167  std::vector< std::string >& var_names,
168  std::vector< std::string >& desired_names,
169  std::vector< int >& tstep_nums,
170  std::vector< double >& tstep_vals );
171  /*
172  * Map out the header, from tags on file set; it is the inverse process from
173  * ErrorCode NCHelper::create_conventional_tags
174  */
176 
177  ErrorCode process_concatenated_attribute( const void* attPtr,
178  int attSz,
179  std::vector< int >& attLen,
180  std::map< std::string, AttData >& attributes );
181 
182  //! Interface instance
185 
186  //! File var
187  const char* fileName;
188 
189  //! File numbers assigned by (p)netcdf
190  int fileId;
191 
192  //! Debug stuff
194 
195 #ifdef MOAB_HAVE_MPI
196  ParallelComm* myPcomm;
197 #endif
198 
199  //! Write options
200  bool noMesh;
201  bool noVars;
202  bool append;
203 
204  //! Cached tags for writing. This will be important for ordering the data, in parallel
206 
207  //! Are we writing in parallel? (probably in the future)
209 
210  //! CAM Euler, etc,
211  std::string grid_type;
212 
213  //! Helper class instance
215 };
216 
217 } // namespace moab
218 
219 #endif