Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.1-cd005eec8 committed by Constantine Khrulev on 2025-03-07
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
localMassBalance.hh
Go to the documentation of this file.
1// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017, 2018, 2020, 2021, 2022, 2023 Ed Bueler and Constantine Khroulev
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#ifndef __localMassBalance_hh
20#define __localMassBalance_hh
21
22#include "pism/util/array/Scalar.hh" // only needed for FaustoGrevePDDObject
23#include "pism/util/ConfigInterface.hh" // needed to get Config::ConstPtr
24
25namespace pism {
26namespace surface {
27
28//! \brief Base class for a model which computes surface mass flux rate (ice
29//! thickness per time) from precipitation and temperature.
30/*!
31 This is a process model. At each spatial location, it uses a 1D array, with a
32 time dimension, for the temperature used in melting snow or ice. At each spatial
33 location it assumes the precipitation is time-independent.
34
35 This process model does not know its location on the ice sheet, but
36 simply computes the surface mass balance from three quantities:
37 - the time interval \f$[t,t+\Delta t]\f$,
38 - time series of values of surface temperature at \f$N\f$ equally-spaced
39 times in the time interval
40 - a scalar precipation rate which is taken to apply in the time interval.
41
42 This model also uses degree day factors passed-in in DegreeDayFactors `ddf`,
43 and the standard deviation `pddStdDev`. The latter is the standard deviation of the
44 modeled temperature away from the input temperature time series which contains
45 the part of location-dependent temperature cycle on the time interval.
46
47 @note
48 - Please avoid using `config.get...("...")` calls
49 inside those methods of this class which are called inside loops over
50 spatial grids. Doing otherwise increases computational costs.
51 - This base class should be more general. For instance, it could allow as
52 input a time series for precipation rate.
53*/
55public:
56
57 //! A struct which holds degree day factors.
58 /*!
59 Degree day factors convert positive degree days (=PDDs) into amount of melt.
60 */
62 //! m day^-1 K^-1; ice-equivalent amount of snow melted, per PDD
63 double snow;
64 //! m day^-1 K^-1; ice-equivalent amount of ice melted, per PDD
65 double ice;
66 //! fraction of melted snow which refreezes as ice
68 };
69
71 virtual ~LocalMassBalance() = default;
72
73 std::string method() const;
74
75 virtual unsigned int get_timeseries_length(double dt) = 0;
76
77 //! Count positive degree days (PDDs). Returned value in units of K day.
78 /*! Inputs T[0],...,T[N-1] are temperatures (K) at times t, t+dt_series, ..., t+(N-1)dt_series.
79 Inputs `t`, `dt_series` are in seconds. */
80 virtual void get_PDDs(double dt_series,
81 const std::vector<double> &S,
82 const std::vector<double> &T,
83 std::vector<double> &PDDs) = 0;
84
85 /*! Remove rain from precipitation. */
86 virtual void get_snow_accumulation(const std::vector<double> &T,
87 std::vector<double> &precip_rate) = 0;
88
89 class Changes {
90 public:
91 Changes();
92
93 double firn_depth;
94 double snow_depth;
95 double melt;
96 double runoff;
97 double smb;
98 };
99
100 /**
101 * Take a step of the PDD model.
102 *
103 * @param[in] ddf degree day factors
104 * @param[in] PDDs number of positive degree days during the time step [K day]
105 * @param[in] old_firn_depth firn depth [ice equivalent meters]
106 * @param[in] old_snow_depth snow depth [ice equivalent meters]
107 * @param[in] accumulation total solid (snow) accumulation during the time-step [ice equivalent meters]
108 */
109 virtual Changes step(const DegreeDayFactors &ddf,
110 double PDDs,
111 double ice_thickness,
112 double old_firn_depth,
113 double old_snow_depth,
114 double accumulation) = 0;
115
116protected:
117 std::string m_method;
118
121 const double m_seconds_per_day;
122};
123
124
125//! A PDD implementation which computes the local mass balance based on an expectation integral.
126/*!
127 The expected number of positive degree days is computed by an integral in \ref CalovGreve05.
128
129 Uses degree day factors which are location-independent.
130*/
132
133public:
135 virtual ~PDDMassBalance() {}
136
137 virtual unsigned int get_timeseries_length(double dt);
138 virtual void get_PDDs(double dt_series,
139 const std::vector<double> &S,
140 const std::vector<double> &T,
141 std::vector<double> &PDDs);
142
143 void get_snow_accumulation(const std::vector<double> &T,
144 std::vector<double> &precip_rate);
145
146 Changes step(const DegreeDayFactors &ddf,
147 double PDDs,
148 double ice_thickness,
149 double firn_depth,
150 double snow_depth,
151 double accumulation);
152
153protected:
154 //! interpret all the precipitation as snow (no rain)
156 //! refreeze melted ice
158 //! the temperature below which all precipitation is snow
159 double Tmin;
160 //! the temperature above which all precipitation is rain
161 double Tmax;
162 //! threshold temperature for the PDD computation
164};
165
166
167//! An alternative PDD implementation which simulates a random process to get the number of PDDs.
168/*!
169 Uses a GSL random number generator. Significantly slower because new random numbers are
170 generated for each grid point.
171
172 The way the number of positive degree-days are used to produce a surface mass balance
173 is identical to the base class PDDMassBalance.
174
175 \note
176 A more realistic pattern for the variability of surface melting might have correlation
177 with appropriate spatial and temporal ranges.
178*/
180public:
181
183
185 units::System::Ptr system,
186 Kind kind);
187 virtual ~PDDrandMassBalance();
188
189 virtual unsigned int get_timeseries_length(double dt);
190
191 virtual void get_PDDs(double dt_series,
192 const std::vector<double> &S,
193 const std::vector<double> &T,
194 std::vector<double> &PDDs);
195protected:
196 struct Impl;
198};
199
200
201/*!
202 The PDD scheme described by Formula (6) in [\ref Faustoetal2009] requires
203 special knowledge of latitude and mean July temp to set degree day factors
204 for Greenland.
205
206 These formulas are inherited by [\ref Faustoetal2009] from [\ref Greve2005geothermal].
207 There was, apparently, tuning in [\ref Greve2005geothermal] which mixed ice
208 dynamical ideas and surface process ideas. That is, these formulas and parameter
209 choices arise from looking at margin shape. This may not be a good source of
210 PDD parameters.
211
212 This may become a derived class of a LocationDependentPDDObject, if the idea
213 is needed more in the future.
214*/
216
217public:
218 FaustoGrevePDDObject(std::shared_ptr<const Grid> g);
219 virtual ~FaustoGrevePDDObject() = default;
220
221 void update_temp_mj(const array::Scalar &surfelev,
222 const array::Scalar &lat,
223 const array::Scalar &lon);
224
225 /*! If this method is called, it is assumed that i,j is in the ownership range
226 for array::Scalar temp_mj. */
227 LocalMassBalance::DegreeDayFactors degree_day_factors(int i, int j, double latitude);
228
229protected:
230 std::shared_ptr<const Grid> m_grid;
232
235 double m_T_c;
236 double m_T_w;
243
245};
246
247
248} // end of namespace surface
249} // end of namespace pism
250
251#endif
std::shared_ptr< const Config > ConstPtr
virtual ~FaustoGrevePDDObject()=default
LocalMassBalance::DegreeDayFactors degree_day_factors(int i, int j, double latitude)
std::shared_ptr< const Grid > m_grid
void update_temp_mj(const array::Scalar &surfelev, const array::Scalar &lat, const array::Scalar &lon)
Updates mean July near-surface air temperature.
const units::System::Ptr m_unit_system
virtual ~LocalMassBalance()=default
virtual void get_PDDs(double dt_series, const std::vector< double > &S, const std::vector< double > &T, std::vector< double > &PDDs)=0
Count positive degree days (PDDs). Returned value in units of K day.
virtual Changes step(const DegreeDayFactors &ddf, double PDDs, double ice_thickness, double old_firn_depth, double old_snow_depth, double accumulation)=0
virtual void get_snow_accumulation(const std::vector< double > &T, std::vector< double > &precip_rate)=0
virtual unsigned int get_timeseries_length(double dt)=0
Base class for a model which computes surface mass flux rate (ice thickness per time) from precipitat...
void get_snow_accumulation(const std::vector< double > &T, std::vector< double > &precip_rate)
Extract snow accumulation from mixed (snow and rain) precipitation using the temperature time-series.
bool refreeze_ice_melt
refreeze melted ice
bool precip_as_snow
interpret all the precipitation as snow (no rain)
virtual void get_PDDs(double dt_series, const std::vector< double > &S, const std::vector< double > &T, std::vector< double > &PDDs)
Compute the expected number of positive degree days from the input temperature time-series.
double Tmax
the temperature above which all precipitation is rain
Changes step(const DegreeDayFactors &ddf, double PDDs, double ice_thickness, double firn_depth, double snow_depth, double accumulation)
Compute the surface mass balance at a location from the number of positive degree days and the accumu...
double pdd_threshold_temp
threshold temperature for the PDD computation
double Tmin
the temperature below which all precipitation is snow
virtual unsigned int get_timeseries_length(double dt)
Compute the number of points for temperature and precipitation time-series.
A PDD implementation which computes the local mass balance based on an expectation integral.
virtual unsigned int get_timeseries_length(double dt)
virtual void get_PDDs(double dt_series, const std::vector< double > &S, const std::vector< double > &T, std::vector< double > &PDDs)
An alternative PDD implementation which simulates a random process to get the number of PDDs.
std::shared_ptr< System > Ptr
Definition Units.hh:47
static const double g
Definition exactTestP.cc:36
double ice
m day^-1 K^-1; ice-equivalent amount of ice melted, per PDD
double refreeze_fraction
fraction of melted snow which refreezes as ice
double snow
m day^-1 K^-1; ice-equivalent amount of snow melted, per PDD
A struct which holds degree day factors.
static double S(unsigned n)
Definition test_cube.c:58