19 #include <gsl/gsl_poly.h>
22 #include "pism/coupler/ocean/GivenTH.hh"
23 #include "pism/coupler/util/options.hh"
24 #include "pism/geometry/Geometry.hh"
25 #include "pism/util/ConfigInterface.hh"
26 #include "pism/util/Grid.hh"
27 #include "pism/util/Time.hh"
28 #include "pism/util/array/Forcing.hh"
66 unsigned int buffer_size =
m_config->get_number(
"input.forcing.buffer_size");
88 .long_name(
"potential temperature of the adjacent ocean")
92 .long_name(
"salinity of the adjacent ocean")
99 "* Initializing the 3eqn melting parameterization ocean model\n"
100 " reading ocean temperature and salinity from a file...\n");
116 double salinity =
m_config->get_number(
"constants.sea_water.salinity",
"g / kg");
120 m_log->message(2,
" Variable '%s' not found; using constant salinity: %f (g / kg).\n",
121 variable_name.c_str(), salinity);
131 ice_density =
m_config->get_number(
"constants.ice.density"),
132 water_density =
m_config->get_number(
"constants.sea_water.density"),
133 g =
m_config->get_number(
"constants.standard_gravity");
154 &temperature, &mass_flux};
156 for (
auto p =
m_grid->points(); p; p.next()) {
157 const int i = p.i(), j = p.j();
159 double potential_temperature_celsius = (*m_theta_ocean)(i,j) - 273.15;
162 shelf_base_temp_celsius = 0.0,
163 shelf_base_massflux = 0.0;
167 potential_temperature_celsius,
169 &shelf_base_temp_celsius,
170 &shelf_base_massflux);
173 temperature(i,j) = shelf_base_temp_celsius + 273.15;
174 mass_flux(i,j) = shelf_base_massflux;
181 ice_density =
m_config->get_number(
"constants.ice.density"),
182 water_density =
m_config->get_number(
"constants.sea_water.density"),
183 g =
m_config->get_number(
"constants.standard_gravity");
199 double salinity,
double ice_thickness) {
200 return c.
a[0] * salinity + c.
a[1] + c.
a[2] * ice_thickness;
212 double sea_water_salinity,
double basal_salinity) {
232 double sea_water_salinity,
233 double sea_water_potential_temperature,
235 double *shelf_base_temperature_out,
236 double *shelf_base_melt_rate_out) {
238 assert(thickness >= 0.0);
247 if (sea_water_salinity < min_salinity) {
248 sea_water_salinity = min_salinity;
249 }
else if (sea_water_salinity > max_salinity) {
250 sea_water_salinity = max_salinity;
254 double basal_salinity = sea_water_salinity;
255 subshelf_salinity(constants, sea_water_salinity, sea_water_potential_temperature,
256 thickness, &basal_salinity);
261 if (basal_salinity <= min_salinity) {
262 basal_salinity = min_salinity;
263 }
else if (basal_salinity >= max_salinity) {
264 basal_salinity = max_salinity;
270 *shelf_base_melt_rate_out =
shelf_base_melt_rate(constants, sea_water_salinity, basal_salinity);
273 if (thickness == 0.0) {
274 *shelf_base_melt_rate_out = 0.0;
291 double sea_water_salinity,
292 double sea_water_potential_temperature,
294 double *shelf_base_salinity) {
295 double basal_salinity = sea_water_salinity;
300 thickness, &basal_salinity);
304 if (basal_melt_rate > 0.0) {
307 *shelf_base_salinity = basal_salinity;
316 thickness, &basal_salinity);
320 if (basal_melt_rate < 0.0) {
323 *shelf_base_salinity = basal_salinity;
333 thickness, &basal_salinity);
335 *shelf_base_salinity = basal_salinity;
371 double sea_water_salinity,
372 double sea_water_potential_temperature,
374 double *shelf_base_salinity) {
381 S_W = sea_water_salinity,
382 Theta_W = sea_water_potential_temperature;
389 const double B = (c.
gamma_S * (
L - c_pI * (T_S + c.
a[0] * S_W - c.
a[2] * thickness - c.
a[1])) +
390 c.
gamma_T * c_pW * (Theta_W - c.
b[2] * thickness - c.
b[1]));
391 const double C = -c.
gamma_S * S_W * (
L - c_pI * (T_S - c.
a[2] * thickness - c.
a[1]));
393 double S1 = 0.0, S2 = 0.0;
394 const int n_roots = gsl_poly_solve_quadratic(A, B,
C, &S1, &S2);
399 *shelf_base_salinity = S2;
428 double sea_water_salinity,
429 double sea_water_potential_temperature,
431 double *shelf_base_salinity) {
436 S_W = sea_water_salinity,
437 Theta_W = sea_water_potential_temperature,
444 const double A = -c.
b[0] * c.
gamma_T * c_pW;
445 const double B = c.
gamma_S *
L + c.
gamma_T * c_pW * (Theta_W - c.
b[2] * h - c.
b[1]);
448 double S1 = 0.0, S2 = 0.0;
449 const int n_roots = gsl_poly_solve_quadratic(A, B,
C, &S1, &S2);
454 *shelf_base_salinity = S2;
488 double sea_water_salinity,
489 double sea_water_potential_temperature,
491 double *shelf_base_salinity) {
497 S_W = sea_water_salinity,
498 Theta_W = sea_water_potential_temperature,
508 const double A = -(c.
b[0] * c.
gamma_T * h * rho_W * c_pW - c.
a[0] * rho_I * c_pI * kappa) / (h * rho_W);
509 const double B = ((rho_I * c_pI * kappa * (T_S - c.
a[2] * h - c.
a[1])) / (h * rho_W) +
513 double S1 = 0.0, S2 = 0.0;
514 const int n_roots = gsl_poly_solve_quadratic(A, B,
C, &S1, &S2);
519 *shelf_base_salinity = S2;
const Time & time() const
const Config::ConstPtr m_config
configuration database used by this component
const Logger::ConstPtr m_log
logger (for easy access)
const std::shared_ptr< const Grid > m_grid
grid used by this component
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
bool get_flag(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
A class for storing and accessing PISM configuration flags and parameters.
VariableLookupData find_variable(const std::string &short_name, const std::string &std_name) const
Find a variable using its standard name and/or short name.
High-level PISM I/O class.
array::Scalar2 ice_thickness
Combines the max. time step with the flag indicating if a restriction is active. Makes is possible to...
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
static std::shared_ptr< Forcing > Constant(std::shared_ptr< const Grid > grid, const std::string &short_name, double value)
std::shared_ptr< array::Scalar > m_shelf_base_mass_flux
std::shared_ptr< array::Scalar > m_shelf_base_temperature
Constants(const Config &config)
double gamma_S
Turbulent salt transfer coefficient:
double ice_thermal_diffusivity
double water_latent_heat_fusion
double shelf_top_surface_temperature
double ice_specific_heat_capacity
bool limit_salinity_range
double sea_water_specific_heat_capacity
double gamma_T
Turbulent heat transfer coefficient:
GivenTH(std::shared_ptr< const Grid > g)
void subshelf_salinity_diffusion_only(const Constants &constants, double sea_water_salinity, double sea_water_potential_temperature, double ice_thickness, double *shelf_base_salinity)
Compute basal salinity in the case of no basal melt and no freeze-on, with the diffusion-only tempera...
void subshelf_salinity_melt(const Constants &constants, double sea_water_salinity, double sea_water_potential_temperature, double ice_thickness, double *shelf_base_salinity)
std::shared_ptr< array::Forcing > m_salinity_ocean
std::shared_ptr< array::Forcing > m_theta_ocean
void subshelf_salinity_freeze_on(const Constants &constants, double sea_water_salinity, double sea_water_potential_temperature, double ice_thickness, double *shelf_base_salinity)
MaxTimestep max_timestep_impl(double t) const
void pointwise_update(const Constants &constants, double sea_water_salinity, double sea_water_potential_temperature, double ice_thickness, double *shelf_base_temperature_out, double *shelf_base_melt_rate_out)
Compute temperature and melt rate at the base of the shelf. Based on [HellmerOlbers1989] and [Holland...
void subshelf_salinity(const Constants &constants, double sea_water_salinity, double sea_water_potential_temperature, double ice_thickness, double *shelf_base_salinity)
Compute the basal salinity and make sure that it is consistent with the basal melt rate.
void update_impl(const Geometry &geometry, double t, double dt)
void init_impl(const Geometry &geometry)
std::shared_ptr< array::Scalar > m_water_column_pressure
void update(const Geometry &geometry, double t, double dt)
A very rudimentary PISM ocean model.
@ PISM_READONLY
open an existing file for reading only
bool ocean(int M)
An ocean cell (floating ice or ice-free).
static double melting_point_temperature(GivenTH::Constants c, double salinity, double ice_thickness)
void compute_average_water_column_pressure(const Geometry &geometry, double ice_density, double water_density, double g, array::Scalar &result)
static double shelf_base_melt_rate(GivenTH::Constants c, double sea_water_salinity, double basal_salinity)