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