MOAB: Mesh Oriented datABase
(version 5.4.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, 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