Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pism.cc
Go to the documentation of this file.
1// Copyright (C) 2004--2025 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 "util/io/IO_Flags.hh"
20static char help[] =
21 "Ice sheet driver for PISM ice sheet simulations, initialized from data.\n"
22 "The basic PISM executable for evolution runs.\n";
23
24#include <memory>
25#include <petscsys.h> // PETSC_COMM_WORLD
26
27#include "pism/icemodel/IceModel.hh"
28#include "pism/icemodel/IceEISModel.hh"
29#include "pism/verification/iceCompModel.hh"
30#include "pism/util/Config.hh"
31#include "pism/util/Grid.hh"
32
33#include "pism/util/Context.hh"
34#include "pism/util/Profiling.hh"
35#include "pism/util/error_handling.hh"
36#include "pism/util/petscwrappers/PetscInitializer.hh"
37#include "pism/util/pism_options.hh"
38#include "pism/util/EnthalpyConverter.hh"
39
40#include "pism/regional/IceRegionalModel.hh"
41
42using namespace pism;
43
44namespace eismint2 {
45
46static void set_config_defaults(Config &config) {
47 config.set_number("grid.Lx", 750); // in km
48 config.set_number("grid.Ly", 750); // in km
49 config.set_string("grid.periodicity", "none");
50 config.set_string("grid.registration", "corner");
51 config.set_string("stress_balance.sia.flow_law", "pb");
52
53 config.set_string("energy.model", "cold");
54
55 // Set sea level elevation to -1e4 meters to remove ocean interaction
56 config.set_number("sea_level.constant.value", -1e4);
57
58 // purely SIA, and E=1
59 config.set_number("stress_balance.sia.enhancement_factor", 1.0);
60
61 // none use bed smoothing & bed roughness parameterization
62 config.set_number("stress_balance.sia.bed_smoother.range", 0.0);
63
64 // basal melt does not change computation of mass continuity or vertical velocity:
65 config.set_flag("geometry.update.use_basal_melt_rate", false);
66
67 // Make bedrock thermal material properties into ice properties. Note that
68 // zero thickness bedrock layer is the default, but we want the ice/rock
69 // interface segment to have geothermal flux applied directly to ice without
70 // jump in material properties at base.
71 config.set_number("energy.bedrock_thermal.density",
72 config.get_number("constants.ice.density"));
73 config.set_number("energy.bedrock_thermal.conductivity",
74 config.get_number("constants.ice.thermal_conductivity"));
75 config.set_number("energy.bedrock_thermal.specific_heat_capacity",
76 config.get_number("constants.ice.specific_heat_capacity"));
77
78 // no sliding + SIA
79 config.set_string("stress_balance.model", "sia");
80}
81} // namespace eismint2
82
83namespace verification {
84
85//! Allocate the verification mode context. Uses ColdEnthalpyConverter.
86std::shared_ptr<Context> context(MPI_Comm com, const std::string &prefix) {
87 // unit system
88 auto sys = std::make_shared<units::System>();
89
90 // logger
91 auto logger = logger_from_options(com);
92
93 // configuration parameters
94 auto config = config_from_options(com, *logger, sys);
95
96 config->set_string("grid.periodicity", "none");
97 config->set_string("grid.registration", "corner");
98
99 set_config_from_options(sys, *config);
100 config->resolve_filenames();
101
102 print_config(*logger, 3, *config);
103
104 auto time = std::make_shared<Time>(com, config, *logger, sys);
105
106 auto EC = std::make_shared<ColdEnthalpyConverter>(*config);
107
108 return std::make_shared<Context>(com, sys, config, EC, time, logger, prefix);
109}
110
112 // This sets the defaults for each test; command-line options can override this.
113
114 int Mx = 61, My = 61;
115 double Lx = 1e3, Ly = 1e3;
116 grid::Parameters P(*config, Mx, My, Lx, Ly);
117
118 // use the cell corner grid registration
120 // use the non-periodic grid:
122
123 // equal spacing is the default for all the tests except K
124 auto spacing = pism::grid::EQUAL;
125 double Lz = config->get_number("grid.Lz");
126 unsigned int Mz = config->get_number("grid.Mz");
127
128 switch (testname) {
129 case 'A':
130 case 'B':
131 case 'H':
132 // use 2400km by 2400km by 4000m rectangular domain
133 P.Lx = 1200e3;
134 P.Ly = P.Lx;
135 Lz = 4000;
136 break;
137 case 'C':
138 case 'D':
139 // use 2000km by 2000km by 4000m rectangular domain
140 P.Lx = 1000e3;
141 P.Ly = P.Lx;
142 Lz = 4000;
143 break;
144 case 'F':
145 case 'G':
146 case 'L':
147 // use 1800km by 1800km by 4000m rectangular domain
148 P.Lx = 900e3;
149 P.Ly = P.Lx;
150 Lz = 4000;
151 break;
152 case 'K':
153 case 'O':
154 // use 2000km by 2000km by 4000m rectangular domain, but make truely periodic
155 config->set_number("grid.Mbz", 2);
156 config->set_number("grid.Lbz", 1000);
157 P.Lx = 1000e3;
158 P.Ly = P.Lx;
159 Lz = 4000;
161 spacing = pism::grid::QUADRATIC;
162 break;
163 case 'V':
164 P.My = 3; // it's a flow-line setup
165 P.Lx = 500e3; // 500 km long
167 break;
168 default:
169 throw RuntimeError(PISM_ERROR_LOCATION, "desired test not implemented\n");
170 }
171
172 P.z = grid::compute_vertical_levels(Lz, Mz, spacing, config->get_number("grid.lambda"));
173 return P;
174}
175
176std::shared_ptr<Grid> grid(std::shared_ptr<Context> ctx, char testname) {
177 auto config = ctx->config();
178
179 auto input_file_name = config->get_string("input.file");
180
181 if (config->get_flag("input.bootstrap")) {
182 throw RuntimeError(PISM_ERROR_LOCATION, "PISM does not support bootstrapping in verification mode");
183 }
184
185 if (not input_file_name.empty()) {
186 auto r = grid::string_to_registration(config->get_string("grid.registration"));
187
188
189 File input_file(ctx->com(), input_file_name, pism::io::PISM_NETCDF3, pism::io::PISM_READONLY);
190 // get grid from a PISM input file
191 return Grid::FromFile(ctx, input_file, { "enthalpy", "temp" }, r);
192 }
193
194 // use defaults set by grid_defaults()
195 auto P = grid_defaults(config, testname);
196
197 P.horizontal_size_and_extent_from_options(*config);
198 P.vertical_grid_from_options(*config);
199 P.ownership_ranges_from_options(*config, ctx->size());
200
201 return std::make_shared<Grid>(ctx, P);
202}
203} // namespace verification
204
205int main(int argc, char *argv[]) {
206
207 MPI_Comm com = MPI_COMM_WORLD;
208 petsc::Initializer petsc(argc, argv, help);
209
210 com = PETSC_COMM_WORLD;
211
212 int exit_code = 0;
213 try {
214 // Note: EISMINT II experiments G and H are not supported.
215 auto eisII = options::Keyword("-eisII",
216 "EISMINT II experiment name",
217 "A,B,C,D,E,F,I,J,K,L", "A");
218
219 auto verification_test =
220 options::Keyword("-test", "Specifies PISM verification test", "A,B,C,D,F,G,H,K,L,V", "A");
221
222 if (eisII.is_set() and verification_test.is_set()) {
223 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "please set -test or -eisII (not both)");
224 }
225
226 std::shared_ptr<Context> ctx;
227 if (verification_test.is_set()) {
228 ctx = verification::context(com, "pism");
229 } else {
230 ctx = context_from_options(com, "pism", false);
231 }
232
233 Logger::Ptr log = ctx->log();
234 Config::Ptr config = ctx->config();
235
236 std::vector<std::string> required_options{};
237 if (eisII.is_set()) {
238 // set defaults:
240
241 // process -config_override
242 DefaultConfig::Ptr overrides(new DefaultConfig(com,
243 "pism_overrides",
244 "-config_override",
245 ctx->unit_system()));
246 overrides->init(*ctx->log());
247 config->import_from(*overrides);
248 // process command-line options
249 set_config_from_options(ctx->unit_system(), *config);
250 config->resolve_filenames();
251 } else if (not verification_test.is_set()) {
252 required_options.emplace_back("-i");
253 }
254
255 print_config(*ctx->log(), 3, *config);
256
257 std::string usage =
258 " pism -i IN.nc [-bootstrap] [-regional] [OTHER PISM & PETSc OPTIONS]\n"
259 "where:\n"
260 " -i IN.nc is input file in NetCDF format: contains PISM-written model state\n"
261 " -bootstrap enable heuristics to produce an initial state from an incomplete input\n"
262 " -regional enable \"regional mode\"\n"
263 " -eisII [experiment] enable EISMINT II mode\n"
264 " -test [verification_test] enable verification mode\n"
265 "notes:\n"
266 " * option -i is required\n"
267 " * if -bootstrap is used then also '-Mx A -My B -Mz C -Lz D' are required\n";
268 {
269 bool done = show_usage_check_req_opts(*log, "PISM (basic evolution run mode)" ,
270 required_options, usage);
271 if (done) {
272 return 0;
273 }
274 }
275
276 options::String profiling_log = options::String("-profile",
277 "Save detailed profiling data to a file.");
278
279 if (profiling_log.is_set()) {
280 ctx->profiling().start();
281 }
282
283 std::shared_ptr<Grid> grid;
284 std::shared_ptr<IceModel> model;
285 std::shared_ptr<IceCompModel> verification_model;
286
287 if (verification_test.is_set()) {
288 char test = verification_test.value()[0];
289 grid = verification::grid(ctx, test);
290
291 verification_model = std::make_shared<IceCompModel>(grid, ctx, test);
292 model = verification_model;
293 } else {
294 grid = Grid::FromOptions(ctx);
295
296 if (options::Bool("-regional", "enable regional (outlet glacier) mode")) {
297 model = std::make_shared<IceRegionalModel>(grid, ctx);
298 } else if (eisII.is_set()) {
299 char experiment = eisII.value()[0];
300
301 model = std::make_shared<IceEISModel>(grid, ctx, experiment);
302 } else {
303 model = std::make_shared<IceModel>(grid, ctx);
304 }
305 }
306
307 model->init();
308
309 auto list_type = options::Keyword("-list_diagnostics",
310 "List available diagnostic quantities and stop.",
311 "all,spatial,scalar,json",
312 "all");
313
314 if (list_type.is_set()) {
315 model->list_diagnostics(list_type);
316 } else {
317 auto termination_reason = model->run();
318
319 switch (termination_reason) {
320 case PISM_CHEKPOINT:
321 {
322 exit_code = static_cast<int>(config->get_number("output.checkpoint.exit_code"));
323 log->message(2, "... stopping (exit_code=%d) after saving the checkpoint file\n",
324 exit_code);
325 break;
326 }
327 case PISM_SIGNAL:
328 {
329 exit_code = 0;
330 break;
331 }
332 case PISM_DONE:
333 {
334 log->message(2, "... done with the run\n");
335 model->save_results();
336 exit_code = 0;
337
338 if (verification_model and
339 not options::Bool("-no_report", "do not print the error report")) {
340 verification_model->reportErrors();
341 }
342 break;
343 }
344 }
345 }
346 print_unused_parameters(*log, 3, *config);
347
348 if (profiling_log.is_set()) {
349 ctx->profiling().report(profiling_log);
350 }
351 }
352 catch (...) {
354 exit_code = 1;
355 }
356
357 return exit_code;
358}
std::shared_ptr< Config > Ptr
void set_string(const std::string &name, const std::string &value, ConfigSettingFlag flag=CONFIG_FORCE)
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
void set_flag(const std::string &name, bool value, ConfigSettingFlag flag=CONFIG_FORCE)
void set_number(const std::string &name, double value, ConfigSettingFlag flag=CONFIG_FORCE)
A class for storing and accessing PISM configuration flags and parameters.
std::shared_ptr< DefaultConfig > Ptr
Definition Config.hh:80
Default PISM configuration database: uses NetCDF files; can be initialized from a file specified usin...
Definition Config.hh:72
High-level PISM I/O class.
Definition File.hh:55
static std::shared_ptr< Grid > FromFile(std::shared_ptr< const Context > ctx, const File &file, const std::vector< std::string > &var_names, grid::Registration r)
Create a grid using one of variables in var_names in file.
Definition Grid.cc:250
static std::shared_ptr< Grid > FromOptions(std::shared_ptr< const Context > ctx)
Create a grid using command-line options and (possibly) an input file.
Definition Grid.cc:1441
std::shared_ptr< Logger > Ptr
Definition Logger.hh:45
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
Periodicity periodicity
Grid periodicity.
Definition Grid.hh:163
std::vector< double > z
Vertical levels.
Definition Grid.hh:165
Registration registration
Grid registration.
Definition Grid.hh:161
double Ly
Domain half-width in the Y direction.
Definition Grid.hh:151
double Lx
Domain half-width in the X direction.
Definition Grid.hh:149
unsigned int My
Number of grid points in the Y direction.
Definition Grid.hh:159
Grid parameters; used to collect defaults before an Grid is allocated.
Definition Grid.hh:123
bool is_set() const
Definition options.hh:35
#define PISM_ERROR_LOCATION
static void set_config_defaults(Config &config)
Definition pism.cc:46
@ EQUAL
Definition Grid.hh:53
@ QUADRATIC
Definition Grid.hh:53
@ XY_PERIODIC
Definition Grid.hh:54
@ Y_PERIODIC
Definition Grid.hh:54
@ NOT_PERIODIC
Definition Grid.hh:54
Registration string_to_registration(const std::string &keyword)
Definition Grid.cc:844
@ CELL_CORNER
Definition Grid.hh:56
std::vector< double > compute_vertical_levels(double new_Lz, size_t new_Mz, grid::VerticalSpacing spacing, double lambda)
Set the vertical levels in the ice according to values in Mz (number of levels), Lz (domain height),...
Definition Grid.cc:737
@ PISM_NETCDF3
Definition IO_Flags.hh:57
@ PISM_READONLY
open an existing file for reading only
Definition IO_Flags.hh:68
bool Bool(const std::string &option, const std::string &description)
Definition options.cc:190
std::shared_ptr< Context > context_from_options(MPI_Comm com, const std::string &prefix, bool print)
Create a default context using options.
Definition Context.cc:121
Logger::Ptr logger_from_options(MPI_Comm com)
Definition Logger.cc:107
Config::Ptr config_from_options(MPI_Comm com, const Logger &log, units::System::Ptr unit_system)
Create a configuration database using command-line options.
@ PISM_SIGNAL
Definition IceModel.hh:114
@ PISM_DONE
Definition IceModel.hh:114
@ PISM_CHEKPOINT
Definition IceModel.hh:114
void handle_fatal_errors(MPI_Comm com)
void set_config_from_options(units::System::Ptr unit_system, Config &config)
Set configuration parameters using command-line options.
bool show_usage_check_req_opts(const Logger &log, const std::string &execname, const std::vector< std::string > &required_options, const std::string &usage)
In a single call a driver program can provide a usage string to the user and check if required option...
void print_unused_parameters(const Logger &log, int verbosity_threshhold, const Config &config)
Report unused configuration parameters to stdout.
void print_config(const Logger &log, int verbosity_threshhold, const Config &config)
Report configuration parameters to stdout.
std::shared_ptr< Context > context(MPI_Comm com, const std::string &prefix)
Allocate the verification mode context. Uses ColdEnthalpyConverter.
Definition pism.cc:86
std::shared_ptr< Grid > grid(std::shared_ptr< Context > ctx, char testname)
Definition pism.cc:176
grid::Parameters grid_defaults(Config::Ptr config, char testname)
Definition pism.cc:111
int main(int argc, char *argv[])
Definition pism.cc:205
static char help[]
Definition pism.cc:20