Loading [MathJax]/extensions/tex2jax.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
GoldsbyKohlstedt.cc
Go to the documentation of this file.
1/* Copyright (C) 2015, 2016, 2021, 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/rheology/GoldsbyKohlstedt.hh"
21#include <cmath> // for pow, exp, fabs, M_PI
22#include <memory> // for __shared_ptr_access
23#include <stdexcept> // for runtime_error
24
25namespace pism {
26namespace rheology {
27
28// Goldsby-Kohlstedt (forward) ice flow law
29
30GoldsbyKohlstedt::GoldsbyKohlstedt(const std::string &prefix,
31 const Config &config, EnthalpyConverter::Ptr ec)
32 : FlowLaw(prefix, config, ec) {
33 m_name = "Goldsby-Kohlstedt / Paterson-Budd (hybrid)";
34
35 m_V_act_vol = -13.e-6; // m^3/mol
36 m_d_grain_size = 1.0e-3; // m (see p. ?? of G&K paper)
37 //--- dislocation creep ---
38 m_disl_crit_temp = 258.0; // kelvin
39 //disl_A_cold = 4.0e5; // MPa^{-4.0} s^{-1}
40 //disl_A_warm = 6.0e28; // MPa^{-4.0} s^{-1}
41 m_disl_A_cold = 4.0e-19; // Pa^{-4.0} s^{-1}
42 m_disl_A_warm = 6.0e4; // Pa^{-4.0} s^{-1} (GK)
43 m_disl_n = 4.0; // stress exponent
44 m_disl_Q_cold = 60.e3; // J/mol Activation energy
45 m_disl_Q_warm = 180.e3; // J/mol Activation energy (GK)
46 //--- grain boundary sliding ---
47 m_gbs_crit_temp = 255.0; // kelvin
48 //gbs_A_cold = 3.9e-3; // MPa^{-1.8} m^{1.4} s^{-1}
49 //gbs_A_warm = 3.e26; // MPa^{-1.8} m^{1.4} s^{-1}
50 m_gbs_A_cold = 6.1811e-14; // Pa^{-1.8} m^{1.4} s^{-1}
51 m_gbs_A_warm = 4.7547e15; // Pa^{-1.8} m^{1.4} s^{-1}
52 m_gbs_n = 1.8; // stress exponent
53 m_gbs_Q_cold = 49.e3; // J/mol Activation energy
54 m_gbs_Q_warm = 192.e3; // J/mol Activation energy
55 m_p_grain_sz_exp = 1.4; // from Peltier
56 //--- easy slip (basal) ---
57 //basal_A = 5.5e7; // MPa^{-2.4} s^{-1}
58 m_basal_A = 2.1896e-7; // Pa^{-2.4} s^{-1}
59 m_basal_n = 2.4; // stress exponent
60 m_basal_Q = 60.e3; // J/mol Activation energy
61 //--- diffusional flow ---
62 m_diff_crit_temp = 258.0; // when to use enhancement factor
63 m_diff_V_m = 1.97e-5; // Molar volume (m^3/mol)
64 m_diff_D_0v = 9.10e-4; // Preexponential volume diffusion (m^2 second-1)
65 m_diff_Q_v = 59.4e3; // activation energy, vol. diff. (J/mol)
66 m_diff_D_0b = 5.8e-4; // preexponential grain boundary coeff.
67 m_diff_Q_b = 49.e3; // activation energy, g.b. (J/mol)
68 m_diff_delta = 9.04e-10; // grain boundary width (m)
69}
70
71double GoldsbyKohlstedt::flow_impl(double stress, double E,
72 double pressure, double grainsize) const {
73 double temp = m_EC->temperature(E, pressure);
74 return flow_from_temp(stress, temp, pressure, grainsize);
75}
76
77double GoldsbyKohlstedt::hardness_impl(double enthalpy, double pressure) const {
78
79 // We use the Paterson-Budd relation for the hardness parameter. It would be nice if we didn't
80 // have to, but we currently need ice hardness to compute the strain heating. See
81 // SIAFD::compute_volumetric_strain_heating().
82 double
83 T_pa = m_EC->pressure_adjusted_temperature(enthalpy, pressure),
84 A = softness_paterson_budd(T_pa);
85
86 return pow(A, m_hardness_power);
87}
88
89double GoldsbyKohlstedt::softness_impl(double , double) const {
90 throw std::runtime_error("double GoldsbyKohlstedt::softness is not implemented");
91
92#ifndef __GNUC__
93 return 0;
94#endif
95}
96
97/*!
98 This is the (forward) Goldsby-Kohlstedt flow law. See:
99 D. L. Goldsby & D. L. Kohlstedt (2001), "Superplastic deformation
100 of ice: experimental observations", J. Geophys. Res. 106(M6), 11017-11030.
101*/
102double GoldsbyKohlstedt::flow_from_temp(double stress, double temp,
103 double pressure, double gs) const {
104 double eps_diff, eps_disl, eps_basal, eps_gbs, diff_D_b;
105
106 if (fabs(stress) < 1e-10) {
107 return 0;
108 }
109 const double T = temp + (m_beta_CC_grad / (m_rho * m_standard_gravity)) * pressure;
110 const double pV = pressure * m_V_act_vol;
111 const double RT = m_ideal_gas_constant * T;
112 // Diffusional Flow
113 const double diff_D_v = m_diff_D_0v * exp(-m_diff_Q_v/RT);
114 diff_D_b = m_diff_D_0b * exp(-m_diff_Q_b/RT);
115 if (T > m_diff_crit_temp) {
116 diff_D_b *= 1000; // Coble creep scaling
117 }
118 eps_diff = 42 * m_diff_V_m *
119 (diff_D_v + M_PI * m_diff_delta * diff_D_b / gs) / (RT*(gs*gs));
120 // Dislocation Creep
121 if (T > m_disl_crit_temp) {
122 eps_disl = m_disl_A_warm * pow(stress, m_disl_n-1) * exp(-(m_disl_Q_warm + pV)/RT);
123 } else {
124 eps_disl = m_disl_A_cold * pow(stress, m_disl_n-1) * exp(-(m_disl_Q_cold + pV)/RT);
125 }
126 // Basal Slip
127 eps_basal = m_basal_A * pow(stress, m_basal_n-1) * exp(-(m_basal_Q + pV)/RT);
128 // Grain Boundary Sliding
129 if (T > m_gbs_crit_temp) {
130 eps_gbs = m_gbs_A_warm * (pow(stress, m_gbs_n-1) / pow(gs, m_p_grain_sz_exp)) *
131 exp(-(m_gbs_Q_warm + pV)/RT);
132 } else {
133 eps_gbs = m_gbs_A_cold * (pow(stress, m_gbs_n-1) / pow(gs, m_p_grain_sz_exp)) *
134 exp(-(m_gbs_Q_cold + pV)/RT);
135 }
136
137 return eps_diff + eps_disl + (eps_basal * eps_gbs) / (eps_basal + eps_gbs);
138}
139
140
141/*****************
142THE NEXT PROCEDURE REPEATS CODE; INTENDED ONLY FOR DEBUGGING
143*****************/
144GKparts GoldsbyKohlstedt::flowParts(double stress, double temp, double pressure) const {
145 double gs, eps_diff, eps_disl, eps_basal, eps_gbs, diff_D_b;
146 GKparts p;
147
148 if (fabs(stress) < 1e-10) {
149 p.eps_total=0.0;
150 p.eps_diff=0.0; p.eps_disl=0.0; p.eps_gbs=0.0; p.eps_basal=0.0;
151 return p;
152 }
153 const double T = temp + (m_beta_CC_grad / (m_rho * m_standard_gravity)) * pressure;
154 const double pV = pressure * m_V_act_vol;
155 const double RT = m_ideal_gas_constant * T;
156 // Diffusional Flow
157 const double diff_D_v = m_diff_D_0v * exp(-m_diff_Q_v/RT);
158 diff_D_b = m_diff_D_0b * exp(-m_diff_Q_b/RT);
159 if (T > m_diff_crit_temp) {
160 diff_D_b *= 1000; // Coble creep scaling
161 }
162 gs = m_d_grain_size;
163 eps_diff = 14 * m_diff_V_m *
164 (diff_D_v + M_PI * m_diff_delta * diff_D_b / gs) / (RT*(gs*gs));
165 // Dislocation Creep
166 if (T > m_disl_crit_temp) {
167 eps_disl = m_disl_A_warm * pow(stress, m_disl_n-1) * exp(-(m_disl_Q_warm + pV)/RT);
168 } else {
169 eps_disl = m_disl_A_cold * pow(stress, m_disl_n-1) * exp(-(m_disl_Q_cold + pV)/RT);
170 }
171 // Basal Slip
172 eps_basal = m_basal_A * pow(stress, m_basal_n-1) * exp(-(m_basal_Q + pV)/RT);
173 // Grain Boundary Sliding
174 if (T > m_gbs_crit_temp) {
175 eps_gbs = m_gbs_A_warm * (pow(stress, m_gbs_n-1) / pow(gs, m_p_grain_sz_exp)) *
176 exp(-(m_gbs_Q_warm + pV)/RT);
177 } else {
178 eps_gbs = m_gbs_A_cold * (pow(stress, m_gbs_n-1) / pow(gs, m_p_grain_sz_exp)) *
179 exp(-(m_gbs_Q_cold + pV)/RT);
180 }
181
182 p.eps_diff=eps_diff;
183 p.eps_disl=eps_disl;
184 p.eps_basal=eps_basal;
185 p.eps_gbs=eps_gbs;
186 p.eps_total=eps_diff + eps_disl + (eps_basal * eps_gbs) / (eps_basal + eps_gbs);
187 return p;
188}
189/*****************/
190
192 const Config &config,
194 : GoldsbyKohlstedt(prefix, config, ec) {
195 m_name = "Goldsby-Kohlstedt / Paterson-Budd (hybrid, simplified)";
196
197 m_d_grain_size_stripped = 3.0e-3; // m; = 3mm (see Peltier et al 2000 paper)
198}
199
200
201double GoldsbyKohlstedtStripped::flow_from_temp(double stress, double temp, double pressure, double) const {
202 // note value of gs is ignored
203 // note pressure only effects the temperature; the "P V" term is dropped
204 // note no diffusional flow
205 double eps_disl, eps_basal, eps_gbs;
206
207 if (fabs(stress) < 1e-10) {
208 return 0;
209 }
210 const double T = temp + (m_beta_CC_grad / (m_rho * m_standard_gravity)) * pressure;
211 const double RT = m_ideal_gas_constant * T;
212 // NO Diffusional Flow
213 // Dislocation Creep
214 if (T > m_disl_crit_temp) {
215 eps_disl = m_disl_A_warm * pow(stress, m_disl_n-1) * exp(-m_disl_Q_warm/RT);
216 } else {
217 eps_disl = m_disl_A_cold * pow(stress, m_disl_n-1) * exp(-m_disl_Q_cold/RT);
218 }
219 // Basal Slip
220 eps_basal = m_basal_A * pow(stress, m_basal_n-1) * exp(-m_basal_Q/RT);
221 // Grain Boundary Sliding
222 if (T > m_gbs_crit_temp) {
223 eps_gbs = m_gbs_A_warm *
224 (pow(stress, m_gbs_n-1) / pow(m_d_grain_size_stripped, m_p_grain_sz_exp)) *
225 exp(-m_gbs_Q_warm/RT);
226 } else {
227 eps_gbs = m_gbs_A_cold *
228 (pow(stress, m_gbs_n-1) / pow(m_d_grain_size_stripped, m_p_grain_sz_exp)) *
229 exp(-m_gbs_Q_cold/RT);
230 }
231
232 return eps_disl + (eps_basal * eps_gbs) / (eps_basal + eps_gbs);
233}
234
235
236} // end of namespace rheology
237} // end of namespace pism
A class for storing and accessing PISM configuration flags and parameters.
std::shared_ptr< EnthalpyConverter > Ptr
double softness_paterson_budd(double T_pa) const
Return the softness parameter A(T) for a given temperature T.
Definition FlowLaw.cc:80
double m_standard_gravity
acceleration due to gravity
Definition FlowLaw.hh:150
double m_rho
ice density
Definition FlowLaw.hh:120
double m_hardness_power
; used to compute hardness
Definition FlowLaw.hh:136
double m_beta_CC_grad
Clausius-Clapeyron gradient.
Definition FlowLaw.hh:122
double m_ideal_gas_constant
ideal gas constant
Definition FlowLaw.hh:152
EnthalpyConverter::Ptr m_EC
Definition FlowLaw.hh:126
virtual double flow_from_temp(double stress, double temp, double pressure, double gs) const
GoldsbyKohlstedtStripped(const std::string &prefix, const Config &config, EnthalpyConverter::Ptr EC)
virtual double flow_impl(double stress, double E, double pressure, double grainsize) const
double hardness_impl(double E, double p) const
double softness_impl(double E, double p) const __attribute__((noreturn))
GKparts flowParts(double stress, double temp, double pressure) const
virtual double flow_from_temp(double stress, double temp, double pressure, double gs) const
GoldsbyKohlstedt(const std::string &prefix, const Config &config, EnthalpyConverter::Ptr EC)
A hybrid of Goldsby-Kohlstedt (2001) ice (constitutive form) and Paterson-Budd (1982)-Glen (viscosity...