Loading [MathJax]/jax/input/TeX/config.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
basal_resistance.cc
Go to the documentation of this file.
1// Copyright (C) 2004-2017, 2019, 2021, 2023, 2024 Jed Brown, Ed Bueler, and Constantine Khroulev
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#include <cmath> // pow, sqrt
20
21#include "pism/basalstrength/basal_resistance.hh"
22
23#include "pism/util/ConfigInterface.hh"
24#include "pism/util/Logger.hh"
25
26namespace pism {
27
28static double square(double x) {
29 return x * x;
30}
31
32/* Purely plastic */
33
35 m_plastic_regularize = config.get_number("basal_resistance.plastic.regularization", "m second-1");
36}
37
39 int threshold,
40 units::System::Ptr system) const {
41 log.message(threshold, "Using purely plastic till with eps = %10.5e m year-1.\n",
42 units::convert(system, m_plastic_regularize, "m second^-1", "m year^-1"));
43}
44
45
46//! Compute the drag coefficient for the basal shear stress.
47double IceBasalResistancePlasticLaw::drag(double tauc, double vx, double vy) const {
48 const double magreg2 = square(m_plastic_regularize) + square(vx) + square(vy);
49
50 return tauc / sqrt(magreg2);
51}
52
53//! Compute the drag coefficient and its derivative with respect to \f$ \alpha = \frac 1 2 (u_x^2 + u_y^2) \f$
54/**
55 * @f{align*}{
56 * \beta &= \frac{\tau_{c}}{|\mathbf{u}|} = \tau_{c}\cdot (|\mathbf{u}|^{2})^{-1/2}\\
57 * \diff{\beta}{\frac12 |\mathbf{u}|^{2}} &= -\frac{1}{|\mathbf{u}|^{2}}\cdot \beta
58 * @f}
59 */
60void IceBasalResistancePlasticLaw::drag_with_derivative(double tauc, double vx, double vy,
61 double *beta, double *dbeta) const {
62 const double magreg2 = square(m_plastic_regularize) + square(vx) + square(vy);
63
64 *beta = tauc / sqrt(magreg2);
65
66 if (dbeta) {
67 *dbeta = -1 * (*beta) / magreg2;
68 }
69}
70
71/* Pseudo-plastic */
72
75 m_q = config.get_number("basal_resistance.pseudo_plastic.q");
76 m_u_threshold = config.get_number("basal_resistance.pseudo_plastic.u_threshold", "m second-1");
77 m_sliding_scale_factor_reduces_tauc = config.get_number("basal_resistance.pseudo_plastic.sliding_scale_factor");
78
80}
81
83 int threshold,
84 units::System::Ptr system) const {
85
86 if (m_q == 1.0) {
87 log.message(threshold,
88 "Using linearly viscous till with u_threshold = %.2f m year-1.\n",
89 units::convert(system, m_u_threshold, "m second^-1", "m year^-1"));
90 } else {
91 log.message(threshold,
92 "Using pseudo-plastic till with eps = %10.5e m year-1, q = %.4f,"
93 " and u_threshold = %.2f m year-1.\n",
94 units::convert(system, m_plastic_regularize, "m second^-1", "m year^-1"),
95 m_q,
96 units::convert(system, m_u_threshold, "m second^-1", "m year^-1"));
97 }
98}
99
100//! Compute the drag coefficient for the basal shear stress.
101/*!
102
103 The basal shear stress term @f$ \tau_b @f$ in the SSA stress balance
104 for ice is minus the return value here times (vx,vy). Thus this
105 method computes the basal shear stress as
106
107 @f[ \tau_b = - \frac{\tau_c}{|\mathbf{U}|^{1-q} U_{\mathtt{th}}^q} \mathbf{U} @f]
108
109 where @f$ \tau_b=(\tau_{(b)x},\tau_{(b)y}) @f$ , @f$ U=(u,v) @f$ ,
110 @f$ q= @f$ `pseudo_q`, and @f$ U_{\mathtt{th}}= @f$
111 `pseudo_u_threshold`. Typical values for the constants are
112 @f$ q=0.25 @f$ and @f$ U_{\mathtt{th}} = 100 @f$ m year-1.
113
114 The linearly-viscous till case pseudo_q = 1.0 is allowed, in which
115 case @f$ \beta = \tau_c/U_{\mathtt{th}} @f$ . The purely-plastic till
116 case pseudo_q = 0.0 is also allowed; note that there is still a
117 regularization with data member plastic_regularize.
118
119 One can scale tauc if desired:
120
121 A scale factor of @f$ A @f$ is intended to increase basal sliding rate
122 by @f$ A @f$ . It would have exactly this effect \e if the driving
123 stress were \e hypothetically completely held by the basal
124 resistance. Thus this scale factor is used to reduce (if
125 `-sliding_scale_factor_reduces_tauc` @f$ A @f$ with @f$ A > 1 @f$) or increase (if @f$ A <
126 1 @f$) the value of the (pseudo-) yield stress `tauc`. The concept
127 behind this is described at
128 [the SeaRISE wiki](https://web.archive.org/web/20120126164914/http://websrv.cs.umt.edu/isis/index.php/Category_1:_Whole_Ice_Sheet#Initial_Experiment_-_E1_-_Increased_Basal_Lubrication).
129
130 Specifically, the concept behind this mechanism is to suppose
131 equality of driving and basal shear stresses,
132
133 @f[ \rho g H \nabla h = \frac{\tau_c}{|\mathbf{U}|^{1-q} U_{\mathtt{th}}^q} \mathbf{U}. @f]
134
135 (*For emphasis:* The membrane stress held by the ice itself is
136 missing from this incomplete stress balance.) Thus the pseudo yield
137 stress @f$ \tau_c @f$ would be related to the sliding speed
138 @f$ |\mathbf{U}| @f$ by
139
140 @f[ |\mathbf{U}| = \frac{C}{\tau_c^{1/q}} \f]
141
142 for some (geometry-dependent) constant @f$ C @f$ . Multiplying
143 @f$ |\mathbf{U}| @f$ by @f$ A @f$ in this equation corresponds to
144 dividing @f$ \tau_c @f$ by @f$ A^q @f$ .
145
146 Note that the mechanism has no effect whatsoever if @f$ q=0 @f$ , which
147 is the purely plastic case. In that case there is \e no direct
148 relation between the yield stress and the sliding velocity, and the
149 difference between the driving stress and the yield stress is
150 entirely held by the membrane stresses. (There is also no singular
151 mathematical operation as @f$ A^q = A^0 = 1 @f$ .)
152*/
153double IceBasalResistancePseudoPlasticLaw::drag(double tauc, double vx, double vy) const {
154 const double magreg2 = square(m_plastic_regularize) + square(vx) + square(vy);
155
156 double Aq = 1.0;
157
160 }
161
162 return (tauc / Aq) * pow(magreg2, 0.5*(m_q - 1)) * m_u_threshold_factor;
163}
164
165
166//! Compute the drag coefficient and its derivative with respect to @f$ \alpha = \frac 1 2 (u_x^2 + u_y^2) @f$
167/**
168 * @f{align*}{
169 * \beta &= \frac{\tau_{c}}{u_{\text{threshold}}^q}\cdot (|u|^{2})^{\frac{q-1}{2}} \\
170 * \diff{\beta}{\frac12 |\mathbf{u}|^{2}} &= \frac{\tau_{c}}{u_{\text{threshold}}^q}\cdot \frac{q-1}{2}\cdot (|\mathbf{u}|^{2})^{\frac{q-1}{2} - 1}\cdot 2 \\
171 * &= \frac{q-1}{|\mathbf{u}|^{2}}\cdot \beta(\mathbf{u}) \\
172 * @f}
173 */
174void IceBasalResistancePseudoPlasticLaw::drag_with_derivative(double tauc, double vx, double vy,
175 double *beta, double *dbeta) const
176{
177 const double magreg2 = square(m_plastic_regularize) + square(vx) + square(vy);
178
181 *beta = (tauc / Aq) * pow(magreg2, 0.5*(m_q - 1)) * m_u_threshold_factor;
182 } else {
183 *beta = tauc * pow(magreg2, 0.5*(m_q - 1)) * m_u_threshold_factor;
184 }
185
186 if (dbeta) {
187 *dbeta = (m_q - 1) * (*beta) / magreg2;
188 }
189
190}
191
192/* Regularized Coulomb */
193
196 m_q = config.get_number("basal_resistance.pseudo_plastic.q");
197 m_u_threshold = config.get_number("basal_resistance.pseudo_plastic.u_threshold", "m second-1");
198 m_sliding_scale_factor_reduces_tauc = config.get_number("basal_resistance.pseudo_plastic.sliding_scale_factor");
199}
200
202 int threshold,
203 units::System::Ptr system) const {
204 log.message(threshold,
205 "Using regularized Coulomb till with eps = %10.5e m year-1, q = %.4f,"
206 " and u_threshold = %.2f m year-1.\n",
207 units::convert(system, m_plastic_regularize, "m second^-1", "m year^-1"),
208 m_q,
209 units::convert(system, m_u_threshold, "m second^-1", "m year^-1"));
210}
211
212double IceBasalResistanceRegularizedLaw::drag(double tauc, double vx, double vy) const {
213 const double magreg2sqr = sqrt(square(m_plastic_regularize) + square(vx) + square(vy));
214
217 return (tauc / Aq) * pow(magreg2sqr, (m_q - 1)) * pow((magreg2sqr + m_u_threshold), -m_q);
218 } else {
219 return tauc * pow(magreg2sqr, (m_q - 1)) * pow((magreg2sqr + m_u_threshold), -m_q);
220 }
221}
222
223//! Compute the drag coefficient and its derivative with respect to @f$ \alpha = \frac 1 2 (u_x^2 + u_y^2) @f$
224/**
225 * @f{align*}{
226 * \beta &= \frac{\tau_{c}}{ \left( (|u|^{2})^{\frac12} + u_{\text{threshold}} \right)^{q} }\cdot (|\mathbf{u}|^{2})^{\frac{q-1}{2}} \\
227 * \diff{\beta}{\frac12 |\mathbf{u}|^{2}} &= \frac{\tau_{c}}{ \left( (|\mathbf{u}|^{2})^{\frac12} + u_{\text{threshold}}\right)^{q} }\cdot \frac{q-1}{2}\cdot (|\mathbf{u}|^{2})^{\frac{q-1}{2} - 1}\cdot 2 - \frac{\tau_{c}}{ \left( (|\mathbf{u}|^{2})^{\frac12} + u_{\text{threshold}}\right)^{q+1} }\cdot \frac{2 \cdot q }{(|\mathbf{u}|^{2})^{\frac12}} \cdot (|\mathbf{u}|^{2})^{\frac{q-1}{2} } \\
228 * &= \left( \frac{q-1}{|\mathbf{u}|^{2}} - \frac{q}{|\mathbf{u}| \cdot ( |\mathbf{u}| + u_{\text{threshold}}) } \right) \cdot \beta(\mathbf{u})\\
229 * @f}
230 * Same parameters are used as in the pseudo-plastic case, namely @f$ q, u_{\text{threshold}}, A_q @f$.
231 * It should be noted, that in the original equation (3) in Zoet et al, 2020 the exponent @f$ q=1/p @f$ is used.
232 */
233void IceBasalResistanceRegularizedLaw::drag_with_derivative(double tauc, double vx, double vy,
234 double *beta, double *dbeta) const {
235 const double magreg2 = square(m_plastic_regularize) + square(vx) + square(vy),
236 magreg2sqr = sqrt(magreg2);
237
240 *beta = (tauc / Aq) * pow(magreg2sqr, (m_q - 1)) * pow((magreg2sqr + m_u_threshold), -m_q);
241 } else {
242 *beta = tauc * pow(magreg2sqr, (m_q - 1)) * pow((magreg2sqr + m_u_threshold), -m_q);
243 }
244
245 if (dbeta) {
246 *dbeta = (((m_q - 1) / magreg2) - (m_q / (magreg2sqr * (magreg2sqr + m_u_threshold)))) * (*beta);
247 }
248}
249
250
251} // end of namespace pism
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
A class for storing and accessing PISM configuration flags and parameters.
virtual double drag(double tauc, double vx, double vy) const
Compute the drag coefficient for the basal shear stress.
virtual void print_info(const Logger &log, int threshold, units::System::Ptr system) const
IceBasalResistancePlasticLaw(const Config &config)
virtual void drag_with_derivative(double tauc, double vx, double vy, double *drag, double *ddrag) const
Compute the drag coefficient and its derivative with respect to .
Class containing physical constants and the constitutive relation describing till for SSA.
IceBasalResistancePseudoPlasticLaw(const Config &config)
virtual double drag(double tauc, double vx, double vy) const
Compute the drag coefficient for the basal shear stress.
virtual void print_info(const Logger &log, int threshold, units::System::Ptr system) const
virtual void drag_with_derivative(double tauc, double vx, double vy, double *drag, double *ddrag) const
Compute the drag coefficient and its derivative with respect to .
virtual double drag(double tauc, double vx, double vy) const
Compute the drag coefficient for the basal shear stress.
virtual void print_info(const Logger &log, int threshold, units::System::Ptr system) const
IceBasalResistanceRegularizedLaw(const Config &config)
virtual void drag_with_derivative(double tauc, double vx, double vy, double *drag, double *ddrag) const
Compute the drag coefficient and its derivative with respect to .
void message(int threshold, const char format[],...) const __attribute__((format(printf
Print a message to the log.
Definition Logger.cc:49
A basic logging class.
Definition Logger.hh:40
std::shared_ptr< System > Ptr
Definition Units.hh:47
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
static double square(double x)