22#include "pism/geometry/Geometry.hh"
24#include "pism/util/array/CellType.hh"
25#include "pism/util/Mask.hh"
26#include "pism/util/pism_utilities.hh"
27#include "pism/geometry/grounded_cell_fraction.hh"
28#include "pism/util/Context.hh"
29#include "pism/util/VariableMetadata.hh"
30#include "pism/util/io/File.hh"
31#include "pism/util/io/io_helpers.hh"
32#include "pism/util/io/IO_Flags.hh"
33#include "pism/util/Time.hh"
34#include "pism/util/io/SynchronousOutputWriter.hh"
41 : latitude(grid,
"lat"),
42 longitude(grid,
"lon"),
43 bed_elevation(grid,
"topg"),
44 sea_level_elevation(grid,
"sea_level"),
45 ice_thickness(grid,
"thk"),
46 ice_area_specific_volume(grid,
"ice_area_specific_volume"),
47 cell_type(grid,
"mask"),
48 cell_grounded_fraction(grid,
"cell_grounded_fraction"),
49 ice_surface_elevation(grid,
"usurf") {
53 .
units(
"degree_north")
73 .
long_name(
"sea level elevation above reference ellipsoid")
75 .
standard_name(
"sea_surface_height_above_reference_ellipsoid");
84 .
long_name(
"ice-volume-per-area in partially-filled grid cells")
87 "this variable represents the amount of ice in a partially-filled cell and not "
88 "the corresponding geometry, so thinking about it as 'thickness' is not helpful";
91 .
long_name(
"ice-type (ice-free/grounded/floating/ocean) integer mask")
96 "ice_free_bedrock grounded_ice floating_ice ice_free_ocean";
99 "fractional grounded/floating mask (floating=0, grounded=1)");
102 .
long_name(
"ice upper surface elevation")
118 auto config = grid->ctx()->config();
128 for (
auto p : grid->points()) {
129 const int i = p.i(), j = p.j();
133 "H = %e (negative) at point i=%d, j=%d",
155 for (
auto p : grid->points()) {
156 const int i = p.i(), j = p.j();
175 ice_density = config->get_number(
"constants.ice.density"),
176 ocean_density = config->get_number(
"constants.sea_water.density");
186 e.
add_context(
"computing the grounded cell fraction");
188 std::string output_file = config->get_string(
"output.file");
190 "_grounded_cell_fraction_failed",
"");
192 dump(o_file.c_str());
199 auto ctx = grid->ctx();
200 auto config = ctx->config();
203 auto writer = std::make_shared<SynchronousOutputWriter>(ctx->com(), *config);
204 writer->initialize({},
true);
208 auto time = grid->ctx()->time();
223 for (
const auto *v : variables) {
224 for (
const auto &var : v->all_metadata()) {
233 for (
const auto *v : variables) {
243 auto grid = result.
grid();
244 auto config = grid->ctx()->config();
247 ice_density = config->get_number(
"constants.ice.density"),
248 water_density = config->get_number(
"constants.sea_water.density"),
249 alpha = ice_density / water_density;
259 for (
auto p : grid->points()) {
260 const int i = p.i(), j = p.j();
263 b_grounded = bed_elevation(i, j),
264 b_floating = sea_level(i, j) - alpha * ice_thickness(i, j);
266 result(i, j) = std::max(b_grounded, b_floating);
279 auto config = grid->ctx()->config();
285 auto cell_area = grid->cell_area();
288 for (
auto p : grid->points()) {
289 const int i = p.i(), j = p.j();
298 if (config->get_flag(
"geometry.part_grid.enabled")) {
300 for (
auto p : grid->points()) {
301 const int i = p.i(), j = p.j();
311 double thickness_threshold) {
313 auto config = grid->ctx()->config();
316 sea_water_density = config->get_number(
"constants.sea_water.density"),
317 ice_density = config->get_number(
"constants.ice.density"),
318 cell_area = grid->cell_area();
325 for (
auto p : grid->points()) {
326 const int i = p.i(), j = p.j();
334 double max_floating_thickness =
335 std::max(sea_level - bed, 0.0) * (sea_water_density / ice_density);
336 volume += cell_area * (thickness - max_floating_thickness);
344 double cell_area = grid.cell_area();
347 for (
auto p : grid.points()) {
348 const int i = p.i(), j = p.j();
350 if (condition(i, j)) {
362 return geometry.ice_thickness(i, j) >= thickness_threshold;
370 return (geometry.cell_type.grounded(i, j) and
371 geometry.ice_thickness(i, j) >= thickness_threshold);
379 return (geometry.cell_type.ocean(i, j) and geometry.ice_thickness(i, j) >= thickness_threshold);
389 water_density = config->get_number(
"constants.fresh_water.density"),
390 ice_density = config->get_number(
"constants.ice.density"),
391 ocean_area = config->get_number(
"constants.global_ocean_area");
395 thickness_threshold),
396 additional_water_volume = (ice_density / water_density) * volume,
397 sea_level_change = additional_water_volume / ocean_area;
399 return sea_level_change;
415 for (
auto p : grid.points()) {
416 const int i = p.i(), j = p.j();
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
Describes the PISM grid and the distribution of data across processors.
void append_time(double time_seconds) const
void define_variable(const VariableMetadata &variable) const
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)
std::shared_ptr< const Grid > grid() const
void set(double c)
Result: v[j] <- c for all j.
void update_ghosts()
Updates ghost points.
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata object containing metadata for the compoment N.
Abstract class for reading, writing, allocating, and accessing a DA-based PETSc Vec (2D and 3D fields...
bool grounded(int i, int j) const
#define PISM_ERROR_LOCATION
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...
double ice_volume_not_displacing_seawater(const Geometry &geometry, double thickness_threshold)
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)
static double compute_area(const Grid &grid, std::function< bool(int, int)> condition)
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)