Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
WriteNC.hpp
Go to the documentation of this file.
00001 /**
00002  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003  * storing and accessing finite element mesh data.
00004  *
00005  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
00006  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007  * retains certain rights in this software.
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  */
00015 
00016 #ifndef WRITENC_HPP_
00017 #define WRITENC_HPP_
00018 
00019 #ifndef IS_BUILDING_MB
00020 #error "WriteNC.hpp isn't supposed to be included into an application"
00021 #endif
00022 
00023 #include <vector>
00024 #include <map>
00025 #include <set>
00026 #include <string>
00027 
00028 #include "moab/WriterIface.hpp"
00029 #include "moab/ScdInterface.hpp"
00030 #include "DebugOutput.hpp"
00031 
00032 #ifdef MOAB_HAVE_MPI
00033 #include "moab_mpi.h"
00034 #include "moab/ParallelComm.hpp"
00035 #endif
00036 
00037 #ifdef MOAB_HAVE_PNETCDF
00038 #include "pnetcdf.h"
00039 #define NCFUNC( func ) ncmpi_##func
00040 
00041 //! Collective I/O mode put
00042 #define NCFUNCAP( func ) ncmpi_put##func##_all
00043 
00044 //! Independent I/O mode put
00045 #define NCFUNCP( func ) ncmpi_put##func
00046 
00047 //! Nonblocking put (request aggregation)
00048 #define NCFUNCREQP( func ) ncmpi_iput##func
00049 
00050 #define NCDF_SIZE MPI_Offset
00051 #define NCDF_DIFF MPI_Offset
00052 #else
00053 #include "netcdf.h"
00054 #define NCFUNC( func )   nc_##func
00055 #define NCFUNCAP( func ) nc_put##func
00056 #define NCFUNCP( func )  nc_put##func
00057 #define NCDF_SIZE        size_t
00058 #define NCDF_DIFF        ptrdiff_t
00059 #endif
00060 
00061 namespace moab
00062 {
00063 
00064 class WriteUtilIface;
00065 class NCWriteHelper;
00066 
00067 /**
00068  * \brief Export NC files.
00069  */
00070 class WriteNC : public WriterIface
00071 {
00072     friend class NCWriteHelper;
00073     friend class ScdNCWriteHelper;
00074     friend class UcdNCWriteHelper;
00075     friend class NCWriteEuler;
00076     friend class NCWriteFV;
00077     friend class NCWriteHOMME;
00078     friend class NCWriteMPAS;
00079     friend class NCWriteGCRM;
00080 
00081   public:
00082     //! Factory method
00083     static WriterIface* factory( Interface* );
00084 
00085     //! Constructor
00086     WriteNC( Interface* impl = NULL );
00087 
00088     //! Destructor
00089     virtual ~WriteNC();
00090 
00091     //! Writes out a file
00092     ErrorCode write_file( const char* file_name,
00093                           const bool overwrite,
00094                           const FileOptions& opts,
00095                           const EntityHandle* output_list,
00096                           const int num_sets,
00097                           const std::vector< std::string >& qa_list,
00098                           const Tag* tag_list  = NULL,
00099                           int num_tags         = 0,
00100                           int export_dimension = 3 );
00101 
00102   private:
00103     //! ENTLOCNSEDGE for north/south edge
00104     //! ENTLOCWEEDGE for west/east edge
00105     enum EntityLocation
00106     {
00107         ENTLOCVERT = 0,
00108         ENTLOCNSEDGE,
00109         ENTLOCEWEDGE,
00110         ENTLOCFACE,
00111         ENTLOCSET,
00112         ENTLOCEDGE,
00113         ENTLOCREGION
00114     };
00115 
00116     class AttData
00117     {
00118       public:
00119         AttData() : attId( -1 ), attLen( 0 ), attVarId( -2 ), attDataType( NC_NAT ) {}
00120         int attId;
00121         NCDF_SIZE attLen;
00122         int attVarId;
00123         nc_type attDataType;
00124         std::string attValue;
00125     };
00126 
00127     class VarData
00128     {
00129       public:
00130         VarData() : varId( -1 ), numAtts( -1 ), entLoc( ENTLOCSET ), numLev( 0 ), sz( 0 ), has_tsteps( false ) {}
00131         int varId;
00132         int numAtts;
00133         nc_type varDataType;
00134         std::vector< int > varDims;  // The dimension indices making up this multi-dimensional variable
00135         std::map< std::string, AttData > varAtts;
00136         std::string varName;
00137         std::vector< Tag > varTags;            // Tags created for this variable, e.g. one tag per timestep
00138         std::vector< void* > memoryHogs;       // These will point to the real data; fill before writing the data
00139         std::vector< NCDF_SIZE > writeStarts;  // Starting index for writing data values along each dimension
00140         std::vector< NCDF_SIZE > writeCounts;  // Number of data values to be written along each dimension
00141         int entLoc;
00142         int numLev;
00143         int sz;
00144         bool has_tsteps;  // Indicate whether timestep numbers are appended to tag names
00145     };
00146 
00147     //! This info will be reconstructed from metadata stored on conventional fileSet tags
00148     //! Dimension names
00149     std::vector< std::string > dimNames;
00150 
00151     //! Dimension lengths
00152     std::vector< int > dimLens;
00153 
00154     //! Will collect used dimensions (coordinate variables)
00155     std::set< std::string > usedCoordinates;
00156 
00157     //! Dummy variables (for dimensions that have no corresponding coordinate variables)
00158     std::set< std::string > dummyVarNames;
00159 
00160     //! Global attribs
00161     std::map< std::string, AttData > globalAtts;
00162 
00163     //! Variable info
00164     std::map< std::string, VarData > varInfo;
00165 
00166     ErrorCode parse_options( const FileOptions& opts,
00167                              std::vector< std::string >& var_names,
00168                              std::vector< std::string >& desired_names,
00169                              std::vector< int >& tstep_nums,
00170                              std::vector< double >& tstep_vals );
00171     /*
00172      * Map out the header, from tags on file set; it is the inverse process from
00173      * ErrorCode NCHelper::create_conventional_tags
00174      */
00175     ErrorCode process_conventional_tags( EntityHandle fileSet );
00176 
00177     ErrorCode process_concatenated_attribute( const void* attPtr,
00178                                               int attSz,
00179                                               std::vector< int >& attLen,
00180                                               std::map< std::string, AttData >& attributes );
00181 
00182     //! Interface instance
00183     Interface* mbImpl;
00184     WriteUtilIface* mWriteIface;
00185 
00186     //! File var
00187     const char* fileName;
00188 
00189     //! File numbers assigned by (p)netcdf
00190     int fileId;
00191 
00192     //! Debug stuff
00193     DebugOutput dbgOut;
00194 
00195 #ifdef MOAB_HAVE_MPI
00196     ParallelComm* myPcomm;
00197 #endif
00198 
00199     //! Write options
00200     bool noMesh;
00201     bool noVars;
00202     bool append;
00203 
00204     //! Cached tags for writing. This will be important for ordering the data, in parallel
00205     Tag mGlobalIdTag;
00206 
00207     //! Are we writing in parallel? (probably in the future)
00208     bool isParallel;
00209 
00210     //! CAM Euler, etc,
00211     std::string grid_type;
00212 
00213     //! Helper class instance
00214     NCWriteHelper* myHelper;
00215 };
00216 
00217 }  // namespace moab
00218 
00219 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines