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
AtmosphereModel.cc
Go to the documentation of this file.
1/* Copyright (C) 2016, 2017, 2018, 2019, 2020, 2022, 2023, 2024 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 <gsl/gsl_math.h> // GSL_NAN
21#include <memory>
22
23#include "pism/coupler/AtmosphereModel.hh"
24#include "pism/util/Time.hh"
25#include "pism/util/error_handling.hh"
26#include "pism/util/MaxTimestep.hh"
27#include "pism/util/Context.hh"
28
29namespace pism {
30namespace atmosphere {
31
32std::shared_ptr<array::Scalar> AtmosphereModel::allocate_temperature(std::shared_ptr<const Grid> grid) {
33 auto result = std::make_shared<array::Scalar>(grid, "air_temp");
34
35 result->metadata(0)
36 .long_name("mean annual near-surface air temperature")
37 .units("kelvin");
38
39 return result;
40}
41
42std::shared_ptr<array::Scalar> AtmosphereModel::allocate_precipitation(std::shared_ptr<const Grid> grid) {
43 auto result = std::make_shared<array::Scalar>(grid, "precipitation");
44
45 result->metadata(0)
46 .long_name("precipitation rate")
47 .units("kg m^-2 second^-1")
48 .output_units("kg m^-2 year^-1")
49 .standard_name("precipitation_flux");
50
51 return result;
52}
53
54AtmosphereModel::AtmosphereModel(std::shared_ptr<const Grid> g)
55 : Component(g) {
56 // empty
57}
58
59AtmosphereModel::AtmosphereModel(std::shared_ptr<const Grid> g,
60 std::shared_ptr<AtmosphereModel> input)
61 :Component(g), m_input_model(input) {
62 // empty
63}
64
65void AtmosphereModel::init(const Geometry &geometry) {
66 this->init_impl(geometry);
67}
68
69void AtmosphereModel::update(const Geometry &geometry, double t, double dt) {
70 this->update_impl(geometry, t, dt);
71}
72
74 return this->precipitation_impl();
75}
76
80
84
88
89void AtmosphereModel::init_timeseries(const std::vector<double> &ts) const {
90 this->init_timeseries_impl(ts);
91}
92
93void AtmosphereModel::precip_time_series(int i, int j, std::vector<double> &result) const {
94 result.resize(m_ts_times.size());
95 this->precip_time_series_impl(i, j, result);
96}
97
98void AtmosphereModel::temp_time_series(int i, int j, std::vector<double> &result) const {
99 result.resize(m_ts_times.size());
100 this->temp_time_series_impl(i, j, result);
101}
102
103namespace diagnostics {
104
105/*! @brief Instantaneous near-surface air temperature. */
106class AirTemperatureSnapshot : public Diag<AtmosphereModel> {
107public:
109 m_vars = { { m_sys, "air_temp_snapshot" } };
110 m_vars[0].long_name("instantaneous value of the near-surface air temperature").units("kelvin");
111 }
112
113protected:
114 std::shared_ptr<array::Array> compute_impl() const {
115
116 auto result = allocate<array::Scalar>("air_temp_snapshot");
117
118 std::vector<double> current_time = { m_grid->ctx()->time()->current() };
119 std::vector<double> temperature = { 0.0 };
120
121 model->init_timeseries(current_time);
122
123 model->begin_pointwise_access();
124
125 array::AccessScope list(*result);
126 ParallelSection loop(m_grid->com);
127 try {
128 for (auto p = m_grid->points(); p; p.next()) {
129 const int i = p.i(), j = p.j();
130
131 model->temp_time_series(i, j, temperature);
132
133 (*result)(i, j) = temperature[0];
134 }
135 } catch (...) {
136 loop.failed();
137 }
138 loop.check();
139
140 model->end_pointwise_access();
141
142 return result;
143 }
144};
145
146/*! @brief Effective near-surface mean-annual air temperature. */
147class AirTemperature : public Diag<AtmosphereModel> {
148public:
150 m_vars = { { m_sys, "effective_air_temp" } };
151 m_vars[0].long_name("effective mean-annual near-surface air temperature").units("kelvin");
152 }
153
154protected:
155 std::shared_ptr<array::Array> compute_impl() const {
156 auto result = allocate<array::Scalar>("effective_air_temp");
157
158 result->copy_from(model->air_temperature());
159
160 return result;
161 }
162};
163
164/*! @brief Effective precipitation rate (average over time step). */
165class Precipitation : public Diag<AtmosphereModel> {
166public:
168 m_vars = { { m_sys, "effective_precipitation" } };
169 m_vars[0]
170 .long_name("effective precipitation rate")
171 .standard_name("precipitation_flux")
172 .units("kg m^-2 second^-1")
173 .output_units("kg m^-2 year^-1");
174 }
175
176protected:
177 std::shared_ptr<array::Array> compute_impl() const {
178 auto result = allocate<array::Scalar>("effective_precipitation");
179
180 result->copy_from(model->precipitation());
181
182 return result;
183 }
184};
185
186} // end of namespace diagnostics
187
188void AtmosphereModel::update_impl(const Geometry &geometry, double t, double dt) {
189 if (m_input_model) {
190 m_input_model->update_impl(geometry, t, dt);
191 }
192}
193
195 if (m_input_model) {
196 return m_input_model->max_timestep(my_t);
197 }
198 return MaxTimestep("atmosphere model");
199}
200
202 using namespace diagnostics;
203
204 DiagnosticList result = {
205 {"air_temp_snapshot", Diagnostic::Ptr(new AirTemperatureSnapshot(this))},
206 {"effective_air_temp", Diagnostic::Ptr(new AirTemperature(this))},
207 {"effective_precipitation", Diagnostic::Ptr(new Precipitation(this))},
208 };
209
210 if (m_input_model) {
211 result = combine(result, m_input_model->diagnostics());
212 }
213
214 return result;
215}
216
218 if (m_input_model) {
219 return m_input_model->ts_diagnostics();
220 }
221
222 return {};
223}
224
226 if (m_input_model) {
227 m_input_model->define_model_state(output);
228 }
229}
230
232 if (m_input_model) {
233 m_input_model->write_model_state(output);
234 }
235}
236
238 if (m_input_model) {
239 return m_input_model->precipitation();
240 }
241 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
242}
243
245 if (m_input_model) {
246 return m_input_model->air_temperature();
247 }
248 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
249}
250
252 if (m_input_model) {
253 m_input_model->begin_pointwise_access();
254 } else {
255 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
256 }
257}
258
260 if (m_input_model) {
261 m_input_model->end_pointwise_access();
262 } else {
263 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
264 }
265}
266
267void AtmosphereModel::temp_time_series_impl(int i, int j, std::vector<double> &result) const {
268 if (m_input_model) {
269 m_input_model->temp_time_series(i, j, result);
270 } else {
271 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
272 }
273}
274
275void AtmosphereModel::precip_time_series_impl(int i, int j, std::vector<double> &result) const {
276 if (m_input_model) {
277 m_input_model->precip_time_series(i, j, result);
278 } else {
279 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
280 }
281}
282
283void AtmosphereModel::init_timeseries_impl(const std::vector<double> &ts) const {
284 if (m_input_model) {
285 m_input_model->init_timeseries(ts);
286 m_ts_times = ts;
287 } else {
288 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
289 }
290}
291
292} // end of namespace atmosphere
293} // end of namespace pism
std::shared_ptr< const Grid > grid() const
Definition Component.cc:105
DiagnosticList diagnostics() const
Definition Component.cc:89
A class defining a common interface for most PISM sub-models.
Definition Component.hh:118
const AtmosphereModel * model
A template derived from Diagnostic, adding a "Model".
const units::System::Ptr m_sys
the unit system
std::vector< SpatialVariableMetadata > m_vars
metadata corresponding to NetCDF variables
std::shared_ptr< Diagnostic > Ptr
Definition Diagnostic.hh:65
std::shared_ptr< const Grid > m_grid
the grid
High-level PISM I/O class.
Definition File.hh:55
Combines the max. time step with the flag indicating if a restriction is active. Makes is possible to...
void failed()
Indicates a failure of a parallel section.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition Array.hh:64
virtual DiagnosticList diagnostics_impl() const
void update(const Geometry &geometry, double t, double dt)
virtual TSDiagnosticList ts_diagnostics_impl() const
virtual void update_impl(const Geometry &geometry, double t, double dt)=0
virtual void write_model_state_impl(const File &output) const
The default (empty implementation).
virtual void define_model_state_impl(const File &output) const
The default (empty implementation).
virtual void init_timeseries_impl(const std::vector< double > &ts) const
const array::Scalar & air_temperature() const
Sets result to the mean near-surface air temperature, in kelvin.
static std::shared_ptr< array::Scalar > allocate_temperature(std::shared_ptr< const Grid > grid)
void init_timeseries(const std::vector< double > &ts) const
const array::Scalar & precipitation() const
Sets result to the mean precipitation, in "kg m-2 second-1".
virtual void init_impl(const Geometry &geometry)=0
virtual const array::Scalar & precipitation_impl() const
void init(const Geometry &geometry)
virtual void precip_time_series_impl(int i, int j, std::vector< double > &result) const
virtual void begin_pointwise_access_impl() const
std::shared_ptr< AtmosphereModel > m_input_model
void temp_time_series(int i, int j, std::vector< double > &result) const
Sets a pre-allocated N-element array "result" to the time-series of near-surface air temperature (kel...
virtual const array::Scalar & air_temperature_impl() const
virtual void end_pointwise_access_impl() const
AtmosphereModel(std::shared_ptr< const Grid > g)
virtual void temp_time_series_impl(int i, int j, std::vector< double > &result) const
static std::shared_ptr< array::Scalar > allocate_precipitation(std::shared_ptr< const Grid > grid)
virtual MaxTimestep max_timestep_impl(double my_t) const
void precip_time_series(int i, int j, std::vector< double > &result) const
Sets a pre-allocated N-element array "result" to the time-series of ice-equivalent precipitation (m/s...
A purely virtual class defining the interface of a PISM Atmosphere Model.
std::shared_ptr< array::Array > compute_impl() const
Instantaneous near-surface air temperature.
std::shared_ptr< array::Array > compute_impl() const
Effective near-surface mean-annual air temperature.
std::shared_ptr< array::Array > compute_impl() const
Effective precipitation rate (average over time step).
#define PISM_ERROR_LOCATION
static const double g
Definition exactTestP.cc:36
std::map< std::string, TSDiagnostic::Ptr > TSDiagnosticList
std::map< std::string, Diagnostic::Ptr > DiagnosticList
T combine(const T &a, const T &b)