PISM, A Parallel Ice Sheet Model  stable v2.0.4 committed by Constantine Khrulev on 2022-05-25 12:02:27 -0800
AtmosphereModel.cc
Go to the documentation of this file.
1 /* Copyright (C) 2016, 2017, 2018, 2019, 2020 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 
22 #include "pism/coupler/AtmosphereModel.hh"
23 #include "pism/util/Time.hh"
24 #include "pism/util/error_handling.hh"
25 #include "pism/util/MaxTimestep.hh"
26 #include "pism/util/Context.hh"
27 
28 namespace pism {
29 namespace atmosphere {
30 
32  IceModelVec2S::Ptr result(new IceModelVec2S(grid, "air_temp", WITHOUT_GHOSTS));
33 
34  result->set_attrs("climate_forcing", "mean annual near-surface air temperature",
35  "Kelvin", "Kelvin", "", 0);
36 
37  return result;
38 }
39 
41  IceModelVec2S::Ptr result(new IceModelVec2S(grid, "precipitation", WITHOUT_GHOSTS));
42  result->set_attrs("climate_forcing", "precipitation rate",
43  "kg m-2 second-1", "kg m-2 year-1",
44  "precipitation_flux", 0);
45 
46  return result;
47 }
48 
50  : Component(g) {
51  // empty
52 }
53 
55  std::shared_ptr<AtmosphereModel> input)
56  :Component(g), m_input_model(input) {
57  // empty
58 }
59 
60 void AtmosphereModel::init(const Geometry &geometry) {
61  this->init_impl(geometry);
62 }
63 
64 void AtmosphereModel::update(const Geometry &geometry, double t, double dt) {
65  this->update_impl(geometry, t, dt);
66 }
67 
69  return this->mean_precipitation_impl();
70 }
71 
73  return this->mean_annual_temp_impl();
74 }
75 
78 }
79 
82 }
83 
84 void AtmosphereModel::init_timeseries(const std::vector<double> &ts) const {
85  this->init_timeseries_impl(ts);
86 }
87 
88 void AtmosphereModel::precip_time_series(int i, int j, std::vector<double> &result) const {
89  result.resize(m_ts_times.size());
90  this->precip_time_series_impl(i, j, result);
91 }
92 
93 void AtmosphereModel::temp_time_series(int i, int j, std::vector<double> &result) const {
94  result.resize(m_ts_times.size());
95  this->temp_time_series_impl(i, j, result);
96 }
97 
98 namespace diagnostics {
99 
100 /*! @brief Instantaneous near-surface air temperature. */
101 class AirTemperatureSnapshot : public Diag<AtmosphereModel> {
102 public:
104  : Diag<AtmosphereModel>(m) {
105 
106  /* set metadata: */
107  m_vars = {SpatialVariableMetadata(m_sys, "air_temp_snapshot")};
108 
109  set_attrs("instantaneous value of the near-surface air temperature",
110  "", // no standard name
111  "Kelvin", "Kelvin", 0);
112  }
113 protected:
115 
116  IceModelVec2S::Ptr result(new IceModelVec2S(m_grid, "air_temp_snapshot", WITHOUT_GHOSTS));
117  result->metadata(0) = m_vars[0];
118 
119  std::vector<double> current_time(1, m_grid->ctx()->time()->current());
120  std::vector<double> temperature(1, 0.0);
121 
122  model->init_timeseries(current_time);
123 
124  model->begin_pointwise_access();
125 
126  IceModelVec::AccessList list(*result);
127  ParallelSection loop(m_grid->com);
128  try {
129  for (Points p(*m_grid); p; p.next()) {
130  const int i = p.i(), j = p.j();
131 
132  model->temp_time_series(i, j, temperature);
133 
134  (*result)(i, j) = temperature[0];
135  }
136  } catch (...) {
137  loop.failed();
138  }
139  loop.check();
140 
141  model->end_pointwise_access();
142 
143  return result;
144  }
145 };
146 
147 /*! @brief Effective near-surface mean-annual air temperature. */
148 class AirTemperature : public Diag<AtmosphereModel> {
149 public:
151  : Diag<AtmosphereModel>(m) {
152 
153  /* set metadata: */
154  m_vars = {SpatialVariableMetadata(m_sys, "effective_air_temp")};
155 
156  set_attrs("effective mean-annual near-surface air temperature", "",
157  "Kelvin", "Kelvin", 0);
158  }
159 protected:
161 
162  IceModelVec2S::Ptr result(new IceModelVec2S(m_grid, "effective_air_temp", WITHOUT_GHOSTS));
163  result->metadata(0) = m_vars[0];
164 
165  result->copy_from(model->mean_annual_temp());
166 
167  return result;
168  }
169 };
170 
171 /*! @brief Effective precipitation rate (average over time step). */
172 class Precipitation : public Diag<AtmosphereModel> {
173 public:
175  : Diag<AtmosphereModel>(m) {
176 
177  /* set metadata: */
178  m_vars = {SpatialVariableMetadata(m_sys, "effective_precipitation")};
179 
180  set_attrs("effective precipitation rate",
181  "precipitation_flux",
182  "kg m-2 second-1", "kg m-2 year-1", 0);
183  }
184 protected:
186 
187  IceModelVec2S::Ptr result(new IceModelVec2S(m_grid, "effective_precipitation", WITHOUT_GHOSTS));
188  result->metadata(0) = m_vars[0];
189 
190  result->copy_from(model->mean_precipitation());
191 
192  return result;
193  }
194 };
195 
196 } // end of namespace diagnostics
197 
198 void AtmosphereModel::update_impl(const Geometry &geometry, double t, double dt) {
199  if (m_input_model) {
200  m_input_model->update_impl(geometry, t, dt);
201  }
202 }
203 
205  if (m_input_model) {
206  return m_input_model->max_timestep(my_t);
207  } else {
208  return MaxTimestep("atmosphere model");
209  }
210 }
211 
213  using namespace diagnostics;
214 
215  DiagnosticList result = {
216  {"air_temp_snapshot", Diagnostic::Ptr(new AirTemperatureSnapshot(this))},
217  {"effective_air_temp", Diagnostic::Ptr(new AirTemperature(this))},
218  {"effective_precipitation", Diagnostic::Ptr(new Precipitation(this))},
219  };
220 
221  if (m_input_model) {
222  result = combine(result, m_input_model->diagnostics());
223  }
224 
225  return result;
226 }
227 
229  if (m_input_model) {
230  return m_input_model->ts_diagnostics();
231  }
232 
233  return {};
234 }
235 
237  if (m_input_model) {
238  m_input_model->define_model_state(output);
239  }
240 }
241 
243  if (m_input_model) {
244  m_input_model->write_model_state(output);
245  }
246 }
247 
249  if (m_input_model) {
250  return m_input_model->mean_precipitation();
251  } else {
252  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
253  }
254 }
255 
257  if (m_input_model) {
258  return m_input_model->mean_annual_temp();
259  } else {
260  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
261  }
262 }
263 
265  if (m_input_model) {
266  m_input_model->begin_pointwise_access();
267  } else {
268  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
269  }
270 }
271 
273  if (m_input_model) {
274  m_input_model->end_pointwise_access();
275  } else {
276  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
277  }
278 }
279 
280 void AtmosphereModel::temp_time_series_impl(int i, int j, std::vector<double> &result) const {
281  if (m_input_model) {
282  m_input_model->temp_time_series(i, j, result);
283  } else {
284  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
285  }
286 }
287 
288 void AtmosphereModel::precip_time_series_impl(int i, int j, std::vector<double> &result) const {
289  if (m_input_model) {
290  m_input_model->precip_time_series(i, j, result);
291  } else {
292  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
293  }
294 }
295 
296 void AtmosphereModel::init_timeseries_impl(const std::vector<double> &ts) const {
297  if (m_input_model) {
298  m_input_model->init_timeseries(ts);
299  m_ts_times = ts;
300  } else {
301  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
302  }
303 }
304 
305 } // end of namespace atmosphere
306 } // end of namespace pism
Makes sure that we call begin_access() and end_access() for all accessed IceModelVecs.
Definition: iceModelVec.hh:59
IceGrid::ConstPtr 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:101
const AtmosphereModel * model
Definition: Diagnostic.hh:166
A template derived from Diagnostic, adding a "Model".
Definition: Diagnostic.hh:161
const units::System::Ptr m_sys
the unit system
Definition: Diagnostic.hh:108
std::vector< SpatialVariableMetadata > m_vars
metadata corresponding to NetCDF variables
Definition: Diagnostic.hh:112
std::shared_ptr< Diagnostic > Ptr
Definition: Diagnostic.hh:64
IceGrid::ConstPtr m_grid
the grid
Definition: Diagnostic.hh:106
void set_attrs(const std::string &long_name, const std::string &standard_name, const std::string &units, const std::string &glaciological_units, unsigned int N=0)
A method for setting common variable attributes.
Definition: Diagnostic.cc:132
High-level PISM I/O class.
Definition: File.hh:51
std::shared_ptr< const IceGrid > ConstPtr
Definition: IceGrid.hh:233
std::shared_ptr< IceModelVec2S > Ptr
Definition: iceModelVec.hh:341
std::shared_ptr< IceModelVec > Ptr
Definition: iceModelVec.hh:206
Combines the max. time step with the flag indicating if a restriction is active. Makes is possible to...
Definition: MaxTimestep.hh:31
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
Spatial NetCDF variable (corresponding to a 2D or 3D scalar field).
virtual DiagnosticList diagnostics_impl() const
void update(const Geometry &geometry, double t, double dt)
virtual TSDiagnosticList ts_diagnostics_impl() const
const IceModelVec2S & mean_annual_temp() const
Sets result to the mean annual near-surface air temperature, in degrees Kelvin.
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
virtual const IceModelVec2S & mean_precipitation_impl() const
void init_timeseries(const std::vector< double > &ts) const
virtual void init_impl(const Geometry &geometry)=0
virtual const IceModelVec2S & mean_annual_temp_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 (deg...
const IceModelVec2S & mean_precipitation() const
Sets result to the mean precipitation, in m/s ice equivalent.
AtmosphereModel(IceGrid::ConstPtr g)
virtual void end_pointwise_access_impl() const
virtual void temp_time_series_impl(int i, int j, std::vector< double > &result) const
virtual MaxTimestep max_timestep_impl(double my_t) const
std::vector< double > m_ts_times
static IceModelVec2S::Ptr allocate_precipitation(IceGrid::ConstPtr grid)
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...
static IceModelVec2S::Ptr allocate_temperature(IceGrid::ConstPtr grid)
A purely virtual class defining the interface of a PISM Atmosphere Model.
Instantaneous near-surface air temperature.
Effective near-surface mean-annual air temperature.
Effective precipitation rate (average over time step).
#define PISM_ERROR_LOCATION
static const double g
Definition: exactTestP.cc:39
std::map< std::string, TSDiagnostic::Ptr > TSDiagnosticList
Definition: Diagnostic.hh:346
std::map< std::string, Diagnostic::Ptr > DiagnosticList
Definition: Diagnostic.hh:117
T combine(const T &a, const T &b)
@ WITHOUT_GHOSTS
Definition: iceModelVec.hh:49