23 #include "pism/coupler/surface/DEBMSimplePointwise.hh"
24 #include "pism/util/ConfigInterface.hh"
25 #include "pism/util/Context.hh"
26 #include "pism/util/Time.hh"
69 double Z = temperature / (sqrt(2.0) * sigma);
70 return (sigma / sqrt(2.0 * M_PI)) * exp(-Z * Z) + (temperature / 2.0) * erfc(-Z);
86 static double hour_angle(
double phi,
double latitude,
double declination) {
87 double cos_h_phi = ((sin(
phi) - sin(latitude) * sin(declination)) /
88 (cos(latitude) * cos(declination)));
103 double perihelion_longitude) {
106 double E = eccentricity;
108 double E3 = E * E * E;
109 double L_p = perihelion_longitude;
112 const double equinox_day_number = 80.0;
113 double delta_lambda = 2.0 * M_PI * (year_fraction - equinox_day_number / 365.0);
114 double beta = sqrt(1.0 - E2);
116 double lambda_m = (-2.0 * ((E / 2.0 + E3 / 8.0) * (1.0 + beta) * sin(-L_p) -
117 E2 / 4.0 * (1.0 / 2.0 + beta) * sin(-2.0 * L_p) +
118 E3 / 8.0 * (1.0 / 3.0 + beta) * sin(-3.0 * L_p)) +
122 (2.0 * E - E3 / 4.0) * sin(lambda_m - L_p) +
123 (5.0 / 4.0) * E2 * sin(2.0 * (lambda_m - L_p)) +
124 (13.0 / 12.0) * E3 * sin(3.0 * (lambda_m - L_p)));
149 double t = 2. * M_PI * year_fraction;
152 a1 * cos(t) + b1 * sin(t) +
153 a2 * cos(2. * t) + b2 * sin(2. * t));
166 double perihelion_longitude,
168 double E = eccentricity;
173 "invalid eccentricity value: 1.0");
176 return pow((1.0 + E * cos(
solar_longitude - perihelion_longitude)) / (1.0 - E * E), 2);
196 double t = 2. * M_PI * year_fraction;
199 a1 * cos(t) + b1 * sin(t) +
200 a2 * cos(2. * t) + b2 * sin(2. * t) +
201 a3 * cos(3. * t) + b3 * sin(3. * t));
267 double distance_factor,
270 double declination) {
275 return ((solar_constant /
hour_angle) * distance_factor *
276 (
hour_angle * sin(latitude) * sin(declination) +
277 cos(latitude) * cos(declination) * sin(
hour_angle)));
291 temperature_melt = 0.0;
292 insolation_melt = 0.0;
303 m_L = config.
get_number(
"constants.fresh_water.latent_heat_of_fusion");
329 std::string paleo_file = config.
get_string(
"surface.debm_simple.paleo.file");
331 if (not paleo_file.empty()) {
335 "1",
"eccentricity of the earth"));
338 "degree",
"obliquity of the earth"));
341 new ScalarForcing(ctx,
"surface.debm_simple.paleo",
"perihelion_longitude",
"radian",
342 "degree",
"longitude of the perihelion relative to the vernal equinox"));
360 assert(melt_rate >= 0.0);
377 double declination = 0.0;
378 double distance_factor = 0.0;
380 double year_fraction =
m_time->year_fraction(time);
400 return {declination, distance_factor};
411 double distance_factor,
412 double latitude_degrees)
const {
413 const double degrees_to_radians = M_PI / 180.0;
414 double latitude_rad = latitude_degrees * degrees_to_radians;
440 double distance_factor,
442 double T_std_deviation,
444 double surface_elevation,
449 const double degrees_to_radians = M_PI / 180.0;
450 double latitude_rad = latitude * degrees_to_radians;
462 const double eps = 1.0e-4;
497 double old_snow_depth,
498 double accumulation)
const {
502 snow_depth = old_snow_depth,
506 assert(ice_thickness >= 0);
509 snow_depth =
std::min(snow_depth, ice_thickness);
511 assert(snow_depth >= 0);
513 snow_depth += accumulation;
515 if (max_melt <= 0.0) {
518 }
else if (max_melt <= snow_depth) {
521 snow_melted = max_melt;
525 snow_melted = snow_depth;
526 ice_melted =
std::min(max_melt - snow_melted, ice_thickness);
534 snow_depth =
std::max(snow_depth - snow_melted, 0.0);
536 double total_melt = (snow_melted + ice_melted);
537 double runoff = total_melt - ice_created_by_refreeze;
538 double smb = accumulation - runoff;
540 result.
snow_depth = snow_depth - old_snow_depth;
541 result.
melt = total_melt;
543 result.
smb = ice_thickness + smb >= 0 ? smb : -ice_thickness;
545 assert(ice_thickness + result.
smb >= 0);
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
std::string get_string(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.
std::shared_ptr< const Config > config() const
std::shared_ptr< const Time > time() const
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
double albedo(double melt_rate, MaskValue cell_type) const
double m_melt_threshold_temp
double insolation(double declination, double distance_factor, double latitude_degrees) const
double m_transmissivity_slope
slope used in the linear parameterization of transmissivity
std::unique_ptr< ScalarForcing > m_eccentricity
double m_constant_obliquity
std::unique_ptr< ScalarForcing > m_obliquity
double m_refreeze_fraction
refreeze fraction
double m_positive_threshold_temperature
threshold temperature for the computation of temperature-driven melt
double eccentricity(double time) const
DEBMSimpleMelt melt(double declination, double distance_factor, double dt, double T_std_deviation, double T, double surface_elevation, double lat, double albedo) const
double m_albedo_slope
slope used in the linear parameterization of the albedo as a function of melt
bool m_refreeze_ice_melt
refreeze melted ice
double perihelion_longitude(double time) const
double m_solar_constant
the solar constant
Changes step(double ice_thickness, double max_melt, double snow_depth, double accumulation) const
Compute the surface mass balance at a location from the amount of melted snow and the solid accumulat...
double m_constant_perihelion_longitude
double m_phi
minimum solar elevation angle above which melt is possible
double atmosphere_transmissivity(double elevation) const
double m_constant_eccentricity
std::unique_ptr< ScalarForcing > m_perihelion_longitude
std::shared_ptr< const Time > m_time
double m_L
latent heat of fusion
double obliquity(double time) const
OrbitalParameters orbital_parameters(double time) const
DEBMSimplePointwise(const Context &ctx)
double m_transmissivity_intercept
#define PISM_ERROR_LOCATION
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
double min(const array::Scalar &input)
Finds minimum over all the values in an array::Scalar object. Ignores ghosts.
static double solar_declination_paleo(double obliquity, double solar_longitude)
static double solar_longitude(double year_fraction, double eccentricity, double perihelion_longitude)
static double hour_angle(double phi, double latitude, double declination)
static double CalovGreveIntegrand(double sigma, double temperature)
static double distance_factor_present_day(double year_fraction)
static double solar_declination_present_day(double year_fraction)
static double distance_factor_paleo(double eccentricity, double perihelion_longitude, double solar_longitude)
static double insolation(double solar_constant, double distance_factor, double hour_angle, double latitude, double declination)