Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
NCWriteHelper.hpp
Go to the documentation of this file.
1 /*
2  * NCWriteHelper.hpp
3  *
4  * Purpose : Climate NC writer file helper; abstract, will be implemented for each type
5  *
6  * Created on: Mar 28, 2014
7  */
8 
9 #ifndef NCWRITEHELPER_HPP_
10 #define NCWRITEHELPER_HPP_
11 #include "WriteNC.hpp"
12 
13 #ifdef WIN32
14 #ifdef size_t
15 #undef size_t
16 #endif
17 #endif
18 
19 namespace moab
20 {
21 
23 {
24  public:
25  NCWriteHelper( WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet )
26  : _writeNC( writeNC ), _fileId( fileId ), _opts( opts ), _fileSet( fileSet ), nTimeSteps( 0 ), nLevels( 1 ),
27  tDim( -1 ), levDim( -1 )
28  {
29  }
30  virtual ~NCWriteHelper() {};
31 
32  //! Get appropriate helper instance for WriteNC class based on some info in the file set
33  static NCWriteHelper* get_nc_helper( WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet );
34 
35  //! Collect necessary info about local mesh (implemented in child classes)
37 
38  //! Collect data for specified variables (partially implemented in child classes)
39  virtual ErrorCode collect_variable_data( std::vector< std::string >& var_names, std::vector< int >& tstep_nums );
40 
41  //! Initialize file: this is where all defines are done.
42  //! Virtual so that grid-output writers (NCWriteScrip / NCWriteESMF /
43  //! NCWriteDomain) can synthesize a fresh schema from mesh state
44  //! instead of going through the climate var_names plumbing.
45  virtual ErrorCode init_file( std::vector< std::string >& var_names,
46  std::vector< std::string >& desired_names,
47  bool _append );
48 
49  //! Take the info from VarData and write first non-set variables, then set variables.
50  //! Virtual for the same reason as init_file.
51  virtual ErrorCode write_values( std::vector< std::string >& var_names, std::vector< int >& tstep_nums );
52 
53  private:
54  // Write set variables (common to scd mesh and ucd mesh)
55  ErrorCode write_set_variables( std::vector< WriteNC::VarData >& vsetdatas, std::vector< int >& tstep_nums );
56 
57  protected:
58  // Write non-set variables (implemented in child classes)
59  virtual ErrorCode write_nonset_variables( std::vector< WriteNC::VarData >& vdatas,
60  std::vector< int >& tstep_nums ) = 0;
61 
62  //! Allow NCWriteHelper to directly access members of WriteNC
64 
65  //! Cache some information from WriteNC
66  int _fileId;
69 
70  //! Dimensions of time and level
72 
73  //! Dimension numbers for time and level
74  int tDim, levDim;
75 
76  //! Local owned cells, edges and vertices
78 
79  //! Time values of output timesteps
80  std::vector< double > timeStepVals;
81 };
82 
83 //! Child helper class for scd mesh, e.g. CAM_EL or CAM_FV
85 {
86  public:
87  ScdNCWriteHelper( WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet )
88  : NCWriteHelper( writeNC, fileId, opts, fileSet )
89  {
90  for( unsigned int i = 0; i < 6; i++ )
91  {
92  lDims[i] = -1;
93  lCDims[i] = -1;
94  }
95  }
96  virtual ~ScdNCWriteHelper() override {}
97 
98  private:
99  //! Implementation of NCWriteHelper::collect_mesh_info()
100  ErrorCode collect_mesh_info() override;
101 
102  //! Collect data for specified variables
103  ErrorCode collect_variable_data( std::vector< std::string >& var_names, std::vector< int >& tstep_nums ) override;
104 
105  //! Implementation of NCWriteHelper::write_nonset_variables()
106  ErrorCode write_nonset_variables( std::vector< WriteNC::VarData >& vdatas, std::vector< int >& tstep_nums ) override;
107 
108  template < typename T >
109  static void jik_to_kji( size_t ni, size_t nj, size_t nk, T* dest, T* source )
110  {
111  size_t nik = ni * nk, nij = ni * nj;
112  for( std::size_t k = 0; k != nk; k++ )
113  for( std::size_t j = 0; j != nj; j++ )
114  for( std::size_t i = 0; i != ni; i++ )
115  dest[k * nij + j * ni + i] = source[j * nik + i * nk + k];
116  }
117 
118  protected:
119  //! Dimensions of my local part of grid
120  int lDims[6];
121 
122  //! Center dimensions of my local part of grid
123  int lCDims[6];
124 };
125 
126 //! Child helper class for ucd mesh, e.g. CAM_SE (HOMME) or MPAS
128 {
129  public:
130  UcdNCWriteHelper( WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet )
131  : NCWriteHelper( writeNC, fileId, opts, fileSet ), cDim( -1 ), eDim( -1 ), vDim( -1 )
132  {
133  }
134  virtual ~UcdNCWriteHelper() override {}
135 
136  protected:
137  //! This version takes as input the moab range, from which we actually need just the
138  //! size of each sequence, for a proper transpose of the data
139  template < typename T >
140  static void jik_to_kji_stride( size_t, size_t nj, size_t nk, T* dest, T* source, Range& localGid )
141  {
142  std::size_t idxInSource = 0; // Position of the start of the stride
143  // For each subrange, we will transpose a matrix of size
144  // subrange*nj*nk (subrange takes the role of ni)
145  for( Range::pair_iterator pair_iter = localGid.pair_begin(); pair_iter != localGid.pair_end(); ++pair_iter )
146  {
147  std::size_t size_range = pair_iter->second - pair_iter->first + 1;
148  std::size_t nik = size_range * nk, nij = size_range * nj;
149  for( std::size_t k = 0; k != nk; k++ )
150  for( std::size_t j = 0; j != nj; j++ )
151  for( std::size_t i = 0; i != size_range; i++ )
152  dest[idxInSource + k * nij + j * size_range + i] = source[idxInSource + j * nik + i * nk + k];
153  idxInSource += ( size_range * nj * nk );
154  }
155  }
156 
157  //! Dimension numbers for nCells, nEdges and nVertices
158  int cDim, eDim, vDim;
159 
160  //! Local global ID for owned cells, edges and vertices
162 };
163 
164 } // namespace moab
165 
166 #endif