PISM, A Parallel Ice Sheet Model 2.3.0-79cae578d committed by Constantine Khrulev on 2026-03-22
Loading...
Searching...
No Matches
DischargeGiven.cc
Go to the documentation of this file.
1// Copyright (C) 2018, 2019, 2021, 2022, 2023, 2024, 2025 Andy Aschwanden and Constantine Khroulev
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/coupler/frontalmelt/DischargeGiven.hh"
20
21#include "pism/coupler/frontalmelt/FrontalMeltPhysics.hh"
22#include "pism/coupler/util/options.hh"
23#include "pism/geometry/Geometry.hh"
24#include "pism/util/Grid.hh"
25#include "pism/util/array/Forcing.hh"
26#include "pism/util/Logger.hh"
27#include "pism/util/io/IO_Flags.hh"
28
29namespace pism {
30namespace frontalmelt {
31
32DischargeGiven::DischargeGiven(std::shared_ptr<const Grid> grid)
33 : FrontalMelt(grid, nullptr), m_frontal_melt_rate(grid, "frontal_melt_rate") {
34
36 .long_name("frontal melt rate")
37 .units("m s^-1")
38 .output_units("m day^-1");
39
40 m_log->message(2, "* Initializing the frontal melt model\n"
41 " UAF-UT\n");
42
43 m_theta_ocean = array::Forcing::Constant(grid, "theta_ocean", 0.0);
44
45 m_subglacial_discharge = array::Forcing::Constant(grid, "subglacial_discharge", 0.0);
46}
47
48void DischargeGiven::init_impl(const Geometry &geometry) {
49 (void)geometry;
50
51 ForcingOptions opt(*m_grid->ctx(), "frontal_melt.discharge_given");
52
53 {
54 unsigned int buffer_size = m_config->get_number("input.forcing.buffer_size");
55
57
58 m_theta_ocean = std::make_shared<array::Forcing>(m_grid, file, "theta_ocean",
59 "", // no standard name
60 buffer_size, opt.periodic);
61
62 m_subglacial_discharge = std::make_shared<array::Forcing>(m_grid, file, "subglacial_discharge",
63 "", // no standard name
64 buffer_size, opt.periodic);
65 }
66
67 m_theta_ocean->metadata(0)
68 .long_name("potential temperature of the adjacent ocean")
69 .units("degree_Celsius");
70
71 m_theta_ocean->init(opt.filename, opt.periodic);
72
73 m_subglacial_discharge->metadata(0)
74 .long_name("subglacial discharge")
75 .units("kg m^-2 s^-1")
76 .output_units("kg m^-2 year^-1");
77
79}
80
81/*!
82 * Initialize potential temperature from arrays instead of an input
83 * file (for testing).
84 */
86 m_theta_ocean->copy_from(theta);
87 m_subglacial_discharge->copy_from(sgl);
88}
89
90void DischargeGiven::update_impl(const FrontalMeltInputs &inputs, double t, double dt) {
91
92 m_theta_ocean->update(t, dt);
93 m_subglacial_discharge->update(t, dt);
94
95 m_theta_ocean->average(t, dt);
96 m_subglacial_discharge->average(t, dt);
97
99
100 const auto &cell_type = inputs.geometry->cell_type;
101 const array::Scalar &bed_elevation = inputs.geometry->bed_elevation;
102 const array::Scalar &sea_level_elevation = inputs.geometry->sea_level_elevation;
103
104 array::AccessScope list{ &bed_elevation,
105 &cell_type,
106 &sea_level_elevation,
107 m_theta_ocean.get(),
110
111 double water_density = m_config->get_number("constants.fresh_water.density"),
112 seconds_per_day = 86400;
113
114 for (auto p : m_grid->points()) {
115 const int i = p.i(), j = p.j();
116
117 if (cell_type.icy(i, j)) {
118 // Assume for now that thermal forcing is equal to theta_ocean. Also, thermal
119 // forcing is generally not available at the grounding line.
120 double TF = (*m_theta_ocean)(i, j);
121
122 // Convert subglacial discharge (kg /(m^2 * s)) to an "effective subglacial freshwater
123 // velocity" or volume flux per unit area of ice front in m/day (see Xu et al 2013,
124 // section 2, paragraph 11).
125 //
126 // [flux] = kg / (m^2 * s), so
127 // [flux / water_density] = m / s, so
128 // [flux / water_density * (s / day) ] = m / day
129 double q_sg = ((*m_subglacial_discharge)(i, j) / water_density) * seconds_per_day;
130
131 double water_depth = sea_level_elevation(i, j) - bed_elevation(i, j);
132
133 m_frontal_melt_rate(i, j) = physics.frontal_melt_from_undercutting(water_depth, q_sg, TF);
134 // convert from m / day to m / s
135 m_frontal_melt_rate(i, j) /= seconds_per_day;
136 } else {
137 m_frontal_melt_rate(i, j) = 0.0;
138 }
139 } // end of the loop over grid points
140
141 // Set frontal melt rate *near* grounded termini to the average of grounded icy
142 // neighbors: front retreat code uses values at these locations (the rest is for
143 // visualization).
144
146
147 for (auto p : m_grid->points()) {
148 const int i = p.i(), j = p.j();
149
150 if (apply(cell_type, i, j) and cell_type.ice_free(i, j)) {
151
152 auto R = m_frontal_melt_rate.star(i, j);
153 auto M = cell_type.star_int(i, j);
154
155 int N = 0;
156 double R_sum = 0.0;
157 for (auto d : { North, East, South, West }) {
158 if (mask::grounded_ice(M[d]) or (m_include_floating_ice and mask::icy(M[d]))) {
159 R_sum += R[d];
160 N++;
161 }
162 }
163
164 if (N > 0) {
165 m_frontal_melt_rate(i, j) = R_sum / N;
166 }
167 }
168 }
169}
170
174
176
177 auto dt = std::min(m_theta_ocean->max_timestep(t), m_subglacial_discharge->max_timestep(t));
178
179 if (dt.finite()) {
180 return {dt.value(), "frontal_melt discharge_given"};
181 }
182
183 return {"frontal_melt discharge_given"};
184}
185
186} // end of namespace frontalmelt
187} // end of namespace pism
std::shared_ptr< const Grid > grid() const
Definition Component.cc:107
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
std::shared_ptr< const Logger > m_log
logger (for easy access)
Definition Component.hh:164
High-level PISM I/O class.
Definition File.hh:57
const Geometry * geometry
array::Scalar1 sea_level_elevation
Definition Geometry.hh:48
array::CellType2 cell_type
Definition Geometry.hh:55
array::Scalar2 bed_elevation
Definition Geometry.hh:47
Combines the max. time step with the flag indicating if a restriction is active. Makes is possible to...
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
stencils::Star< T > star(int i, int j) const
Definition Array2D.hh:107
void update_ghosts()
Updates ghost points.
Definition Array.cc:645
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata object containing metadata for the compoment N.
Definition Array.cc:467
static std::shared_ptr< Forcing > Constant(std::shared_ptr< const Grid > grid, const std::string &short_name, double value)
Definition Forcing.cc:148
const array::Scalar & frontal_melt_rate_impl() const
MaxTimestep max_timestep_impl(double t) const
void update_impl(const FrontalMeltInputs &inputs, double t, double dt)
std::shared_ptr< array::Forcing > m_subglacial_discharge
DischargeGiven(std::shared_ptr< const Grid > g)
void initialize(const array::Scalar &theta, const array::Scalar &sgl)
std::shared_ptr< array::Forcing > m_theta_ocean
void init_impl(const Geometry &geometry)
double frontal_melt_from_undercutting(double ice_thickness, double discharge_flux, double potential_temperature) const
bool apply(const array::CellType1 &M, int i, int j) const
A very rudimentary PISM frontal melt model.
@ PISM_NETCDF3
Definition IO_Flags.hh:58
@ PISM_READONLY
open an existing file for reading only
Definition IO_Flags.hh:69
bool icy(int M)
Ice-filled cell (grounded or floating).
Definition Mask.hh:48
bool grounded_ice(int M)
Definition Mask.hh:51
@ North
Definition stencils.hh:24
@ East
Definition stencils.hh:24
@ South
Definition stencils.hh:24
@ West
Definition stencils.hh:24
std::string filename
Definition options.hh:33