PISM, A Parallel Ice Sheet Model 2.3.0-79cae578d committed by Constantine Khrulev on 2026-03-22
Loading...
Searching...
No Matches
Hydrology.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2025 PISM Authors
2//
3// This file is part of PISM.
4//
5// PISM is free software; you can redistribute it and/or modify it under the
6// terms of the GNU General Public License as published by the Free Software
7// Foundation; either version 3 of the License, or (at your option) any later
8// version.
9//
10// PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13// details.
14//
15// You should have received a copy of the GNU General Public License
16// along with PISM; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19#include "pism/hydrology/Hydrology.hh"
20#include "pism/util/error_handling.hh"
21#include "pism/util/io/File.hh"
22#include "pism/util/array/CellType.hh"
23#include "pism/geometry/Geometry.hh"
24#include "pism/util/io/IO_Flags.hh"
25
26namespace pism {
27namespace hydrology {
28
29namespace diagnostics {
30
31class TendencyOfWaterMass : public DiagAverageRate<Hydrology>
32{
33public:
35 : DiagAverageRate<Hydrology>(m, "tendency_of_subglacial_water_mass", TOTAL_CHANGE) {
36
37 m_accumulator.metadata()["units"] = "kg";
38
39 m_vars = { { m_sys, "tendency_of_subglacial_water_mass", *m_grid } };
40 m_vars[0]
41 .long_name("rate of change of the total mass of subglacial water")
42 .units("kg second^-1")
43 .output_units("Gt year^-1");
44 m_vars[0]["cell_methods"] = "time: mean";
45
46 m_vars[0]["_FillValue"] = {to_internal(m_fill_value)};
47 m_vars[0]["comment"] = "positive flux corresponds to water gain";
48 }
49
50protected:
52 return model->mass_change();
53 }
54};
55
56/*! @brief Report water input rate from the ice surface into the subglacial water system.
57 */
58class TotalInputRate : public DiagAverageRate<Hydrology>
59{
60public:
62 : DiagAverageRate<Hydrology>(m, "subglacial_water_input_rate_from_surface", RATE) {
63
64 m_accumulator.metadata()["units"] = "m";
65
66 m_vars = { { m_sys, "subglacial_water_input_rate_from_surface", *m_grid } };
67 m_vars[0]
68 .long_name("water input rate from the ice surface into the subglacial water system")
69 .units("m second^-1")
70 .output_units("m year^-1");
71 m_vars[0]["cell_methods"] = "time: mean";
72 m_vars[0]["_FillValue"] = { to_internal(m_fill_value) };
73 m_vars[0]["comment"] = "positive flux corresponds to water gain";
74 }
75
76protected:
78 return model->surface_input_rate();
79 }
80};
81
82/*! @brief Report water flux due to input (basal melt and drainage from the surface). */
83class WaterInputFlux : public DiagAverageRate<Hydrology> {
84public:
86 : DiagAverageRate<Hydrology>(m, "tendency_of_subglacial_water_mass_due_to_input",
88 m_accumulator.metadata()["units"] = "kg";
89
90 m_vars = { { m_sys, "tendency_of_subglacial_water_mass_due_to_input", *m_grid } };
91 m_vars[0]
92 .long_name("subglacial water flux due to input")
93 .units("kg second^-1")
94 .output_units("Gt year^-1");
95 m_vars[0]["cell_methods"] = "time: mean";
96 m_vars[0]["_FillValue"] = {to_internal(m_fill_value)};
97 m_vars[0]["comment"] = "positive flux corresponds to water gain";
98 }
99
100protected:
102 return model->mass_change_due_to_input();
103 }
104};
105
106/*! @brief Report advective subglacial water flux. */
107class SubglacialWaterFlux : public DiagAverageRate<Hydrology>
108{
109public:
111 : DiagAverageRate<Hydrology>(m, "subglacial_water_flux", RATE),
112 m_flux_magnitude(m_grid, "flux_magnitude"){
113
114 m_accumulator.metadata()["units"] = "m^2";
115
116 m_vars = { { m_sys, "subglacial_water_flux", *m_grid } };
117 m_vars[0]
118 .long_name("magnitude of the subglacial water flux")
119 .units("m^2 second^-1")
120 .output_units("m^2 year^-1");
121 m_vars[0]["cell_methods"] = "time: mean";
122 m_vars[0]["_FillValue"] = {to_internal(m_fill_value)};
123
125 .long_name("magnitude of the subglacial water flux")
126 .units("m^2 s^-1");
127 }
128
129protected:
130 void update_impl(double dt) {
131 compute_magnitude(model->flux(), m_flux_magnitude);
132
134
135 m_interval_length += dt;
136 }
137
139};
140
141
142/*! @brief Report water flux at the grounded margin. */
143class GroundedMarginFlux : public DiagAverageRate<Hydrology> {
144public:
146 : DiagAverageRate<Hydrology>(m, "tendency_of_subglacial_water_mass_at_grounded_margins",
147 TOTAL_CHANGE) {
148
149 m_accumulator.metadata()["units"] = "kg";
150
151 m_vars = { { m_sys, "tendency_of_subglacial_water_mass_at_grounded_margins", *m_grid } };
152 m_vars[0]
153 .long_name("subglacial water flux at grounded ice margins")
154 .units("kg second^-1")
155 .output_units("Gt year^-1");
156 m_vars[0]["cell_methods"] = "time: mean";
157 m_vars[0]["_FillValue"] = { to_internal(m_fill_value) };
158 m_vars[0]["comment"] = "positive flux corresponds to water gain";
159 }
160
161protected:
163 return model->mass_change_at_grounded_margin();
164 }
165};
166
167/*! @brief Report subglacial water flux at grounding lines. */
168class GroundingLineFlux : public DiagAverageRate<Hydrology> {
169public:
171 : DiagAverageRate<Hydrology>(m, "tendency_of_subglacial_water_mass_at_grounding_line",
172 TOTAL_CHANGE) {
173
174 m_accumulator.metadata()["units"] = "kg";
175
176 m_vars = { { m_sys, "tendency_of_subglacial_water_mass_at_grounding_line", *m_grid } };
177 m_vars[0]
178 .long_name("subglacial water flux at grounding lines")
179 .units("kg second^-1")
180 .output_units("Gt year^-1");
181 m_vars[0]["cell_methods"] = "time: mean";
182
183 m_vars[0]["_FillValue"] = { to_internal(m_fill_value) };
184 m_vars[0]["comment"] = "positive flux corresponds to water gain";
185 }
186
187protected:
189 return model->mass_change_at_grounding_line();
190 }
191};
192
193/*! @brief Report subglacial water conservation error flux (mass added to preserve non-negativity). */
194class ConservationErrorFlux : public DiagAverageRate<Hydrology> {
195public:
197 : DiagAverageRate<Hydrology>(m, "tendency_of_subglacial_water_mass_due_to_conservation_error",
198 TOTAL_CHANGE) {
199
200 m_accumulator.metadata()["units"] = "kg";
201
202 m_vars = { { m_sys, "tendency_of_subglacial_water_mass_due_to_conservation_error", *m_grid } };
203 m_vars[0]
204 .long_name(
205 "subglacial water flux due to conservation error (mass added to preserve non-negativity)")
206 .units("kg second^-1")
207 .output_units("Gt year^-1");
208 m_vars[0]["cell_methods"] = "time: mean";
209 m_vars[0]["_FillValue"] = { to_internal(m_fill_value) };
210 m_vars[0]["comment"] = "positive flux corresponds to water gain";
211 }
212
213protected:
215 return model->mass_change_due_to_conservation_error();
216 }
217};
218
219/*! @brief Report subglacial water flux at domain boundary (in regional model configurations). */
220class DomainBoundaryFlux : public DiagAverageRate<Hydrology> {
221public:
223 : DiagAverageRate<Hydrology>(m, "tendency_of_subglacial_water_mass_at_domain_boundary",
224 TOTAL_CHANGE) {
225
226 m_accumulator.metadata()["units"] = "kg";
227
228 m_vars = { { m_sys, "tendency_of_subglacial_water_mass_at_domain_boundary", *m_grid } };
229 m_vars[0]
230 .long_name("subglacial water flux at domain boundary (in regional model configurations)")
231 .units("kg second^-1")
232 .output_units("Gt year^-1");
233 m_vars[0]["cell_methods"] = "time: mean";
234 m_vars[0]["_FillValue"] = { to_internal(m_fill_value) };
235 m_vars[0]["comment"] = "positive flux corresponds to water gain";
236 }
237
238protected:
240 return model->mass_change_at_domain_boundary();
241 }
242};
243
244/*! @brief Report water flux at the grounded margin. */
246public:
248 : DiagAverageRate<Hydrology>(m, "tendency_of_subglacial_water_mass_due_to_flow",
249 TOTAL_CHANGE) {
250
251 m_accumulator.metadata()["units"] = "kg";
252
253 m_vars = { { m_sys, "tendency_of_subglacial_water_mass_due_to_flow", *m_grid } };
254 m_vars[0]
255 .long_name("rate of change subglacial water mass due to lateral flow")
256 .units("kg second^-1")
257 .output_units("Gt year^-1");
258 m_vars[0]["cell_methods"] = "time: mean";
259 m_vars[0]["_FillValue"] = { to_internal(m_fill_value) };
260 m_vars[0]["comment"] = "positive flux corresponds to water gain";
261 }
262
263protected:
265 return model->mass_change_due_to_lateral_flow();
266 }
267};
268
269} // end of namespace diagnostics
270
272 geometry = nullptr;
273 surface_input_rate = nullptr;
274 basal_melt_rate = nullptr;
275 ice_sliding_speed = nullptr;
276 no_model_mask = nullptr;
277}
278
279Hydrology::Hydrology(std::shared_ptr<const Grid> g)
280 : Component(g),
281 m_Q(m_grid, "water_flux"),
282 m_Wtill(m_grid, "tillwat"),
283 m_W(m_grid, "bwat"),
284 m_Pover(m_grid, "overburden_pressure"),
285 m_surface_input_rate(m_grid, "water_input_rate_from_surface"),
286 m_basal_melt_rate(m_grid, "water_input_rate_due_to_basal_melt"),
287 m_flow_change_incremental(m_grid, "water_thickness_change_due_to_flow"),
288 m_conservation_error_change(m_grid, "conservation_error_change"),
289 m_grounded_margin_change(m_grid, "grounded_margin_change"),
290 m_grounding_line_change(m_grid, "grounding_line_change"),
291 m_input_change(m_grid, "water_mass_change_due_to_input"),
292 m_no_model_mask_change(m_grid, "no_model_mask_change"),
293 m_total_change(m_grid, "water_mass_change"),
294 m_flow_change(m_grid, "water_mass_change_due_to_flow") {
295
297 .long_name("hydrology model workspace for water input rate from the ice surface")
298 .units("m s^-1");
299
301 .long_name("hydrology model workspace for water input rate due to basal melt")
302 .units("m s^-1");
303
304 // *all* Hydrology classes have layer of water stored in till as a state variable
306 .long_name("effective thickness of subglacial water stored in till")
307 .units("m");
308 m_Wtill.metadata()["valid_min"] = { 0.0 };
309
310 m_Pover.metadata(0).long_name("overburden pressure").units("Pa");
311 m_Pover.metadata()["valid_min"] = { 0.0 };
312
313 // needs ghosts in Routing and Distributed
314 m_W.metadata(0)
315 .long_name("thickness of transportable subglacial water layer")
316 .units("m");
317 m_W.metadata()["valid_min"] = { 0.0 };
318
319 m_Q.metadata(0)
320 .long_name("advective subglacial water flux")
321 .units("m^2 s^-1")
322 .output_units("m^2 day^-1");
323 m_Q.set(0.0);
324
325 // storage for water conservation reporting quantities
326 m_total_change.metadata(0).long_name("total change in water mass over one time step").units("kg");
327
329 .long_name(
330 "change in water mass over one time step due to the input (basal melt and surface drainage)")
331 .units("kg");
332
334 .long_name("change in water mass due to lateral flow (over one time step)")
335 .units("kg");
336
338 .long_name("changes in subglacial water thickness at the grounded margin")
339 .units("kg");
340
342 .long_name("changes in subglacial water thickness at the grounding line")
343 .units("kg");
344
346 .long_name(
347 "changes in subglacial water thickness at the edge of the modeling domain (regional models)")
348 .units("kg");
349
351 .long_name(
352 "changes in subglacial water thickness required to preserve non-negativity or keep water thickness within bounds")
353 .units("kg");
354}
355
356void Hydrology::restart(const File &input_file, int record) {
358 this->restart_impl(input_file, record);
359}
360
361void Hydrology::bootstrap(const File &input_file, const array::Scalar &ice_thickness) {
363 this->bootstrap_impl(input_file, ice_thickness);
364}
365
366void Hydrology::init(const array::Scalar &W_till, const array::Scalar &W, const array::Scalar &P) {
368 this->init_impl(W_till, W, P);
369}
370
371void Hydrology::restart_impl(const File &input_file, int record) {
372 m_Wtill.read(input_file, record);
373
374 // whether or not we could initialize from file, we could be asked to regrid from file
375 regrid("Hydrology", m_Wtill);
376}
377
378void Hydrology::bootstrap_impl(const File &input_file, const array::Scalar &ice_thickness) {
379 (void)ice_thickness;
380
381 double tillwat_default = m_config->get_number("bootstrapping.defaults.tillwat");
382 m_Wtill.regrid(input_file, io::Default(tillwat_default));
383
384 // whether or not we could initialize from file, we could be asked to regrid from file
385 regrid("Hydrology", m_Wtill);
386}
387
389 const array::Scalar &P) {
390 (void)W;
391 (void)P;
392 m_Wtill.copy_from(W_till);
393}
394
395void Hydrology::update(double t, double dt, const Inputs &inputs) {
396
397 // reset water thickness changes
398 {
403 m_flow_change.set(0.0);
404 m_input_change.set(0.0);
405 }
406
408
412
414
415 for (auto p : m_grid->points()) {
416 const int i = p.i(), j = p.j();
417
418 m_total_change(i, j) = m_W(i, j) + m_Wtill(i, j);
419 }
420
421 this->update_impl(t, dt, inputs);
422
423 // compute total change in meters
424 for (auto p : m_grid->points()) {
425 const int i = p.i(), j = p.j();
426 m_total_change(i, j) = (m_W(i, j) + m_Wtill(i, j)) - m_total_change(i, j);
427 }
428
429 // convert from m to kg
430 // kg = m * (kg / m^3) * m^2
431
432 double water_density = m_config->get_number("constants.fresh_water.density"),
433 kg_per_m = water_density * m_grid->cell_area();
434
435 list.add({ &m_flow_change, &m_input_change });
436 for (auto p : m_grid->points()) {
437 const int i = p.i(), j = p.j();
438 m_total_change(i, j) *= kg_per_m;
439 m_input_change(i, j) *= kg_per_m;
440 m_flow_change(i, j) *= kg_per_m;
441 }
442}
443
445 using namespace diagnostics;
446 DiagnosticList result = {
447 { "bwat", Diagnostic::wrap(m_W) },
448 { "tillwat", Diagnostic::wrap(m_Wtill) },
449 { "subglacial_water_input_rate", Diagnostic::Ptr(new TotalInputRate(this)) },
450 { "tendency_of_subglacial_water_mass_due_to_input", Diagnostic::Ptr(new WaterInputFlux(this)) },
451 { "tendency_of_subglacial_water_mass_due_to_flow",
452 Diagnostic::Ptr(new TendencyOfWaterMassDueToFlow(this)) },
453 { "tendency_of_subglacial_water_mass_due_to_conservation_error",
454 Diagnostic::Ptr(new ConservationErrorFlux(this)) },
455 { "tendency_of_subglacial_water_mass", Diagnostic::Ptr(new TendencyOfWaterMass(this)) },
456 { "tendency_of_subglacial_water_mass_at_grounded_margins",
457 Diagnostic::Ptr(new GroundedMarginFlux(this)) },
458 { "tendency_of_subglacial_water_mass_at_grounding_line",
459 Diagnostic::Ptr(new GroundingLineFlux(this)) },
460 { "tendency_of_subglacial_water_mass_at_domain_boundary",
461 Diagnostic::Ptr(new DomainBoundaryFlux(this)) },
462 { "subglacial_water_flux_mag", Diagnostic::Ptr(new SubglacialWaterFlux(this)) },
463 };
464
465 return result;
466}
467
468std::set<VariableMetadata> Hydrology::state_impl() const {
469 return array::metadata({ &m_Wtill });
470}
471
472void Hydrology::write_state_impl(const OutputFile &output) const {
473 m_Wtill.write(output);
474}
475
476//! Update the overburden pressure from ice thickness.
477/*!
478 Uses the standard hydrostatic (shallow) approximation of overburden pressure,
479 \f[ P_0 = \rho_i g H \f]
480*/
482 array::Scalar &result) const {
483 // FIXME issue #15
484
485 const double ice_density = m_config->get_number("constants.ice.density"),
486 standard_gravity = m_config->get_number("constants.standard_gravity");
487
488 array::AccessScope list{ &ice_thickness, &result };
489
490 for (auto p : m_grid->points()) {
491 const int i = p.i(), j = p.j();
492
493 result(i, j) = ice_density * standard_gravity * ice_thickness(i, j);
494 }
495}
496
498 return m_Pover;
499}
500
501//! Return the effective thickness of the water stored in till.
503 return m_Wtill;
504}
505
506//! Return the effective thickness of the transportable basal water layer.
510
511/*!
512 * Return subglacial water flux (time-average over the time step requested at the time of
513 * the update() call).
514 */
516 return m_Q;
517}
518
522
526
530
534
538
540 return m_total_change;
541}
542
546
550
551/*!
552 Checks @f$ 0 \le W \le W^{max} @f$.
553*/
554void check_bounds(const array::Scalar &W, double W_max) {
555
556 std::string name = W.metadata()["long_name"];
557
558 auto grid = W.grid();
559
560 array::AccessScope list(W);
561 ParallelSection loop(grid->com);
562 try {
563 for (auto p : grid->points()) {
564 const int i = p.i(), j = p.j();
565
566 if (W(i,j) < 0.0) {
568 "Hydrology: negative %s of %.6f m at (i, j) = (%d, %d)",
569 name.c_str(), W(i, j), i, j);
570 }
571
572 if (W(i,j) > W_max) {
574 "Hydrology: %s of %.6f m exceeds the maximum value %.6f at (i, j) = (%d, %d)",
575 name.c_str(), W(i, j), W_max, i, j);
576 }
577 }
578 } catch (...) {
579 loop.failed();
580 }
581 loop.check();
582}
583
584
585//! Compute the surface water input rate into the basal hydrology layer in the ice-covered
586//! region.
587/*!
588 This method ignores the input rate in the ice-free region.
589
590 @param[in] mask cell type mask
591 @param[in] surface_input_rate surface input rate (kg m-2 s-1); set to NULL to ignore
592 @param[out] result resulting input rate (water thickness per time)
593*/
595 const array::Scalar *surface_input_rate,
596 array::Scalar &result) {
597
598 if (not surface_input_rate) {
599 result.set(0.0);
600 return;
601 }
602
603 array::AccessScope list{surface_input_rate, &mask, &result};
604
605 const double
606 water_density = m_config->get_number("constants.fresh_water.density");
607
608 for (auto p : m_grid->points()) {
609 const int i = p.i(), j = p.j();
610
611 if (mask.icy(i, j)) {
612 result(i,j) = (*surface_input_rate)(i, j) / water_density;
613 } else {
614 result(i,j) = 0.0;
615 }
616 }
617}
618
619//! Compute the input rate into the basal hydrology layer in the ice-covered
620//! region due to basal melt rate.
621/*!
622 This method ignores the input in the ice-free region.
623
624 @param[in] mask cell type mask
625 @param[in] basal_melt_rate basal melt rate (ice thickness per time)
626 @param[out] result resulting input rate (water thickness per time)
627*/
629 const array::Scalar &basal_melt_rate,
630 array::Scalar &result) {
631
632 array::AccessScope list{&basal_melt_rate, &mask, &result};
633
634 const double
635 ice_density = m_config->get_number("constants.ice.density"),
636 water_density = m_config->get_number("constants.fresh_water.density"),
637 C = ice_density / water_density;
638
639 for (auto p : m_grid->points()) {
640 const int i = p.i(), j = p.j();
641
642 if (mask.icy(i, j)) {
643 result(i,j) = C * basal_melt_rate(i, j);
644 } else {
645 result(i,j) = 0.0;
646 }
647 }
648}
649
650//! Correct the new water thickness based on boundary requirements.
651/*! At ice free locations and ocean locations we require that water thicknesses (i.e. both
652 the transportable water thickness \f$W\f$ and the till water thickness \f$W_{till}\f$)
653 be zero at the end of each time step. Also we require that any negative water
654 thicknesses be set to zero (i.e. we do projection to enforce lower bound).
655
656 This method should be called once for each thickness field which needs to be processed.
657 This method alters the field water_thickness in-place.
658
659 @param[in] cell_type cell type mask
660 @param[in] no_model_mask (optional) mask of zeros and ones, zero within the modeling
661 domain, one outside
662 @param[in] max_thickness maximum allowed water thickness (use a zero or a negative value
663 to disable)
664 @param[in,out] water_thickness adjusted water thickness (till storage or the transport system)
665 @param[in,out] grounded_margin_change change in water thickness at the grounded margin
666 @param[in,out] grounding_line_change change in water thickness at the grounding line
667 @param[in,out] conservation_error_change change in water thickness due to mass conservation errors
668 @param[in,out] no_model_mask_change change in water thickness outside the modeling domain (regional models)
669*/
671 const array::Scalar *no_model_mask,
672 double max_thickness,
673 double ocean_water_thickness,
674 array::Scalar &water_thickness,
675 array::Scalar &grounded_margin_change,
676 array::Scalar &grounding_line_change,
677 array::Scalar &conservation_error_change,
678 array::Scalar &no_model_mask_change) {
679
680 bool include_floating = m_config->get_flag("hydrology.routing.include_floating_ice");
681
682 array::AccessScope list{&water_thickness, &cell_type,
683 &grounded_margin_change, &grounding_line_change, &conservation_error_change,
684 &no_model_mask_change};
685
686 double
687 fresh_water_density = m_config->get_number("constants.fresh_water.density"),
688 kg_per_m = m_grid->cell_area() * fresh_water_density; // kg m-1
689
690 for (auto p : m_grid->points()) {
691 const int i = p.i(), j = p.j();
692
693 if (water_thickness(i, j) < 0.0) {
694 conservation_error_change(i, j) += -water_thickness(i, j) * kg_per_m;
695 water_thickness(i, j) = 0.0;
696 }
697
698 if (max_thickness > 0.0 and water_thickness(i, j) > max_thickness) {
699 double excess = water_thickness(i, j) - max_thickness;
700
701 conservation_error_change(i, j) += -excess * kg_per_m;
702 water_thickness(i, j) = max_thickness;
703 }
704
705 if (cell_type.ice_free_land(i, j)) {
706 double grounded_ice_free_max_thickness = 0.0;
707 double excess = water_thickness(i, j) - grounded_ice_free_max_thickness;
708 grounded_margin_change(i, j) += -excess * kg_per_m;
709 water_thickness(i, j) = grounded_ice_free_max_thickness;
710 }
711
712 // This keeps track of water mass changes at the grounding line due to
713 //
714 // - water leaving the system (drainage into the ocean) and
715 //
716 // - water added to the system when the sea level rises and previously grounded areas
717 // come in contact with the ocean.
718 //
719 // If the sea level rises and covers previously ice free land, the till water amount
720 // at that location should change to the maximum till water thickness.
721 //
722 // When the sea level recedes, the till water at that location will be set to zero by
723 // the if block above. All these changes will be accounted for.
724 if ((include_floating and cell_type.ice_free_ocean(i, j)) or
725 (not include_floating and cell_type.ocean(i, j))) {
726
727 double mismatch = water_thickness(i, j) - ocean_water_thickness;
728
729 grounding_line_change(i, j) += -mismatch * kg_per_m;
730 water_thickness(i, j) = ocean_water_thickness;
731 }
732 }
733
734 if (no_model_mask != nullptr) {
735 const array::Scalar &M = *no_model_mask;
736
737 list.add(M);
738
739 for (auto p : m_grid->points()) {
740 const int i = p.i(), j = p.j();
741
742 if (M(i, j) > 0.0) {
743 no_model_mask_change(i, j) += -water_thickness(i, j) * kg_per_m;
744
745 water_thickness(i, j) = 0.0;
746 }
747 }
748 }
749}
750
751} // end of namespace hydrology
752} // end of namespace pism
std::shared_ptr< const Config > m_config
configuration database used by this component
Definition Component.hh:160
const std::shared_ptr< const Grid > m_grid
grid used by this component
Definition Component.hh:158
void regrid(const std::string &module_name, array::Array &variable, RegriddingFlag flag=NO_REGRID_WITHOUT_REGRID_VARS)
Definition Component.cc:152
A class defining a common interface for most PISM sub-models.
Definition Component.hh:118
const Model * model
std::vector< VariableMetadata > m_vars
metadata corresponding to NetCDF variables
static Ptr wrap(const T &input)
double m_fill_value
fill value (used often enough to justify storing it)
const units::System::Ptr m_sys
the unit system
double to_internal(double x) const
Definition Diagnostic.cc:62
std::shared_ptr< Diagnostic > Ptr
Definition Diagnostic.hh:67
std::shared_ptr< const Grid > m_grid
the grid
High-level PISM I/O class.
Definition File.hh:57
array::CellType2 cell_type
Definition Geometry.hh:55
array::Scalar2 ice_thickness
Definition Geometry.hh:51
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
VariableMetadata & long_name(const std::string &input)
VariableMetadata & units(const std::string &input)
VariableMetadata & output_units(const std::string &input)
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition Array.hh:66
void copy_from(const Array2D< T > &source)
Definition Array2D.hh:101
void add(double alpha, const Array2D< T > &x)
Definition Array2D.hh:93
void read(const std::string &filename, unsigned int time)
Definition Array.cc:753
void write(const OutputFile &file) const
Definition Array.cc:859
std::shared_ptr< const Grid > grid() const
Definition Array.cc:134
void set(double c)
Result: v[j] <- c for all j.
Definition Array.cc:659
void regrid(const std::string &filename, io::Default default_value)
Definition Array.cc:758
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata object containing metadata for the compoment N.
Definition Array.cc:467
bool ice_free_ocean(int i, int j) const
Definition CellType.hh:58
bool ocean(int i, int j) const
Definition CellType.hh:34
bool ice_free_land(int i, int j) const
Definition CellType.hh:62
bool icy(int i, int j) const
Definition CellType.hh:42
"Cell type" mask. Adds convenience methods to array::Scalar.
Definition CellType.hh:30
array::Scalar m_flow_change
Definition Hydrology.hh:196
const array::Scalar & till_water_thickness() const
Return the effective thickness of the water stored in till.
Definition Hydrology.cc:502
void restart(const File &input_file, int record)
Definition Hydrology.cc:356
Hydrology(std::shared_ptr< const Grid > g)
Definition Hydrology.cc:279
virtual void bootstrap_impl(const File &input_file, const array::Scalar &ice_thickness)
Definition Hydrology.cc:378
virtual std::map< std::string, Diagnostic::Ptr > spatial_diagnostics_impl() const
Definition Hydrology.cc:444
array::Scalar m_surface_input_rate
Definition Hydrology.hh:179
array::Scalar m_total_change
Definition Hydrology.hh:195
void bootstrap(const File &input_file, const array::Scalar &ice_thickness)
Definition Hydrology.cc:361
array::Scalar m_grounding_line_change
Definition Hydrology.hh:192
const array::Scalar & mass_change_at_domain_boundary() const
Definition Hydrology.cc:535
virtual std::set< VariableMetadata > state_impl() const
Definition Hydrology.cc:468
const array::Scalar & surface_input_rate() const
Definition Hydrology.cc:519
virtual void initialization_message() const =0
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.
Definition Hydrology.cc:670
const array::Scalar & subglacial_water_thickness() const
Return the effective thickness of the transportable basal water layer.
Definition Hydrology.cc:507
array::Scalar m_basal_melt_rate
Definition Hydrology.hh:182
const array::Scalar & mass_change_due_to_lateral_flow() const
Definition Hydrology.cc:547
virtual void init_impl(const array::Scalar &W_till, const array::Scalar &W, const array::Scalar &P)
Definition Hydrology.cc:388
const array::Scalar & mass_change_due_to_conservation_error() const
Definition Hydrology.cc:531
array::Scalar1 m_W
effective thickness of transportable basal water
Definition Hydrology.hh:173
void compute_overburden_pressure(const array::Scalar &ice_thickness, array::Scalar &result) const
Update the overburden pressure from ice thickness.
Definition Hydrology.cc:481
const array::Scalar & mass_change_at_grounded_margin() const
Definition Hydrology.cc:523
virtual void restart_impl(const File &input_file, int record)
Definition Hydrology.cc:371
array::Scalar m_input_change
Definition Hydrology.hh:193
void update(double t, double dt, const Inputs &inputs)
Definition Hydrology.cc:395
array::Scalar m_Wtill
effective thickness of basal water stored in till
Definition Hydrology.hh:170
const array::Scalar & overburden_pressure() const
Definition Hydrology.cc:497
virtual void update_impl(double t, double dt, const Inputs &inputs)=0
const array::Scalar & mass_change_due_to_input() const
Definition Hydrology.cc:543
array::Scalar m_Pover
overburden pressure
Definition Hydrology.hh:176
const array::Vector & flux() const
Definition Hydrology.cc:515
void compute_basal_melt_rate(const array::CellType &mask, const array::Scalar &basal_melt_rate, array::Scalar &result)
Definition Hydrology.cc:628
array::Scalar m_grounded_margin_change
Definition Hydrology.hh:191
const array::Scalar & mass_change_at_grounding_line() const
Definition Hydrology.cc:527
virtual void write_state_impl(const OutputFile &output) const
The default (empty implementation).
Definition Hydrology.cc:472
array::Scalar m_no_model_mask_change
Definition Hydrology.hh:194
void compute_surface_input_rate(const array::CellType &mask, const array::Scalar *surface_input_rate, array::Scalar &result)
Definition Hydrology.cc:594
void init(const array::Scalar &W_till, const array::Scalar &W, const array::Scalar &P)
Definition Hydrology.cc:366
const array::Scalar & mass_change() const
Definition Hydrology.cc:539
array::Scalar m_conservation_error_change
Definition Hydrology.hh:190
The PISM subglacial hydrology model interface.
Definition Hydrology.hh:109
const Geometry * geometry
Definition Hydrology.hh:37
const array::Scalar * ice_sliding_speed
Definition Hydrology.hh:41
const array::Scalar * surface_input_rate
Definition Hydrology.hh:39
const array::Scalar1 * no_model_mask
Definition Hydrology.hh:35
const array::Scalar * basal_melt_rate
Definition Hydrology.hh:40
Report subglacial water conservation error flux (mass added to preserve non-negativity).
Definition Hydrology.cc:194
Report subglacial water flux at domain boundary (in regional model configurations).
Definition Hydrology.cc:220
Report water flux at the grounded margin.
Definition Hydrology.cc:143
Report subglacial water flux at grounding lines.
Definition Hydrology.cc:168
Report advective subglacial water flux.
Definition Hydrology.cc:108
Report water flux at the grounded margin.
Definition Hydrology.cc:245
Report water input rate from the ice surface into the subglacial water system.
Definition Hydrology.cc:59
Report water flux due to input (basal melt and drainage from the surface).
Definition Hydrology.cc:83
#define PISM_ERROR_LOCATION
std::set< VariableMetadata > metadata(std::initializer_list< const Array * > vecs)
Definition Array.cc:1244
void check_bounds(const array::Scalar &W, double W_max)
Definition Hydrology.cc:554
static const double g
Definition exactTestP.cc:36
std::map< std::string, Diagnostic::Ptr > DiagnosticList