20 #include "pism/geometry/Geometry.hh"
22 #include "pism/util/array/CellType.hh"
23 #include "pism/util/Mask.hh"
24 #include "pism/util/pism_utilities.hh"
25 #include "pism/geometry/grounded_cell_fraction.hh"
26 #include "pism/util/Context.hh"
27 #include "pism/util/VariableMetadata.hh"
28 #include "pism/util/io/File.hh"
29 #include "pism/util/io/io_helpers.hh"
30 #include "pism/util/io/IO_Flags.hh"
37 : latitude(grid,
"lat"),
38 longitude(grid,
"lon"),
39 bed_elevation(grid,
"topg"),
40 sea_level_elevation(grid,
"sea_level"),
41 ice_thickness(grid,
"thk"),
42 ice_area_specific_volume(grid,
"ice_area_specific_volume"),
43 cell_type(grid,
"mask"),
44 cell_grounded_fraction(grid,
"cell_grounded_fraction"),
45 ice_surface_elevation(grid,
"usurf") {
49 .
units(
"degree_north")
69 .
long_name(
"sea level elevation above reference ellipsoid")
71 .
standard_name(
"sea_surface_height_above_reference_ellipsoid");
80 .
long_name(
"ice-volume-per-area in partially-filled grid cells")
83 "this variable represents the amount of ice in a partially-filled cell and not "
84 "the corresponding geometry, so thinking about it as 'thickness' is not helpful";
87 .
long_name(
"ice-type (ice-free/grounded/floating/ocean) integer mask")
92 "ice_free_bedrock grounded_ice floating_ice ice_free_ocean";
95 "fractional grounded/floating mask (floating=0, grounded=1)");
124 for (
auto p = grid->points(); p; p.next()) {
125 const int i = p.i(), j = p.j();
129 "H = %e (negative) at point i=%d, j=%d",
151 for (
auto p = grid->points(); p; p.next()) {
152 const int i = p.i(), j = p.j();
171 ice_density = config->get_number(
"constants.ice.density"),
172 ocean_density = config->get_number(
"constants.sea_water.density");
182 e.
add_context(
"computing the grounded cell fraction");
184 std::string output_file = config->get_string(
"output.file");
186 "_grounded_cell_fraction_failed",
"");
188 dump(o_file.c_str());
196 File file(grid->com, filename,
199 grid->ctx()->pio_iosys_id());
219 auto grid = result.
grid();
220 auto config = grid->ctx()->config();
223 ice_density = config->get_number(
"constants.ice.density"),
224 water_density = config->get_number(
"constants.sea_water.density"),
225 alpha = ice_density / water_density;
235 for (
auto p = grid->points(); p; p.next()) {
236 const int i = p.i(), j = p.j();
239 b_grounded = bed_elevation(i, j),
240 b_floating = sea_level(i, j) - alpha * ice_thickness(i, j);
242 result(i, j) =
std::max(b_grounded, b_floating);
255 auto config = grid->ctx()->config();
261 auto cell_area = grid->cell_area();
264 for (
auto p = grid->points(); p; p.next()) {
265 const int i = p.i(), j = p.j();
274 if (config->get_flag(
"geometry.part_grid.enabled")) {
276 for (
auto p = grid->points(); p; p.next()) {
277 const int i = p.i(), j = p.j();
287 double thickness_threshold) {
289 auto config = grid->ctx()->config();
292 sea_water_density = config->get_number(
"constants.sea_water.density"),
293 ice_density = config->get_number(
"constants.ice.density"),
294 cell_area = grid->cell_area();
301 for (
auto p = grid->points(); p; p.next()) {
302 const int i = p.i(), j = p.j();
310 const double cell_ice_volume = thickness * cell_area;
311 if (bed > sea_level) {
312 volume += cell_ice_volume;
314 const double max_floating_volume = (sea_level - bed) * cell_area * (sea_water_density / ice_density);
315 volume += cell_ice_volume - max_floating_volume;
329 auto cell_area = grid->cell_area();
332 for (
auto p = grid->points(); p; p.next()) {
333 const int i = p.i(), j = p.j();
349 auto cell_area = grid->cell_area();
352 for (
auto p = grid->points(); p; p.next()) {
353 const int i = p.i(), j = p.j();
370 auto cell_area = grid->cell_area();
373 for (
auto p = grid->points(); p; p.next()) {
374 const int i = p.i(), j = p.j();
391 water_density = config->get_number(
"constants.fresh_water.density"),
392 ice_density = config->get_number(
"constants.ice.density"),
393 ocean_area = config->get_number(
"constants.global_ocean_area");
397 thickness_threshold),
398 additional_water_volume = (ice_density / water_density) * volume,
399 sea_level_change = additional_water_volume / ocean_area;
401 return sea_level_change;
418 const int i = p.i(), j = p.j();
std::shared_ptr< const Config > ConstPtr
High-level PISM I/O class.
void set_icefree_thickness(double threshold)
void compute(const array::Scalar &sea_level, const array::Scalar &bed, const array::Scalar &thickness, array::Scalar &out_mask, array::Scalar &out_surface) const
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
void dump(const char *filename) const
array::Scalar2 ice_thickness
Geometry(const std::shared_ptr< const Grid > &grid)
array::Scalar2 bed_elevation
PointsWithGhosts points(unsigned int stencil_width=0) const
Describes the PISM grid and the distribution of data across processors.
void failed()
Indicates a failure of a parallel section.
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
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void add(double alpha, const Array2D< T > &x)
void write(const std::string &filename) const
std::shared_ptr< const Grid > grid() const
void set(double c)
Result: v[j] <- c for all j.
void update_ghosts()
Updates ghost points.
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
bool ocean(int i, int j) const
bool grounded(int i, int j) const
#define PISM_ERROR_LOCATION
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
bool in_null_strip(const Grid &grid, int i, int j, double strip_width)
Check if a point (i,j) is in the strip of stripwidth meters around the edge of the computational doma...
void append_time(const File &file, const Config &config, double time_seconds)
Prepare a file for output.
@ PISM_READWRITE_CLOBBER
create a file for writing, overwrite if present
void define_time(const File &file, const Context &ctx)
Prepare a file for output.
double ice_volume_not_displacing_seawater(const Geometry &geometry, double thickness_threshold)
io::Backend string_to_backend(const std::string &backend)
double ice_area(const Geometry &geometry, double thickness_threshold)
Computes ice area, in m^2.
void set_no_model_strip(const Grid &grid, double width, array::Scalar &result)
Set no_model_mask variable to have value 1 in strip of width 'strip' m around edge of computational d...
void compute_grounded_cell_fraction(double ice_density, double ocean_density, const array::Scalar1 &sea_level, const array::Scalar1 &ice_thickness, const array::Scalar1 &bed_topography, array::Scalar &result)
double ice_area_floating(const Geometry &geometry, double thickness_threshold)
Computes floating ice area, in m^2.
double sea_level_rise_potential(const Geometry &geometry, double thickness_threshold)
Computes the sea level rise that would result if all the ice were melted.
std::string filename_add_suffix(const std::string &filename, const std::string &separator, const std::string &suffix)
Adds a suffix to a filename.
double ice_volume(const Geometry &geometry, double thickness_threshold)
Computes the ice volume, in m^3.
void ice_bottom_surface(const Geometry &geometry, array::Scalar &result)
double ice_area_grounded(const Geometry &geometry, double thickness_threshold)
Computes grounded ice area, in m^2.
void GlobalSum(MPI_Comm comm, double *local, double *result, int count)