PISM, A Parallel Ice Sheet Model 2.3.0-79cae578d committed by Constantine Khrulev on 2026-03-22
Loading...
Searching...
No Matches
PIK.cc
Go to the documentation of this file.
1// Copyright (C) 2009-2018, 2023, 2025 Ricarda Winkelmann, Torsten Albrecht, Constantine Khrulev
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 2 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// Implementation of the atmosphere model using constant-in-time precipitation
20// and a cosine yearly cycle for near-surface air temperatures.
21
22// This includes the PIK temperature parameterization.
23
24#include "pism/coupler/atmosphere/PIK.hh"
25
26#include "pism/geometry/Geometry.hh"
27#include "pism/util/Config.hh"
28#include "pism/util/Grid.hh"
29#include "pism/util/MaxTimestep.hh"
30#include "pism/util/error_handling.hh"
31#include "pism/util/Logger.hh"
32
33namespace pism {
34namespace atmosphere {
35
36PIK::PIK(std::shared_ptr<const Grid> g)
37 : YearlyCycle(g) {
38
39 auto parameterization = m_config->get_string("atmosphere.pik.parameterization");
40
41 std::map<std::string, Parameterization>
42 models = {{"martin", MARTIN},
43 {"huybrechts_dewolde", HUYBRECHTS_DEWOLDE},
44 {"martin_huybrechts_dewolde", MARTIN_HUYBRECHTS_DEWOLDE},
45 {"era_interim", ERA_INTERIM},
46 {"era_interim_sin", ERA_INTERIM_SIN},
47 {"era_interim_lon", ERA_INTERIM_LON}};
48
49 if (models.find(parameterization) == models.end()) {
51 "invalid pik parameterization: %s",
52 parameterization.c_str());
53 }
54
55 m_parameterization = models[parameterization];
56}
57
58void PIK::init_impl(const Geometry &geometry) {
59
60 m_log->message(2,
61 "* Initializing PIK atmosphere model with air temperature parameterization based on \n"
62 " Huybrechts & De Wolde (1999) or multiple regression analysis of ERA INTERIM data...\n"
63 " Uses a time-independent precipitation field read from a file.");
64
65 m_reference = "Winkelmann et al.";
66
67 auto precip_file = m_config->get_string("atmosphere.pik.file");
68
69 if (not precip_file.empty()) {
71 true, /* do regrid */
72 0 /* start (irrelevant) */);
73 } else {
74 // try to read precipitation from the input (-i) file
75 YearlyCycle::init_impl(geometry);
76 }
77
78 switch (m_parameterization) {
80 m_log->message(2,
81 " Parameterization based on: Huybrechts & De Wolde (1999).\n");
82 break;
83 case ERA_INTERIM:
84 m_log->message(2,
85 " Parameterization based on: multiple regression analysis of ERA INTERIM data.\n");
86 break;
87 case ERA_INTERIM_SIN:
88 m_log->message(2,
89 " Parameterization based on: multiple regression analysis of ERA INTERIM data with a sin(lat) dependence.\n");
90 break;
91 case ERA_INTERIM_LON:
92 m_log->message(2,
93 " Parameterization based on: multiple regression analysis of ERA INTERIM data with a cos(lon) dependence.\n");
94 break;
96 m_log->message(2,
97 " Mean annual temperature: as in Martin et al (2011).\n"
98 " Mean summer temperature: anomaly to the parameterization used by Huybrechts & De Wolde (1999).\n");
99 break;
100 default:
101 case MARTIN:
102 m_log->message(2,
103 " Mean annual temperature: as in Martin et al (2011).\n"
104 " No seasonal variation in air temperature.\n");
105 }
106}
107
109 (void) t;
110 return MaxTimestep("atmosphere pik");
111}
112
113/*!
114 * See equation C1 in HuybrechtsdeWolde.
115 */
116static double huybrechts_dewolde_mean_annual(double surface_elevation, double latitude) {
117 double gamma_a = surface_elevation < 1500.0 ? -0.005102 : -0.014285;
118 return 273.15 + 34.46 + gamma_a * surface_elevation - 0.68775 * latitude * (-1.0);
119}
120
121/*!
122 * See equation C2 in HuybrechtsdeWolde.
123 */
124static double huybrechts_dewolde_mean_summer(double surface_elevation, double latitude) {
125 return 273.15 + 16.81 - 0.00692 * surface_elevation - 0.27937 * latitude * (-1.0);
126}
127
128/*!
129 * Parameterization of mean annual and mean summer near-surface temperature as in
130 * Huybrechts & DeWolde (1999)
131 */
132static void huybrechts_dewolde(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms) {
133 auto grid = T_ma.grid();
134
135 const array::Scalar
136 &h = geometry.ice_surface_elevation,
137 &lat = geometry.latitude;
138
139 array::AccessScope list{&h, &lat, &T_ma, &T_ms};
140
141 for (auto p : grid->points()) {
142 const int i = p.i(), j = p.j();
143
144 T_ma(i, j) = huybrechts_dewolde_mean_annual(h(i, j), lat(i, j));
145 T_ms(i, j) = huybrechts_dewolde_mean_summer(h(i, j), lat(i, j));
146 }
147}
148
149/*!
150 * Parametrization based on multiple regression analysis of ERA INTERIM data
151 */
152static void era_interim(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms) {
153 auto grid = T_ma.grid();
154
155 const array::Scalar
156 &h = geometry.ice_surface_elevation,
157 &lat = geometry.latitude;
158
159 array::AccessScope list{&h, &lat, &T_ma, &T_ms};
160
161 for (auto p : grid->points()) {
162 const int i = p.i(), j = p.j();
163
164 T_ma(i, j) = 273.15 + 29.2 - 0.0082 * h(i, j) - 0.576 * lat(i, j) * (-1.0);
165 T_ms(i, j) = 273.15 + 16.5 - 0.0068 * h(i, j) - 0.248 * lat(i, j) * (-1.0);
166 }
167}
168
169/*!
170 * Parametrization based on multiple regression analysis of ERA INTERIM data with sin(lat)
171 */
172static void era_interim_sin(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms) {
173 auto grid = T_ma.grid();
174
175 const array::Scalar
176 &h = geometry.ice_surface_elevation,
177 &lat = geometry.latitude;
178
179 array::AccessScope list{&h, &lat, &T_ma, &T_ms};
180
181 for (auto p : grid->points()) {
182 const int i = p.i(), j = p.j();
183
184 T_ma(i, j) = 273.15 - 2.0 - 0.0082 * h(i, j) + 18.4 * (sin(3.1415 * lat(i, j) / 180.0) + 0.8910) / (1 - 0.8910);
185 T_ms(i, j) = 273.15 + 3.2 - 0.0067 * h(i, j) + 8.3 * (sin(3.1415 * lat(i, j) / 180.0) + 0.8910) / (1 - 0.8910);
186 }
187}
188
189/*!
190 * Parametrization based on multiple regression analysis of ERA INTERIM data with cos(lon)
191 */
192static void era_interim_lon(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms) {
193 auto grid = T_ma.grid();
194
195 const array::Scalar
196 &h = geometry.ice_surface_elevation,
197 &lat = geometry.latitude,
198 &lon = geometry.longitude;
199
200 array::AccessScope list{&h, &lat, &lon, &T_ma, &T_ms};
201
202 for (auto p : grid->points()) {
203 const int i = p.i(), j = p.j();
204
205 double hmod = std::max(1000.0, h(i, j));
206 T_ma(i, j) = 273.15 + 37.49 - 0.0095 * hmod - 0.644 * lat(i, j) * (-1.0) + 2.146 * cos(3.1415 * (lon(i, j) + 110.0) / 180.0);
207 T_ms(i, j) = 273.15 + 15.74 - 0.0083 * hmod - 0.196 * lat(i, j) * (-1.0) + 0.225 * cos(3.1415 * (lon(i, j) + 110.0) / 180.0);
208
209 }
210}
211
212/*!
213 * Parameterization of the mean annual near-surface air temperature, see equation (1) in
214 * Martin et al, 2011.
215 */
216static double martin2011_mean_annual(double elevation, double latitude) {
217 return 273.15 + 30 - 0.0075 * elevation - 0.68775 * latitude * (-1.0);
218}
219
220/*!
221 * - annual mean temperature as in Martin et al. (2011)
222 * - no seasonal variation of air temperature
223 */
224static void martin2011(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms) {
225 auto grid = T_ma.grid();
226
227 const array::Scalar
228 &h = geometry.ice_surface_elevation,
229 &lat = geometry.latitude;
230
231 array::AccessScope list{&h, &lat, &T_ma, &T_ms};
232
233 for (auto p : grid->points()) {
234 const int i = p.i(), j = p.j();
235
236 T_ma(i, j) = martin2011_mean_annual(h(i, j), lat(i, j));
237 T_ms(i, j) = T_ma(i, j);
238 }
239}
240
241/*!
242 * - annual mean temperature as in Martin et al. (2011)
243 * - summer mean temperature computed as an anomaly to Huybrechts & DeWolde (1999)
244 */
245static void martin_huybrechts_dewolde(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms) {
246 auto grid = T_ma.grid();
247
248 const array::Scalar
249 &h = geometry.ice_surface_elevation,
250 &lat = geometry.latitude;
251
252 array::AccessScope list{&h, &lat, &T_ma, &T_ms};
253
254 for (auto p : grid->points()) {
255 const int i = p.i(), j = p.j();
256
257 // mean annual surface temperature as in Martin et al. 2011, equation (1)
258 T_ma(i, j) = 273.15 + 30 - 0.0075 * h(i, j) - 0.68775 * lat(i, j) * (-1.0);
259
260 double
261 TMA = huybrechts_dewolde_mean_annual(h(i, j), lat(i, j)),
262 TMS = huybrechts_dewolde_mean_summer(h(i, j), lat(i, j));
263
264 T_ms(i, j) = T_ma(i, j) + (TMS - TMA);
265 }
266}
267
268
269/*!
270 * Updates mean annual and mean summer (January) near-surface air temperatures. Note that
271 * the precipitation rate is time-independent and does not need to be updated.
272 */
273void PIK::update_impl(const Geometry &geometry, double t, double dt) {
274 (void) t;
275 (void) dt;
276
277 if (geometry.latitude.metadata().has_attribute("missing_at_bootstrap")) {
279 "latitude variable was missing at bootstrap;\n"
280 "PIK atmosphere model depends on latitude and would return nonsense!");
281 }
282
283 switch (m_parameterization) {
286 break;
287 case ERA_INTERIM:
289 break;
290 case ERA_INTERIM_SIN:
292 break;
293 case ERA_INTERIM_LON:
295 break;
298 break;
299 default:
300 case MARTIN:
302 break;
303 }
304}
305
306} // end of namespace atmosphere
307} // end of namespace pism
std::shared_ptr< const Config > m_config
configuration database used by this component
Definition Component.hh:160
std::shared_ptr< const Logger > m_log
logger (for easy access)
Definition Component.hh:164
array::Scalar2 ice_surface_elevation
Definition Geometry.hh:57
array::Scalar longitude
Definition Geometry.hh:42
array::Scalar latitude
Definition Geometry.hh:41
Combines the max. time step with the flag indicating if a restriction is active. Makes is possible to...
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
bool has_attribute(const std::string &name) const
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition Array.hh:66
std::shared_ptr< const Grid > grid() const
Definition Array.cc:134
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata object containing metadata for the compoment N.
Definition Array.cc:467
MaxTimestep max_timestep_impl(double t) const
Definition PIK.cc:108
@ MARTIN_HUYBRECHTS_DEWOLDE
Definition PIK.hh:38
void update_impl(const Geometry &geometry, double t, double dt)
Definition PIK.cc:273
PIK(std::shared_ptr< const Grid > g)
Definition PIK.cc:36
void init_impl(const Geometry &geometry)
Reads in the precipitation data from the input file.
Definition PIK.cc:58
Parameterization m_parameterization
Definition PIK.hh:41
array::Scalar m_air_temp_mean_summer
void init_internal(const std::string &input_filename, bool regrid, unsigned int start)
Read precipitation data from a given file.
virtual void init_impl(const Geometry &geometry)
Reads in the precipitation data from the input file.
array::Scalar m_air_temp_mean_annual
#define PISM_ERROR_LOCATION
static void martin2011(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms)
Definition PIK.cc:224
static void era_interim_sin(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms)
Definition PIK.cc:172
static void martin_huybrechts_dewolde(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms)
Definition PIK.cc:245
static void era_interim_lon(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms)
Definition PIK.cc:192
static void era_interim(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms)
Definition PIK.cc:152
static void huybrechts_dewolde(const Geometry &geometry, array::Scalar &T_ma, array::Scalar &T_ms)
Definition PIK.cc:132
static double huybrechts_dewolde_mean_summer(double surface_elevation, double latitude)
Definition PIK.cc:124
static double huybrechts_dewolde_mean_annual(double surface_elevation, double latitude)
Definition PIK.cc:116
static double martin2011_mean_annual(double elevation, double latitude)
Definition PIK.cc:216
static const double g
Definition exactTestP.cc:36