PISM, A Parallel Ice Sheet Model 2.3.0-79cae578d committed by Constantine Khrulev on 2026-03-22
Loading...
Searching...
No Matches
IceRegionalModel.cc
Go to the documentation of this file.
1/* Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 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
20#include "pism/regional/IceRegionalModel.hh"
21#include "pism/coupler/SurfaceModel.hh"
22#include "pism/energy/BedThermalUnit.hh"
23#include "pism/energy/CHSystem.hh"
24#include "pism/energy/utilities.hh"
25#include "pism/hydrology/Hydrology.hh"
26#include "pism/regional/EnthalpyModel_Regional.hh"
27#include "pism/regional/RegionalYieldStress.hh"
28#include "pism/stressbalance/StressBalance.hh"
29#include "pism/util/array/Forcing.hh"
30#include "pism/util/io/File.hh"
31#include "pism/util/io/IO_Flags.hh"
32
33namespace pism {
34
35IceRegionalModel::IceRegionalModel(std::shared_ptr<Grid> g, std::shared_ptr<Context> c)
36 : IceModel(g, c),
37 m_no_model_mask(m_grid, "no_model_mask"),
38 m_usurf_stored(m_grid, "usurfstore"),
39 m_thk_stored(m_grid, "thkstore") {
41
42 if (m_config->get_flag("energy.ch_warming.enabled")) {
44 new array::Array3D(m_grid, "ch_warming_flux", array::WITHOUT_GHOSTS, m_grid->z()));
45 }
46}
47
48
50
52
53 m_log->message(2, " creating IceRegionalModel vecs ...\n");
54
55 // stencil width of 2 needed by SIAFD_Regional::compute_surface_gradient()
57 .long_name("mask: zeros (modeling domain) and ones (no-model buffer near grid edges)")
58 .set_time_dependent(false)
59 .set_output_type(io::PISM_INT); // no units and no standard name
60 m_no_model_mask.metadata()["flag_values"] = { 0, 1 };
61 m_no_model_mask.metadata()["flag_meanings"] = "normal special_treatment";
62
64
65 // stencil width of 2 needed for differentiation because GHOSTS=1
67 .long_name(
68 "saved surface elevation for use to keep surface gradient constant in no_model strip")
69 .units("m"); // no standard name
70
71 // stencil width of 1 needed for differentiation
73 .long_name("saved ice thickness for use to keep driving stress constant in no_model strip")
74 .units("m"); // no standard name
75
78}
79
81
82 // initialize the model state (including special fields)
83 IceModel::model_state_setup(input_options);
84
85 // Initialize stored ice thickness and surface elevation. This goes here and not in
86 // bootstrap_2d because bed topography is not initialized at the time bootstrap_2d is
87 // called.
88 if (input_options.type == INIT_BOOTSTRAP) {
89 if (m_config->get_flag("regional.zero_gradient")) {
91 m_thk_stored.set(0.0);
92 } else {
95 }
96 }
97
98 m_geometry_evolution->set_no_model_mask(m_no_model_mask);
99
100 if (m_ch_system) {
101 const bool use_input_file =
102 input_options.type == INIT_BOOTSTRAP or input_options.type == INIT_RESTART;
103
104 std::unique_ptr<File> input_file;
105
106 if (use_input_file) {
107 input_file.reset(
108 new File(m_grid->com, input_options.filename, io::PISM_GUESS, io::PISM_READONLY));
109 }
110
111 switch (input_options.type) {
112 case INIT_RESTART: {
113 m_ch_system->restart(*input_file, input_options.record);
114 break;
115 }
116 case INIT_BOOTSTRAP: {
117
118 m_ch_system->bootstrap(*input_file, m_geometry.ice_thickness, m_surface->temperature(),
119 m_surface->mass_flux(), m_btu->flux_through_top_surface());
120 break;
121 }
122 case INIT_OTHER:
123 default: {
124 m_basal_melt_rate.set(m_config->get_number("bootstrapping.defaults.bmelt"));
125
127 m_surface->mass_flux(), m_btu->flux_through_top_surface());
128 }
129 }
130 }
131}
132
135 return;
136 }
137
138 m_log->message(2, "# Allocating the geometry evolution model (regional version)...\n");
139
141
142 m_submodels["geometry_evolution"] = m_geometry_evolution.get();
143}
144
146
147 if (m_energy_model != NULL) {
148 return;
149 }
150
151 m_log->message(2, "# Allocating an energy balance model...\n");
152
153 auto energy_model = m_config->get_string("energy.model");
154
155 if (energy_model == "enthalpy") {
156 m_energy_model = std::make_shared<energy::EnthalpyModel_Regional>(m_grid, m_stress_balance);
157 } else if (energy_model == "cold") {
159 "pism -regional does not support the 'cold' energy.model");
160 } else {
161 m_energy_model = std::make_shared<energy::DummyEnergyModel>(m_grid, m_stress_balance);
162 }
163
164 m_submodels["energy balance model"] = m_energy_model.get();
165
166 if (m_config->get_flag("energy.ch_warming.enabled") and
167 not m_ch_system) {
168
169 m_log->message(2, "# Allocating the cryo-hydrologic warming model...\n");
170
171 m_ch_system = std::make_shared<energy::CHSystem>(m_grid, m_stress_balance);
172 m_submodels["cryo-hydrologic warming"] = m_ch_system.get();
173 }
174}
175
177
178 if (m_stress_balance) {
179 return;
180 }
181
182 bool regional = true;
183 m_stress_balance = stressbalance::create(m_config->get_string("stress_balance.model"),
184 m_grid, regional);
185
186 m_submodels["stress balance"] = m_stress_balance.get();
187}
188
189
191
193 return;
194 }
195
197
199 // IceModel allocated a basal yield stress model. This means that we are using a
200 // stress balance model that uses it and we need to add regional modifications.
202
203 m_submodels["basal yield stress"] = m_basal_yield_stress_model.get();
204 }
205}
206
207//! Bootstrap a "regional" model.
208/*!
209 * Need to initialize all the variables managed by IceModel, as well as
210 * - no_model_mask
211 * - usurf_stored
212 * - thk_stored
213 */
214void IceRegionalModel::bootstrap_2d(const File &input_file) {
215
216 IceModel::bootstrap_2d(input_file);
217
218 // no_model_mask
219 {
220 if (input_file.variable_exists(m_no_model_mask.metadata().get_name())) {
222 } else {
223 // set using the no_model_strip parameter
224 double strip_width = m_config->get_number("regional.no_model_strip", "meters");
226 }
227
228 // m_no_model_mask was added to m_model_state, so
229 // IceModel::regrid() will take care of regridding it, if necessary.
230 }
231
232 if (m_config->get_flag("stress_balance.ssa.dirichlet_bc")) {
235
236 for (auto p : m_grid->points()) {
237 const int i = p.i(), j = p.j();
238
239 if (m_no_model_mask(i, j) > 0.5) {
240 m_velocity_bc_mask(i, j) = 1;
241 m_ice_thickness_bc_mask(i, j) = 1;
242 }
243 }
244 }
245}
246
256
264
265void IceRegionalModel::energy_step(double t, double dt) {
266
267 if (m_ch_system) {
269
271 const array::Array3D *strain_heating = inputs.volumetric_heating_rate;
273
274 energy::cryo_hydrologic_warming_flux(m_config->get_number("constants.ice.thermal_conductivity"),
275 m_config->get_number("energy.ch_warming.average_channel_spacing"),
277 m_energy_model->enthalpy(),
278 m_ch_system->enthalpy(),
280
281 // Convert to the loss of energy by the CH system:
282 m_ch_warming_flux->scale(-1.0);
283
284 m_ch_system->update(t, dt, inputs);
285
286 // Add CH warming flux to the strain heating term:
287 m_ch_warming_flux->scale(-1.0);
288 m_ch_warming_flux->add(1.0, *strain_heating);
289
290 m_energy_model->update(t, dt, inputs);
291
292 m_stdout_flags = m_energy_model->stdout_flags() + m_stdout_flags;
293 } else {
295 }
296}
297
305
309
310/*! @brief Report temperature of the cryo-hydrologic system */
311class CHTemperature : public Diag<IceRegionalModel>
312{
313public:
315 : Diag<IceRegionalModel>(m) {
316
317 m_vars = { { m_sys, "ch_temp", *m_grid, m_grid->z() } };
318 m_vars[0].long_name("temperature of the cryo-hydrologic system").units("kelvin");
319 }
320
321protected:
322 std::shared_ptr<array::Array> compute_impl() const {
323
324 std::shared_ptr<array::Array3D> result(new array::Array3D(m_grid, "ch_temp", array::WITHOUT_GHOSTS, m_grid->z()));
325
328 *result);
329 result->metadata(0) = m_vars[0];
330
331 return result;
332 }
333};
334
335/*! @brief Report liquid water fraction in the cryo-hydrologic system */
336class CHLiquidWaterFraction : public Diag<IceRegionalModel>
337{
338public:
340 : Diag<IceRegionalModel>(m) {
341
342 m_vars = { { m_sys, "ch_liqfrac", *m_grid, m_grid->z() } };
343
344 m_vars[0].long_name("liquid water fraction in the cryo-hydrologic system").units("1");
345 }
346
347protected:
348 std::shared_ptr<array::Array> compute_impl() const {
349
350 std::shared_ptr<array::Array3D> result(new array::Array3D(m_grid, "ch_liqfrac", array::WITHOUT_GHOSTS, m_grid->z()));
351
354 *result);
355 result->metadata(0) = m_vars[0];
356 return result;
357 }
358};
359
360
361/*! @brief Report rate of cryo-hydrologic warming */
362class CHHeatFlux : public Diag<IceRegionalModel>
363{
364public:
366 : Diag<IceRegionalModel>(m) {
367
368 m_vars = { { m_sys, "ch_heat_flux", *m_grid, m_grid->z() } };
369 m_vars[0].long_name("rate of cryo-hydrologic warming").units("W m^-3");
370 }
371
372protected:
373 std::shared_ptr<array::Array> compute_impl() const {
374
375 std::shared_ptr<array::Array3D> result(new array::Array3D(m_grid, "ch_heat_flux", array::WITHOUT_GHOSTS, m_grid->z()));
376 result->metadata(0) = m_vars[0];
377
378 energy::cryo_hydrologic_warming_flux(m_config->get_number("constants.ice.thermal_conductivity"),
379 m_config->get_number("energy.ch_warming.average_channel_spacing"),
383 *result);
384 return result;
385 }
386};
387
388std::map<std::string, Diagnostic::Ptr> IceRegionalModel::allocate_spatial_diagnostics() {
390
391 if (m_ch_system) {
392 result["ch_temp"] = Diagnostic::Ptr(new CHTemperature(this));
393 result["ch_liqfrac"] = Diagnostic::Ptr(new CHLiquidWaterFraction(this));
394 result["ch_heat_flux"] = Diagnostic::Ptr(new CHHeatFlux(this));
395 }
396 return result;
397}
398
399void IceRegionalModel::hydrology_step(double t, double dt) {
400 hydrology::Inputs inputs;
401
402 array::Scalar &sliding_speed = *m_work2d[0];
403 compute_magnitude(m_stress_balance->advective_velocity(), sliding_speed);
404
406 inputs.geometry = &m_geometry;
407 inputs.surface_input_rate = nullptr;
409 inputs.ice_sliding_speed = &sliding_speed;
410
415 } else if (m_config->get_flag("hydrology.surface_input_from_runoff")) {
416 // convert [kg m-2] to [kg m-2 s-1]
417 array::Scalar &surface_input_rate = *m_work2d[1];
418 surface_input_rate.copy_from(m_surface->runoff());
419 surface_input_rate.scale(1.0 / dt);
420 inputs.surface_input_rate = &surface_input_rate;
421 }
422
423 m_subglacial_hydrology->update(t, dt, inputs);
424}
425
426
427} // end of namespace pism
CHHeatFlux(const IceRegionalModel *m)
std::shared_ptr< array::Array > compute_impl() const
Report rate of cryo-hydrologic warming.
CHLiquidWaterFraction(const IceRegionalModel *m)
std::shared_ptr< array::Array > compute_impl() const
Report liquid water fraction in the cryo-hydrologic system.
CHTemperature(const IceRegionalModel *m)
std::shared_ptr< array::Array > compute_impl() const
Report temperature of the cryo-hydrologic system.
const IceRegionalModel * model
A template derived from Diagnostic, adding a "Model".
std::vector< VariableMetadata > m_vars
metadata corresponding to NetCDF variables
const units::System::Ptr m_sys
the unit system
std::shared_ptr< const Config > m_config
Configuration flags and parameters.
std::shared_ptr< Diagnostic > Ptr
Definition Diagnostic.hh:67
std::shared_ptr< const Grid > m_grid
the grid
bool variable_exists(const std::string &short_name) const
Checks if a variable exists.
Definition File.cc:378
High-level PISM I/O class.
Definition File.hh:57
array::Scalar2 ice_surface_elevation
Definition Geometry.hh:57
array::Scalar2 ice_thickness
Definition Geometry.hh:51
std::map< std::string, const Component * > m_submodels
the list of sub-models, for writing model states and obtaining diagnostics
Definition IceModel.hh:297
virtual energy::Inputs energy_model_inputs()
Definition IceModel.cc:365
const Geometry & geometry() const
Definition IceModel.cc:903
std::shared_ptr< stressbalance::StressBalance > m_stress_balance
Definition IceModel.hh:439
std::shared_ptr< surface::SurfaceModel > m_surface
Definition IceModel.hh:324
virtual stressbalance::Inputs stress_balance_inputs()
Definition IceModel.cc:339
std::shared_ptr< Config > m_config
Configuration flags and parameters.
Definition IceModel.hh:278
virtual void bootstrap_2d(const File &input_file)
virtual std::map< std::string, Diagnostic::Ptr > allocate_spatial_diagnostics()
Geometry m_geometry
Definition IceModel.hh:333
std::shared_ptr< YieldStress > m_basal_yield_stress_model
Definition IceModel.hh:300
std::shared_ptr< Logger > m_log
Logger.
Definition IceModel.hh:284
array::Scalar m_basal_melt_rate
rate of production of basal meltwater (ice-equivalent); no ghosts
Definition IceModel.hh:340
std::shared_ptr< array::Forcing > m_surface_input_for_hydrology
Definition IceModel.hh:302
const energy::EnergyModel * energy_balance_model() const
Definition IceModel.cc:923
std::vector< std::shared_ptr< array::Scalar2 > > m_work2d
Definition IceModel.hh:437
double dt() const
Definition IceModel.cc:151
virtual void allocate_storage()
Allocate all Arrays defined in IceModel.
Definition IceModel.cc:196
array::Scalar2 m_velocity_bc_mask
mask to determine Dirichlet boundary locations for the sliding velocity
Definition IceModel.hh:347
virtual void allocate_basal_yield_stress()
Decide which basal yield stress model to use.
std::string m_stdout_flags
Definition IceModel.hh:366
std::unique_ptr< GeometryEvolution > m_geometry_evolution
Definition IceModel.hh:334
virtual void energy_step(double t, double dt)
Manage the solution of the energy equation, and related parallel communication.
Definition energy.cc:60
std::shared_ptr< energy::BedThermalUnit > m_btu
Definition IceModel.hh:304
virtual void model_state_setup(InputOptions input_options)
Sets the starting values of model state variables.
std::set< array::Array * > m_model_state
Definition IceModel.hh:459
array::Scalar1 m_ice_thickness_bc_mask
Mask prescribing locations where ice thickness is held constant.
Definition IceModel.hh:352
virtual void bedrock_thermal_model_step(double t, double dt)
Definition energy.cc:38
virtual YieldStressInputs yield_stress_inputs()
Definition IceModel.cc:387
std::unique_ptr< hydrology::Hydrology > m_subglacial_hydrology
Definition IceModel.hh:299
std::shared_ptr< energy::EnergyModel > m_energy_model
Definition IceModel.hh:305
const std::shared_ptr< Grid > m_grid
Computational grid.
Definition IceModel.hh:276
energy::Inputs energy_model_inputs()
void allocate_stressbalance()
Decide which stress balance model to use.
void allocate_storage()
Allocate all Arrays defined in IceModel.
const energy::CHSystem * cryo_hydrologic_system() const
void allocate_basal_yield_stress()
Decide which basal yield stress model to use.
array::Scalar2 m_usurf_stored
std::shared_ptr< array::Array3D > m_ch_warming_flux
stressbalance::Inputs stress_balance_inputs()
IceRegionalModel(std::shared_ptr< Grid > g, std::shared_ptr< Context > c)
array::Scalar2 m_no_model_mask
void energy_step(double t, double dt)
Manage the solution of the energy equation, and related parallel communication.
std::map< std::string, Diagnostic::Ptr > allocate_spatial_diagnostics()
virtual void bootstrap_2d(const File &input_file)
Bootstrap a "regional" model.
std::shared_ptr< energy::CHSystem > m_ch_system
YieldStressInputs yield_stress_inputs()
void hydrology_step(double t, double dt)
void model_state_setup(InputOptions input_options)
Sets the starting values of model state variables.
A version of the PISM core class (IceModel) which knows about the no_model_mask and its semantics.
VariableMetadata & long_name(const std::string &input)
VariableMetadata & units(const std::string &input)
VariableMetadata & set_output_type(io::Type type)
VariableMetadata & set_time_dependent(bool flag)
std::string get_name() const
const array::Scalar * no_model_mask
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
A virtual class collecting methods common to ice and bedrock 3D fields.
Definition Array3D.hh:33
void set_interpolation_type(InterpolationType type)
Definition Array.cc:181
void scale(double alpha)
Result: v <- v * alpha. Calls VecScale.
Definition Array.cc:227
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
const array::Array3D & enthalpy() const
const array::Scalar * no_model_mask
const array::Array3D * volumetric_heating_rate
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
static Default Nil()
Definition IO_Flags.hh:94
const array::Scalar * no_model_ice_thickness
const array::Scalar2 * no_model_surface_elevation
const array::Scalar2 * no_model_mask
#define PISM_ERROR_LOCATION
@ WITHOUT_GHOSTS
Definition Array.hh:63
void compute_liquid_water_fraction(const array::Array3D &enthalpy, const array::Scalar &ice_thickness, array::Array3D &result)
Compute the liquid fraction corresponding to enthalpy and ice_thickness.
Definition utilities.cc:136
void cryo_hydrologic_warming_flux(double k, double R, const array::Scalar &ice_thickness, const array::Array3D &ice_enthalpy, const array::Array3D &ch_enthalpy, array::Array3D &result)
Definition CHSystem.cc:252
void compute_temperature(const array::Array3D &enthalpy, const array::Scalar &ice_thickness, array::Array3D &result)
Definition utilities.cc:76
@ PISM_GUESS
Definition IO_Flags.hh:57
@ PISM_READONLY
open an existing file for reading only
Definition IO_Flags.hh:69
std::shared_ptr< StressBalance > create(const std::string &model, std::shared_ptr< const Grid > grid, bool regional)
Definition factory.cc:39
void set_no_model_strip(const Grid &grid, double width, array::Scalar &result)
Set no_model_mask variable to have value 1 in strip of width 'strip' m around edge of computational d...
Definition Geometry.cc:407
static const double g
Definition exactTestP.cc:36
@ INIT_BOOTSTRAP
Definition Component.hh:56
@ INIT_OTHER
Definition Component.hh:56
@ INIT_RESTART
Definition Component.hh:56
T combine(const T &a, const T &b)
InitializationType type
initialization type
Definition Component.hh:61
std::string filename
name of the input file (if applicable)
Definition Component.hh:63
unsigned int record
index of the record to re-start from
Definition Component.hh:65