MOAB: Mesh Oriented datABase
(version 5.3.1)
|
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