25#include "pism/icemodel/IceModel.hh"
27#include "pism/basalstrength/YieldStress.hh"
28#include "pism/frontretreat/util/IcebergRemover.hh"
29#include "pism/energy/BedThermalUnit.hh"
30#include "pism/hydrology/Hydrology.hh"
31#include "pism/stressbalance/StressBalance.hh"
32#include "pism/util/Grid.hh"
33#include "pism/util/Config.hh"
34#include "pism/util/Diagnostic.hh"
35#include "pism/util/error_handling.hh"
36#include "pism/coupler/SeaLevel.hh"
37#include "pism/coupler/OceanModel.hh"
38#include "pism/coupler/SurfaceModel.hh"
39#include "pism/earth/BedDef.hh"
40#include "pism/util/pism_signal.h"
41#include "pism/util/Vars.hh"
42#include "pism/util/Profiling.hh"
43#include "pism/util/pism_utilities.hh"
44#include "pism/age/AgeModel.hh"
45#include "pism/age/Isochrones.hh"
46#include "pism/energy/EnergyModel.hh"
47#include "pism/util/io/File.hh"
48#include "pism/util/array/Forcing.hh"
49#include "pism/fracturedensity/FractureDensity.hh"
50#include "pism/coupler/util/options.hh"
51#include "pism/coupler/ocean/PyOceanModel.hh"
52#include "pism/util/io/SynchronousOutputWriter.hh"
53#include "pism/util/io/IO_Flags.hh"
55#if (Pism_USE_YAC == 1)
56#include "pism/util/io/YacOutputWriter.hh"
63 m_config(context->config()),
65 m_sys(context->unit_system()),
66 m_log(context->log()),
67 m_time(context->time()),
68 m_output_global_attributes(
"PISM_GLOBAL", m_sys),
70 m_new_bed_elevation(true),
71 m_basal_yield_stress(m_grid,
"tauc"),
72 m_basal_melt_rate(m_grid,
"bmelt"),
73 m_bedtoptemp(m_grid,
"bedtoptemp"),
74 m_velocity_bc_mask(m_grid,
"vel_bc_mask"),
75 m_velocity_bc_values(m_grid,
"_bc"),
76 m_ice_thickness_bc_mask(grid,
"thk_bc_mask"),
78 m_thickness_change(grid),
79 m_scalar_times(new std::vector<
double>()) {
116 auto surface_input_file =
m_config->get_string(
"hydrology.surface_input.file");
117 if (not surface_input_file.empty()) {
119 int buffer_size =
static_cast<int>(
m_config->get_number(
"input.forcing.buffer_size"));
124 std::make_shared<array::Forcing>(
m_grid, file,
"water_input_rate",
126 buffer_size, surface_input.
periodic);
128 .long_name(
"water input rate for the subglacial hydrology model")
129 .units(
"kg m^-2 s^-1")
130 .output_units(
"kg m^-2 year^-1");
138#if (Pism_USE_YAC == 1)
140 auto yac_writer = std::make_shared<YacOutputWriter>(
m_grid->com, *
m_config);
161 int year_increment =
static_cast<int>(
m_config->get_number(
"time_stepping.hit_multiples"));
163 if (year_increment > 0) {
167 int last_multiple = year - year % year_increment;
170 last_multiple -= year_increment *
static_cast<int>(year % year_increment < 0);
207 if (
m_config->get_flag(
"geometry.grounded_cell_fraction")) {
211 if (
m_config->get_flag(
"geometry.part_grid.enabled")) {
219 .
long_name(
"yield stress for basal till (plastic or pseudo-plastic model)")
226 .
long_name(
"temperature at the top surface of the bedrock thermal layer")
233 "ice basal melt rate from energy conservation and subshelf melt, in ice thickness per time")
243 .
long_name(
"Mask prescribing Dirichlet boundary locations for the sliding velocity")
253 double fill_value =
m_config->get_number(
"output.fill_value");
254 const double huge_value = 1e6;
257 "X-component of the SSA velocity boundary conditions");
259 "Y-component of the SSA velocity boundary conditions");
260 for (
int j : { 0, 1 }) {
270 .
long_name(
"Mask specifying locations where ice thickness is held constant")
328 for (
auto p :
m_grid->points()) {
329 const int i = p.i(), j = p.j();
341 if (
m_config->get_flag(
"geometry.update.use_basal_melt_rate")) {
353 if (
m_config->get_flag(
"stress_balance.ssa.dirichlet_bc")) {
358 if (
m_config->get_flag(
"fracture_density.enabled")) {
408 double current_time =
m_time->current();
431 m_ocean->shelf_base_mass_flux(),
437 profiling.
begin(
"stress_balance");
439 profiling.
end(
"stress_balance");
443 e.
add_context(
"performing a time step. (Note: Model state was saved to '%s'.)",
444 output_file.c_str());
455 double dt = dt_info.dt;
462 profiling.
begin(
"basal_yield_stress");
464 profiling.
end(
"basal_yield_stress");
481 profiling.
begin(
"age");
483 profiling.
end(
"age");
493 profiling.
begin(
"energy");
495 profiling.
end(
"energy");
502 if (
m_config->get_flag(
"fracture_density.enabled")) {
503 profiling.
begin(
"fracture_density");
505 profiling.
end(
"fracture_density");
511 if (do_mass_continuity) {
515 profiling.
begin(
"mass_transport");
541 {
"flux_staggered",
"flux_divergence"});
543 e.
add_context(
"performing a mass transport time step (dt=%f s). (Note: Model state was saved to '%s'.)",
544 dt, output_file.c_str());
552 profiling.
end(
"mass_transport");
555 profiling.
begin(
"front_retreat");
557 profiling.
end(
"front_retreat");
564 profiling.
begin(
"sea_level");
566 profiling.
end(
"sea_level");
568 profiling.
begin(
"ocean");
572 m_ocean->update(inputs, current_time,
dt);
574 profiling.
end(
"ocean");
581 profiling.
begin(
"surface");
583 profiling.
end(
"surface");
586 if (do_mass_continuity) {
607 bool add_values =
true;
627 profiling.
begin(
"basal_hydrology");
629 profiling.
end(
"basal_hydrology");
634 int topg_state_counter =
m_beddef->bed_elevation().state_counter();
636 profiling.
begin(
"bed_deformation");
640 profiling.
end(
"bed_deformation");
647 if (
m_config->get_flag(
"time_stepping.assume_bed_elevation_changed")) {
675 "Ice thickness exceeds the height of the computational box (%7.4f m).\n"
676 "The model state was saved to '%s'. To continue this simulation,\n"
678 "-i %s -bootstrap -regrid_file %s -allow_extrapolation -Lz N [other options]\n"
680 m_grid->Lz(), o_file.c_str(), o_file.c_str(), o_file.c_str(),
m_grid->Lz());
708 }
else if (
m_config->get_flag(
"hydrology.surface_input_from_runoff")) {
712 surface_input_rate.
scale(1.0 /
dt);
756 bool do_mass_conserve =
m_config->get_flag(
"geometry.update.enabled");
757 bool do_energy =
set_member(
m_config->get_string(
"energy.model"), {
"cold",
"enthalpy"});
758 bool do_skip =
m_config->get_flag(
"time_stepping.skip.enabled");
771 const double time =
m_time->current();
773 d.second->update(time, time);
777 m_log->message(2,
"running forward ...\n");
795 m_dt =
step(do_mass_conserve, do_skip);
801 bool tempAgeStep = updateAtDepth and (
m_age_model or do_energy);
803 double time_resolution =
m_config->get_number(
"time_stepping.resolution");
804 const bool show_step = tempAgeStep or fabs(
m_time->current() -
m_time->end()) < time_resolution;
811 profiling.
begin(
"io");
817 if (stop_after_chekpoint) {
827 profiling.
stage_end(
"time-stepping loop");
829 return termination_reason;
846 profiling.
begin(
"initialization");
852 if (not
m_config->get_flag(
"geometry.update.enabled") &&
853 m_config->get_flag(
"time_stepping.skip.enabled")) {
855 "PISM WARNING: time_stepping.skip.enabled is 'true' and\n"
856 " geometry.update.enabled is 'false'\n"
857 " skipping time steps makes sense only with evolving geometry.\n");
863 bool use_calendar =
m_config->get_flag(
"output.runtime.time_use_calendar");
866 m_log->message(2,
"* Run time: [%s, %s] (%s years, using the '%s' calendar)\n",
868 m_time->run_length().c_str(),
m_time->calendar().c_str());
870 std::string time_units =
m_config->get_string(
"output.runtime.time_unit_name");
872 double start =
m_time->convert_time_interval(
m_time->start(), time_units),
873 end =
m_time->convert_time_interval(
m_time->end(), time_units), length = end - start;
875 m_log->message(2,
"* Run time: [%f %s, %f %s] (%f %s)\n", start, time_units.c_str(), end,
876 time_units.c_str(), length, time_units.c_str());
892 m_log->message(2,
"Computational domain and grid:\n");
893 m_grid->report_parameters();
900 profiling.
end(
"initialization");
957 : calving(grid,
"thickness_change_due_to_calving"),
958 frontal_melt(grid,
"thickness_change_due_to_frontal_melt"),
959 forced_retreat(grid,
"thickness_change_due_to_forced_retreat") {
964 m_ocean = std::make_shared<ocean::PyOceanModelAdapter>(
m_grid, model);
High-level PISM I/O class.
array::Scalar1 sea_level_elevation
array::Scalar cell_grounded_fraction
void ensure_consistency(double ice_free_thickness_threshold)
array::Scalar2 ice_surface_elevation
array::Scalar1 ice_area_specific_volume
array::CellType2 cell_type
array::Scalar2 ice_thickness
array::Scalar2 bed_elevation
std::string m_adaptive_timestep_reason
std::map< std::string, const Component * > m_submodels
the list of sub-models, for writing model states and obtaining diagnostics
virtual energy::Inputs energy_model_inputs()
virtual int process_signals()
Catch signals -USR1, -USR2 and -TERM.
virtual void hydrology_step(double t, double dt)
void enforce_consistency_of_geometry(ConsistencyFlag flag)
Update the surface elevation and the flow-type mask when the geometry has changed.
const Geometry & geometry() const
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)
std::shared_ptr< stressbalance::StressBalance > m_stress_balance
std::shared_ptr< Isochrones > m_isochrones
IceModelTerminationReason run()
std::shared_ptr< ocean::OceanModel > m_ocean
virtual void post_step_hook()
Virtual. Does nothing in IceModel. Derived classes can do more computation in each time step.
const ocean::OceanModel * ocean_model() const
std::shared_ptr< surface::SurfaceModel > m_surface
void write_snapshot()
Writes a snapshot of the model state (if necessary)
unsigned int m_step_counter
virtual stressbalance::Inputs stress_balance_inputs()
std::shared_ptr< FractureDensity > m_fracture
std::shared_ptr< Config > m_config
Configuration flags and parameters.
ThicknessChanges m_thickness_change
double m_dt_TempAge
enthalpy/temperature and age time-steps
virtual void update_fracture_density(double dt)
const GeometryEvolution & geometry_evolution() const
const stressbalance::StressBalance * stress_balance() const
static const int m_n_work2d
std::shared_ptr< YieldStress > m_basal_yield_stress_model
std::shared_ptr< calving::IcebergRemover > m_iceberg_remover
double m_timestep_hit_multiples_last_time
std::shared_ptr< Context > m_ctx
Execution context.
std::shared_ptr< Logger > m_log
Logger.
array::Scalar m_basal_melt_rate
rate of production of basal meltwater (ice-equivalent); no ghosts
std::shared_ptr< array::Forcing > m_surface_input_for_hydrology
double m_t_TempAge
time of last update for enthalpy/temperature
array::Scalar m_bedtoptemp
temperature at the top surface of the bedrock thermal layer
const energy::EnergyModel * energy_balance_model() const
virtual void update_diagnostics(double t, double dt)
std::shared_ptr< OutputWriter > m_snapshot_writer
std::string save_state_on_error(const std::string &suffix, const std::set< std::string > &additional_variables)
VariableMetadata m_output_global_attributes
stores global attributes saved in a PISM output file
std::shared_ptr< OutputWriter > m_spatial_writer
std::shared_ptr< Time > m_time
Time manager.
const array::Scalar & frontal_melt() const
const array::Scalar & forced_retreat() const
std::vector< std::shared_ptr< array::Scalar2 > > m_work2d
void write_spatial_diagnostics()
Write spatially-variable diagnostic quantities.
bool write_checkpoint()
Write a checkpoint (i.e. an intermediate result of a run).
virtual void allocate_storage()
Allocate all Arrays defined in IceModel.
array::Scalar2 m_velocity_bc_mask
mask to determine Dirichlet boundary locations for the sliding velocity
std::string m_stdout_flags
std::unique_ptr< GeometryEvolution > m_geometry_evolution
virtual void energy_step(double t, double dt)
Manage the solution of the energy equation, and related parallel communication.
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.
virtual void front_retreat_step(double t, double dt)
void init(DiagnosticReport report_type=DIAG_NONE)
Manage the initialization of the IceModel object.
std::shared_ptr< energy::BedThermalUnit > m_btu
virtual void model_state_setup(InputOptions input_options)
Sets the starting values of model state variables.
std::set< array::Array * > m_model_state
array::Scalar1 m_ice_thickness_bc_mask
Mask prescribing locations where ice thickness is held constant.
std::shared_ptr< AgeModel > m_age_model
const bed::BedDef * bed_deformation_model() const
std::map< std::string, TSDiagnostic::Ptr > m_available_scalar_diagnostics
Available scalar diagnostics.
array::Vector2 m_velocity_bc_values
Dirichlet boundary velocities.
IceModel(std::shared_ptr< Grid > grid, const std::shared_ptr< Context > &context)
std::shared_ptr< ocean::sea_level::SeaLevel > m_sea_level
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...
std::shared_ptr< OutputWriter > m_output_writer
virtual double step(bool do_mass_continuity, bool do_skip)
The contents of the main PISM time-step.
virtual void update_viewers()
Update the runtime graphical viewers.
const array::Scalar & calving() const
virtual void pre_step_hook()
Virtual. Does nothing in IceModel. Derived classes can do more computation in each time step.
unsigned int m_skip_countdown
IceModelTerminationReason run_to(double run_end)
virtual YieldStressInputs yield_stress_inputs()
virtual void misc_setup(InputOptions input_options, DiagnosticReport report_type)
Miscellaneous initialization tasks plus tasks that need the fields that can come from regridding.
const YieldStress * basal_yield_stress_model() const
std::unique_ptr< hydrology::Hydrology > m_subglacial_hydrology
const energy::BedThermalUnit * bedrock_thermal_model() const
virtual void print_summary(bool tempAndAge, double dt)
void set_python_ocean_model(std::shared_ptr< ocean::PyOceanModel > model)
double m_dt
mass continuity time step, s
std::shared_ptr< energy::EnergyModel > m_energy_model
const std::shared_ptr< Grid > m_grid
Computational grid.
std::shared_ptr< bed::BedDef > m_beddef
virtual TimesteppingInfo max_timestep(unsigned int counter)
Use various stability criteria to determine the time step for an evolution run.
virtual void allocate_submodels()
Allocate PISM's sub-models implementing some physical processes.
array::Scalar2 m_basal_yield_stress
ghosted
void begin(const char *name) const
void end(const char *name) const
void stage_end(const char *name) const
void stage_begin(const char *name) const
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
The PISM basal yield stress model interface (virtual base class)
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void copy_from(const Array2D< T > &source)
void set_interpolation_type(InterpolationType type)
void scale(double alpha)
Result: v <- v * alpha. Calls VecScale.
void set(double c)
Result: v[j] <- c for all j.
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata object containing metadata for the compoment N.
bool next_to_ice(int i, int j) const
Ice-free margin (at least one of four neighbors has ice).
PISM bed deformation model (base class).
Given the temperature of the top of the bedrock, for the duration of one time-step,...
A very rudimentary PISM ocean model.
The class defining PISM's interface to the shallow stress balance code.
#define PISM_ERROR_LOCATION
@ PISM_READONLY
open an existing file for reading only
double get_time(MPI_Comm comm)
std::string printf(const char *format,...)
IceModelTerminationReason
std::string args_string()
Uses argc and argv to create the string with current PISM command-line arguments.
InputOptions process_input_options(MPI_Comm com, std::shared_ptr< const Config > config)
bool set_member(const std::string &string, const std::set< std::string > &set)
volatile sig_atomic_t pism_signal
void pism_signal_handler(int sig)
array::Scalar forced_retreat
ThicknessChanges(const std::shared_ptr< const Grid > &grid)
array::Scalar frontal_melt