URI:
       tScalarForcing.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
       ---
       tScalarForcing.cc (3463B)
       ---
            1 /* Copyright (C) 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 
           20 #include "ScalarForcing.hh"
           21 
           22 #include "pism/util/ConfigInterface.hh"
           23 #include "pism/util/Timeseries.hh"
           24 #include "pism/util/Time.hh"
           25 #include "pism/util/error_handling.hh"
           26 #include "pism/util/Logger.hh"
           27 #include "pism/util/io/File.hh"
           28 
           29 namespace pism {
           30 
           31 ScalarForcing::ScalarForcing(Context::ConstPtr ctx,
           32                              const std::string &prefix,
           33                              const std::string &variable_name,
           34                              const std::string &units,
           35                              const std::string &glaciological_units,
           36                              const std::string &long_name)
           37   : m_ctx(ctx), m_period(0), m_reference_time(0.0), m_current(0.0) {
           38 
           39   Config::ConstPtr config = ctx->config();
           40 
           41   m_prefix = prefix;
           42 
           43   m_data.reset(new Timeseries(ctx->com(), ctx->unit_system(),
           44                               variable_name,
           45                               config->get_string("time.dimension_name")));
           46   m_data->variable().set_string("units", units);
           47   m_data->variable().set_string("glaciological_units", glaciological_units);
           48   m_data->variable().set_string("long_name", long_name);
           49 
           50   m_data->dimension().set_string("units", ctx->time()->units_string());
           51 }
           52 
           53 ScalarForcing::~ScalarForcing() {
           54   // empty
           55 }
           56 
           57 void ScalarForcing::init() {
           58 
           59   Config::ConstPtr config = m_ctx->config();
           60 
           61   auto   filename       = config->get_string(m_prefix + ".file");
           62   int    period         = config->get_number(m_prefix + ".period");
           63   double reference_year = config->get_number(m_prefix + ".reference_year");
           64 
           65   if (filename.empty()) {
           66     throw RuntimeError::formatted(PISM_ERROR_LOCATION,
           67                                   "%s.file is required", m_prefix.c_str());
           68   }
           69 
           70   if (period < 0.0) {
           71     throw RuntimeError::formatted(PISM_ERROR_LOCATION,
           72                                   "invalid %s.period %d (period length cannot be negative)",
           73                                   m_prefix.c_str(), period);
           74   }
           75 
           76   m_period = (unsigned int)period;
           77 
           78   m_reference_time = units::convert(m_ctx->unit_system(),
           79                                     reference_year, "years", "seconds");
           80 
           81   m_ctx->log()->message(2,
           82                         "  reading %s data from forcing file %s...\n",
           83                         m_data->name().c_str(), filename.c_str());
           84 
           85   File file(m_ctx->com(), filename, PISM_NETCDF3, PISM_READONLY);
           86   {
           87     m_data->read(file, *m_ctx->time(), *m_ctx->log());
           88   }
           89 }
           90 
           91 void ScalarForcing::update(double t, double dt) {
           92   m_current = value(t + 0.5 * dt);
           93 }
           94 
           95 double ScalarForcing::value() const {
           96   return m_current;
           97 }
           98 
           99 double ScalarForcing::value(double t) const {
          100   t = m_ctx->time()->mod(t - m_reference_time, m_period);
          101 
          102   return (*m_data)(t);
          103 }
          104 
          105 } // end of namespace pism