Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
IceRegionalModel.cc
Go to the documentation of this file.
1/* Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024 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
32namespace pism {
33
34IceRegionalModel::IceRegionalModel(std::shared_ptr<Grid> g, std::shared_ptr<Context> c)
35 : IceModel(g, c),
36 m_no_model_mask(m_grid, "no_model_mask"),
37 m_usurf_stored(m_grid, "usurfstore"),
38 m_thk_stored(m_grid, "thkstore") {
40
41 if (m_config->get_flag("energy.ch_warming.enabled")) {
43 new array::Array3D(m_grid, "ch_warming_flux", array::WITHOUT_GHOSTS, m_grid->z()));
44 }
45}
46
47
49
51
52 m_log->message(2, " creating IceRegionalModel vecs ...\n");
53
54 // stencil width of 2 needed by SIAFD_Regional::compute_surface_gradient()
56 .long_name("mask: zeros (modeling domain) and ones (no-model buffer near grid edges)")
58 .set_output_type(io::PISM_INT); // no units and no standard name
59 m_no_model_mask.metadata()["flag_values"] = { 0, 1 };
60 m_no_model_mask.metadata()["flag_meanings"] = "normal special_treatment";
61
63
64 // stencil width of 2 needed for differentiation because GHOSTS=1
66 .long_name(
67 "saved surface elevation for use to keep surface gradient constant in no_model strip")
68 .units("m"); // no standard name
69
70 // stencil width of 1 needed for differentiation
72 .long_name("saved ice thickness for use to keep driving stress constant in no_model strip")
73 .units("m"); // no standard name
74
78}
79
81
82 // initialize the model state (including special fields)
84
86
87 // Initialize stored ice thickness and surface elevation. This goes here and not in
88 // bootstrap_2d because bed topography is not initialized at the time bootstrap_2d is
89 // called.
90 if (input.type == INIT_BOOTSTRAP) {
91 if (m_config->get_flag("regional.zero_gradient")) {
93 m_thk_stored.set(0.0);
94 } else {
97 }
98 }
99
100 m_geometry_evolution->set_no_model_mask(m_no_model_mask);
101
102 if (m_ch_system) {
103 const bool use_input_file = input.type == INIT_BOOTSTRAP or input.type == INIT_RESTART;
104
105 std::unique_ptr<File> input_file;
106
107 if (use_input_file) {
108 input_file.reset(new File(m_grid->com, input.filename, io::PISM_GUESS, io::PISM_READONLY));
109 }
110
111 switch (input.type) {
112 case INIT_RESTART: {
113 m_ch_system->restart(*input_file, input.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(); p; p.next()) {
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
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_TempAge, dt_TempAge, 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_TempAge, dt_TempAge, 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->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->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->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
390
391 if (m_ch_system) {
392 m_diagnostics["ch_temp"] = Diagnostic::Ptr(new CHTemperature(this));
393 m_diagnostics["ch_liqfrac"] = Diagnostic::Ptr(new CHLiquidWaterFraction(this));
394 m_diagnostics["ch_heat_flux"] = Diagnostic::Ptr(new CHHeatFlux(this));
395 }
396}
397
399 hydrology::Inputs inputs;
400
401 array::Scalar &sliding_speed = *m_work2d[0];
402 compute_magnitude(m_stress_balance->advective_velocity(), sliding_speed);
403
405 inputs.geometry = &m_geometry;
406 inputs.surface_input_rate = nullptr;
408 inputs.ice_sliding_speed = &sliding_speed;
409
411 m_surface_input_for_hydrology->update(m_time->current(), m_dt);
412 m_surface_input_for_hydrology->average(m_time->current(), m_dt);
414 } else if (m_config->get_flag("hydrology.surface_input_from_runoff")) {
415 // convert [kg m-2] to [kg m-2 s-1]
416 array::Scalar &surface_input_rate = *m_work2d[1];
417 surface_input_rate.copy_from(m_surface->runoff());
418 surface_input_rate.scale(1.0 / m_dt);
419 inputs.surface_input_rate = &surface_input_rate;
420 }
421
422 m_subglacial_hydrology->update(m_time->current(), m_dt, inputs);
423}
424
425
426} // 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".
const units::System::Ptr m_sys
the unit system
std::vector< SpatialVariableMetadata > m_vars
metadata corresponding to NetCDF variables
std::shared_ptr< Diagnostic > Ptr
Definition Diagnostic.hh:65
std::shared_ptr< const Grid > m_grid
the grid
const Config::ConstPtr m_config
Configuration flags and parameters.
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:55
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:252
virtual energy::Inputs energy_model_inputs()
Definition IceModel.cc:342
const Geometry & geometry() const
Definition IceModel.cc:877
virtual void model_state_setup()
Sets the starting values of model state variables.
std::shared_ptr< stressbalance::StressBalance > m_stress_balance
Definition IceModel.hh:395
virtual void energy_step()
Manage the solution of the energy equation, and related parallel communication.
Definition energy.cc:60
std::shared_ptr< surface::SurfaceModel > m_surface
Definition IceModel.hh:279
virtual stressbalance::Inputs stress_balance_inputs()
Definition IceModel.cc:316
virtual void bootstrap_2d(const File &input_file)
const Time::Ptr m_time
Time manager.
Definition IceModel.hh:246
Geometry m_geometry
Definition IceModel.hh:288
std::shared_ptr< YieldStress > m_basal_yield_stress_model
Definition IceModel.hh:255
std::shared_ptr< Context > m_ctx
Execution context.
Definition IceModel.hh:240
array::Scalar m_basal_melt_rate
rate of production of basal meltwater (ice-equivalent); no ghosts
Definition IceModel.hh:295
const Logger::Ptr m_log
Logger.
Definition IceModel.hh:244
std::shared_ptr< array::Forcing > m_surface_input_for_hydrology
Definition IceModel.hh:257
const energy::EnergyModel * energy_balance_model() const
Definition IceModel.cc:897
std::vector< std::shared_ptr< array::Scalar2 > > m_work2d
Definition IceModel.hh:393
virtual void allocate_storage()
Allocate all Arrays defined in IceModel.
Definition IceModel.cc:171
array::Scalar2 m_velocity_bc_mask
mask to determine Dirichlet boundary locations for the sliding velocity
Definition IceModel.hh:302
virtual void allocate_basal_yield_stress()
Decide which basal yield stress model to use.
std::string m_stdout_flags
Definition IceModel.hh:321
Config::Ptr m_config
Configuration flags and parameters.
Definition IceModel.hh:238
std::unique_ptr< GeometryEvolution > m_geometry_evolution
Definition IceModel.hh:289
virtual void bedrock_thermal_model_step()
Definition energy.cc:38
std::shared_ptr< energy::BedThermalUnit > m_btu
Definition IceModel.hh:259
std::set< array::Array * > m_model_state
Definition IceModel.hh:415
array::Scalar1 m_ice_thickness_bc_mask
Mask prescribing locations where ice thickness is held constant.
Definition IceModel.hh:307
double t_TempAge
time of last update for enthalpy/temperature
Definition IceModel.hh:313
std::map< std::string, Diagnostic::Ptr > m_diagnostics
Requested spatially-variable diagnostics.
Definition IceModel.hh:417
virtual YieldStressInputs yield_stress_inputs()
Definition IceModel.cc:364
virtual void init_diagnostics()
std::unique_ptr< hydrology::Hydrology > m_subglacial_hydrology
Definition IceModel.hh:254
double dt_TempAge
enthalpy/temperature and age time-steps
Definition IceModel.hh:315
double m_dt
mass continuity time step, s
Definition IceModel.hh:311
std::shared_ptr< energy::EnergyModel > m_energy_model
Definition IceModel.hh:260
const std::shared_ptr< Grid > m_grid
Computational grid.
Definition IceModel.hh:236
energy::Inputs energy_model_inputs()
void energy_step()
Manage the solution of the energy equation, and related parallel communication.
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
void model_state_setup()
Sets the starting values of model state variables.
stressbalance::Inputs stress_balance_inputs()
IceRegionalModel(std::shared_ptr< Grid > g, std::shared_ptr< Context > c)
array::Scalar2 m_no_model_mask
virtual void bootstrap_2d(const File &input_file)
Bootstrap a "regional" model.
std::shared_ptr< energy::CHSystem > m_ch_system
YieldStressInputs yield_stress_inputs()
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)
std::string get_name() const
VariableMetadata & set_time_independent(bool flag)
const array::Scalar * no_model_mask
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition Array.hh:64
void copy_from(const Array2D< T > &source)
Definition Array2D.hh:73
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:178
void scale(double alpha)
Result: v <- v * alpha. Calls VecScale.
Definition Array.cc:224
void set(double c)
Result: v[j] <- c for all j.
Definition Array.cc:629
void regrid(const std::string &filename, io::Default default_value)
Definition Array.cc:736
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
Definition Array.cc:476
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:93
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:61
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:251
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:56
@ PISM_READONLY
open an existing file for reading only
Definition IO_Flags.hh:68
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:384
InputOptions process_input_options(MPI_Comm com, Config::ConstPtr config)
Definition Component.cc:43
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
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