PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
OceanModel.cc
Go to the documentation of this file.
1 /* Copyright (C) 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2021, 2022, 2023 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/OceanModel.hh"
23 #include "pism/util/MaxTimestep.hh"
24 #include "pism/util/pism_utilities.hh"
25 #include "pism/geometry/Geometry.hh"
26 
27 namespace pism {
28 
29 namespace ocean {
30 
31 std::shared_ptr<array::Scalar> OceanModel::allocate_shelf_base_temperature(std::shared_ptr<const Grid> g) {
32  auto result = std::make_shared<array::Scalar>(g, "shelfbtemp");
33  result->metadata(0)
34  .long_name("ice temperature at the bottom of floating ice")
35  .units("Kelvin");
36  return result;
37 }
38 
39 std::shared_ptr<array::Scalar> OceanModel::allocate_shelf_base_mass_flux(std::shared_ptr<const Grid> g) {
40  auto result = std::make_shared<array::Scalar>(g, "shelfbmassflux");
41 
42  result->metadata(0)
43  .long_name("shelf base mass flux")
44  .units("kg m-2 s-1")
45  .output_units("kg m-2 year-1");
46  return result;
47 }
48 
49 std::shared_ptr<array::Scalar> OceanModel::allocate_water_column_pressure(std::shared_ptr<const Grid> g) {
50  auto result = std::make_shared<array::Scalar>(g, "average_water_column_pressure");
51 
52  result->metadata(0).long_name("vertically-averaged water column pressure").units("Pa");
53 
54  return result;
55 }
56 
57 // "modifier" constructor
58 OceanModel::OceanModel(std::shared_ptr<const Grid> g, std::shared_ptr<OceanModel> input)
59  : Component(g), m_input_model(input) {
60 
61  if (not input) {
63  }
64 }
65 
66 // "model" constructor
67 OceanModel::OceanModel(std::shared_ptr<const Grid> g)
68  : OceanModel(g, std::shared_ptr<OceanModel>()) {
69  // empty
70 }
71 
72 void OceanModel::init(const Geometry &geometry) {
73  this->init_impl(geometry);
74 }
75 
76 void OceanModel::init_impl(const Geometry &geometry) {
77  if (m_input_model) {
78  m_input_model->init(geometry);
79  } else {
80  double ice_density = m_config->get_number("constants.ice.density"),
81  water_density = m_config->get_number("constants.sea_water.density"),
82  g = m_config->get_number("constants.standard_gravity");
83 
84  compute_average_water_column_pressure(geometry, ice_density, water_density, g,
86  }
87 }
88 
89 void OceanModel::update(const Geometry &geometry, double t, double dt) {
90  this->update_impl(geometry, t, dt);
91 }
92 
95 }
96 
99 }
100 
103 }
104 
105 // pass-through default implementations for "modifiers"
106 
107 void OceanModel::update_impl(const Geometry &geometry, double t, double dt) {
108  if (m_input_model) {
109  m_input_model->update(geometry, t, dt);
110  } else {
111  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
112  }
113 }
114 
116  if (m_input_model) {
117  return m_input_model->max_timestep(t);
118  }
119  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
120 }
121 
122 void OceanModel::define_model_state_impl(const File &output) const {
123  if (m_input_model) {
124  return m_input_model->define_model_state(output);
125  }
126  // no state to define
127 }
128 
129 void OceanModel::write_model_state_impl(const File &output) const {
130  if (m_input_model) {
131  return m_input_model->write_model_state(output);
132  }
133  // no state to write
134 }
135 
137  if (m_input_model) {
138  return m_input_model->shelf_base_temperature();
139  }
140  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
141 }
142 
144  if (m_input_model) {
145  return m_input_model->shelf_base_mass_flux();
146  }
147  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "no input model");
148 }
149 
151  if (m_input_model) {
152  return m_input_model->average_water_column_pressure();
153  }
154  return *m_water_column_pressure;
155 }
156 
157 namespace diagnostics {
158 
159 /*! @brief Shelf base temperature. */
160 class PO_shelf_base_temperature : public Diag<OceanModel> {
161 public:
163  m_vars = { { m_sys, "shelfbtemp" } };
164  m_vars[0].long_name("ice temperature at the basal surface of ice shelves").units("Kelvin");
165  }
166 
167 protected:
168  std::shared_ptr<array::Array> compute_impl() const {
169  auto result = allocate<array::Scalar>("shelfbtemp");
170 
171  result->copy_from(model->shelf_base_temperature());
172 
173  return result;
174  }
175 };
176 
177 
178 /*! @brief Shelf base mass flux. */
179 class PO_shelf_base_mass_flux : public Diag<OceanModel> {
180 public:
182  m_vars = { { m_sys, "shelfbmassflux" } };
183  m_vars[0].long_name("mass flux at the basal surface of ice shelves").units("kg m-2 s-1");
184  }
185 
186 protected:
187  std::shared_ptr<array::Array> compute_impl() const {
188  auto result = allocate<array::Scalar>("shelfbmassflux");
189 
190  result->copy_from(model->shelf_base_mass_flux());
191 
192  return result;
193  }
194 };
195 
196 } // end of namespace diagnostics
197 
199  using namespace diagnostics;
200  DiagnosticList result = { { "shelfbtemp", Diagnostic::Ptr(new PO_shelf_base_temperature(this)) },
201  { "shelfbmassflux",
202  Diagnostic::Ptr(new PO_shelf_base_mass_flux(this)) } };
203 
204  if (m_input_model) {
205  return combine(m_input_model->diagnostics(), result);
206  }
207  return result;
208 }
209 
211  if (m_input_model) {
212  return m_input_model->ts_diagnostics();
213  }
214  return {};
215 }
216 
217 void compute_average_water_column_pressure(const Geometry &geometry, double ice_density,
218  double water_density, double g, array::Scalar &result) {
219 
220  auto grid = result.grid();
221 
222  const array::Scalar &bed = geometry.bed_elevation, &H = geometry.ice_thickness,
223  &z_s = geometry.sea_level_elevation;
224 
225  array::AccessScope l{ &bed, &H, &z_s, &result };
226 
227  ParallelSection loop(grid->com);
228  try {
229  for (auto p = grid->points(); p; p.next()) {
230  const int i = p.i(), j = p.j();
231 
232  result(i, j) = pism::average_water_column_pressure(H(i, j), bed(i, j), z_s(i, j), ice_density,
233  water_density, g);
234  }
235  } catch (...) {
236  loop.failed();
237  }
238  loop.check();
239 }
240 
241 
242 } // end of namespace ocean
243 } // end of namespace pism
std::shared_ptr< const Grid > grid() const
Definition: Component.cc:105
const Config::ConstPtr m_config
configuration database used by this component
Definition: Component.hh:158
DiagnosticList diagnostics() const
Definition: Component.cc:89
A class defining a common interface for most PISM sub-models.
Definition: Component.hh:118
const OceanModel * model
Definition: Diagnostic.hh:172
A template derived from Diagnostic, adding a "Model".
Definition: Diagnostic.hh:166
const units::System::Ptr m_sys
the unit system
Definition: Diagnostic.hh:116
std::vector< SpatialVariableMetadata > m_vars
metadata corresponding to NetCDF variables
Definition: Diagnostic.hh:120
std::shared_ptr< Diagnostic > Ptr
Definition: Diagnostic.hh:65
High-level PISM I/O class.
Definition: File.hh:56
array::Scalar1 sea_level_elevation
Definition: Geometry.hh:48
array::Scalar2 ice_thickness
Definition: Geometry.hh:51
array::Scalar2 bed_elevation
Definition: Geometry.hh:47
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
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition: Array.hh:65
std::shared_ptr< const Grid > grid() const
Definition: Array.cc:132
std::shared_ptr< OceanModel > m_input_model
Definition: OceanModel.hh:72
virtual MaxTimestep max_timestep_impl(double t) const
Definition: OceanModel.cc:115
const array::Scalar & shelf_base_mass_flux() const
Definition: OceanModel.cc:93
std::shared_ptr< array::Scalar > m_water_column_pressure
Definition: OceanModel.hh:73
virtual void define_model_state_impl(const File &output) const
The default (empty implementation).
Definition: OceanModel.cc:122
static std::shared_ptr< array::Scalar > allocate_shelf_base_temperature(std::shared_ptr< const Grid > g)
Definition: OceanModel.cc:31
static std::shared_ptr< array::Scalar > allocate_shelf_base_mass_flux(std::shared_ptr< const Grid > g)
Definition: OceanModel.cc:39
const array::Scalar & average_water_column_pressure() const
Definition: OceanModel.cc:101
static std::shared_ptr< array::Scalar > allocate_water_column_pressure(std::shared_ptr< const Grid > g)
Definition: OceanModel.cc:49
virtual DiagnosticList diagnostics_impl() const
Definition: OceanModel.cc:198
virtual TSDiagnosticList ts_diagnostics_impl() const
Definition: OceanModel.cc:210
void update(const Geometry &geometry, double t, double dt)
Definition: OceanModel.cc:89
virtual const array::Scalar & shelf_base_temperature_impl() const
Definition: OceanModel.cc:136
virtual const array::Scalar & shelf_base_mass_flux_impl() const
Definition: OceanModel.cc:143
virtual void init_impl(const Geometry &geometry)
Definition: OceanModel.cc:76
void init(const Geometry &geometry)
Definition: OceanModel.cc:72
virtual void write_model_state_impl(const File &output) const
The default (empty implementation).
Definition: OceanModel.cc:129
OceanModel(std::shared_ptr< const Grid > g, std::shared_ptr< OceanModel > input)
Definition: OceanModel.cc:58
virtual void update_impl(const Geometry &geometry, double t, double dt)
Definition: OceanModel.cc:107
virtual const array::Scalar & average_water_column_pressure_impl() const
Definition: OceanModel.cc:150
const array::Scalar & shelf_base_temperature() const
Definition: OceanModel.cc:97
A very rudimentary PISM ocean model.
Definition: OceanModel.hh:33
std::shared_ptr< array::Array > compute_impl() const
Definition: OceanModel.cc:187
std::shared_ptr< array::Array > compute_impl() const
Definition: OceanModel.cc:168
#define PISM_ERROR_LOCATION
bool ocean(int M)
An ocean cell (floating ice or ice-free).
Definition: Mask.hh:40
void compute_average_water_column_pressure(const Geometry &geometry, double ice_density, double water_density, double g, array::Scalar &result)
Definition: OceanModel.cc:217
double average_water_column_pressure(double ice_thickness, double bed, double floatation_level, double rho_ice, double rho_water, double g)
static const double g
Definition: exactTestP.cc:36
std::map< std::string, TSDiagnostic::Ptr > TSDiagnosticList
Definition: Diagnostic.hh:343
std::map< std::string, Diagnostic::Ptr > DiagnosticList
Definition: Diagnostic.hh:125
T combine(const T &a, const T &b)