21 #include <gsl/gsl_math.h>
24 #include "pism/coupler/SurfaceModel.hh"
25 #include "pism/coupler/AtmosphereModel.hh"
26 #include "pism/util/io/File.hh"
27 #include "pism/util/Grid.hh"
28 #include "pism/util/MaxTimestep.hh"
29 #include "pism/util/pism_utilities.hh"
30 #include "pism/util/Context.hh"
36 auto result = std::make_shared<array::Scalar>(
grid,
"surface_layer_mass");
39 .long_name(
"mass held in the surface layer")
42 result->metadata()[
"valid_min"] = { 0.0 };
49 auto result = std::make_shared<array::Scalar>(
grid,
"surface_layer_thickness");
52 .long_name(
"thickness of the surface process layer at the top surface of the ice")
55 result->metadata()[
"valid_min"] = { 0.0 };
62 auto result = std::make_shared<array::Scalar>(
grid,
"ice_surface_liquid_water_fraction");
65 .long_name(
"liquid water fraction of the ice at the top surface")
68 result->metadata()[
"valid_range"] = { 0.0, 1.0 };
75 auto result = std::make_shared<array::Scalar>(
grid,
"climatic_mass_balance");
78 .long_name(
"surface mass balance (accumulation/ablation) rate")
79 .units(
"kg m-2 second-1")
80 .output_units(
"kg m-2 year-1")
81 .standard_name(
"land_ice_surface_specific_mass_balance_flux");
83 auto config =
grid->ctx()->config();
84 const double smb_max = config->get_number(
"surface.given.smb_max",
"kg m-2 second-1");
86 result->metadata()[
"valid_range"] = { -smb_max, smb_max };
91 std::shared_ptr<array::Scalar>
94 auto result = std::make_shared<array::Scalar>(
grid,
"ice_surface_temp");
97 .long_name(
"temperature of the ice at the ice surface but below firn processes")
100 result->metadata()[
"valid_range"] = { 0.0, 323.15 };
105 std::shared_ptr<array::Scalar>
108 auto result = std::make_shared<array::Scalar>(
grid,
"surface_accumulation_flux");
110 result->metadata(0).long_name(
"surface accumulation (precipitation minus rain)").units(
"kg m-2");
117 auto result = std::make_shared<array::Scalar>(
grid,
"surface_melt_flux");
119 result->metadata(0).long_name(
"surface melt").units(
"kg m-2");
126 auto result = std::make_shared<array::Scalar>(
grid,
"surface_runoff_flux");
128 result->metadata(0).long_name(
"surface meltwater runoff").units(
"kg m-2");
159 std::shared_ptr<atmosphere::AtmosphereModel> atmosphere)
364 for (
auto p =
m_grid->points(); p; p.next()) {
365 const int i = p.i(), j = p.j();
366 result(i,j) =
std::max(smb(i,j), 0.0);
384 for (
auto p =
m_grid->points(); p; p.next()) {
385 const int i = p.i(), j = p.j();
386 result(i,j) =
std::max(-smb(i,j), 0.0);
403 namespace diagnostics {
458 .long_name(
"surface mass balance (accumulation/ablation) rate")
459 .standard_name(
"land_ice_surface_specific_mass_balance_flux")
460 .units(
"kg m-2 second-1")
461 .output_units(
"kg m-2 year-1");
465 auto result = allocate<array::Scalar>(
"climatic_mass_balance");
467 result->copy_from(
model->mass_flux());
474 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
476 m_vars = { {
m_sys, ismip6 ?
"litemptop" :
"ice_surface_temp" } };
478 .long_name(
"ice temperature at the top ice surface")
479 .standard_name(
"temperature_at_top_of_ice_sheet_model")
484 auto result = allocate<array::Scalar>(
"ice_surface_temp");
486 result->copy_from(
model->temperature());
492 m_vars = { {
m_sys,
"ice_surface_liquid_water_fraction" } };
493 m_vars[0].long_name(
"ice liquid water fraction at the ice surface").units(
"1");
498 auto result = allocate<array::Scalar>(
"ice_surface_liquid_water_fraction");
500 result->copy_from(
model->liquid_water_fraction());
507 m_vars[0].long_name(
"mass of the surface layer (snow and firn)").units(
"kg");
512 auto result = allocate<array::Scalar>(
"surface_layer_mass");
514 result->copy_from(
model->layer_mass());
521 m_vars[0].long_name(
"thickness of the surface layer (snow and firn)").units(
"meters");
526 auto result = allocate<array::Scalar>(
"surface_layer_thickness");
528 result->copy_from(
model->layer_thickness());
542 ?
"surface_melt_flux"
543 :
"surface_melt_rate",
550 name =
"surface_melt_flux",
551 long_name =
"surface melt, averaged over the reporting interval",
552 standard_name =
"surface_snow_and_ice_melt_flux",
553 accumulator_units =
"kg m-2",
554 internal_units =
"kg m-2 second-1",
555 external_units =
"kg m-2 year-1";
557 name =
"surface_melt_rate";
559 accumulator_units =
"kg",
560 internal_units =
"kg second-1";
561 external_units =
"Gt year-1" ;
568 .long_name(long_name)
569 .standard_name(standard_name)
570 .units(internal_units)
571 .output_units(external_units);
572 m_vars[0][
"cell_methods"] =
"time: mean";
581 double cell_area =
m_grid->cell_area();
585 for (
auto p =
m_grid->points(); p; p.next()) {
586 const int i = p.i(), j = p.j();
606 ?
"surface_runoff_flux"
607 :
"surface_runoff_rate",
613 name =
"surface_runoff_flux",
614 long_name =
"surface runoff, averaged over the reporting interval",
615 standard_name =
"surface_runoff_flux",
616 accumulator_units =
"kg m-2",
617 internal_units =
"kg m-2 second-1",
618 external_units =
"kg m-2 year-1";
620 name =
"surface_runoff_rate";
622 accumulator_units =
"kg",
623 internal_units =
"kg second-1";
624 external_units =
"Gt year-1" ;
631 .long_name(long_name)
632 .standard_name(standard_name)
633 .units(internal_units)
634 .output_units(external_units);
635 m_vars[0][
"cell_methods"] =
"time: mean";
644 double cell_area =
m_grid->cell_area();
648 for (
auto p =
m_grid->points(); p; p.next()) {
649 const int i = p.i(), j = p.j();
655 return runoff_amount;
669 ?
"surface_accumulation_flux"
670 :
"surface_accumulation_rate",
677 name =
"surface_accumulation_flux",
678 long_name =
"accumulation (precipitation minus rain), averaged over the reporting interval",
679 accumulator_units =
"kg m-2",
680 internal_units =
"kg m-2 second-1",
681 external_units =
"kg m-2 year-1";
683 name =
"surface_accumulation_rate";
684 accumulator_units =
"kg",
685 internal_units =
"kg second-1";
686 external_units =
"Gt year-1" ;
693 .long_name(long_name)
694 .units(internal_units)
695 .output_units(external_units);
696 m_vars[0][
"cell_methods"] =
"time: mean";
705 double cell_area =
m_grid->cell_area();
709 for (
auto p =
m_grid->points(); p; p.next()) {
710 const int i = p.i(), j = p.j();
716 return accumulation_amount;
729 auto grid = input.
grid();
731 double cell_area = grid->cell_area();
737 for (
auto p = grid->points(); p; p.next()) {
738 const int i = p.i(), j = p.j();
740 result += input(i, j) * cell_area;
755 m_variable[
"long_name"] =
"surface accumulation rate (PDD model)";
772 m_variable[
"long_name"] =
"surface melt rate (PDD model)";
789 m_variable[
"long_name"] =
"surface runoff rate (PDD model)";
809 {
"climatic_mass_balance",
Diagnostic::Ptr(
new PS_climatic_mass_balance(
this))},
811 {
"ice_surface_liquid_water_fraction",
Diagnostic::Ptr(
new PS_liquid_water_fraction(
this))},
813 {
"surface_layer_thickness",
Diagnostic::Ptr(
new PS_layer_thickness(
this))}
816 if (
m_config->get_flag(
"output.ISMIP6")) {
835 {
"surface_accumulation_rate",
TSDiagnostic::Ptr(
new TotalSurfaceAccumulation(
this))},
std::shared_ptr< const Grid > grid() const
const Config::ConstPtr m_config
configuration database used by this component
const std::shared_ptr< const Grid > m_grid
grid used by this component
DiagnosticList diagnostics() const
A class defining a common interface for most PISM sub-models.
array::Scalar m_accumulator
const SurfaceModel * model
A template derived from Diagnostic, adding a "Model".
double m_fill_value
fill value (used often enough to justify storing it)
const units::System::Ptr m_sys
the unit system
double to_internal(double x) const
std::vector< SpatialVariableMetadata > m_vars
metadata corresponding to NetCDF variables
std::shared_ptr< Diagnostic > Ptr
std::shared_ptr< const Grid > m_grid
the grid
const Config::ConstPtr m_config
Configuration flags and parameters.
High-level PISM I/O class.
Combines the max. time step with the flag indicating if a restriction is active. Makes is possible to...
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
const SurfaceModel * model
void set_units(const std::string &units, const std::string &output_units)
VariableMetadata m_variable
std::shared_ptr< TSDiagnostic > Ptr
Scalar diagnostic reporting a "flux".
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
std::shared_ptr< const Grid > grid() const
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
const array::Scalar & melt() const
Returns melt.
static std::shared_ptr< array::Scalar > allocate_runoff(std::shared_ptr< const Grid > grid)
virtual const array::Scalar & layer_mass_impl() const
const array::Scalar & liquid_water_fraction() const
Returns the liquid water fraction of the ice at the top ice surface.
const array::Scalar & layer_mass() const
Returns mass held in the surface layer.
void update(const Geometry &geometry, double t, double dt)
std::shared_ptr< atmosphere::AtmosphereModel > m_atmosphere
static std::shared_ptr< array::Scalar > allocate_mass_flux(std::shared_ptr< const Grid > grid)
virtual DiagnosticList diagnostics_impl() const
void dummy_accumulation(const array::Scalar &smb, array::Scalar &result)
virtual void update_impl(const Geometry &geometry, double t, double dt)
std::shared_ptr< array::Scalar > m_melt
void init(const Geometry &geometry)
virtual void write_model_state_impl(const File &output) const
The default (empty implementation).
virtual void define_model_state_impl(const File &output) const
The default (empty implementation).
std::shared_ptr< array::Scalar > m_layer_thickness
const array::Scalar & mass_flux() const
static std::shared_ptr< array::Scalar > allocate_temperature(std::shared_ptr< const Grid > grid)
virtual const array::Scalar & accumulation_impl() const
const array::Scalar & accumulation() const
Returns accumulation.
virtual const array::Scalar & liquid_water_fraction_impl() const
static std::shared_ptr< array::Scalar > allocate_accumulation(std::shared_ptr< const Grid > grid)
virtual MaxTimestep max_timestep_impl(double my_t) const
static std::shared_ptr< array::Scalar > allocate_melt(std::shared_ptr< const Grid > grid)
SurfaceModel(std::shared_ptr< const Grid > g)
std::shared_ptr< array::Scalar > m_runoff
static std::shared_ptr< array::Scalar > allocate_layer_thickness(std::shared_ptr< const Grid > grid)
void dummy_melt(const array::Scalar &smb, array::Scalar &result)
std::shared_ptr< SurfaceModel > m_input_model
static std::shared_ptr< array::Scalar > allocate_layer_mass(std::shared_ptr< const Grid > grid)
const array::Scalar & temperature() const
std::shared_ptr< array::Scalar > m_layer_mass
virtual const array::Scalar & mass_flux_impl() const
virtual TSDiagnosticList ts_diagnostics_impl() const
virtual const array::Scalar & runoff_impl() const
std::shared_ptr< array::Scalar > m_accumulation
std::shared_ptr< array::Scalar > m_liquid_water_fraction
virtual void init_impl(const Geometry &geometry)
const array::Scalar & layer_thickness() const
Returns thickness of the surface layer. Could be used to compute surface elevation as a sum of elevat...
const array::Scalar & runoff() const
Returns runoff.
virtual const array::Scalar & melt_impl() const
virtual const array::Scalar & layer_thickness_impl() const
void dummy_runoff(const array::Scalar &smb, array::Scalar &result)
virtual const array::Scalar & temperature_impl() const
static std::shared_ptr< array::Scalar > allocate_liquid_water_fraction(std::shared_ptr< const Grid > grid)
The interface of PISM's surface models.
const array::Scalar & model_input()
array::Scalar m_accumulation_mass
Accumulation(const SurfaceModel *m, AmountKind kind)
Report accumulation (precipitation minus rain), averaged over the reporting interval.
PS_climatic_mass_balance(const SurfaceModel *m)
std::shared_ptr< array::Array > compute_impl() const
std::shared_ptr< array::Array > compute_impl() const
PS_ice_surface_temp(const SurfaceModel *m)
std::shared_ptr< array::Array > compute_impl() const
PS_layer_mass(const SurfaceModel *m)
Mass of the surface layer (snow and firn).
PS_layer_thickness(const SurfaceModel *m)
std::shared_ptr< array::Array > compute_impl() const
Surface layer (snow and firn) thickness.
std::shared_ptr< array::Array > compute_impl() const
PS_liquid_water_fraction(const SurfaceModel *m)
Ice liquid water fraction at the ice surface.
SurfaceMelt(const SurfaceModel *m, AmountKind kind)
const array::Scalar & model_input()
array::Scalar m_melt_mass
Report surface melt, averaged over the reporting interval.
array::Scalar m_runoff_mass
SurfaceRunoff(const SurfaceModel *m, AmountKind kind)
const array::Scalar & model_input()
Report surface runoff, averaged over the reporting interval.
TotalSurfaceAccumulation(const SurfaceModel *m)
Reports the total accumulation rate.
TotalSurfaceMelt(const SurfaceModel *m)
Reports the total melt rate.
TotalSurfaceRunoff(const SurfaceModel *m)
Reports the total top surface ice flux.
#define PISM_ERROR_LOCATION
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
static double integrate(const array::Scalar &input)
std::map< std::string, TSDiagnostic::Ptr > TSDiagnosticList
std::map< std::string, Diagnostic::Ptr > DiagnosticList
T combine(const T &a, const T &b)
void GlobalSum(MPI_Comm comm, double *local, double *result, int count)