PISM, A Parallel Ice Sheet Model  stable v2.1.1 committed by Constantine Khrulev on 2024-12-04 13:36:58 -0900
HayhurstCalving.cc
Go to the documentation of this file.
1 /* Copyright (C) 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 "pism/frontretreat/calving/HayhurstCalving.hh"
21 
22 #include "pism/util/Grid.hh"
23 #include "pism/util/error_handling.hh"
24 #include "pism/util/array/CellType.hh"
25 
26 namespace pism {
27 namespace calving {
28 
29 HayhurstCalving::HayhurstCalving(std::shared_ptr<const Grid> grid)
30  : Component(grid),
31  m_calving_rate(grid, "hayhurst_calving_rate")
32 {
34  .long_name("horizontal calving rate due to Hayhurst calving")
35  .units("m s-1")
36  .output_units("m day-1");
37 }
38 
40 
41  m_log->message(2,
42  "* Initializing the 'Hayhurst calving' mechanism...\n");
43 
44  m_B_tilde = m_config->get_number("calving.hayhurst_calving.B_tilde");
45  m_exponent_r = m_config->get_number("calving.hayhurst_calving.exponent_r");
46  m_sigma_threshold = m_config->get_number("calving.hayhurst_calving.sigma_threshold", "Pa");
47 
48  m_log->message(2,
49  " B tilde parameter: %3.3f MPa-%3.3f yr-1.\n", m_B_tilde, m_exponent_r);
50  m_log->message(2,
51  " Hayhurst calving threshold: %3.3f MPa.\n",
52  convert(m_sys, m_sigma_threshold, "Pa", "MPa"));
53 
54  if (fabs(m_grid->dx() - m_grid->dy()) / std::min(m_grid->dx(), m_grid->dy()) > 1e-2) {
56  "-calving hayhurst_calving using a non-square grid cell is not implemented (yet);\n"
57  "dx = %f, dy = %f, relative difference = %f",
58  m_grid->dx(), m_grid->dy(),
59  fabs(m_grid->dx() - m_grid->dy()) / std::max(m_grid->dx(), m_grid->dy()));
60  }
61 
62 }
63 
65  const array::Scalar &ice_thickness,
66  const array::Scalar &sea_level,
67  const array::Scalar &bed_elevation) {
68 
69  using std::min;
70 
71  const double
72  ice_density = m_config->get_number("constants.ice.density"),
73  water_density = m_config->get_number("constants.sea_water.density"),
74  gravity = m_config->get_number("constants.standard_gravity"),
75  // convert "Pa" to "MPa" and "m yr-1" to "m s-1"
76  unit_scaling = pow(1e-6, m_exponent_r) * convert(m_sys, 1.0, "m year-1", "m second-1");
77 
78  array::AccessScope list{&ice_thickness, &cell_type, &m_calving_rate, &sea_level,
79  &bed_elevation};
80 
81  for (auto pt = m_grid->points(); pt; pt.next()) {
82  const int i = pt.i(), j = pt.j();
83 
84  double water_depth = sea_level(i, j) - bed_elevation(i, j);
85 
86  if (cell_type.icy(i, j) and water_depth > 0.0) {
87  // note that ice_thickness > 0 at icy locations
88  assert(ice_thickness(i, j) > 0);
89 
90  double H = ice_thickness(i, j);
91 
92  // Note that for ice at floatation water_depth = H * (ice_density / water_density),
93  // so omega cannot exceed ice_density / water_density.
94  double omega = water_depth / H;
95 
96  // Extend the calving parameterization to ice shelves. This tweak should (I hope)
97  // prevent a feedback in which the creation of an ice shelf reduces the calving
98  // rate, which leads to an advance of the front and an even lower calving rate, etc.
99  if (omega > ice_density / water_density) {
100  // ice at the front is floating
101  double freeboard = (1.0 - ice_density / water_density) * H;
102  H = water_depth + freeboard;
103  omega = water_depth / H;
104  }
105 
106  // [\ref Mercenier2018] maximum tensile stress approximation
107  double sigma_0 = (0.4 - 0.45 * pow(omega - 0.065, 2.0)) * ice_density * gravity * H;
108 
109  // ensure that sigma_0 - m_sigma_threshold >= 0
110  sigma_0 = std::max(sigma_0, m_sigma_threshold);
111 
112  // [\ref Mercenier2018] equation 22
113  m_calving_rate(i, j) = (m_B_tilde * unit_scaling *
114  (1.0 - pow(omega, 2.8)) *
115  pow(sigma_0 - m_sigma_threshold, m_exponent_r) * H);
116  } else { // end of "if (ice_free_ocean and next_to_floating)"
117  m_calving_rate(i, j) = 0.0;
118  }
119  } // end of loop over grid points
120 
121  // Set calving rate *near* grounded termini to the average of grounded icy
122  // neighbors: front retreat code uses values at these locations (the rest is for
123  // visualization).
124 
126 
127  for (auto p = m_grid->points(); p; p.next()) {
128  const int i = p.i(), j = p.j();
129 
130  if (cell_type.ice_free(i, j) and cell_type.next_to_ice(i, j) ) {
131 
132  auto R = m_calving_rate.star(i, j);
133  auto M = cell_type.star(i, j);
134 
135  int N = 0;
136  double R_sum = 0.0;
137  for (auto d : {North, East, South, West}) {
138  if (mask::icy(M[d])) {
139  R_sum += R[d];
140  N++;
141  }
142  }
143 
144  if (N > 0) {
145  m_calving_rate(i, j) = R_sum / N;
146  }
147  }
148  }
149 }
150 
152  return m_calving_rate;
153 }
154 
156  return {{"hayhurst_calving_rate", Diagnostic::wrap(m_calving_rate)}};
157 }
158 
159 } // end of namespace calving
160 } // end of namespace pism
const units::System::Ptr m_sys
unit system used by this component
Definition: Component.hh:160
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
const std::shared_ptr< const Grid > m_grid
grid used by this component
Definition: Component.hh:156
A class defining a common interface for most PISM sub-models.
Definition: Component.hh:118
static Ptr wrap(const T &input)
Definition: Diagnostic.hh:160
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
VariableMetadata & long_name(const std::string &input)
VariableMetadata & output_units(const std::string &input)
VariableMetadata & units(const std::string &input)
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition: Array.hh:65
stencils::Star< T > star(int i, int j) const
Definition: Array2D.hh:79
void update_ghosts()
Updates ghost points.
Definition: Array.cc:693
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
Definition: Array.cc:553
bool next_to_ice(int i, int j) const
Ice-free margin (at least one of four neighbors has ice).
Definition: CellType.hh:87
bool ice_free(int i, int j) const
Definition: CellType.hh:54
bool icy(int i, int j) const
Definition: CellType.hh:42
const array::Scalar & calving_rate() const
DiagnosticList diagnostics_impl() const
HayhurstCalving(std::shared_ptr< const Grid > grid)
void update(const array::CellType1 &cell_type, const array::Scalar &ice_thickness, const array::Scalar &sea_level, const array::Scalar &bed_elevation)
#define PISM_ERROR_LOCATION
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:165
double min(const array::Scalar &input)
Finds minimum over all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:193
bool icy(int M)
Ice-filled cell (grounded or floating).
Definition: Mask.hh:48
double convert(System::Ptr system, double input, const std::string &spec1, const std::string &spec2)
Convert a quantity from unit1 to unit2.
Definition: Units.cc:70
std::map< std::string, Diagnostic::Ptr > DiagnosticList
Definition: Diagnostic.hh:125
@ North
Definition: stencils.hh:24
@ East
Definition: stencils.hh:24
@ South
Definition: stencils.hh:24
@ West
Definition: stencils.hh:24