PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
IceModel.cc
Go to the documentation of this file.
1 // Copyright (C) 2004-2023 Jed Brown, Ed Bueler 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 <cmath>
20 #include <cstring>
21 #include <algorithm>
22 #include <petscsys.h>
23 
24 #include "pism/pism_config.hh"
25 
26 #include "pism/icemodel/IceModel.hh"
27 
28 #include "pism/basalstrength/YieldStress.hh"
29 #include "pism/frontretreat/util/IcebergRemover.hh"
30 #include "pism/energy/BedThermalUnit.hh"
31 #include "pism/hydrology/Hydrology.hh"
32 #include "pism/stressbalance/StressBalance.hh"
33 #include "pism/util/Grid.hh"
34 #include "pism/util/ConfigInterface.hh"
35 #include "pism/util/Diagnostic.hh"
36 #include "pism/util/error_handling.hh"
37 #include "pism/coupler/SeaLevel.hh"
38 #include "pism/coupler/OceanModel.hh"
39 #include "pism/coupler/SurfaceModel.hh"
40 #include "pism/earth/BedDef.hh"
41 #include "pism/util/pism_signal.h"
42 #include "pism/util/Vars.hh"
43 #include "pism/util/Profiling.hh"
44 #include "pism/util/pism_utilities.hh"
45 #include "pism/age/AgeModel.hh"
46 #include "pism/age/Isochrones.hh"
47 #include "pism/energy/EnergyModel.hh"
48 #include "pism/util/io/File.hh"
49 #include "pism/util/array/Forcing.hh"
50 #include "pism/fracturedensity/FractureDensity.hh"
51 #include "pism/coupler/util/options.hh" // ForcingOptions
52 #include "pism/coupler/ocean/PyOceanModel.hh"
53 
54 namespace pism {
55 
56 IceModel::IceModel(std::shared_ptr<Grid> grid, const std::shared_ptr<Context> &context)
57  : m_grid(grid),
58  m_config(context->config()),
59  m_ctx(context),
60  m_sys(context->unit_system()),
61  m_log(context->log()),
62  m_time(context->time()),
63  m_wide_stencil(static_cast<int>(m_config->get_number("grid.max_stencil_width"))),
64  m_output_global_attributes("PISM_GLOBAL", m_sys),
65  m_geometry(m_grid),
66  m_new_bed_elevation(true),
67  m_basal_yield_stress(m_grid, "tauc"),
68  m_basal_melt_rate(m_grid, "bmelt"),
69  m_bedtoptemp(m_grid, "bedtoptemp"),
70  m_velocity_bc_mask(m_grid, "vel_bc_mask"),
71  m_velocity_bc_values(m_grid, "_bc"), // u_bc and v_bc
72  m_ice_thickness_bc_mask(grid, "thk_bc_mask"),
73  m_step_counter(0),
74  m_thickness_change(grid),
75  m_ts_times(new std::vector<double>()),
76  m_extra_bounds("time_bounds", m_sys),
77  m_timestamp("timestamp", m_sys) {
78 
81 
82  m_extra_bounds["units"] = m_time->units_string();
83 
84  m_timestamp["units"] = "hours";
85  m_timestamp["long_name"] = "wall-clock time since the beginning of the run";
86 
87  pism_signal = 0;
88  signal(SIGTERM, pism_signal_handler);
89  signal(SIGUSR1, pism_signal_handler);
90  signal(SIGUSR2, pism_signal_handler);
91 
92  m_surface = nullptr;
93  m_ocean = nullptr;
94  m_beddef = nullptr;
95 
96  m_btu = nullptr;
97  m_energy_model = nullptr;
98 
99  m_output_global_attributes["Conventions"] = "CF-1.6";
101 
102  // Do not save snapshots by default:
103  m_save_snapshots = false;
104  // Do not save time-series by default:
105  m_save_extra = false;
106 
107  m_fracture = nullptr;
108 
109  reset_counters();
110 
111  // allocate temporary storage
112  {
113  // 2d work vectors
114  for (int j = 0; j < m_n_work2d; j++) {
115  m_work2d.push_back(
116  std::make_shared<array::Scalar2>(m_grid, pism::printf("work_vector_%d", j)));
117  }
118  m_work2d_proc0 = m_work2d[0]->allocate_proc0_copy();
119  }
120 
121  auto surface_input_file = m_config->get_string("hydrology.surface_input.file");
122  if (not surface_input_file.empty()) {
123  ForcingOptions surface_input(*m_ctx, "hydrology.surface_input");
124  int buffer_size = static_cast<int>(m_config->get_number("input.forcing.buffer_size"));
125 
126  File file(m_grid->com, surface_input.filename, io::PISM_NETCDF3, io::PISM_READONLY);
127 
129  std::make_shared<array::Forcing>(m_grid, file, "water_input_rate",
130  "", // no standard name
131  buffer_size, surface_input.periodic);
132  m_surface_input_for_hydrology->metadata(0)
133  .long_name("water input rate for the subglacial hydrology model")
134  .units("kg m-2 s-1")
135  .output_units("kg m-2 year-1");
136  m_surface_input_for_hydrology->metadata()["valid_min"] = { 0.0 };
137  }
138 }
139 
140 double IceModel::dt() const {
141  return m_dt;
142 }
143 
145  dt_TempAge = 0.0;
146  m_dt = 0.0;
147  m_skip_countdown = 0;
148 
149  {
150  int year_increment = static_cast<int>(m_config->get_number("time_stepping.hit_multiples"));
151 
152  if (year_increment > 0) {
153  // start year:
154  auto year = m_time->units().date(m_time->current(), m_time->calendar()).year;
155 
156  int last_multiple = year - year % year_increment;
157  // correct last_multiple if 'year' is negative
158  // and not a multiple of year_increment:
159  last_multiple -= year_increment * static_cast<int>(year % year_increment < 0);
160 
161  units::DateTime last_date{ last_multiple, 1, 1, 0, 0, 0.0 };
162 
163  m_timestep_hit_multiples_last_time = m_time->units().time(last_date, m_time->calendar());
164  } else {
166  }
167  }
168 }
169 
170 
172  // empty; defined here to be able to use more forward-declared classes in IceModel.hh
173 }
174 
175 
176 //! Allocate all Arrays defined in IceModel.
177 /*!
178  This procedure allocates the memory used to store model state, diagnostic and
179  work vectors and sets metadata.
180 
181  Default values should not be set here; please use set_vars_from_options().
182 
183  All the memory allocated here is freed by Arrays' destructors.
184 */
186 
187  // FIXME: this should do for now, but we should pass a const reference to Geometry to sub-models
188  // as a function argument.
189  m_grid->variables().add(m_geometry.ice_surface_elevation);
190  m_grid->variables().add(m_geometry.ice_thickness);
191  m_grid->variables().add(m_geometry.cell_type);
192  m_grid->variables().add(m_geometry.sea_level_elevation);
193  m_grid->variables().add(m_geometry.longitude);
194  m_grid->variables().add(m_geometry.latitude);
195 
196  if (m_config->get_flag("geometry.grounded_cell_fraction")) {
197  m_grid->variables().add(m_geometry.cell_grounded_fraction);
198  }
199 
200  if (m_config->get_flag("geometry.part_grid.enabled")) {
201  m_grid->variables().add(m_geometry.ice_area_specific_volume);
202  }
203 
204  // yield stress for basal till (plastic or pseudo-plastic model)
205  {
206  // PROPOSED standard_name = land_ice_basal_material_yield_stress
208  .long_name("yield stress for basal till (plastic or pseudo-plastic model)")
209  .units("Pa");
210  m_grid->variables().add(m_basal_yield_stress);
211  }
212 
213  {
215  .long_name("temperature at the top surface of the bedrock thermal layer")
216  .units("Kelvin");
217  }
218 
219  // basal melt rate
221  .long_name(
222  "ice basal melt rate from energy conservation and subshelf melt, in ice thickness per time")
223  .units("m s-1")
224  .output_units("m year-1")
225  .standard_name("land_ice_basal_melt_rate");
226  m_basal_melt_rate.metadata()["comment"] = "positive basal melt rate corresponds to ice loss";
227  m_grid->variables().add(m_basal_melt_rate);
228 
229  // Sliding velocity (usually SSA) Dirichlet B.C. locations and values
230  {
232  .long_name("Mask prescribing Dirichlet boundary locations for the sliding velocity")
234  .set_time_independent(true);
235  m_velocity_bc_mask.metadata()["flag_values"] = { 0, 1 };
236  m_velocity_bc_mask.metadata()["flag_meanings"] = "no_data boundary_condition";
237 
238  m_velocity_bc_mask.set(0.0);
239  }
240  // SSA Dirichlet B.C. values
241  {
242  double fill_value = m_config->get_number("output.fill_value");
243  const double huge_value = 1e6;
244  // vel_bc
246  "X-component of the SSA velocity boundary conditions");
248  "Y-component of the SSA velocity boundary conditions");
249  for (int j : { 0, 1 }) {
250  m_velocity_bc_values.metadata(j)["valid_range"] = { -huge_value, huge_value };
251  m_velocity_bc_values.metadata(j)["_FillValue"] = { fill_value };
252  m_velocity_bc_values.metadata(j).units("m s-1");
253  }
254  }
255 
256  // Ice thickness BC mask
257  {
259  .long_name("Mask specifying locations where ice thickness is held constant")
260  .set_time_independent(true)
262  m_ice_thickness_bc_mask.metadata()["flag_values"] = {0, 1};
263  m_ice_thickness_bc_mask.metadata()["flag_meanings"] = "no_data boundary_condition";
264 
266  }
267 
268  // Add some variables to the list of "model state" fields.
271 
273 
278 }
279 
280 //! Update the surface elevation and the flow-type mask when the geometry has changed.
281 /*!
282  This procedure should be called whenever necessary to maintain consistency of geometry.
283 
284  For instance, it should be called when either ice thickness or bed elevation change.
285  In particular we always want \f$h = H + b\f$ to apply at grounded points, and, on the
286  other hand, we want the mask to reflect that the ice is floating if the flotation
287  criterion applies at a point.
288 
289  If `flag == REMOVE_ICEBERGS`, also calls the code which removes icebergs, to avoid
290  stress balance solver problems caused by ice that is not attached to the grounded ice
291  sheet.
292 */
294 
295  m_geometry.bed_elevation.copy_from(m_beddef->bed_elevation());
297 
298  if (m_iceberg_remover and flag == REMOVE_ICEBERGS) {
299  // The iceberg remover has to use the same mask as the stress balance code, hence the
300  // stress-balance-related threshold here.
301  m_geometry.ensure_consistency(m_config->get_number("stress_balance.ice_free_thickness_standard"));
302 
306  // The call above modifies ice thickness and updates the mask accordingly, but we re-compute the
307  // mask (we need to use a different threshold).
308  }
309 
310  // This will ensure that ice area specific volume is zero if ice thickness is greater
311  // than zero, then compute new surface elevation and mask.
312  m_geometry.ensure_consistency(m_config->get_number("geometry.ice_free_thickness_standard"));
313 
314  if (flag == REMOVE_ICEBERGS) {
315  // clean up partially-filled cells that are not next to ice
318 
319  for (auto p = m_grid->points(); p; p.next()) {
320  const int i = p.i(), j = p.j();
321 
322  if (m_geometry.ice_area_specific_volume(i, j) > 0.0 and
323  not m_geometry.cell_type.next_to_ice(i, j)) {
325  }
326  }
327  }
328 }
329 
331  stressbalance::Inputs result;
332  if (m_config->get_flag("geometry.update.use_basal_melt_rate")) {
334  }
335 
337  result.geometry = &m_geometry;
339  result.enthalpy = &m_energy_model->enthalpy();
340  result.age = m_age_model ? &m_age_model->age() : nullptr;
341 
342  result.water_column_pressure = &m_ocean->average_water_column_pressure();
343 
344  if (m_config->get_flag("stress_balance.ssa.dirichlet_bc")) {
345  result.bc_mask = &m_velocity_bc_mask;
347  }
348 
349  if (m_config->get_flag("fracture_density.enabled")) {
350  result.fracture_density = &m_fracture->density();
351  }
352 
353  return result;
354 }
355 
357  energy::Inputs result;
358 
359  result.basal_frictional_heating = &m_stress_balance->basal_frictional_heating();
360  result.basal_heat_flux = &m_btu->flux_through_top_surface(); // bedrock thermal layer
361  result.cell_type = &m_geometry.cell_type; // geometry
362  result.ice_thickness = &m_geometry.ice_thickness; // geometry
363  result.shelf_base_temp = &m_ocean->shelf_base_temperature(); // ocean model
364  result.till_water_thickness = &m_subglacial_hydrology->till_water_thickness();
365  result.surface_liquid_fraction = &m_surface->liquid_water_fraction(); // surface model
366  result.surface_temp = &m_surface->temperature(); // surface model
367 
368  result.volumetric_heating_rate = &m_stress_balance->volumetric_strain_heating();
369  result.u3 = &m_stress_balance->velocity_u();
370  result.v3 = &m_stress_balance->velocity_v();
371  result.w3 = &m_stress_balance->velocity_w();
372 
373  result.check(); // make sure all data members were set
374 
375  return result;
376 }
377 
379  YieldStressInputs result;
380 
381  result.geometry = &m_geometry;
382  result.till_water_thickness = &m_subglacial_hydrology->till_water_thickness();
383  result.subglacial_water_thickness = &m_subglacial_hydrology->subglacial_water_thickness();
384 
385  return result;
386 }
387 
388 std::string IceModel::save_state_on_error(const std::string &suffix,
389  const std::set<std::string> &additional_variables) {
390  std::string output_file = m_config->get_string("output.file");
391 
392  if (output_file.empty()) {
393  m_log->message(2, "WARNING: output.file is empty. Using unnamed.nc instead.");
394  output_file = "unnamed.nc";
395  }
396 
397  output_file = filename_add_suffix(output_file, suffix, "");
398 
399  File file(m_grid->com,
400  output_file,
401  string_to_backend(m_config->get_string("output.format")),
403  m_ctx->pio_iosys_id());
404 
405  run_stats();
406 
408 
409  auto variables = output_variables("small");
410  for (const auto &v : additional_variables) {
411  variables.insert(v);
412  }
413 
414  save_variables(file, INCLUDE_MODEL_STATE, variables, m_time->current());
415 
416  return output_file;
417 }
418 
419 //! The contents of the main PISM time-step.
420 /*!
421 During the time-step we perform the following actions:
422  */
423 void IceModel::step(bool do_mass_continuity,
424  bool do_skip) {
425 
426  m_step_counter++;
427 
428  const Profiling &profiling = m_ctx->profiling();
429 
430  double current_time = m_time->current();
431 
432  //! \li call pre_step_hook() to let derived classes do more
433  pre_step_hook();
434 
435  //! \li update the velocity field; in some cases the whole three-dimensional
436  //! field is updated and in some cases just the vertically-averaged
437  //! horizontal velocity is updated
438 
439  // always "update" ice velocity (possibly trivially); only update
440  // SSA and only update velocities at depth if suggested by temp and age
441  // stability criterion; note *lots* of communication is avoided by skipping
442  // SSA (and temp/age)
443 
444  const bool updateAtDepth = (m_skip_countdown == 0);
445 
446  // Combine basal melt rate in grounded (computed during the energy
447  // step) and floating (provided by an ocean model) areas.
448  //
449  // Basal melt rate may be used by a stress balance model to compute vertical velocity of
450  // ice.
451  {
453  m_ocean->shelf_base_mass_flux(),
454  m_energy_model->basal_melt_rate(),
456  }
457 
458  try {
459  profiling.begin("stress_balance");
460  m_stress_balance->update(stress_balance_inputs(), updateAtDepth);
461  profiling.end("stress_balance");
462  } catch (RuntimeError &e) {
463  std::string output_file = save_state_on_error("_stressbalance_failed", {});
464 
465  e.add_context("performing a time step. (Note: Model state was saved to '%s'.)",
466  output_file.c_str());
467  throw;
468  }
469 
470 
471  m_stdout_flags += m_stress_balance->stdout_report();
472 
473  m_stdout_flags += (updateAtDepth ? "v" : "V");
474 
475  //! \li determine the time step according to a variety of stability criteria
476  auto dt_info = max_timestep(m_skip_countdown);
477  m_dt = dt_info.dt;
478  m_adaptive_timestep_reason = dt_info.reason;
479  m_skip_countdown = dt_info.skip_counter;
480 
481  //! \li update the yield stress for the plastic till model (if appropriate)
483  profiling.begin("basal_yield_stress");
484  m_basal_yield_stress_model->update(yield_stress_inputs(), current_time, m_dt);
485  profiling.end("basal_yield_stress");
486  m_basal_yield_stress.copy_from(m_basal_yield_stress_model->basal_material_yield_stress());
487  m_stdout_flags += "y";
488  } else {
489  m_stdout_flags += "$";
490  }
491 
492  dt_TempAge += m_dt;
493 
494  //! \li update the age of the ice (if appropriate)
495  if (m_age_model and updateAtDepth) {
496  AgeModelInputs inputs;
498  inputs.u3 = &m_stress_balance->velocity_u();
499  inputs.v3 = &m_stress_balance->velocity_v();
500  inputs.w3 = &m_stress_balance->velocity_w();
501 
502  profiling.begin("age");
503  m_age_model->update(current_time, dt_TempAge, inputs);
504  profiling.end("age");
505  m_stdout_flags += "a";
506  } else {
507  m_stdout_flags += "$";
508  }
509 
510  //! \li update the enthalpy (or temperature) field according to the conservation of
511  //! energy model based (especially) on the new velocity field; see
512  //! energy_step()
513  if (updateAtDepth) { // do the energy step
514  profiling.begin("energy");
515  energy_step();
516  profiling.end("energy");
517  m_stdout_flags += "E";
518  } else {
519  m_stdout_flags += "$";
520  }
521 
522  //! \li update the fracture density field; see update_fracture_density()
523  if (m_config->get_flag("fracture_density.enabled")) {
524  profiling.begin("fracture_density");
526  profiling.end("fracture_density");
527  }
528 
529  //! \li update the thickness of the ice according to the mass conservation model and calving
530  //! parameterizations
531 
532  if (do_mass_continuity) {
533  // reset the conservation error field:
534  m_geometry_evolution->reset();
535 
536  profiling.begin("mass_transport");
537  {
538  // Note that there are three adaptive time-stepping criteria. Two of them (using max.
539  // diffusion and 2D CFL) are limiting the mass-continuity time-step and the third (3D
540  // CFL) limits the energy and age time-steps.
541 
542  // The mass-continuity time-step is usually smaller, and the skipping mechanism lets us
543  // do several mass-continuity steps for each energy step.
544 
545  // When -no_mass is set, mass-continuity-related time-step restrictions are disabled,
546  // making "skipping" unnecessary.
547 
548  // This is why the following two lines appear here and are executed only if
549  // do_mass_continuity is true.
550  if (do_skip and m_skip_countdown > 0) {
552  }
553 
554  try {
555  m_geometry_evolution->flow_step(m_geometry,
556  m_dt,
557  m_stress_balance->advective_velocity(),
558  m_stress_balance->diffusive_flux(),
560  } catch (RuntimeError &e) {
561  std::string output_file = save_state_on_error("_mass_transport_failed",
562  {"flux_staggered", "flux_divergence"});
563 
564  e.add_context("performing a mass transport time step (dt=%f s). (Note: Model state was saved to '%s'.)",
565  m_dt, output_file.c_str());
566  throw;
567  }
568 
569  m_geometry_evolution->apply_flux_divergence(m_geometry);
570 
572  }
573  profiling.end("mass_transport");
574 
575  // calving, frontal melt, and discharge accounting
576  profiling.begin("front_retreat");
578  profiling.end("front_retreat");
579 
580  m_stdout_flags += "h";
581  } else {
582  m_stdout_flags += "$";
583  }
584 
585  profiling.begin("sea_level");
586  m_sea_level->update(m_geometry, current_time, m_dt);
587  profiling.end("sea_level");
588 
589  profiling.begin("ocean");
590  m_ocean->update(m_geometry, current_time, m_dt);
591  profiling.end("ocean");
592 
593  // The sea level elevation might have changed, so we need to update the mask, etc. Note
594  // that THIS MAY PRODUCE ICEBERGS, but we assume that the surface model does not care.
596 
597  //! \li Update surface and ocean models.
598  profiling.begin("surface");
599  m_surface->update(m_geometry, current_time, m_dt);
600  profiling.end("surface");
601 
602 
603  if (do_mass_continuity) {
604  // compute and apply effective surface and basal mass balance
605 
606  m_geometry_evolution->source_term_step(m_geometry, m_dt,
608  m_surface->mass_flux(),
610  m_geometry_evolution->apply_mass_fluxes(m_geometry);
611 
612  // add removed icebergs to discharge due to calving
613  {
614  auto &old_H = *m_work2d[0], &old_Href = *m_work2d[1];
615 
616  {
617  old_H.copy_from(m_geometry.ice_thickness);
618  old_Href.copy_from(m_geometry.ice_area_specific_volume);
619  }
620 
621  // the last call has to remove icebergs
623 
624  bool add_values = true;
627  old_H, old_Href,
628  add_values,
630  }
631  }
632 
633  if (m_isochrones) {
634  m_isochrones->update(current_time, m_dt,
635  m_stress_balance->velocity_u(),
636  m_stress_balance->velocity_v(),
638  m_geometry_evolution->top_surface_mass_balance(),
639  m_geometry_evolution->bottom_surface_mass_balance());
640  }
641 
642  //! \li update the state variables in the subglacial hydrology model (typically
643  //! water thickness and sometimes pressure)
644  profiling.begin("basal_hydrology");
645  hydrology_step();
646  profiling.end("basal_hydrology");
647 
648  //! \li compute the bed deformation, which depends on current thickness, bed elevation,
649  //! and sea level
650  if (m_beddef) {
651  int topg_state_counter = m_beddef->bed_elevation().state_counter();
652 
653  profiling.begin("bed_deformation");
656  current_time, m_dt);
657  profiling.end("bed_deformation");
658 
659  m_new_bed_elevation = m_beddef->bed_elevation().state_counter() != topg_state_counter;
660  } else {
661  m_new_bed_elevation = false;
662  }
663 
664  if (m_config->get_flag("time_stepping.assume_bed_elevation_changed")) {
665  m_new_bed_elevation = true;
666  }
667 
668  if (m_new_bed_elevation) {
670  m_stdout_flags += "b";
671  } else {
672  m_stdout_flags += " ";
673  }
674 
675  //! \li call post_step_hook() to let derived classes do more
676  post_step_hook();
677 
678  // Done with the step; now adopt the new time.
679  m_time->step(m_dt);
680 
681  if (updateAtDepth) {
682  t_TempAge = m_time->current();
683  dt_TempAge = 0.0;
684  }
685 
686  // Check if the ice thickness exceeded the height of the computational box and stop if it did.
687  if (max(m_geometry.ice_thickness) > m_grid->Lz()) {
688  auto o_file = save_state_on_error("_max_thickness", {});
689 
691  "Ice thickness exceeds the height of the computational box (%7.4f m).\n"
692  "The model state was saved to '%s'. To continue this simulation,\n"
693  "run with\n"
694  "-i %s -bootstrap -regrid_file %s -allow_extrapolation -Lz N [other options]\n"
695  "where N > %7.4f.",
696  m_grid->Lz(), o_file.c_str(), o_file.c_str(), o_file.c_str(), m_grid->Lz());
697  }
698 
699  // end the flag line
701 }
702 
703 /*!
704  * Note: don't forget to update IceRegionalModel::hydrology_step() if necessary.
705  */
707  hydrology::Inputs inputs;
708 
709  array::Scalar &sliding_speed = *m_work2d[0];
710  compute_magnitude(m_stress_balance->advective_velocity(), sliding_speed);
711 
712  inputs.no_model_mask = nullptr;
713  inputs.geometry = &m_geometry;
714  inputs.surface_input_rate = nullptr;
716  inputs.ice_sliding_speed = &sliding_speed;
717 
719  m_surface_input_for_hydrology->update(m_time->current(), m_dt);
720  m_surface_input_for_hydrology->average(m_time->current(), m_dt);
722  } else if (m_config->get_flag("hydrology.surface_input_from_runoff")) {
723  // convert [kg m-2] to [kg m-2 s-1]
724  array::Scalar &surface_input_rate = *m_work2d[1];
725  surface_input_rate.copy_from(m_surface->runoff());
726  surface_input_rate.scale(1.0 / m_dt);
727  inputs.surface_input_rate = &surface_input_rate;
728  }
729 
730  m_subglacial_hydrology->update(m_time->current(), m_dt, inputs);
731 }
732 
733 //! Virtual. Does nothing in `IceModel`. Derived classes can do more computation in each time step.
735  // empty
736 }
737 
738 //! Virtual. Does nothing in `IceModel`. Derived classes can do more computation in each time step.
740  // empty
741 }
742 
743 /**
744  * Run the time-stepping loop from the current model time to `time`.
745  *
746  * This should be called by the coupler controlling PISM when it is
747  * running alongside a GCM.
748  *
749  * @param run_end model time (in seconds) to run to
750  *
751  * @return 0 on success
752  */
754 
755  m_time->set_end(run_end);
756 
757  return run();
758 }
759 
760 
761 /**
762  * Run the time-stepping loop from the current time until the time
763  * specified by the IceModel::grid::time object.
764  *
765  * This is the method used by PISM in the "standalone" mode.
766  */
768  const Profiling &profiling = m_ctx->profiling();
769 
770  bool do_mass_conserve = m_config->get_flag("geometry.update.enabled");
771  bool do_energy = m_config->get_flag("energy.enabled");
772  bool do_skip = m_config->get_flag("time_stepping.skip.enabled");
773 
774  // de-allocate diagnostics that are not needed
776 
777  // Enforce consistency *and* remove icebergs. During time-stepping we remove icebergs at
778  // the end of the time step, so we need to ensure that ice geometry is "OK" before the
779  // first step.
781 
782  // Update spatially-variable diagnostics at the beginning of the run.
783  write_extras();
784 
785  // Update scalar time series to remember the state at the beginning of the run.
786  // This is needed to compute rates of change of the ice mass, volume, etc.
787  {
788  const double time = m_time->current();
789  for (const auto &d : m_ts_diagnostics) {
790  d.second->update(time, time);
791  }
792  }
793 
794  m_log->message(2, "running forward ...\n");
795 
796  m_stdout_flags.erase(); // clear it out
797  print_summary_line(true, do_energy, 0.0, 0.0, 0.0, 0.0, 0.0);
798  print_summary(do_energy); // report starting state
799 
800  t_TempAge = m_time->current();
801  dt_TempAge = 0.0;
802 
803  IceModelTerminationReason termination_reason = PISM_DONE;
804  // main loop for time evolution
805  // IceModel::step calls Time::step(dt), ensuring that this while loop
806  // will terminate
807  profiling.stage_begin("time-stepping loop");
808  while (m_time->current() < m_time->end()) {
809 
810  m_stdout_flags.erase(); // clear it out
811 
812  step(do_mass_conserve, do_skip);
813 
815 
816  // report a summary for major steps or the last one
817  bool updateAtDepth = m_skip_countdown == 0;
818  bool tempAgeStep = updateAtDepth and (m_age_model or do_energy);
819 
820  double time_resolution = m_config->get_number("time_stepping.resolution");
821  const bool show_step = tempAgeStep or fabs(m_time->current() - m_time->end()) < time_resolution;
822  print_summary(show_step);
823 
824  // update viewers before writing extras because writing extras resets diagnostics
825  update_viewers();
826 
827  // writing these fields here ensures that we do it after the last time-step
828  profiling.begin("io");
829  write_snapshot();
830  write_extras();
831  bool stop_after_chekpoint = write_checkpoint();
832  profiling.end("io");
833 
834  if (stop_after_chekpoint) {
835  termination_reason = PISM_CHEKPOINT;
836  break;
837  }
838 
839  if (process_signals() != 0) {
840  termination_reason = PISM_SIGNAL;
841  break;
842  }
843  } // end of the time-stepping loop
844  profiling.stage_end("time-stepping loop");
845 
846  return termination_reason;
847 }
848 
849 //! Manage the initialization of the IceModel object.
850 /*!
851 Please see the documenting comments of the functions called below to find
852 explanations of their intended uses.
853  */
855  // Get the start time in seconds and ensure that it is consistent
856  // across all processors.
857  m_start_time = get_time(m_grid->com);
858 
859  const Profiling &profiling = m_ctx->profiling();
860 
861  profiling.begin("initialization");
862 
863  //! The IceModel initialization sequence is this:
864 
865  //! 1) Initialize model time:
866  time_setup();
867 
868  //! 2) Process the options:
869  process_options();
870 
871  //! 3) Memory allocation:
873 
874  //! 4) Allocate PISM components modeling some physical processes.
876 
877  //! 6) Initialize coupler models and fill the model state variables
878  //! (from a PISM output file, from a bootstrapping file using some
879  //! modeling choices or using formulas). Calls IceModel::regrid()
881 
882  //! 7) Report grid parameters:
883  m_grid->report_parameters();
884 
885  //! 8) Miscellaneous stuff: set up the bed deformation model, initialize the
886  //! basal till model, initialize snapshots. This has to happen *after*
887  //! regridding.
888  misc_setup();
889 
890  profiling.end("initialization");
891 }
892 
893 const Geometry& IceModel::geometry() const {
894  return m_geometry;
895 }
896 
898  return *m_geometry_evolution;
899 }
900 
902  return this->m_stress_balance.get();
903 }
904 
906  return m_ocean.get();
907 }
908 
910  return m_btu.get();
911 }
912 
914  return m_energy_model.get();
915 }
916 
918  return m_basal_yield_stress_model.get();
919 }
920 
922  return m_beddef.get();
923 }
924 
925 /*!
926  * Return thickness change due to calving (over the last time step).
927  */
930 }
931 
932 /*!
933  * Return thickness change due to frontal melt (over the last time step).
934  */
937 }
938 
939 /*!
940  * Return thickness change due to forced retreat (over the last time step).
941  */
944 }
945 
946 void warn_about_missing(const Logger &log,
947  const std::set<std::string> &vars,
948  const std::string &type,
949  const std::set<std::string> &available,
950  bool stop) {
951  std::vector<std::string> missing;
952  for (const auto &v : vars) {
953  if (available.find(v) == available.end()) {
954  missing.push_back(v);
955  }
956  }
957 
958  if (not missing.empty()) {
959  size_t N = missing.size();
960  const char *ending = N > 1 ? "s" : "";
961  const char *verb = N > 1 ? "are" : "is";
962  if (stop) {
964  "%s variable%s %s %s not available!\n"
965  "Available variables:\n- %s",
966  type.c_str(),
967  ending,
968  join(missing, ",").c_str(),
969  verb,
970  set_join(available, ",\n- ").c_str());
971  }
972 
973  log.message(2,
974  "\nWARNING: %s variable%s %s %s not available!\n\n",
975  type.c_str(),
976  ending,
977  join(missing, ",").c_str(),
978  verb);
979  }
980 }
981 
982 /*!
983  * De-allocate diagnostics that were not requested.
984  *
985  * Checks viewers, -extra_vars, -checkpoint, -save_vars, and regular output.
986  *
987  * FIXME: I need to make sure that these reporting mechanisms are active. It is possible that
988  * variables are on a list, but that list is not actually used.
989  */
991 
992  // get the list of available diagnostics
993  std::set<std::string> available;
994  for (const auto &d : m_diagnostics) {
995  available.insert(d.first);
996  }
997 
998  auto m_extra_stop = m_config->get_flag("output.extra.stop_missing");
999  warn_about_missing(*m_log, m_output_vars, "output", available, false);
1000  warn_about_missing(*m_log, m_snapshot_vars, "snapshot", available, false);
1001  warn_about_missing(*m_log, m_checkpoint_vars, "checkpoint", available, false);
1002  warn_about_missing(*m_log, m_extra_vars, "diagnostic", available, m_extra_stop);
1003 
1004  // get the list of requested diagnostics
1005  auto requested = set_split(m_config->get_string("output.runtime.viewer.variables"), ',');
1006  requested = combine(requested, m_output_vars);
1007  requested = combine(requested, m_snapshot_vars);
1008  requested = combine(requested, m_extra_vars);
1009  requested = combine(requested, m_checkpoint_vars);
1010 
1011  // de-allocate diagnostics that were not requested
1012  for (const auto &v : available) {
1013  if (requested.find(v) == requested.end()) {
1014  m_diagnostics.erase(v);
1015  }
1016  }
1017 
1018  // scalar time series
1019  std::vector<std::string> missing;
1020  if (not m_ts_filename.empty() and m_ts_vars.empty()) {
1021  // use all diagnostics
1022  } else {
1023  TSDiagnosticList diagnostics;
1024  for (const auto &v : m_ts_vars) {
1025  if (m_ts_diagnostics.find(v) != m_ts_diagnostics.end()) {
1026  diagnostics[v] = m_ts_diagnostics[v];
1027  } else {
1028  missing.push_back(v);
1029  }
1030  }
1031  // replace m_ts_diagnostics with requested diagnostics, de-allocating the rest
1032  m_ts_diagnostics = diagnostics;
1033  }
1034 
1035  if (not missing.empty()) {
1037  "requested scalar diagnostics %s are not available",
1038  join(missing, ",").c_str());
1039  }
1040 }
1041 
1042 /*!
1043  * Update diagnostics.
1044  *
1045  * This usually involves accumulating data needed to computed time-averaged quantities.
1046  *
1047  * Call this after prune_diagnostics() to avoid unnecessary work.
1048  */
1050  for (const auto &d : m_diagnostics) {
1051  d.second->update(dt);
1052  }
1053 
1054  const double time = m_time->current();
1055  for (const auto &d : m_ts_diagnostics) {
1056  d.second->update(time - dt, time);
1057  }
1058 }
1059 
1060 /*!
1061  * Reset accumulators in diagnostics that compute time-averaged quantities.
1062  */
1064  for (auto &d : m_diagnostics) {
1065  d.second->reset();
1066  }
1067 }
1068 
1069 IceModel::ThicknessChanges::ThicknessChanges(const std::shared_ptr<const Grid> &grid)
1070  : calving(grid, "thickness_change_due_to_calving"),
1071  frontal_melt(grid, "thickness_change_due_to_frontal_melt"),
1072  forced_retreat(grid, "thickness_change_due_to_forced_retreat") {
1073  // empty
1074 }
1075 
1076 void IceModel::set_python_ocean_model(std::shared_ptr<ocean::PyOceanModel> model) {
1077  m_ocean = std::make_shared<ocean::PyOceanModelAdapter>(m_grid, model);
1078  m_submodels["ocean model"] = m_ocean.get();
1079 }
1080 
1081 } // end of namespace pism
const array::Array3D * w3
Definition: AgeModel.hh:41
const array::Array3D * v3
Definition: AgeModel.hh:40
const array::Array3D * u3
Definition: AgeModel.hh:39
const array::Scalar * ice_thickness
Definition: AgeModel.hh:38
High-level PISM I/O class.
Definition: File.hh:56
array::Scalar1 sea_level_elevation
Definition: Geometry.hh:48
array::Scalar cell_grounded_fraction
Definition: Geometry.hh:56
void ensure_consistency(double ice_free_thickness_threshold)
Definition: Geometry.cc:112
array::Scalar2 ice_surface_elevation
Definition: Geometry.hh:57
array::Scalar1 ice_area_specific_volume
Definition: Geometry.hh:52
array::CellType2 cell_type
Definition: Geometry.hh:55
array::Scalar2 ice_thickness
Definition: Geometry.hh:51
array::Scalar longitude
Definition: Geometry.hh:42
array::Scalar2 bed_elevation
Definition: Geometry.hh:47
array::Scalar latitude
Definition: Geometry.hh:41
std::string m_adaptive_timestep_reason
Definition: IceModel.hh:326
std::map< std::string, const Component * > m_submodels
the list of sub-models, for writing model states and obtaining diagnostics
Definition: IceModel.hh:259
virtual energy::Inputs energy_model_inputs()
Definition: IceModel.cc:356
std::set< std::string > m_snapshot_vars
Definition: IceModel.hh:430
virtual int process_signals()
Catch signals -USR1, -USR2 and -TERM.
Definition: utilities.cc:47
void enforce_consistency_of_geometry(ConsistencyFlag flag)
Update the surface elevation and the flow-type mask when the geometry has changed.
Definition: IceModel.cc:293
const Geometry & geometry() const
Definition: IceModel.cc:893
void compute_geometry_change(const array::Scalar &thickness, const array::Scalar &Href, const array::Scalar &thickness_old, const array::Scalar &Href_old, bool add_values, array::Scalar &output)
virtual void model_state_setup()
Sets the starting values of model state variables.
double m_start_time
Definition: IceModel.hh:477
std::shared_ptr< stressbalance::StressBalance > m_stress_balance
Definition: IceModel.hh:397
std::shared_ptr< Isochrones > m_isochrones
Definition: IceModel.hh:270
VariableMetadata m_timestamp
Definition: IceModel.hh:476
IceModelTerminationReason run()
Definition: IceModel.cc:767
std::shared_ptr< ocean::OceanModel > m_ocean
Definition: IceModel.hh:287
virtual void post_step_hook()
Virtual. Does nothing in IceModel. Derived classes can do more computation in each time step.
Definition: IceModel.cc:739
const ocean::OceanModel * ocean_model() const
Definition: IceModel.cc:905
VariableMetadata run_stats() const
Definition: utilities.cc:92
std::map< std::string, TSDiagnostic::Ptr > m_ts_diagnostics
Requested scalar diagnostics.
Definition: IceModel.hh:421
virtual void energy_step()
Manage the solution of the energy equation, and related parallel communication.
Definition: energy.cc:60
std::shared_ptr< petsc::Vec > m_work2d_proc0
Definition: IceModel.hh:395
std::shared_ptr< surface::SurfaceModel > m_surface
Definition: IceModel.hh:286
const Config::Ptr m_config
Configuration flags and parameters.
Definition: IceModel.hh:243
void write_extras()
Write spatially-variable diagnostic quantities.
void write_snapshot()
Writes a snapshot of the model state (if necessary)
Definition: output_save.cc:111
unsigned int m_step_counter
Definition: IceModel.hh:330
bool m_save_extra
Definition: IceModel.hh:446
virtual stressbalance::Inputs stress_balance_inputs()
Definition: IceModel.cc:330
std::shared_ptr< FractureDensity > m_fracture
Definition: IceModel.hh:306
ThicknessChanges m_thickness_change
Definition: IceModel.hh:412
virtual ~IceModel()
Definition: IceModel.cc:171
void init()
Manage the initialization of the IceModel object.
Definition: IceModel.cc:854
const Time::Ptr m_time
Time manager.
Definition: IceModel.hh:251
Geometry m_geometry
Definition: IceModel.hh:295
const GeometryEvolution & geometry_evolution() const
Definition: IceModel.cc:897
const stressbalance::StressBalance * stress_balance() const
Definition: IceModel.cc:901
bool m_new_bed_elevation
Definition: IceModel.hh:297
virtual void reset_diagnostics()
Definition: IceModel.cc:1063
static const int m_n_work2d
Definition: IceModel.hh:392
std::shared_ptr< YieldStress > m_basal_yield_stress_model
Definition: IceModel.hh:262
std::shared_ptr< calving::IcebergRemover > m_iceberg_remover
Definition: IceModel.hh:272
double m_timestep_hit_multiples_last_time
Definition: IceModel.hh:467
array::Scalar m_basal_melt_rate
rate of production of basal meltwater (ice-equivalent); no ghosts
Definition: IceModel.hh:302
virtual void front_retreat_step()
Definition: frontretreat.cc:86
const std::shared_ptr< Context > m_ctx
Execution context.
Definition: IceModel.hh:245
virtual void misc_setup()
Miscellaneous initialization tasks plus tasks that need the fields that can come from regridding.
const Logger::Ptr m_log
Logger.
Definition: IceModel.hh:249
std::shared_ptr< array::Forcing > m_surface_input_for_hydrology
Definition: IceModel.hh:264
virtual void print_summary(bool tempAndAge)
Definition: printout.cc:89
virtual void update_diagnostics(double dt)
Definition: IceModel.cc:1049
array::Scalar m_bedtoptemp
temperature at the top surface of the bedrock thermal layer
Definition: IceModel.hh:304
const energy::EnergyModel * energy_balance_model() const
Definition: IceModel.cc:913
std::string save_state_on_error(const std::string &suffix, const std::set< std::string > &additional_variables)
Definition: IceModel.cc:388
VariableMetadata m_output_global_attributes
stores global attributes saved in a PISM output file
Definition: IceModel.hh:256
const array::Scalar & frontal_melt() const
Definition: IceModel.cc:935
const array::Scalar & forced_retreat() const
Definition: IceModel.cc:942
std::vector< std::shared_ptr< array::Scalar2 > > m_work2d
Definition: IceModel.hh:393
virtual void process_options()
double dt() const
Definition: IceModel.cc:140
bool write_checkpoint()
Write a checkpoint (i.e. an intermediate result of a run).
virtual void allocate_storage()
Allocate all Arrays defined in IceModel.
Definition: IceModel.cc:185
std::set< std::string > m_checkpoint_vars
Definition: IceModel.hh:461
array::Scalar2 m_velocity_bc_mask
mask to determine Dirichlet boundary locations for the sliding velocity
Definition: IceModel.hh:309
void reset_counters()
Definition: IceModel.cc:144
std::string m_stdout_flags
Definition: IceModel.hh:328
std::unique_ptr< GeometryEvolution > m_geometry_evolution
Definition: IceModel.hh:296
virtual void step(bool do_mass_continuity, bool do_skip)
The contents of the main PISM time-step.
Definition: IceModel.cc:423
virtual void combine_basal_melt_rate(const Geometry &geometry, const array::Scalar &shelf_base_mass_flux, const array::Scalar &grounded_basal_melt_rate, array::Scalar &result)
Combine basal melt rate in grounded and floating areas.
Definition: energy.cc:85
virtual void hydrology_step()
Definition: IceModel.cc:706
virtual void time_setup()
Initialize time from an input file or command-line options.
std::shared_ptr< energy::BedThermalUnit > m_btu
Definition: IceModel.hh:266
virtual void save_variables(const File &file, OutputKind kind, const std::set< std::string > &variables, double time, io::Type default_diagnostics_type=io::PISM_FLOAT) const
Definition: output.cc:169
std::set< array::Array * > m_model_state
Definition: IceModel.hh:417
array::Scalar1 m_ice_thickness_bc_mask
Mask prescribing locations where ice thickness is held constant.
Definition: IceModel.hh:314
@ DONT_REMOVE_ICEBERGS
Definition: IceModel.hh:356
std::shared_ptr< AgeModel > m_age_model
Definition: IceModel.hh:269
const bed::BedDef * bed_deformation_model() const
Definition: IceModel.cc:921
virtual std::set< std::string > output_variables(const std::string &keyword)
Assembles a list of diagnostics corresponding to an output file size.
double t_TempAge
time of last update for enthalpy/temperature
Definition: IceModel.hh:320
array::Vector2 m_velocity_bc_values
Dirichlet boundary velocities.
Definition: IceModel.hh:311
virtual void prune_diagnostics()
Definition: IceModel.cc:990
std::string m_ts_filename
file to write scalar time-series to
Definition: IceModel.hh:437
virtual void update_fracture_density()
std::map< std::string, Diagnostic::Ptr > m_diagnostics
Requested spatially-variable diagnostics.
Definition: IceModel.hh:419
IceModel(std::shared_ptr< Grid > grid, const std::shared_ptr< Context > &context)
Definition: IceModel.cc:56
std::shared_ptr< ocean::sea_level::SeaLevel > m_sea_level
Definition: IceModel.hh:289
virtual void print_summary_line(bool printPrototype, bool tempAndAge, double delta_t, double volume, double area, double meltfrac, double max_diffusivity)
Print a line to stdout which summarizes the state of the modeled ice sheet at the end of the time ste...
Definition: printout.cc:164
virtual void update_viewers()
Update the runtime graphical viewers.
Definition: viewers.cc:58
const array::Scalar & calving() const
Definition: IceModel.cc:928
virtual void pre_step_hook()
Virtual. Does nothing in IceModel. Derived classes can do more computation in each time step.
Definition: IceModel.cc:734
std::set< std::string > m_ts_vars
Definition: IceModel.hh:440
unsigned int m_skip_countdown
Definition: IceModel.hh:324
IceModelTerminationReason run_to(double run_end)
Definition: IceModel.cc:753
std::set< std::string > m_extra_vars
Definition: IceModel.hh:451
virtual YieldStressInputs yield_stress_inputs()
Definition: IceModel.cc:378
virtual void write_metadata(const File &file, MappingTreatment mapping_flag, HistoryTreatment history_flag) const
Write time-independent metadata to a file.
Definition: output.cc:72
const YieldStress * basal_yield_stress_model() const
Definition: IceModel.cc:917
std::unique_ptr< hydrology::Hydrology > m_subglacial_hydrology
Definition: IceModel.hh:261
std::set< std::string > m_output_vars
Definition: IceModel.hh:424
const energy::BedThermalUnit * bedrock_thermal_model() const
Definition: IceModel.cc:909
void set_python_ocean_model(std::shared_ptr< ocean::PyOceanModel > model)
Definition: IceModel.cc:1076
double dt_TempAge
enthalpy/temperature and age time-steps
Definition: IceModel.hh:322
double m_dt
mass continuity time step, s
Definition: IceModel.hh:318
std::shared_ptr< energy::EnergyModel > m_energy_model
Definition: IceModel.hh:267
const std::shared_ptr< Grid > m_grid
Computational grid.
Definition: IceModel.hh:241
std::shared_ptr< bed::BedDef > m_beddef
Definition: IceModel.hh:291
virtual TimesteppingInfo max_timestep(unsigned int counter)
Use various stability criteria to determine the time step for an evolution run.
VariableMetadata m_extra_bounds
Definition: IceModel.hh:452
virtual void allocate_submodels()
Allocate PISM's sub-models implementing some physical processes.
bool m_save_snapshots
Definition: IceModel.hh:428
array::Scalar2 m_basal_yield_stress
ghosted
Definition: IceModel.hh:300
void message(int threshold, const char format[],...) const __attribute__((format(printf
Print a message to the log.
Definition: Logger.cc:49
A basic logging class.
Definition: Logger.hh:40
void begin(const char *name) const
Definition: Profiling.cc:75
void end(const char *name) const
Definition: Profiling.cc:91
void stage_end(const char *name) const
Definition: Profiling.cc:119
void stage_begin(const char *name) const
Definition: Profiling.cc:103
void add_context(const std::string &message)
Add a message providing some context. This way we can (sort of) get a stack trace even though C++ exc...
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
VariableMetadata & standard_name(const std::string &input)
VariableMetadata & long_name(const std::string &input)
VariableMetadata & output_units(const std::string &input)
VariableMetadata & set_output_type(io::Type type)
VariableMetadata & units(const std::string &input)
VariableMetadata & set_time_independent(bool flag)
const array::Scalar * till_water_thickness
Definition: YieldStress.hh:34
const array::Scalar * subglacial_water_thickness
Definition: YieldStress.hh:36
const Geometry * geometry
Definition: YieldStress.hh:32
The PISM basal yield stress model interface (virtual base class)
Definition: YieldStress.hh:43
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition: Array.hh:65
void copy_from(const Array2D< T > &source)
Definition: Array2D.hh:73
void set_interpolation_type(InterpolationType type)
Definition: Array.cc:179
void scale(double alpha)
Result: v <- v * alpha. Calls VecScale.
Definition: Array.cc:253
void set(double c)
Result: v[j] <- c for all j.
Definition: Array.cc:707
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
Definition: Array.cc:553
bool next_to_ice(int i, int j) const
Ice-free margin (at least one of four neighbors has ice).
Definition: CellType.hh:87
PISM bed deformation model (base class).
Definition: BedDef.hh:39
Given the temperature of the top of the bedrock, for the duration of one time-step,...
const array::Scalar * surface_liquid_fraction
Definition: EnergyModel.hh:47
const array::Scalar1 * ice_thickness
Definition: EnergyModel.hh:46
const array::Array3D * w3
Definition: EnergyModel.hh:55
void check() const
Definition: EnergyModel.cc:58
const array::Array3D * v3
Definition: EnergyModel.hh:54
const array::Scalar * shelf_base_temp
Definition: EnergyModel.hh:48
const array::Scalar * basal_heat_flux
Definition: EnergyModel.hh:45
const array::Scalar * basal_frictional_heating
Definition: EnergyModel.hh:44
const array::Scalar * till_water_thickness
Definition: EnergyModel.hh:50
const array::Array3D * u3
Definition: EnergyModel.hh:53
const array::Scalar * surface_temp
Definition: EnergyModel.hh:49
const array::CellType * cell_type
Definition: EnergyModel.hh:43
const array::Array3D * volumetric_heating_rate
Definition: EnergyModel.hh:52
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
A very rudimentary PISM ocean model.
Definition: OceanModel.hh:33
const array::Scalar * basal_yield_stress
const array::Scalar * bc_mask
const array::Array3D * age
const array::Scalar * water_column_pressure
const array::Array3D * enthalpy
const array::Scalar * fracture_density
const array::Scalar * basal_melt_rate
const array::Vector * bc_values
The class defining PISM's interface to the shallow stress balance code.
#define PISM_ERROR_LOCATION
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:165
void compute_magnitude(const array::Vector &input, array::Scalar &result)
Definition: Scalar.cc:66
@ PISM_NETCDF3
Definition: IO_Flags.hh:57
@ PISM_READWRITE_MOVE
create a file for writing, move foo.nc to foo.nc~ if present
Definition: IO_Flags.hh:78
@ PISM_READONLY
open an existing file for reading only
Definition: IO_Flags.hh:72
@ PISM_INT
Definition: IO_Flags.hh:50
double get_time(MPI_Comm comm)
io::Backend string_to_backend(const std::string &backend)
Definition: File.cc:57
std::string set_join(const std::set< std::string > &input, const std::string &separator)
std::map< std::string, TSDiagnostic::Ptr > TSDiagnosticList
Definition: Diagnostic.hh:343
std::string printf(const char *format,...)
IceModelTerminationReason
Definition: IceModel.hh:114
@ PISM_SIGNAL
Definition: IceModel.hh:114
@ PISM_DONE
Definition: IceModel.hh:114
@ PISM_CHEKPOINT
Definition: IceModel.hh:114
std::set< std::string > set_split(const std::string &input, char separator)
Transform a separator-separated list (a string) into a set of strings.
void warn_about_missing(const Logger &log, const std::set< std::string > &vars, const std::string &type, const std::set< std::string > &available, bool stop)
Definition: IceModel.cc:946
std::string filename_add_suffix(const std::string &filename, const std::string &separator, const std::string &suffix)
Adds a suffix to a filename.
std::string version()
T combine(const T &a, const T &b)
std::string join(const std::vector< std::string > &strings, const std::string &separator)
Concatenate strings, inserting separator between elements.
volatile sig_atomic_t pism_signal
Definition: pism_signal.c:23
void pism_signal_handler(int sig)
Definition: pism_signal.c:25
std::string filename
Definition: options.hh:33
ThicknessChanges(const std::shared_ptr< const Grid > &grid)
Definition: IceModel.cc:1069