URI:
       tCache.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
       ---
       tCache.cc (4975B)
       ---
            1 /* Copyright (C) 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 
           20 #include <cassert>
           21 #include <algorithm>            // for std::min
           22 
           23 #include "Cache.hh"
           24 #include "pism/util/Time.hh"
           25 #include "pism/util/pism_options.hh"
           26 #include "pism/util/IceGrid.hh"
           27 #include "pism/util/error_handling.hh"
           28 #include "pism/util/pism_utilities.hh"
           29 #include "pism/util/MaxTimestep.hh"
           30 
           31 namespace pism {
           32 namespace surface {
           33 
           34 Cache::Cache(IceGrid::ConstPtr grid, std::shared_ptr<SurfaceModel> in)
           35   : SurfaceModel(grid, in) {
           36 
           37   m_next_update_time = m_grid->ctx()->time()->current();
           38   m_update_interval_years = m_config->get_number("surface.cache.update_interval", "years");
           39 
           40   if (m_update_interval_years <= 0) {
           41     throw RuntimeError::formatted(PISM_ERROR_LOCATION,
           42                                   "surface.cache.update_interval has to be strictly positive.");
           43   }
           44 
           45   {
           46     m_mass_flux             = allocate_mass_flux(grid);
           47     m_temperature           = allocate_temperature(grid);
           48     m_liquid_water_fraction = allocate_liquid_water_fraction(grid);
           49     m_layer_mass            = allocate_layer_mass(grid);
           50     m_layer_thickness       = allocate_layer_thickness(grid);
           51     m_accumulation          = allocate_accumulation(grid);
           52     m_melt                  = allocate_melt(grid);
           53     m_runoff                = allocate_runoff(grid);
           54   }
           55 }
           56 
           57 Cache::~Cache() {
           58   // empty
           59 }
           60 
           61 void Cache::init_impl(const Geometry &geometry) {
           62   m_input_model->init(geometry);
           63 
           64   m_log->message(2, "* Initializing the 'caching' surface model modifier...\n");
           65 
           66   m_next_update_time = m_grid->ctx()->time()->current();
           67 }
           68 
           69 void Cache::update_impl(const Geometry &geometry, double t, double dt) {
           70   // ignore dt and always use 1 year long time-steps when updating
           71   // the input model
           72   (void) dt;
           73 
           74   if (t >= m_next_update_time or fabs(t - m_next_update_time) < 1.0) {
           75 
           76     double
           77       one_year_from_now = m_grid->ctx()->time()->increment_date(t, 1.0),
           78       update_dt         = one_year_from_now - t;
           79 
           80     assert(update_dt > 0.0);
           81 
           82     m_input_model->update(geometry, t, update_dt);
           83 
           84     m_next_update_time = m_grid->ctx()->time()->increment_date(m_next_update_time,
           85                                                                m_update_interval_years);
           86 
           87     // store outputs of the input model
           88     m_mass_flux->copy_from(m_input_model->mass_flux());
           89     m_temperature->copy_from(m_input_model->temperature());
           90     m_liquid_water_fraction->copy_from(m_input_model->liquid_water_fraction());
           91     m_layer_mass->copy_from(m_input_model->layer_mass());
           92     m_layer_thickness->copy_from(m_input_model->layer_thickness());
           93     m_accumulation->copy_from(m_input_model->accumulation());
           94     m_melt->copy_from(m_input_model->melt());
           95     m_runoff->copy_from(m_input_model->runoff());
           96   }
           97 }
           98 
           99 MaxTimestep Cache::max_timestep_impl(double t) const {
          100   double dt = m_next_update_time - t;
          101 
          102   // if we got very close to the next update time, set time step
          103   // length to the interval between updates
          104   if (dt < 1.0) {
          105     double update_time_after_next = m_grid->ctx()->time()->increment_date(m_next_update_time,
          106                                                                           m_update_interval_years);
          107 
          108     dt = update_time_after_next - m_next_update_time;
          109     assert(dt > 0.0);
          110   }
          111 
          112   assert(m_input_model != NULL);
          113 
          114   MaxTimestep cache_dt(dt, "surface cache");
          115 
          116   MaxTimestep input_max_timestep = m_input_model->max_timestep(t);
          117   if (input_max_timestep.finite()) {
          118     return std::min(input_max_timestep, cache_dt);
          119   } else {
          120     return cache_dt;
          121   }
          122 }
          123 
          124 const IceModelVec2S &Cache::layer_thickness_impl() const {
          125   return *m_layer_thickness;
          126 }
          127 
          128 const IceModelVec2S &Cache::mass_flux_impl() const {
          129   return *m_mass_flux;
          130 }
          131 
          132 const IceModelVec2S &Cache::temperature_impl() const {
          133   return *m_temperature;
          134 }
          135 
          136 const IceModelVec2S &Cache::liquid_water_fraction_impl() const {
          137   return *m_liquid_water_fraction;
          138 }
          139 
          140 const IceModelVec2S &Cache::layer_mass_impl() const {
          141   return *m_layer_mass;
          142 }
          143 
          144 const IceModelVec2S& Cache::accumulation_impl() const {
          145   return *m_accumulation;
          146 }
          147 
          148 const IceModelVec2S& Cache::melt_impl() const {
          149   return *m_melt;
          150 }
          151 
          152 const IceModelVec2S& Cache::runoff_impl() const {
          153   return *m_runoff;
          154 }
          155 
          156 } // end of namespace surface
          157 } // end of namespace pism