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