21 #include "pism/geometry/Geometry.hh"
22 #include "pism/hydrology/Distributed.hh"
23 #include "pism/util/array/CellType.hh"
24 #include "pism/util/error_handling.hh"
25 #include "pism/util/io/File.hh"
26 #include "pism/util/pism_utilities.hh"
32 :
Routing(
g), m_P(m_grid,
"bwp"), m_Pnew(m_grid,
"Pnew_internal") {
36 .
long_name(
"pressure of transportable water in subglacial layer")
41 .
long_name(
"new transportable subglacial water pressure during update")
48 "* Initializing the distributed, linked-cavities subglacial hydrology model...\n");
62 double bwp_default =
m_config->get_number(
"bootstrapping.defaults.bwp");
67 bool init_P_from_steady =
m_config->get_flag(
"hydrology.distributed.init_p_from_steady");
69 if (init_P_from_steady) {
70 m_log->message(2,
" initializing P from P(W) formula which applies in steady state\n");
77 std::string filename =
m_config->get_string(
"hydrology.distributed.sliding_speed_file");
79 if (filename.empty()) {
81 "hydrology.distributed.sliding_speed_file is not set");
110 std::map<std::string, TSDiagnostic::Ptr> result = {
128 bool enforce_upper) {
134 for (
auto p =
m_grid->points(); p; p.next()) {
135 const int i = p.i(), j = p.j();
139 "negative subglacial water pressure\n"
140 "P(%d, %d) = %.6f Pa",
145 P(i,j) =
std::min(P(i,j), P_o(i,j));
146 }
else if (P(i,j) > P_o(i,j) + 0.001) {
148 "subglacial water pressure P = %.16f Pa exceeds\n"
149 "overburden pressure Po = %.16f Pa at (i,j)=(%d,%d)",
150 P(i, j), P_o(i, j), i, j);
176 ice_softness =
m_config->get_number(
"flow_law.isothermal_Glen.ice_softness"),
177 creep_closure_coefficient =
m_config->get_number(
"hydrology.creep_closure_coefficient"),
178 cavitation_opening_coefficient =
m_config->get_number(
"hydrology.cavitation_opening_coefficient"),
179 Glen_exponent =
m_config->get_number(
"stress_balance.sia.Glen_exponent"),
180 Wr =
m_config->get_number(
"hydrology.roughness_scale");
182 const double CC = cavitation_opening_coefficient / (creep_closure_coefficient * ice_softness);
186 for (
auto p =
m_grid->points(); p; p.next()) {
187 const int i = p.i(), j = p.j();
189 double sb = pow(CC * sliding_speed(i, j), 1.0 / Glen_exponent);
190 if (W(i, j) == 0.0) {
198 result(i, j) = P_overburden(i, j);
201 double Wratio =
std::max(0.0,
Wr - W(i, j)) / W(i, j);
204 result(i, j) =
std::max(0.0, P_overburden(i, j) - sb * pow(Wratio, 1.0 / Glen_exponent));
210 return 2.0 * phi0 * dt_diff_w;
229 n =
m_config->get_number(
"stress_balance.sia.Glen_exponent"),
230 A =
m_config->get_number(
"flow_law.isothermal_Glen.ice_softness"),
231 c1 =
m_config->get_number(
"hydrology.cavitation_opening_coefficient"),
232 c2 =
m_config->get_number(
"hydrology.creep_closure_coefficient"),
233 Wr =
m_config->get_number(
"hydrology.roughness_scale"),
234 phi0 =
m_config->get_number(
"hydrology.regularizing_porosity");
238 CC = (
m_rg * dt) / phi0,
244 &cell_type, &P_overburden, &P_new};
246 for (
auto p =
m_grid->points(); p; p.next()) {
247 const int i = p.i(), j = p.j();
249 auto w = W.
star(i, j);
250 double P_o = P_overburden(i, j);
254 }
else if (cell_type.
ocean(i, j)) {
256 }
else if (w.c <= 0.0) {
259 auto q = Q.
star(i, j);
260 auto k =
K.star(i, j);
261 auto ws = Ws.
star(i, j);
264 Open =
c1 * sliding_speed(i, j) *
std::max(0.0,
Wr - w.c),
265 Close =
c2 * A * pow(P_o - P(i, j),
n) * w.c;
268 const double divadflux = (q.e - q.w) /
m_dx + (q.n - q.s) /
m_dy;
270 De =
m_rg *
k.e * ws.e,
271 Dw =
m_rg *
k.w * ws.w,
272 Dn =
m_rg *
k.n * ws.n,
273 Ds =
m_rg *
k.s * ws.s;
275 double diffW = (wux * (De * (w.e - w.c) - Dw * (w.c - w.w)) +
276 wuy * (Dn * (w.n - w.c) - Ds * (w.c - w.s)));
278 double divflux = -divadflux + diffW;
281 double Wtill_change = Wtill_new(i, j) - Wtill(i, j);
283 double ZZ = Close - Open + total_input - Wtill_change / dt;
285 P_new(i, j) = P(i, j) + CC * (divflux + ZZ);
288 P_new(i, j) =
clip(P_new(i, j), 0.0, P_o);
310 dt_max =
m_config->get_number(
"hydrology.maximum_time_step",
"seconds"),
311 phi0 =
m_config->get_number(
"hydrology.regularizing_porosity"),
312 tillwat_max =
m_config->get_number(
"hydrology.tillwat_max");
320 unsigned int step_counter = 0;
321 for (; ht < t_final; ht += hdt) {
325 double huge_number = 1e6;
333 bool enforce_upper = (step_counter == 1);
364 hdt =
std::min(t_final - ht, dt_max);
370 m_log->message(3,
" hydrology step %05d, dt = %f s\n", step_counter, hdt);
427 m_config->get_flag(
"hydrology.routing.include_floating_ice"),
432 " took %d hydrology sub-steps with average dt = %.6f years (%.6f s)\n",
const units::System::Ptr m_sys
unit system used by this component
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)
High-level PISM I/O class.
array::CellType2 cell_type
void failed()
Indicates a failure of a parallel section.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void copy_from(const Array2D< T > &source)
stencils::Star< T > star(int i, int j) const
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 scale(double alpha)
Result: v <- v * alpha. Calls VecScale.
void set(double c)
Result: v[j] <- c for all j.
void regrid(const std::string &filename, io::Default default_value)
void add(double alpha, const Array &x)
Result: v <- v + alpha * x. Calls VecAXPY.
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 ocean(int i, int j) const
bool ice_free_land(int i, int j) const
"Cell type" mask. Adds convenience methods to array::Scalar.
stencils::Star< double > star(int i, int j) const
Returns the values at interfaces of the cell i,j using the staggered grid.
void write_model_state_impl(const File &output) const
The default (empty implementation).
virtual void bootstrap_impl(const File &input_file, const array::Scalar &ice_thickness)
void define_model_state_impl(const File &output) const
The default (empty implementation).
void update_P(double dt, const array::CellType &cell_type, const array::Scalar &sliding_speed, const array::Scalar &surface_input_rate, const array::Scalar &basal_melt_rate, const array::Scalar &P_overburden, const array::Scalar &Wtill, const array::Scalar &Wtill_new, const array::Scalar &P, const array::Scalar1 &W, const array::Staggered1 &Ws, const array::Staggered1 &K, const array::Staggered1 &Q, array::Scalar &P_new) const
virtual void init_impl(const array::Scalar &W_till, const array::Scalar &W, const array::Scalar &P)
std::map< std::string, TSDiagnostic::Ptr > ts_diagnostics_impl() const
void P_from_W_steady(const array::Scalar &W, const array::Scalar &P_overburden, const array::Scalar &sliding_speed, array::Scalar &result)
Compute functional relationship P(W) which applies only in steady state.
const array::Scalar & subglacial_water_pressure() const
Copies the P state variable which is the modeled water pressure.
void initialization_message() const
Distributed(std::shared_ptr< const Grid > g)
void update_impl(double t, double dt, const Inputs &inputs)
Update the model state variables W,P by running the subglacial hydrology model.
virtual double max_timestep_P_diff(double phi0, double dt_diff_w) const
void check_P_bounds(array::Scalar &P, const array::Scalar &P_o, bool enforce_upper)
virtual void restart_impl(const File &input_file, int record)
array::Scalar m_surface_input_rate
array::Scalar m_grounding_line_change
const array::Scalar & surface_input_rate() const
void enforce_bounds(const array::CellType &cell_type, const array::Scalar *no_model_mask, double max_thickness, double ocean_water_thickness, array::Scalar &water_thickness, array::Scalar &grounded_margin_change, array::Scalar &grounding_line_change, array::Scalar &conservation_error_change, array::Scalar &no_model_mask_change)
Correct the new water thickness based on boundary requirements.
array::Scalar m_basal_melt_rate
array::Scalar1 m_W
effective thickness of transportable basal water
void compute_overburden_pressure(const array::Scalar &ice_thickness, array::Scalar &result) const
Update the overburden pressure from ice thickness.
array::Scalar m_Wtill
effective thickness of basal water stored in till
array::Scalar m_Pover
overburden pressure
array::Scalar m_grounded_margin_change
array::Scalar m_no_model_mask_change
array::Scalar m_conservation_error_change
virtual void init_impl(const array::Scalar &W_till, const array::Scalar &W, const array::Scalar &P)
array::Staggered1 m_Qstag_average
array::Staggered1 m_Wstag
double max_timestep_W_diff(double KW_max) const
virtual void bootstrap_impl(const File &input_file, const array::Scalar &ice_thickness)
double max_timestep_W_cfl() const
void compute_conductivity(const array::Staggered &W, const array::Scalar &P, const array::Scalar &bed, array::Staggered &result, double &maxKW) const
Compute the nonlinear conductivity at the center of cell edges.
array::Staggered1 m_Kstag
void advective_fluxes(const array::Staggered &V, const array::Scalar &W, array::Staggered &result) const
Compute Q = V W at edge-centers (staggered grid) by first-order upwinding.
void update_W(double dt, const array::Scalar &surface_input_rate, const array::Scalar &basal_melt_rate, const array::Scalar1 &W, const array::Staggered1 &Wstag, const array::Scalar &Wtill, const array::Scalar &Wtill_new, const array::Staggered1 &K, const array::Staggered1 &Q, array::Scalar &W_new)
The computation of Wnew, called by update().
void water_thickness_staggered(const array::Scalar &W, const array::CellType1 &mask, array::Staggered &result)
Average the regular grid water thickness to values at the center of cell edges.
void compute_velocity(const array::Staggered &W, const array::Scalar &P, const array::Scalar &bed, const array::Staggered &K, const array::Scalar1 *no_model_mask, array::Staggered &result) const
Get the advection velocity V at the center of cell edges.
array::Staggered1 m_Qstag
virtual void define_model_state_impl(const File &output) const
The default (empty implementation).
void update_Wtill(double dt, const array::Scalar &Wtill, const array::Scalar &surface_input_rate, const array::Scalar &basal_melt_rate, array::Scalar &Wtill_new)
The computation of Wtillnew, called by update().
virtual void write_model_state_impl(const File &output) const
The default (empty implementation).
virtual void restart_impl(const File &input_file, int record)
array::Scalar1 m_bottom_surface
A subglacial hydrology model which assumes water pressure equals overburden pressure.
#define PISM_ERROR_LOCATION
void staggered_to_regular(const array::CellType1 &cell_type, const array::Staggered1 &input, bool include_floating_ice, array::Scalar &result)
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 K(double psi_x, double psi_y, double speed, double epsilon)
void check_bounds(const array::Scalar &W, double W_max)
double convert(System::Ptr system, double input, const std::string &spec1, const std::string &spec2)
Convert a quantity from unit1 to unit2.
void ice_bottom_surface(const Geometry &geometry, array::Scalar &result)