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);
158 int year_increment =
static_cast<int>(
m_config->get_number(
"time_stepping.hit_multiples"));
160 if (year_increment > 0) {
164 int last_multiple = year - year % year_increment;
167 last_multiple -= year_increment *
static_cast<int>(year % year_increment < 0);
204 if (
m_config->get_flag(
"geometry.grounded_cell_fraction")) {
208 if (
m_config->get_flag(
"geometry.part_grid.enabled")) {
216 .
long_name(
"yield stress for basal till (plastic or pseudo-plastic model)")
223 .
long_name(
"temperature at the top surface of the bedrock thermal layer")
230 "ice basal melt rate from energy conservation and subshelf melt, in ice thickness per time")
240 .
long_name(
"Mask prescribing Dirichlet boundary locations for the sliding velocity")
250 double fill_value =
m_config->get_number(
"output.fill_value");
251 const double huge_value = 1e6;
254 "X-component of the SSA velocity boundary conditions");
256 "Y-component of the SSA velocity boundary conditions");
257 for (
int j : { 0, 1 }) {
267 .
long_name(
"Mask specifying locations where ice thickness is held constant")
325 for (
auto p :
m_grid->points()) {
326 const int i = p.i(), j = p.j();
338 if (
m_config->get_flag(
"geometry.update.use_basal_melt_rate")) {
350 if (
m_config->get_flag(
"stress_balance.ssa.dirichlet_bc")) {
355 if (
m_config->get_flag(
"fracture_density.enabled")) {
405 double current_time =
m_time->current();
428 m_ocean->shelf_base_mass_flux(),
434 profiling.
begin(
"stress_balance");
436 profiling.
end(
"stress_balance");
440 e.
add_context(
"performing a time step. (Note: Model state was saved to '%s'.)",
441 output_file.c_str());
452 double dt = dt_info.dt;
459 profiling.
begin(
"basal_yield_stress");
461 profiling.
end(
"basal_yield_stress");
478 profiling.
begin(
"age");
480 profiling.
end(
"age");
490 profiling.
begin(
"energy");
492 profiling.
end(
"energy");
499 if (
m_config->get_flag(
"fracture_density.enabled")) {
500 profiling.
begin(
"fracture_density");
502 profiling.
end(
"fracture_density");
508 if (do_mass_continuity) {
512 profiling.
begin(
"mass_transport");
538 {
"flux_staggered",
"flux_divergence"});
540 e.
add_context(
"performing a mass transport time step (dt=%f s). (Note: Model state was saved to '%s'.)",
541 dt, output_file.c_str());
549 profiling.
end(
"mass_transport");
552 profiling.
begin(
"front_retreat");
554 profiling.
end(
"front_retreat");
561 profiling.
begin(
"sea_level");
563 profiling.
end(
"sea_level");
565 profiling.
begin(
"ocean");
569 m_ocean->update(inputs, current_time,
dt);
571 profiling.
end(
"ocean");
578 profiling.
begin(
"surface");
580 profiling.
end(
"surface");
583 if (do_mass_continuity) {
604 bool add_values =
true;
624 profiling.
begin(
"basal_hydrology");
626 profiling.
end(
"basal_hydrology");
631 int topg_state_counter =
m_beddef->bed_elevation().state_counter();
633 profiling.
begin(
"bed_deformation");
637 profiling.
end(
"bed_deformation");
644 if (
m_config->get_flag(
"time_stepping.assume_bed_elevation_changed")) {
672 "Ice thickness exceeds the height of the computational box (%7.4f m).\n"
673 "The model state was saved to '%s'. To continue this simulation,\n"
675 "-i %s -bootstrap -regrid_file %s -allow_extrapolation -Lz N [other options]\n"
677 m_grid->Lz(), o_file.c_str(), o_file.c_str(), o_file.c_str(),
m_grid->Lz());
705 }
else if (
m_config->get_flag(
"hydrology.surface_input_from_runoff")) {
709 surface_input_rate.
scale(1.0 /
dt);
753 bool do_mass_conserve =
m_config->get_flag(
"geometry.update.enabled");
754 bool do_energy =
set_member(
m_config->get_string(
"energy.model"), {
"cold",
"enthalpy"});
755 bool do_skip =
m_config->get_flag(
"time_stepping.skip.enabled");
768 const double time =
m_time->current();
770 d.second->update(time, time);
774 m_log->message(2,
"running forward ...\n");
792 m_dt =
step(do_mass_conserve, do_skip);
798 bool tempAgeStep = updateAtDepth and (
m_age_model or do_energy);
800 double time_resolution =
m_config->get_number(
"time_stepping.resolution");
801 const bool show_step = tempAgeStep or fabs(
m_time->current() -
m_time->end()) < time_resolution;
808 profiling.
begin(
"io");
814 if (stop_after_chekpoint) {
824 profiling.
stage_end(
"time-stepping loop");
826 return termination_reason;
843 profiling.
begin(
"initialization");
849 if (not
m_config->get_flag(
"geometry.update.enabled") &&
850 m_config->get_flag(
"time_stepping.skip.enabled")) {
852 "PISM WARNING: time_stepping.skip.enabled is 'true' and\n"
853 " geometry.update.enabled is 'false'\n"
854 " skipping time steps makes sense only with evolving geometry.\n");
860 bool use_calendar =
m_config->get_flag(
"output.runtime.time_use_calendar");
863 m_log->message(2,
"* Run time: [%s, %s] (%s years, using the '%s' calendar)\n",
865 m_time->run_length().c_str(),
m_time->calendar().c_str());
867 std::string time_units =
m_config->get_string(
"output.runtime.time_unit_name");
869 double start =
m_time->convert_time_interval(
m_time->start(), time_units),
870 end =
m_time->convert_time_interval(
m_time->end(), time_units), length = end - start;
872 m_log->message(2,
"* Run time: [%f %s, %f %s] (%f %s)\n", start, time_units.c_str(), end,
873 time_units.c_str(), length, time_units.c_str());
889 m_log->message(2,
"Computational domain and grid:\n");
890 m_grid->report_parameters();
897 profiling.
end(
"initialization");
954 : calving(grid,
"thickness_change_due_to_calving"),
955 frontal_melt(grid,
"thickness_change_due_to_frontal_melt"),
956 forced_retreat(grid,
"thickness_change_due_to_forced_retreat") {
961 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
bool yac_component_defined(const std::string &name)
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