PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
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 
25 namespace pism {
26 namespace 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 */
55 public:
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 
116 protected:
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 
133 public:
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 
153 protected:
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 */
180 public:
181 
182  enum Kind {NOT_REPEATABLE = 0, REPEATABLE = 1};
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);
195 protected:
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 
217 public:
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 
229 protected:
230  std::shared_ptr<const Grid> m_grid;
232 
233  double m_beta_ice_w;
235  double m_T_c;
236  double m_T_w;
237  double m_beta_ice_c;
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
FaustoGrevePDDObject(std::shared_ptr< const Grid > g)
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
const Config::ConstPtr m_config
virtual void get_snow_accumulation(const std::vector< double > &T, std::vector< double > &precip_rate)=0
LocalMassBalance(Config::ConstPtr config, units::System::Ptr system)
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
PDDMassBalance(Config::ConstPtr config, units::System::Ptr system)
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)
PDDrandMassBalance(Config::ConstPtr config, units::System::Ptr system, Kind kind)
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