pism

[fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
git clone git://src.adamsgaard.dk/pism # fast
git clone https://src.adamsgaard.dk/pism.git # slow
Log | Files | Refs | README | LICENSE Back to index

NCFile.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