22#include "pism/icemodel/IceModel.hh"
23#include "pism/basalstrength/ConstantYieldStress.hh"
24#include "pism/basalstrength/MohrCoulombYieldStress.hh"
25#include "pism/basalstrength/OptTillphiYieldStress.hh"
26#include "pism/frontretreat/util/IcebergRemover.hh"
27#include "pism/frontretreat/util/IcebergRemoverFEM.hh"
28#include "pism/frontretreat/calving/CalvingAtThickness.hh"
29#include "pism/frontretreat/calving/EigenCalving.hh"
30#include "pism/frontretreat/calving/FloatKill.hh"
31#include "pism/frontretreat/calving/HayhurstCalving.hh"
32#include "pism/frontretreat/calving/vonMisesCalving.hh"
33#include "pism/energy/BedThermalUnit.hh"
34#include "pism/hydrology/NullTransport.hh"
35#include "pism/hydrology/Routing.hh"
36#include "pism/hydrology/SteadyState.hh"
37#include "pism/hydrology/Distributed.hh"
38#include "pism/stressbalance/StressBalance.hh"
39#include "pism/util/ConfigInterface.hh"
40#include "pism/util/Time.hh"
41#include "pism/util/error_handling.hh"
42#include "pism/util/io/File.hh"
43#include "pism/coupler/OceanModel.hh"
44#include "pism/coupler/SurfaceModel.hh"
45#include "pism/coupler/atmosphere/Factory.hh"
46#include "pism/coupler/ocean/Factory.hh"
47#include "pism/coupler/ocean/Initialization.hh"
48#include "pism/coupler/ocean/sea_level/Factory.hh"
49#include "pism/coupler/ocean/sea_level/Initialization.hh"
50#include "pism/coupler/surface/Factory.hh"
51#include "pism/coupler/surface/Initialization.hh"
52#include "pism/earth/LingleClark.hh"
53#include "pism/earth/BedDef.hh"
54#include "pism/earth/Given.hh"
55#include "pism/util/Vars.hh"
56#include "pism/util/projection.hh"
57#include "pism/util/pism_utilities.hh"
58#include "pism/age/AgeModel.hh"
59#include "pism/age/Isochrones.hh"
60#include "pism/energy/EnthalpyModel.hh"
61#include "pism/energy/TemperatureModel.hh"
62#include "pism/fracturedensity/FractureDensity.hh"
63#include "pism/frontretreat/FrontRetreat.hh"
64#include "pism/frontretreat/PrescribedRetreat.hh"
65#include "pism/coupler/frontalmelt/Factory.hh"
66#include "pism/coupler/util/options.hh"
67#include "pism/util/ScalarForcing.hh"
68#include "pism/stressbalance/ShallowStressBalance.hh"
69#include "pism/util/array/Forcing.hh"
77 bool use_calendar =
m_config->get_flag(
"output.runtime.time_use_calendar");
81 "* Run time: [%s, %s] (%s years, using the '%s' calendar)\n",
84 m_time->run_length().c_str(),
85 m_time->calendar().c_str());
87 std::string time_units =
m_config->get_string(
"output.runtime.time_unit_name");
90 start =
m_time->convert_time_interval(
m_time->start(), time_units),
91 end =
m_time->convert_time_interval(
m_time->end(), time_units),
95 "* Run time: [%f %s, %f %s] (%f %s)\n",
96 start, time_units.c_str(),
97 end, time_units.c_str(),
98 length, time_units.c_str());
130 std::unique_ptr<File> input_file;
132 if (use_input_file) {
139 if (use_input_file) {
140 std::string history = input_file->read_text_attribute(
"PISM_GLOBAL",
"history");
147 switch (input.
type) {
192 switch (input.
type) {
207 W_till.
set(
m_config->get_number(
"bootstrapping.defaults.tillwat"));
208 W.set(
m_config->get_number(
"bootstrapping.defaults.bwat"));
209 P.set(
m_config->get_number(
"bootstrapping.defaults.bwp"));
222 switch (input.
type) {
256 if (
m_btu !=
nullptr) {
275 switch (input.
type) {
288 m_btu->flux_through_top_surface());
300 m_btu->flux_through_top_surface());
317 for (
auto p =
m_grid->points(); p; p.next()) {
318 const int i = p.i(), j = p.j();
330 auto startstr =
pism::printf(
"PISM (%s) started on %d procs.",
331 pism::revision, (
int)
m_grid->size());
336 m_grid->forget_interpolations();
345 std::string filename = input_file.
name();
347 m_log->message(2,
"initializing 2D fields from NetCDF file '%s'...\n", filename.c_str());
350 variable->read(input_file, last_record);
356 m_log->message(2,
"bootstrapping from file '%s'...\n", input_file.
name().c_str());
358 auto usurf = input_file.
find_variable(
"usurf",
"surface_altitude");
366 m_log->message(2,
" WARNING: 'mask' found; IGNORING IT!\n");
370 m_log->message(2,
" WARNING: surface elevation 'usurf' found; IGNORING IT!\n");
373 m_log->message(2,
" reading 2D model state variables by regridding ...\n");
392 if (
m_config->get_flag(
"geometry.part_grid.enabled")) {
404 if (
m_config->get_flag(
"stress_balance.ssa.dirichlet_bc")) {
420 if (max_thickness >
m_grid->Lz()) {
422 "exceeds the height of the computational domain (%3.3f m).",
423 max_thickness,
m_grid->Lz());
436 auto filename =
m_config->get_string(
"input.regrid.file");
440 if (filename.empty()) {
444 m_log->message(2,
"regridding from file %s ...\n", filename.c_str());
449 if (regrid_vars.find(v->get_name()) != regrid_vars.end()) {
460 if (max_thickness >= Lz + 1e-6) {
462 "exceeds the height of the computational domain (%f meters).",
476 m_log->message(2,
"# Allocating a stress balance model...\n");
490 m_log->message(2,
"# Allocating the geometry evolution model...\n");
505 "# Allocating an iceberg remover (part of a calving model)...\n");
507 if (
m_config->get_flag(
"geometry.remove_icebergs")) {
509 auto model =
m_config->get_string(
"stress_balance.model");
510 auto ssa_method =
m_config->get_string(
"stress_balance.ssa.method");
512 if ((
member(model, {
"ssa",
"ssa+sia"}) and ssa_method ==
"fem") or
513 model ==
"blatter") {
529 if (
m_config->get_flag(
"age.enabled")) {
530 m_log->message(2,
"# Allocating an ice age model...\n");
534 "Cannot allocate an age model: m_stress_balance == nullptr.");
548 auto deposition_times =
m_config->get_string(
"isochrones.deposition_times");
549 if (not deposition_times.empty()) {
550 m_log->message(2,
"# Allocating isochrone tracking...\n");
555 "Cannot allocate the isochrone tracking model: m_stress_balance == nullptr.");
570 m_log->message(2,
"# Allocating an energy balance model...\n");
572 auto energy_model =
m_config->get_string(
"energy.model");
573 if (energy_model ==
"enthalpy") {
575 }
else if (energy_model ==
"cold") {
588 if (
m_btu !=
nullptr) {
592 m_log->message(2,
"# Allocating a bedrock thermal layer model...\n");
604 std::string hydrology_model =
m_config->get_string(
"hydrology.model");
610 m_log->message(2,
"# Allocating a subglacial hydrology model...\n");
612 if (hydrology_model ==
"null") {
614 }
else if (hydrology_model ==
"routing") {
616 }
else if (hydrology_model ==
"steady") {
618 }
else if (hydrology_model ==
"distributed") {
622 "unknown 'hydrology.model': %s", hydrology_model.c_str());
636 "# Allocating a basal yield stress model...\n");
638 std::string model =
m_config->get_string(
"stress_balance.model");
641 if (
member(model, {
"ssa",
"ssa+sia",
"blatter"})) {
642 std::string yield_stress_model =
m_config->get_string(
"basal_yield_stress.model");
644 if (yield_stress_model ==
"constant") {
646 }
else if (yield_stress_model ==
"mohr_coulomb") {
648 }
else if (yield_stress_model ==
"tillphi_opt") {
652 yield_stress_model.c_str());
690 if (
m_config->get_flag(
"fracture_density.enabled")) {
702 m_log->message(2,
"# Allocating a surface process model or coupler...\n");
712 m_log->message(2,
"# Allocating sea level forcing...\n");
714 using namespace ocean::sea_level;
722 m_log->message(2,
"# Allocating an ocean model or coupler...\n");
724 using namespace ocean;
735 m_log->message(3,
"Finishing initialization...\n");
746 if (source.empty()) {
748 "PISM WARNING: file '%s' does not have the 'source' global attribute.\n"
749 " If '%s' is a PISM output file, please run the following to get rid of this warning:\n"
750 " ncatted -a source,global,c,c,PISM %s\n",
752 }
else if (source.find(
"PISM") == std::string::npos) {
756 "PISM WARNING: '%s' does not seem to be a PISM output file.\n"
757 " If it is, please make sure that the 'source' global attribute contains the string \"PISM\".\n",
768 const long int two_to_thirty_two = 4294967296L;
773 std::string output_format =
m_config->get_string(
"output.format");
774 if (Mx * My * Mz *
sizeof(
double) > two_to_thirty_two - 4 and
777 "The computational grid is too big to fit in a NetCDF-3 file.\n"
778 "Each 3D variable requires %lu Mb.\n"
779 "Please use '-o_format pnetcdf or -o_format netcdf4_parallel to proceed.",
780 Mx * My * Mz *
sizeof(
double) / (1024 * 1024));
786#if (Pism_USE_PROJ==1)
788 std::string proj_string =
m_grid->get_mapping_info().proj_string;
789 if (not proj_string.empty()) {
807 std::vector<std::string> pik_methods;
808 if (
m_config->get_flag(
"geometry.part_grid.enabled")) {
809 pik_methods.push_back(
"part_grid");
811 if (
m_config->get_flag(
"geometry.remove_icebergs")) {
812 pik_methods.push_back(
"kill_icebergs");
815 if (not pik_methods.empty()) {
817 "* PISM-PIK mass/geometry methods are in use: %s\n",
818 join(pik_methods,
", ").c_str());
834 d.second->init(file, opts.
record);
866 if (not
m_config->get_flag(
"geometry.part_grid.enabled")) {
868 "ERROR: frontal melt models require geometry.part_grid.enabled");
884 auto front_retreat_file =
m_config->get_string(
"geometry.front_retreat.prescribed.file");
886 if (not front_retreat_file.empty()) {
898 std::set<std::string> methods =
set_split(
m_config->get_string(
"calving.methods"),
',');
899 bool allocate_front_retreat =
false;
901 if (
member(
"thickness_calving", methods)) {
908 methods.erase(
"thickness_calving");
914 if (
member(
"eigen_calving", methods)) {
915 allocate_front_retreat =
true;
922 methods.erase(
"eigen_calving");
927 if (
member(
"vonmises_calving", methods)) {
928 allocate_front_retreat =
true;
936 methods.erase(
"vonmises_calving");
941 if (
member(
"hayhurst_calving", methods)) {
942 allocate_front_retreat =
true;
949 methods.erase(
"hayhurst_calving");
954 if (
member(
"float_kill", methods)) {
960 methods.erase(
"float_kill");
965 if (not methods.empty()) {
967 "PISM ERROR: calving method(s) [%s] are not supported.\n",
977 auto filename =
m_config->get_string(
"calving.rate_scaling.file");
978 if (not filename.empty()) {
980 "calving.rate_scaling",
984 "calving rate scaling factor"));
995 "# Allocating a bed deformation model...\n");
997 std::string model =
m_config->get_string(
"bed_deformation.model");
999 if (model ==
"none") {
1002 else if (model ==
"iso") {
1005 else if (model ==
"lc") {
1008 else if (model ==
"given") {
1020 "Processing physics-related command-line options...\n");
1032 if (
m_config->get_number(
"time_stepping.maximum_time_step") <= 0) {
1036 if (not
m_config->get_flag(
"geometry.update.enabled") &&
1037 m_config->get_flag(
"time_stepping.skip.enabled")) {
1039 "PISM WARNING: Both -skip and -no_mass are set.\n"
1040 " -skip only makes sense in runs updating ice geometry.\n");
1043 if (
m_config->get_string(
"calving.methods").find(
"thickness_calving") != std::string::npos &&
1044 not
m_config->get_flag(
"geometry.part_grid.enabled")) {
1046 "PISM WARNING: Calving at certain terminal ice thickness (-calving thickness_calving)\n"
1047 " without application of partially filled grid cell scheme (-part_grid)\n"
1048 " may lead to (incorrect) non-moving ice shelf front.\n");
1055 std::string variables;
1057 if (keyword ==
"none" or
1058 keyword ==
"small") {
1060 }
else if (keyword ==
"medium") {
1061 variables =
m_config->get_string(
"output.sizes.medium");
1062 }
else if (keyword ==
"big_2d") {
1063 variables = (
m_config->get_string(
"output.sizes.medium") +
"," +
1064 m_config->get_string(
"output.sizes.big_2d"));
1065 }
else if (keyword ==
"big") {
1066 variables = (
m_config->get_string(
"output.sizes.medium") +
"," +
1067 m_config->get_string(
"output.sizes.big_2d") +
"," +
1068 m_config->get_string(
"output.sizes.big"));
1076 std::string projection =
m_grid->get_mapping_info().proj_string;
1078 const char *
compute_lon_lat =
"grid.recompute_longitude_and_latitude";
1081 m_log->message(2,
"* Computing longitude and latitude using projection parameters...\n");
1083#if (Pism_USE_PROJ==1)
1088 "Cannot compute longitude and latitude.\n"
1089 "Please rebuild PISM with PROJ\n"
1090 "or set '%s' to 'false'.",
VariableLookupData find_variable(const std::string &short_name, const std::string &std_name) const
Find a variable using its standard name and/or short name.
bool variable_exists(const std::string &short_name) const
Checks if a variable exists.
std::string read_text_attribute(const std::string &var_name, const std::string &att_name) const
Get a text attribute.
High-level PISM I/O class.
array::Scalar1 ice_area_specific_volume
array::Scalar2 ice_thickness
std::map< std::string, const Component * > m_submodels
the list of sub-models, for writing model states and obtaining diagnostics
void enforce_consistency_of_geometry(ConsistencyFlag flag)
Update the surface elevation and the flow-type mask when the geometry has changed.
virtual void allocate_bed_deformation()
virtual void model_state_setup()
Sets the starting values of model state variables.
void init_checkpoints()
Initialize checkpointing (snapshot-on-wallclock-time) mechanism.
std::shared_ptr< stressbalance::StressBalance > m_stress_balance
std::shared_ptr< Isochrones > m_isochrones
virtual void init_calving()
Initialize calving mechanisms.
std::shared_ptr< ocean::OceanModel > m_ocean
std::shared_ptr< surface::SurfaceModel > m_surface
virtual void compute_lat_lon()
std::shared_ptr< FractureDensity > m_fracture
virtual void bootstrap_2d(const File &input_file)
const Time::Ptr m_time
Time manager.
std::shared_ptr< YieldStress > m_basal_yield_stress_model
std::shared_ptr< calving::IcebergRemover > m_iceberg_remover
virtual void initialize_2d()
std::shared_ptr< Context > m_ctx
Execution context.
std::shared_ptr< frontalmelt::FrontalMelt > m_frontal_melt
void init_extras()
Initialize the code saving spatially-variable diagnostic quantities.
array::Scalar m_basal_melt_rate
rate of production of basal meltwater (ice-equivalent); no ghosts
virtual void misc_setup()
Miscellaneous initialization tasks plus tasks that need the fields that can come from regridding.
const Logger::Ptr m_log
Logger.
std::shared_ptr< array::Forcing > m_surface_input_for_hydrology
virtual void allocate_stressbalance()
Decide which stress balance model to use.
std::shared_ptr< calving::EigenCalving > m_eigen_calving
std::unique_ptr< ScalarForcing > m_calving_rate_factor
VariableMetadata m_output_global_attributes
stores global attributes saved in a PISM output file
const array::Scalar & frontal_melt() const
virtual void allocate_iceberg_remover()
std::vector< std::shared_ptr< array::Scalar2 > > m_work2d
virtual void process_options()
std::shared_ptr< calving::CalvingAtThickness > m_thickness_threshold_calving
std::shared_ptr< calving::FloatKill > m_float_kill_calving
virtual void allocate_subglacial_hydrology()
Decide which subglacial hydrology model to use.
std::shared_ptr< PrescribedRetreat > m_prescribed_retreat
array::Scalar2 m_velocity_bc_mask
mask to determine Dirichlet boundary locations for the sliding velocity
virtual void prepend_history(const std::string &string)
Get time and user/host name and add it to the given string.
std::shared_ptr< calving::HayhurstCalving > m_hayhurst_calving
virtual void allocate_basal_yield_stress()
Decide which basal yield stress model to use.
Config::Ptr m_config
Configuration flags and parameters.
std::unique_ptr< GeometryEvolution > m_geometry_evolution
virtual void allocate_energy_model()
virtual void restart_2d(const File &input_file, unsigned int record)
Initialize 2D model state fields managed by IceModel from a file (for re-starting).
virtual void time_setup()
Initialize time from an input file or command-line options.
std::shared_ptr< energy::BedThermalUnit > m_btu
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
virtual void init_front_retreat()
virtual void allocate_bedrock_thermal_unit()
Decide which bedrock thermal unit to use.
virtual std::set< std::string > output_variables(const std::string &keyword)
Assembles a list of diagnostics corresponding to an output file size.
virtual void regrid()
Manage regridding based on user options.
const units::System::Ptr m_sys
Unit system.
array::Vector2 m_velocity_bc_values
Dirichlet boundary velocities.
virtual void allocate_geometry_evolution()
std::map< std::string, Diagnostic::Ptr > m_diagnostics
Requested spatially-variable diagnostics.
void init_snapshots()
Initializes the snapshot-saving mechanism.
std::shared_ptr< ocean::sea_level::SeaLevel > m_sea_level
virtual void allocate_age_model()
virtual YieldStressInputs yield_stress_inputs()
virtual void init_diagnostics()
virtual void allocate_couplers()
std::unique_ptr< hydrology::Hydrology > m_subglacial_hydrology
std::shared_ptr< calving::vonMisesCalving > m_vonmises_calving
void init_timeseries()
Initializes the code writing scalar time-series.
std::set< std::string > m_output_vars
virtual void allocate_isochrones()
virtual void init_frontal_melt()
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 void allocate_submodels()
Allocate PISM's sub-models implementing some physical processes.
std::shared_ptr< FrontRetreat > m_front_retreat
array::Scalar2 m_basal_yield_stress
ghosted
virtual std::shared_ptr< Model > create()
Creates a boundary model. Processes command-line options.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void copy_from(const Array2D< T > &source)
void set(double c)
Result: v[j] <- c for all j.
void regrid(const std::string &filename, io::Default default_value)
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
int as_int(int i, int j) const
static std::shared_ptr< BedThermalUnit > FromOptions(std::shared_ptr< const Grid > g, std::shared_ptr< const Context > ctx)
The PISM subglacial hydrology model for a distributed linked-cavity system.
A subglacial hydrology model which assumes water pressure equals overburden pressure.
#define PISM_ERROR_LOCATION
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
Sub-glacial hydrology models and related diagnostics.
@ PISM_READONLY
open an existing file for reading only
std::shared_ptr< StressBalance > create(const std::string &model, std::shared_ptr< const Grid > grid, bool regional)
InputOptions process_input_options(MPI_Comm com, Config::ConstPtr config)
void compute_latitude(const std::string &projection, array::Scalar &result)
std::string set_join(const std::set< std::string > &input, const std::string &separator)
std::string printf(const char *format,...)
void compute_longitude(const std::string &projection, array::Scalar &result)
std::set< std::string > set_split(const std::string &input, char separator)
Transform a separator-separated list (a string) into a set of strings.
bool member(const std::string &string, const std::set< std::string > &set)
void set_config_from_options(units::System::Ptr unit_system, Config &config)
Set configuration parameters using command-line options.
std::string args_string()
Uses argc and argv to create the string with current PISM command-line arguments.
static void compute_lon_lat(const std::string &projection, LonLat which, array::Scalar &result)
std::string join(const std::vector< std::string > &strings, const std::string &separator)
Concatenate strings, inserting separator between elements.