MOAB: Mesh Oriented datABase  (version 5.2.1)
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, const bool overwrite, const FileOptions& opts,
00093                           const EntityHandle* output_list, const int num_sets,
00094                           const std::vector< std::string >& qa_list, const Tag* tag_list = NULL, int num_tags = 0,
00095                           int export_dimension = 3 );
00096 
00097   private:
00098     //! ENTLOCNSEDGE for north/south edge
00099     //! ENTLOCWEEDGE for west/east edge
00100     enum EntityLocation
00101     {
00102         ENTLOCVERT = 0,
00103         ENTLOCNSEDGE,
00104         ENTLOCEWEDGE,
00105         ENTLOCFACE,
00106         ENTLOCSET,
00107         ENTLOCEDGE,
00108         ENTLOCREGION
00109     };
00110 
00111     class AttData
00112     {
00113       public:
00114         AttData() : attId( -1 ), attLen( 0 ), attVarId( -2 ), attDataType( NC_NAT ) {}
00115         int attId;
00116         NCDF_SIZE attLen;
00117         int attVarId;
00118         nc_type attDataType;
00119         std::string attValue;
00120     };
00121 
00122     class VarData
00123     {
00124       public:
00125         VarData() : varId( -1 ), numAtts( -1 ), entLoc( ENTLOCSET ), numLev( 0 ), sz( 0 ), has_tsteps( false ) {}
00126         int varId;
00127         int numAtts;
00128         nc_type varDataType;
00129         std::vector< int > varDims;  // The dimension indices making up this multi-dimensional variable
00130         std::map< std::string, AttData > varAtts;
00131         std::string varName;
00132         std::vector< Tag > varTags;            // Tags created for this variable, e.g. one tag per timestep
00133         std::vector< void* > memoryHogs;       // These will point to the real data; fill before writing the data
00134         std::vector< NCDF_SIZE > writeStarts;  // Starting index for writing data values along each dimension
00135         std::vector< NCDF_SIZE > writeCounts;  // Number of data values to be written along each dimension
00136         int entLoc;
00137         int numLev;
00138         int sz;
00139         bool has_tsteps;  // Indicate whether timestep numbers are appended to tag names
00140     };
00141 
00142     //! This info will be reconstructed from metadata stored on conventional fileSet tags
00143     //! Dimension names
00144     std::vector< std::string > dimNames;
00145 
00146     //! Dimension lengths
00147     std::vector< int > dimLens;
00148 
00149     //! Will collect used dimensions (coordinate variables)
00150     std::set< std::string > usedCoordinates;
00151 
00152     //! Dummy variables (for dimensions that have no corresponding coordinate variables)
00153     std::set< std::string > dummyVarNames;
00154 
00155     //! Global attribs
00156     std::map< std::string, AttData > globalAtts;
00157 
00158     //! Variable info
00159     std::map< std::string, VarData > varInfo;
00160 
00161     ErrorCode parse_options( const FileOptions& opts, std::vector< std::string >& var_names,
00162                              std::vector< std::string >& desired_names, std::vector< int >& tstep_nums,
00163                              std::vector< double >& tstep_vals );
00164     /*
00165      * Map out the header, from tags on file set; it is the inverse process from
00166      * ErrorCode NCHelper::create_conventional_tags
00167      */
00168     ErrorCode process_conventional_tags( EntityHandle fileSet );
00169 
00170     ErrorCode process_concatenated_attribute( const void* attPtr, int attSz, std::vector< int >& attLen,
00171                                               std::map< std::string, AttData >& attributes );
00172 
00173     //! Interface instance
00174     Interface* mbImpl;
00175     WriteUtilIface* mWriteIface;
00176 
00177     //! File var
00178     const char* fileName;
00179 
00180     //! File numbers assigned by (p)netcdf
00181     int fileId;
00182 
00183     //! Debug stuff
00184     DebugOutput dbgOut;
00185 
00186 #ifdef MOAB_HAVE_MPI
00187     ParallelComm* myPcomm;
00188 #endif
00189 
00190     //! Write options
00191     bool noMesh;
00192     bool noVars;
00193     bool append;
00194 
00195     //! Cached tags for writing. This will be important for ordering the data, in parallel
00196     Tag mGlobalIdTag;
00197 
00198     //! Are we writing in parallel? (probably in the future)
00199     bool isParallel;
00200 
00201     //! CAM Euler, etc,
00202     std::string grid_type;
00203 
00204     //! Helper class instance
00205     NCWriteHelper* myHelper;
00206 };
00207 
00208 }  // namespace moab
00209 
00210 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines