PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
EigenCalving.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 "pism/frontretreat/calving/EigenCalving.hh"
21 
22 #include "pism/util/Grid.hh"
23 #include "pism/util/error_handling.hh"
24 #include "pism/util/array/CellType.hh"
25 #include "pism/stressbalance/StressBalance.hh"
26 
27 namespace pism {
28 namespace calving {
29 
30 EigenCalving::EigenCalving(std::shared_ptr<const Grid> grid)
31  : StressCalving(grid, 2) {
32 
33  m_K = m_config->get_number("calving.eigen_calving.K");
34 
35  m_calving_rate.metadata().set_name("eigen_calving_rate");
37  .long_name("horizontal calving rate due to eigen-calving")
38  .units("m s-1")
39  .output_units("m year-1");
40 }
41 
43 
44  m_log->message(2, "* Initializing the 'eigen-calving' mechanism...\n");
45 
46  if (fabs(m_grid->dx() - m_grid->dy()) / std::min(m_grid->dx(), m_grid->dy()) > 1e-2) {
47  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "-calving eigen_calving using a non-square grid cell is not implemented (yet);\n"
48  "dx = %f, dy = %f, relative difference = %f",
49  m_grid->dx(), m_grid->dy(),
50  fabs(m_grid->dx() - m_grid->dy()) / std::max(m_grid->dx(), m_grid->dy()));
51  }
52 
53  m_strain_rates.set(0.0);
54 }
55 
56 //! \brief Uses principal strain rates to apply "eigencalving" with constant K.
57 /*!
58  See equation (26) in [\ref Winkelmannetal2011].
59 */
60 void EigenCalving::update(const array::CellType &cell_type,
61  const array::Vector1 &ice_velocity) {
62 
63  // make a copy with a wider stencil
64  m_cell_type.copy_from(cell_type);
65  assert(m_cell_type.stencil_width() >= 2);
66 
67  // Distance (grid cells) from calving front where strain rate is evaluated
68  int offset = m_stencil_width;
69 
70  // eigenCalvOffset allows adjusting the transition from compressive to extensive flow
71  // regime
72  const double eigenCalvOffset = 0.0;
73 
76  m_strain_rates.update_ghosts();
77 
79 
80  // Compute the horizontal calving rate
81  for (auto pt = m_grid->points(); pt; pt.next()) {
82  const int i = pt.i(), j = pt.j();
83 
84  // Find partially filled or empty grid boxes on the icefree ocean, which
85  // have floating ice neighbors after the mass continuity step
87 
88  // Average of strain-rate eigenvalues in adjacent floating grid cells to be used for
89  // eigen-calving:
90  double
91  eigen1 = 0.0,
92  eigen2 = 0.0;
93  {
94  int N = 0;
95  for (int p = -1; p < 2; p += 2) {
96  const int I = i + p * offset;
97  if (m_cell_type.floating_ice(I, j) and not m_cell_type.ice_margin(I, j)) {
98  eigen1 += m_strain_rates(I, j).eigen1;
99  eigen2 += m_strain_rates(I, j).eigen2;
100  N += 1;
101  }
102  }
103 
104  for (int q = -1; q < 2; q += 2) {
105  const int J = j + q * offset;
106  if (m_cell_type.floating_ice(i, J) and not m_cell_type.ice_margin(i, J)) {
107  eigen1 += m_strain_rates(i, J).eigen1;
108  eigen2 += m_strain_rates(i, J).eigen2;
109  N += 1;
110  }
111  }
112 
113  if (N > 0) {
114  eigen1 /= N;
115  eigen2 /= N;
116  }
117  }
118 
119  // Calving law
120  //
121  // eigen1 * eigen2 has units [s^-2] and calving_rate_horizontal
122  // [m*s^1] hence, eigen_calving_K has units [m*s]
123  if (eigen2 > eigenCalvOffset and eigen1 > 0.0) {
124  // spreading in all directions
125  m_calving_rate(i, j) = m_K * eigen1 * (eigen2 - eigenCalvOffset);
126  } else {
127  m_calving_rate(i, j) = 0.0;
128  }
129 
130  } else { // end of "if (ice_free_ocean and next_to_floating)"
131  m_calving_rate(i, j) = 0.0;
132  }
133  } // end of the loop over grid points
134 }
135 
137  return {{"eigen_calving_rate", Diagnostic::wrap(m_calving_rate)}};
138 }
139 
140 } // end of namespace calving
141 } // 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
const std::shared_ptr< const Grid > m_grid
grid used by this component
Definition: Component.hh:156
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 & set_name(const std::string &name)
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
void copy_from(const Array2D< T > &source)
Definition: Array2D.hh:73
unsigned int stencil_width() const
Get the stencil width of the current Array. Returns 0 if ghosts are not available.
Definition: Array.cc:331
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
Definition: Array.cc:553
bool ice_margin(int i, int j) const
Ice margin (ice-filled with at least one of four neighbors ice-free).
Definition: CellType.hh:81
bool next_to_floating_ice(int i, int j) const
Definition: CellType.hh:91
bool floating_ice(int i, int j) const
Definition: CellType.hh:50
bool ice_free_ocean(int i, int j) const
Definition: CellType.hh:58
"Cell type" mask. Adds convenience methods to array::Scalar.
Definition: CellType.hh:30
void update(const array::CellType &cell_type, const array::Vector1 &ice_velocity)
Uses principal strain rates to apply "eigencalving" with constant K.
Definition: EigenCalving.cc:60
DiagnosticList diagnostics_impl() const
EigenCalving(std::shared_ptr< const Grid > grid)
Definition: EigenCalving.cc:30
array::Array2D< stressbalance::PrincipalStrainRates > m_strain_rates
array::CellType1 m_cell_type
An abstract class containing fields used by all stress-based calving methods.
#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
void compute_2D_principal_strain_rates(const array::Vector1 &V, const array::CellType1 &mask, array::Array2D< PrincipalStrainRates > &result)
Compute eigenvalues of the horizontal, vertically-integrated strain rate tensor.
std::map< std::string, Diagnostic::Ptr > DiagnosticList
Definition: Diagnostic.hh:125
const int J[]
Definition: ssafd_code.cc:34
const int I[]
Definition: ssafd_code.cc:24