tNCFile.cc - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
HTML git clone git://src.adamsgaard.dk/pism
DIR Log
DIR Files
DIR Refs
DIR LICENSE
---
tNCFile.cc (8607B)
---
1 // Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 PISM Authors
2 //
3 // This file is part of PISM.
4 //
5 // PISM is free software; you can redistribute it and/or modify it under the
6 // terms of the GNU General Public License as published by the Free Software
7 // Foundation; either version 3 of the License, or (at your option) any later
8 // version.
9 //
10 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with PISM; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 #include "NCFile.hh"
20
21 #include <cstdio> // fprintf, stderr, rename, remove
22 #include "pism/util/pism_utilities.hh"
23 #include "pism/util/error_handling.hh"
24 #include "pism/util/IceGrid.hh"
25
26 // The following is a stupid kludge necessary to make NetCDF 4.x work in
27 // serial mode in an MPI program:
28 #ifndef MPI_INCLUDED
29 #define MPI_INCLUDED 1
30 #endif
31 #include <netcdf.h>
32
33 namespace pism {
34 namespace io {
35
36 NCFile::NCFile(MPI_Comm c)
37 : m_com(c), m_file_id(-1), m_define_mode(false) {
38 }
39
40 NCFile::~NCFile() {
41 // empty
42 }
43
44 std::string NCFile::filename() const {
45 return m_filename;
46 }
47
48 void NCFile::def_var_chunking_impl(const std::string &name,
49 std::vector<size_t> &dimensions) const {
50 (void) name;
51 (void) dimensions;
52 // the default implementation does nothing
53 }
54
55
56 void NCFile::open(const std::string &filename, IO_Mode mode) {
57 this->open_impl(filename, mode);
58 m_filename = filename;
59 m_define_mode = false;
60 }
61
62 void NCFile::create(const std::string &filename) {
63 this->create_impl(filename);
64 m_filename = filename;
65 m_define_mode = true;
66 }
67
68 void NCFile::sync() const {
69 enddef();
70 this->sync_impl();
71 }
72
73 void NCFile::close() {
74 this->close_impl();
75 m_filename.clear();
76 m_file_id = -1;
77 }
78
79 void NCFile::enddef() const {
80 if (m_define_mode) {
81 this->enddef_impl();
82 m_define_mode = false;
83 }
84 }
85
86 void NCFile::redef() const {
87 if (not m_define_mode) {
88 this->redef_impl();
89 m_define_mode = true;
90 }
91 }
92
93 void NCFile::def_dim(const std::string &name, size_t length) const {
94 redef();
95 this->def_dim_impl(name, length);
96 }
97
98 void NCFile::inq_dimid(const std::string &dimension_name, bool &exists) const {
99 this->inq_dimid_impl(dimension_name,exists);
100 }
101
102 void NCFile::inq_dimlen(const std::string &dimension_name, unsigned int &result) const {
103 this->inq_dimlen_impl(dimension_name,result);
104 }
105
106 void NCFile::inq_unlimdim(std::string &result) const {
107 this->inq_unlimdim_impl(result);
108 }
109
110 void NCFile::def_var(const std::string &name, IO_Type nctype,
111 const std::vector<std::string> &dims) const {
112 redef();
113 this->def_var_impl(name, nctype, dims);
114 }
115
116 void NCFile::def_var_chunking(const std::string &name,
117 std::vector<size_t> &dimensions) const {
118 this->def_var_chunking_impl(name, dimensions);
119 }
120
121
122 void NCFile::get_vara_double(const std::string &variable_name,
123 const std::vector<unsigned int> &start,
124 const std::vector<unsigned int> &count,
125 double *ip) const {
126 #if (Pism_DEBUG==1)
127 if (start.size() != count.size()) {
128 throw RuntimeError::formatted(PISM_ERROR_LOCATION,
129 "start and count arrays have to have the same size");
130 }
131 #endif
132
133 enddef();
134 this->get_vara_double_impl(variable_name, start, count, ip);
135 }
136
137 void NCFile::put_vara_double(const std::string &variable_name,
138 const std::vector<unsigned int> &start,
139 const std::vector<unsigned int> &count,
140 const double *op) const {
141 #if (Pism_DEBUG==1)
142 if (start.size() != count.size()) {
143 throw RuntimeError::formatted(PISM_ERROR_LOCATION,
144 "start and count arrays have to have the same size");
145 }
146 #endif
147
148 enddef();
149 this->put_vara_double_impl(variable_name, start, count, op);
150 }
151
152
153 void NCFile::write_darray(const std::string &variable_name,
154 const IceGrid &grid,
155 unsigned int z_count,
156 unsigned int record,
157 const double *input) {
158 enddef();
159 this->write_darray_impl(variable_name, grid, z_count, record, input);
160 }
161
162 /*!
163 * The default implementation computes start and count and calls put_vara_double()
164 */
165 void NCFile::write_darray_impl(const std::string &variable_name,
166 const IceGrid &grid,
167 unsigned int z_count,
168 unsigned int record,
169 const double *input) {
170 std::vector<std::string> dims;
171 this->inq_vardimid(variable_name, dims);
172
173 unsigned int ndims = dims.size();
174
175 bool time_dependent = ((z_count > 1 and ndims == 4) or
176 (z_count == 1 and ndims == 3));
177
178 std::vector<unsigned int> start, count;
179
180 // time
181 if (time_dependent) {
182 start.push_back(record);
183 count.push_back(1);
184 }
185
186 // y
187 start.push_back(grid.ys());
188 count.push_back(grid.ym());
189
190 // x
191 start.push_back(grid.xs());
192 count.push_back(grid.xm());
193
194 // z (these are not used when writing 2D fields)
195 start.push_back(0);
196 count.push_back(z_count);
197
198 this->put_vara_double(variable_name, start, count, input);
199 }
200
201
202 void NCFile::get_varm_double(const std::string &variable_name,
203 const std::vector<unsigned int> &start,
204 const std::vector<unsigned int> &count,
205 const std::vector<unsigned int> &imap,
206 double *ip) const {
207
208 #if (Pism_DEBUG==1)
209 if (start.size() != count.size() or
210 start.size() != imap.size()) {
211 throw RuntimeError::formatted(PISM_ERROR_LOCATION,
212 "start, count and imap arrays have to have the same size");
213 }
214 #endif
215
216 enddef();
217 this->get_varm_double_impl(variable_name, start, count, imap, ip);
218 }
219
220 void NCFile::inq_nvars(int &result) const {
221 this->inq_nvars_impl(result);
222 }
223
224 void NCFile::inq_vardimid(const std::string &variable_name, std::vector<std::string> &result) const {
225 this->inq_vardimid_impl(variable_name, result);
226 }
227
228 void NCFile::inq_varnatts(const std::string &variable_name, int &result) const {
229 this->inq_varnatts_impl(variable_name, result);
230 }
231
232 void NCFile::inq_varid(const std::string &variable_name, bool &result) const {
233 this->inq_varid_impl(variable_name, result);
234 }
235
236 void NCFile::inq_varname(unsigned int j, std::string &result) const {
237 this->inq_varname_impl(j, result);
238 }
239
240 void NCFile::get_att_double(const std::string &variable_name,
241 const std::string &att_name,
242 std::vector<double> &result) const {
243 this->get_att_double_impl(variable_name, att_name, result);
244 }
245
246 void NCFile::get_att_text(const std::string &variable_name,
247 const std::string &att_name,
248 std::string &result) const {
249 this->get_att_text_impl(variable_name, att_name, result);
250 }
251
252 void NCFile::put_att_double(const std::string &variable_name,
253 const std::string &att_name,
254 IO_Type xtype,
255 const std::vector<double> &data) const {
256 this->put_att_double_impl(variable_name, att_name, xtype, data);
257 }
258
259 void NCFile::put_att_text(const std::string &variable_name,
260 const std::string &att_name,
261 const std::string &value) const {
262 this->put_att_text_impl(variable_name, att_name, value);
263 }
264
265 void NCFile::inq_attname(const std::string &variable_name,
266 unsigned int n,
267 std::string &result) const {
268 this->inq_attname_impl(variable_name, n, result);
269 }
270
271 void NCFile::inq_atttype(const std::string &variable_name,
272 const std::string &att_name,
273 IO_Type &result) const {
274 this->inq_atttype_impl(variable_name, att_name, result);
275 }
276
277 void NCFile::set_fill(int fillmode, int &old_modep) const {
278 redef();
279 this->set_fill_impl(fillmode, old_modep);
280 }
281
282 void NCFile::del_att(const std::string &variable_name, const std::string &att_name) const {
283 this->del_att_impl(variable_name, att_name);
284 }
285
286 } // end of namespace io
287 } // end of namespace pism