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
PicoPhysics.cc
Go to the documentation of this file.
1/* Copyright (C) 2018, 2019, 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#include <cmath> // sqrt
20#include <cassert> // assert
21#include <algorithm> // std::min
22
23#include "pism/coupler/ocean/PicoPhysics.hh"
24
25#include "pism/util/ConfigInterface.hh"
26
27namespace pism {
28namespace ocean {
29
31
32 // threshold between deep ocean and continental shelf
33 m_continental_shelf_depth = config.get_number("ocean.pico.continental_shelf_depth");
34
35 // value for ocean temperature around Antarctica if no other data available (cold
36 // conditions)
37 m_T_dummy = -1.5 + config.get_number("constants.fresh_water.melting_point_temperature");
38
39 // value for ocean salinity around Antarctica if no other data available (cold
40 // conditions)
41 m_S_dummy = 34.7;
42
43 m_earth_grav = config.get_number("constants.standard_gravity");
44 m_ice_density = config.get_number("constants.ice.density");
45 m_sea_water_density = config.get_number("constants.sea_water.density");
46 m_rho_star = 1033; // kg/m^3
48
49 //Joule / kg
50 m_latentHeat = config.get_number("constants.fresh_water.latent_heat_of_fusion");
51
52 // J/(K*kg), specific heat capacity of ocean mixed layer
53 m_c_p_ocean = 3974.0;
54
55 m_lambda = m_latentHeat / m_c_p_ocean; // °C, NOTE K vs °C
56
57 // Values for linearized potential freezing point (from Xylar Asay-Davis, should be in
58 // Asay-Davis et al 2016, but not correct in there )
59 m_a_pot = -0.0572; // K/psu
60 m_b_pot = 0.0788 + 273.15; // K
61 m_c_pot = 7.77e-4; // K/dbar
62
63 // in-situ pressure melting point from Jenkins et al. 2010 paper
64 m_a_in_situ = -0.0573; // K/p_in_situu
65 m_b_in_situ = 0.0832 + 273.15; // K
66 m_c_in_situ = 7.53e-4; // K/dbar
67
68 // in-situ pressure melting point from Olbers & Hellmer 2010 paper
69 // as = -0.057; // K/psu
70 // bs = 0.0832 + 273.15; // K
71 // cs = 7.64e-4; // K/dbar
72
73 m_alpha = 7.5e-5; // 1/K
74 m_beta = 7.7e-4; // 1/psu
75
76 // m s-1, best fit value in paper
77 m_gamma_T = config.get_number("ocean.pico.heat_exchange_coefficent");
78
79 // m6 kg−1 s−1, best fit value in paper
80 m_overturning_coeff = config.get_number("ocean.pico.overturning_coefficent");
81
82 // for shelf cells where normal box model is not calculated, used in
83 // calculate_basal_melt_missing_cells(), compare POConstantPIK m/s, thermal exchange
84 // velocity for Beckmann-Goosse parameterization this is the same meltFactor as in
85 // POConstantPIK
86 m_meltFactor = config.get_number("ocean.pik_melt_factor");
87}
88
89
90double PicoPhysics::pressure(double ice_thickness) const {
91 // pressure in dbar, 1dbar = 10000 Pa = 1e4 kg m-1 s-2
92 return m_ice_density * m_earth_grav * ice_thickness * 1e-4;
93}
94
95TocBox1 PicoPhysics::Toc_box1(double area, double T_star, double Soc_box0, double Toc_box0) const {
96
97 TocBox1 result = { false, 0.0 };
98
99 const double
100 g1 = area * m_gamma_T,
101 s1 = Soc_box0 / (m_nu * m_lambda),
102 p = p_coeff(g1, s1),
103 q = p * T_star;
104
105 // This can only happen if T_star > 0.25*p, in particular T_star > 0 which can only
106 // happen for values of Toc_box0 close to the local pressure melting point
107 double D = 0.25 * p * p - q;
108 if (D < 0.0) {
109 D = 0.0;
110 result.failed = true;
111 }
112
113 // temperature for box 1, p-q formula
114 // equation A12 in the PICO paper.
115 result.value = Toc_box0 - (-0.5 * p + sqrt(D));
116
117 return result;
118}
119
120double PicoPhysics::Toc(double area, double temperature, double T_star, double overturning, double salinity) const {
121
122 double g1 = area * m_gamma_T;
123 double g2 = g1 / (m_nu * m_lambda);
124
125 // temperature for Box i > 1
126 return temperature + g1 * T_star / (overturning + g1 - g2 * m_a_pot * salinity); // K
127}
128
129double PicoPhysics::Soc_box1(double Toc_box0, double Soc_box0, double Toc) const {
130
131 return Soc_box0 - (Soc_box0 / (m_nu * m_lambda)) * (Toc_box0 - Toc);
132}
133
134double PicoPhysics::Soc(double salinity, double temperature_in_boundary, double Toc) const {
135
136 return salinity - salinity * (temperature_in_boundary - Toc) / (m_nu * m_lambda); // psu;
137}
138
139
140//! equation 5 in the PICO paper.
141//! calculate pressure melting point from potential temperature
142double PicoPhysics::theta_pm(double salinity, double pressure) const {
143 // using coefficients for potential temperature
144 return m_a_pot * salinity + m_b_pot - m_c_pot * pressure;
145}
146
147//! equation 5 in the PICO paper.
148//! calculate pressure melting point from in-situ temperature
149double PicoPhysics::T_pm(double salinity, double pressure) const {
150 // using coefficients for in-situ temperature
151 return m_a_in_situ * salinity + m_b_in_situ - m_c_in_situ * pressure;
152}
153
154//! equation 8 in the PICO paper.
155double PicoPhysics::melt_rate(double pm_point, double Toc) const {
156 // in m/s
157 return m_gamma_T / (m_nu * m_lambda) * (Toc - pm_point);
158}
159
160//! Beckmann & Goosse meltrate
161double PicoPhysics::melt_rate_beckmann_goosse(double pot_pm_point, double Toc) const {
162 // in W/m^2
163 double heat_flux = m_meltFactor * m_sea_water_density * m_c_p_ocean * m_gamma_T * (Toc - pot_pm_point);
164 // in m s-1
165 return heat_flux / (m_latentHeat * m_ice_density);
166}
167
168//! equation 3 in the PICO paper. See also equation 4.
169double PicoPhysics::overturning(double Soc_box0, double Soc, double Toc_box0, double Toc) const {
170 // in m^3/s
171 return m_overturning_coeff * m_rho_star * (m_beta * (Soc_box0 - Soc) - m_alpha * (Toc_box0 - Toc));
172}
173
174//! See equation A6 and lines before in PICO paper
175double PicoPhysics::T_star(double salinity, double temperature, double pressure) const {
176 double T_s = theta_pm(salinity, pressure) - temperature; // in kelvin
177 return T_s;
178}
179
180//! calculate p coefficent for solving the quadratic temperature equation
181//! trough the p-q formula. See equation A12 in the PICO paper.
182//! is only used once in Toc_box1(...)
183double PicoPhysics::p_coeff(double g1, double s1) const {
184 // in 1 / (1/K) = K
185 // inputs g1 and overturning coefficicient are always positive
186 // so output is positive if beta*s1 > alpha
187 // which is shown in the text following equation A12
188 return g1 / (m_overturning_coeff * m_rho_star * (m_beta * s1 - m_alpha));
189}
190
191double PicoPhysics::gamma_T() const {
192 return m_gamma_T;
193}
194
196 return m_overturning_coeff;
197}
198
199double PicoPhysics::T_dummy() const {
200 return m_T_dummy;
201}
202
203double PicoPhysics::S_dummy() const {
204 return m_S_dummy;
205}
206
208 return m_ice_density;
209}
210
214
215} // end of namespace ocean
216} // 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.
double pressure(double ice_thickness) const
double overturning_coeff() const
double ice_density() const
TocBox1 Toc_box1(double area, double T_star, double Soc_box0, double Toc_box0) const
double Toc(double box_area, double temperature, double T_star, double overturning, double salinity) const
double continental_shelf_depth() const
double p_coeff(double g1, double s1) const
double melt_rate(double pm_point, double Toc) const
equation 8 in the PICO paper.
double overturning(double Soc_box0, double Soc, double Toc_box0, double Toc) const
equation 3 in the PICO paper. See also equation 4.
double theta_pm(double salinity, double pressure) const
double Soc_box1(double Toc_box0, double Soc_box0, double Toc) const
double T_pm(double salinity, double pressure) const
double melt_rate_beckmann_goosse(double pot_pm_point, double Toc) const
Beckmann & Goosse meltrate.
double T_star(double salinity, double temperature, double pressure) const
See equation A6 and lines before in PICO paper.
PicoPhysics(const Config &config)
double Soc(double salinity, double temperature, double Toc) const
bool ocean(int M)
An ocean cell (floating ice or ice-free).
Definition Mask.hh:40