PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
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 
27 namespace pism {
28 namespace 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
47  m_nu = m_ice_density / m_sea_water_density; // no unit
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 
90 double 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 
95 TocBox1 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 
120 double 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 
129 double 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 
134 double 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
142 double 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
149 double 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.
155 double 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
161 double 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.
169 double 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
175 double 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(...)
183 double 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 
191 double PicoPhysics::gamma_T() const {
192  return m_gamma_T;
193 }
194 
196  return m_overturning_coeff;
197 }
198 
199 double PicoPhysics::T_dummy() const {
200  return m_T_dummy;
201 }
202 
203 double PicoPhysics::S_dummy() const {
204  return m_S_dummy;
205 }
206 
207 double PicoPhysics::ice_density() const {
208  return m_ice_density;
209 }
210 
213 }
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
Definition: PicoPhysics.cc:90
double overturning_coeff() const
Definition: PicoPhysics.cc:195
double ice_density() const
Definition: PicoPhysics.cc:207
double S_dummy() const
Definition: PicoPhysics.cc:203
TocBox1 Toc_box1(double area, double T_star, double Soc_box0, double Toc_box0) const
Definition: PicoPhysics.cc:95
double Toc(double box_area, double temperature, double T_star, double overturning, double salinity) const
Definition: PicoPhysics.cc:120
double gamma_T() const
Definition: PicoPhysics.cc:191
double continental_shelf_depth() const
Definition: PicoPhysics.cc:211
double p_coeff(double g1, double s1) const
Definition: PicoPhysics.cc:183
double melt_rate(double pm_point, double Toc) const
equation 8 in the PICO paper.
Definition: PicoPhysics.cc:155
double overturning(double Soc_box0, double Soc, double Toc_box0, double Toc) const
equation 3 in the PICO paper. See also equation 4.
Definition: PicoPhysics.cc:169
double theta_pm(double salinity, double pressure) const
Definition: PicoPhysics.cc:142
double Soc_box1(double Toc_box0, double Soc_box0, double Toc) const
Definition: PicoPhysics.cc:129
double T_pm(double salinity, double pressure) const
Definition: PicoPhysics.cc:149
double melt_rate_beckmann_goosse(double pot_pm_point, double Toc) const
Beckmann & Goosse meltrate.
Definition: PicoPhysics.cc:161
double T_star(double salinity, double temperature, double pressure) const
See equation A6 and lines before in PICO paper.
Definition: PicoPhysics.cc:175
PicoPhysics(const Config &config)
Definition: PicoPhysics.cc:30
double T_dummy() const
Definition: PicoPhysics.cc:199
double Soc(double salinity, double temperature, double Toc) const
Definition: PicoPhysics.cc:134
bool ocean(int M)
An ocean cell (floating ice or ice-free).
Definition: Mask.hh:40