22 #include "pism/util/IceGrid.hh"
23 #include "pism/util/Mask.hh"
24 #include "pism/util/error_handling.hh"
25 #include "pism/util/io/File.hh"
26 #include "pism/util/MaxTimestep.hh"
27 #include "pism/util/pism_utilities.hh"
28 #include "pism/util/Time.hh"
29 #include "pism/util/IceModelVec2CellType.hh"
30 #include "pism/util/iceModelVec2T.hh"
31 #include "pism/geometry/Geometry.hh"
32 #include "pism/coupler/util/options.hh"
94 m_name =
"Mohr-Coulomb yield stress model";
97 "friction angle for till under grounded ice sheet",
98 "degrees",
"degrees",
"", 0);
103 std::string hydrology_tillwat_max =
"hydrology.tillwat_max";
104 bool till_is_present =
m_config->get_number(hydrology_tillwat_max) > 0.0;
106 if (not till_is_present) {
108 "The Mohr-Coulomb yield stress model cannot be used without till.\n"
109 "Reset %s or choose a different yield stress model.",
110 hydrology_tillwat_max.c_str());
114 auto delta_file =
m_config->get_string(
"basal_yield_stress.mohr_coulomb.delta.file");
116 if (not delta_file.empty()) {
119 unsigned int buffer_size =
m_config->get_number(
"input.forcing.buffer_size");
125 "mohr_coulomb_delta",
129 m_delta->set_attrs(
"",
"minimum effective pressure on till as a fraction of overburden pressure",
144 auto tauc_to_phi_file =
m_config->get_string(
"basal_yield_stress.mohr_coulomb.tauc_to_phi.file");
146 if (not tauc_to_phi_file.empty()) {
150 " Will compute till friction angle (tillphi) as a function"
151 " of the yield stress (tauc)...\n");
159 }
else if (
m_config->get_flag(
"basal_yield_stress.mohr_coulomb.topg_to_phi.enabled")) {
161 m_log->message(2,
" creating till friction angle map from bed elevation...\n");
166 "PISM WARNING: -topg_to_phi computation will override the '%s' field\n"
167 " present in the input file '%s'!\n",
174 double till_phi_default =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_phi_default");
182 double till_phi_default =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_phi_default");
203 this->
update(inputs,
m_grid->ctx()->time()->current(), 1.0 );
210 auto dt =
m_delta->max_timestep(t);
265 double t,
double dt) {
269 bool slippery_grounding_lines =
m_config->get_flag(
"basal_yield_stress.slippery_grounding_lines"),
270 add_transportable_water =
m_config->get_flag(
"basal_yield_stress.add_transportable_water");
273 ice_density =
m_config->get_number(
"constants.ice.density"),
274 standard_gravity =
m_config->get_number(
"constants.standard_gravity");
276 const double high_tauc =
m_config->get_number(
"basal_yield_stress.ice_free_bedrock"),
277 W_till_max =
m_config->get_number(
"hydrology.tillwat_max"),
278 delta =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_effective_fraction_overburden"),
279 tlftw =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_log_factor_transportable_water");
293 &bed_topography, &sea_level, &ice_thickness};
295 if (add_transportable_water) {
296 list.
add(W_subglacial);
306 const int i = p.i(), j = p.j();
313 double water = W_till(i,j);
315 if (slippery_grounding_lines and
316 bed_topography(i, j) <= sea_level(i, j) and
319 }
else if (add_transportable_water) {
320 water = W_till(i, j) + tlftw * log(1.0 + W_subglacial(i, j) / tlftw);
323 double P_overburden = ice_density * standard_gravity * ice_thickness(i, j);
353 phi_min =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.topg_to_phi.phi_min"),
354 phi_max =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.topg_to_phi.phi_max"),
355 topg_min =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.topg_to_phi.topg_min"),
356 topg_max =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.topg_to_phi.topg_max");
359 " till friction angle (phi) is piecewise-linear function of bed elev (topg):\n"
360 " / %5.2f for topg < %.f\n"
361 " phi = | %5.2f + (topg - (%.f)) * (%.2f / %.f) for %.f < topg < %.f\n"
362 " \\ %5.2f for %.f < topg\n",
364 phi_min, topg_min, phi_max - phi_min, topg_max - topg_min, topg_min, topg_max,
367 if (phi_min >= phi_max) {
369 "invalid -topg_to_phi arguments: phi_min < phi_max is required");
372 if (topg_min >= topg_max) {
374 "invalid -topg_to_phi arguments: topg_min < topg_max is required");
377 const double slope = (phi_max - phi_min) / (topg_max - topg_min);
382 const int i = p.i(), j = p.j();
383 const double bed = bed_topography(i, j);
385 if (bed <= topg_min) {
386 result(i, j) = phi_min;
387 }
else if (bed >= topg_max) {
388 result(i, j) = phi_max;
390 result(i, j) = phi_min + (bed - topg_min) * slope;
414 ice_density =
m_config->get_number(
"constants.ice.density"),
415 standard_gravity =
m_config->get_number(
"constants.standard_gravity");
418 delta =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_effective_fraction_overburden");
421 &W_till = till_water_thickness;
426 const int i = p.i(), j = p.j();
428 if (cell_type.
ocean(i, j)) {
430 }
else if (cell_type.
ice_free(i, j)) {
433 double P_overburden = ice_density * standard_gravity * ice_thickness(i, j);
435 result(i, j) = mc.
till_friction_angle(delta, P_overburden, W_till(i, j), basal_yield_stress(i, j));
Makes sure that we call begin_access() and end_access() for all accessed IceModelVecs.
const Config::ConstPtr m_config
configuration database used by this component
const Logger::ConstPtr m_log
logger (for easy access)
virtual void regrid(const std::string &module_name, IceModelVec &variable, RegriddingFlag flag=NO_REGRID_WITHOUT_REGRID_VARS)
const IceGrid::ConstPtr m_grid
grid used by this component
static Ptr wrap(const T &input)
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.
std::string filename() const
High-level PISM I/O class.
IceModelVec2CellType cell_type
IceModelVec2S bed_elevation
IceModelVec2S sea_level_elevation
IceModelVec2S ice_thickness
std::shared_ptr< const IceGrid > ConstPtr
bool next_to_ice_free_ocean(int i, int j) const
bool next_to_floating_ice(int i, int j) const
bool ocean(int i, int j) const
bool ice_free(int i, int j) const
"Cell type" mask. Adds convenience methods to IceModelVec2Int.
void add(double alpha, const IceModelVec2S &x)
void copy_from(const IceModelVec2S &source)
static std::shared_ptr< IceModelVec2T > ForcingField(IceGrid::ConstPtr grid, const File &file, const std::string &short_name, const std::string &standard_name, int max_buffer_size, bool periodic, InterpolationType interpolation_type=PIECEWISE_CONSTANT)
void update_ghosts()
Updates ghost points.
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
void set_attrs(const std::string &pism_intent, const std::string &long_name, const std::string &units, const std::string &glaciological_units, const std::string &standard_name, unsigned int component)
Sets NetCDF attributes of an IceModelVec object.
void regrid(const std::string &filename, RegriddingFlag flag, double default_value=0.0)
void set(double c)
Result: v[j] <- c for all j.
void read(const std::string &filename, unsigned int time)
void define(const File &file, IO_Type default_type=PISM_DOUBLE) const
Define variables corresponding to an IceModelVec in a file opened using file.
void write(const std::string &filename) const
void set_time_independent(bool flag)
Set the time independent flag for all variables corresponding to this IceModelVec instance.
Combines the max. time step with the flag indicating if a restriction is active. Makes is possible to...
double yield_stress(double delta, double P_overburden, double water_thickness, double phi) const
double till_friction_angle(double delta, double P_overburden, double water_thickness, double yield_stress) const
std::shared_ptr< IceModelVec2T > m_delta
void init_impl(const YieldStressInputs &inputs)
void restart_impl(const File &input_file, int record)
void update_impl(const YieldStressInputs &inputs, double t, double dt)
DiagnosticList diagnostics_impl() const
void write_model_state_impl(const File &output) const
The default (empty implementation).
void set_till_friction_angle(const IceModelVec2S &input)
void define_model_state_impl(const File &output) const
void finish_initialization(const YieldStressInputs &inputs)
MaxTimestep max_timestep_impl(double t) const
void till_friction_angle(const IceModelVec2S &bed_topography, IceModelVec2S &result)
Computes the till friction angle phi as a piecewise linear function of bed elevation,...
void bootstrap_impl(const File &input_file, const YieldStressInputs &inputs)
Initialize the pseudo-plastic till mechanical model.
MohrCoulombYieldStress(IceGrid::ConstPtr g)
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
void update(const YieldStressInputs &inputs, double t, double dt)
IceModelVec2S m_basal_yield_stress
DiagnosticList diagnostics_impl() const
The PISM basal yield stress model interface (virtual base class)
#define PISM_ERROR_LOCATION
std::map< std::string, Diagnostic::Ptr > DiagnosticList
@ PISM_READONLY
open an existing file for reading only
T combine(const T &a, const T &b)