19#include "pism/basalstrength/MohrCoulombYieldStress.hh"
20#include "pism/basalstrength/MohrCoulombPointwise.hh"
22#include "pism/util/Grid.hh"
23#include "pism/util/error_handling.hh"
24#include "pism/util/io/File.hh"
25#include "pism/util/MaxTimestep.hh"
26#include "pism/util/pism_utilities.hh"
27#include "pism/util/Time.hh"
28#include "pism/util/array/CellType.hh"
29#include "pism/util/array/Forcing.hh"
30#include "pism/geometry/Geometry.hh"
31#include "pism/coupler/util/options.hh"
91 m_till_phi(m_grid,
"tillphi") {
93 m_name =
"Mohr-Coulomb yield stress model";
96 .
long_name(
"friction angle for till under grounded ice sheet")
103 std::string hydrology_tillwat_max =
"hydrology.tillwat_max";
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",
130 .long_name(
"minimum effective pressure on till as a fraction of overburden pressure")
145 auto tauc_to_phi_file =
m_config->get_string(
"basal_yield_stress.mohr_coulomb.tauc_to_phi.file");
147 if (not tauc_to_phi_file.empty()) {
151 " Will compute till friction angle (tillphi) as a function"
152 " of the yield stress (tauc)...\n");
160 }
else if (
m_config->get_flag(
"basal_yield_stress.mohr_coulomb.topg_to_phi.enabled")) {
162 m_log->message(2,
" creating till friction angle map from bed elevation...\n");
167 "PISM WARNING: -topg_to_phi computation will override the '%s' field\n"
168 " present in the input file '%s'!\n",
175 double till_phi_default =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_phi_default");
183 double till_phi_default =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_phi_default");
211 auto dt =
m_delta->max_timestep(t);
266 double t,
double dt) {
270 bool slippery_grounding_lines =
m_config->get_flag(
"basal_yield_stress.slippery_grounding_lines"),
271 add_transportable_water =
m_config->get_flag(
"basal_yield_stress.add_transportable_water");
274 ice_density =
m_config->get_number(
"constants.ice.density"),
275 standard_gravity =
m_config->get_number(
"constants.standard_gravity");
277 const double high_tauc =
m_config->get_number(
"basal_yield_stress.ice_free_bedrock"),
278 W_till_max =
m_config->get_number(
"hydrology.tillwat_max"),
279 delta =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_effective_fraction_overburden"),
280 tlftw =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_log_factor_transportable_water");
294 &bed_topography, &sea_level, &ice_thickness};
296 if (add_transportable_water) {
297 list.
add(W_subglacial);
306 for (
auto p =
m_grid->points(); p; p.next()) {
307 const int i = p.i(), j = p.j();
309 if (cell_type.ice_free(i, j)) {
314 double water = W_till(i,j);
316 if (slippery_grounding_lines and
317 bed_topography(i, j) <= sea_level(i, j) and
318 (cell_type.next_to_floating_ice(i, j) or cell_type.next_to_ice_free_ocean(i, j))) {
320 }
else if (add_transportable_water) {
321 water = W_till(i, j) + tlftw * log(1.0 + W_subglacial(i, j) / tlftw);
324 double P_overburden = ice_density * standard_gravity * ice_thickness(i, j);
354 phi_min =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.topg_to_phi.phi_min"),
355 phi_max =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.topg_to_phi.phi_max"),
356 topg_min =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.topg_to_phi.topg_min"),
357 topg_max =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.topg_to_phi.topg_max");
360 " till friction angle (phi) is piecewise-linear function of bed elev (topg):\n"
361 " / %5.2f for topg < %.f\n"
362 " phi = | %5.2f + (topg - (%.f)) * (%.2f / %.f) for %.f < topg < %.f\n"
363 " \\ %5.2f for %.f < topg\n",
365 phi_min, topg_min, phi_max - phi_min, topg_max - topg_min, topg_min, topg_max,
368 if (phi_min >= phi_max) {
370 "invalid -topg_to_phi arguments: phi_min < phi_max is required");
373 if (topg_min >= topg_max) {
375 "invalid -topg_to_phi arguments: topg_min < topg_max is required");
378 const double slope = (phi_max - phi_min) / (topg_max - topg_min);
382 for (
auto p =
m_grid->points(); p; p.next()) {
383 const int i = p.i(), j = p.j();
384 const double bed = bed_topography(i, j);
386 if (bed <= topg_min) {
387 result(i, j) = phi_min;
388 }
else if (bed >= topg_max) {
389 result(i, j) = phi_max;
391 result(i, j) = phi_min + (bed - topg_min) * slope;
415 ice_density =
m_config->get_number(
"constants.ice.density"),
416 standard_gravity =
m_config->get_number(
"constants.standard_gravity");
419 delta =
m_config->get_number(
"basal_yield_stress.mohr_coulomb.till_effective_fraction_overburden");
422 &W_till = till_water_thickness;
424 array::AccessScope list{&cell_type, &basal_yield_stress, &W_till, &ice_thickness, &result};
426 for (
auto p =
m_grid->points(); p; p.next()) {
427 const int i = p.i(), j = p.j();
432 double P_overburden = ice_density * standard_gravity * ice_thickness(i, j);
434 result(i, j) = mc.
till_friction_angle(delta, P_overburden, W_till(i, j), basal_yield_stress(i, j));
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
void regrid(const std::string &module_name, array::Array &variable, RegriddingFlag flag=NO_REGRID_WITHOUT_REGRID_VARS)
static Ptr wrap(const T &input)
bool variable_exists(const std::string &short_name) const
Checks if a variable exists.
High-level PISM I/O class.
array::Scalar1 sea_level_elevation
array::CellType2 cell_type
array::Scalar2 ice_thickness
array::Scalar2 bed_elevation
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
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
MohrCoulombYieldStress(std::shared_ptr< const Grid > g)
void set_till_friction_angle(const array::Scalar &input)
void write_model_state_impl(const File &output) const
The default (empty implementation).
void define_model_state_impl(const File &output) const
void finish_initialization(const YieldStressInputs &inputs)
MaxTimestep max_timestep_impl(double t) const
std::shared_ptr< array::Forcing > m_delta
void till_friction_angle(const array::Scalar &bed_topography, array::Scalar &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.
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)
DiagnosticList diagnostics_impl() const
array::Scalar2 m_basal_yield_stress
The PISM basal yield stress model interface (virtual base class)
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void copy_from(const Array2D< T > &source)
void add(double alpha, const Array2D< T > &x)
void read(const std::string &filename, unsigned int time)
void define(const File &file, io::Type default_type) const
Define variables corresponding to an Array in a file opened using file.
void write(const std::string &filename) const
void set(double c)
Result: v[j] <- c for all j.
void regrid(const std::string &filename, io::Default default_value)
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.
bool ice_free(int i, int j) const
bool ocean(int i, int j) const
"Cell type" mask. Adds convenience methods to array::Scalar.
#define PISM_ERROR_LOCATION
@ PISM_READONLY
open an existing file for reading only
std::map< std::string, Diagnostic::Ptr > DiagnosticList
T combine(const T &a, const T &b)