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 };
91std::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 };
105std::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)
319 std::set<VariableMetadata> result;
368 for (
auto p :
m_grid->points()) {
369 const int i = p.i(), j = p.j();
370 result(i,j) = std::max(smb(i,j), 0.0);
388 for (
auto p :
m_grid->points()) {
389 const int i = p.i(), j = p.j();
390 result(i,j) = std::max(-smb(i,j), 0.0);
407namespace diagnostics {
462 .long_name(
"surface mass balance (accumulation/ablation) rate")
463 .standard_name(
"land_ice_surface_specific_mass_balance_flux")
464 .units(
"kg m^-2 second^-1")
465 .output_units(
"kg m^-2 year^-1");
469 auto result = allocate<array::Scalar>(
"climatic_mass_balance");
471 result->copy_from(
model->mass_flux());
478 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
482 .long_name(
"ice temperature at the top ice surface")
483 .standard_name(
"temperature_at_top_of_ice_sheet_model")
488 auto result = allocate<array::Scalar>(
"ice_surface_temp");
490 result->copy_from(
model->temperature());
497 m_vars[0].long_name(
"ice liquid water fraction at the ice surface").units(
"1");
502 auto result = allocate<array::Scalar>(
"ice_surface_liquid_water_fraction");
504 result->copy_from(
model->liquid_water_fraction());
511 m_vars[0].long_name(
"mass of the surface layer (snow and firn)").units(
"kg");
516 auto result = allocate<array::Scalar>(
"surface_layer_mass");
518 result->copy_from(
model->layer_mass());
525 m_vars[0].long_name(
"thickness of the surface layer (snow and firn)").units(
"meters");
530 auto result = allocate<array::Scalar>(
"surface_layer_thickness");
532 result->copy_from(
model->layer_thickness());
546 ?
"surface_melt_flux"
547 :
"surface_melt_rate",
554 name =
"surface_melt_flux",
555 long_name =
"surface melt, averaged over the reporting interval",
556 standard_name =
"surface_snow_and_ice_melt_flux",
557 accumulator_units =
"kg m^-2",
558 internal_units =
"kg m^-2 second^-1",
559 external_units =
"kg m^-2 year^-1";
561 name =
"surface_melt_rate";
563 accumulator_units =
"kg",
564 internal_units =
"kg second^-1";
565 external_units =
"Gt year^-1" ;
574 .
units(internal_units)
576 m_vars[0][
"cell_methods"] =
"time: mean";
585 double cell_area =
m_grid->cell_area();
589 for (
auto p :
m_grid->points()) {
590 const int i = p.i(), j = p.j();
610 ?
"surface_runoff_flux"
611 :
"surface_runoff_rate",
617 name =
"surface_runoff_flux",
618 long_name =
"surface runoff, averaged over the reporting interval",
619 standard_name =
"surface_runoff_flux",
620 accumulator_units =
"kg m^-2",
621 internal_units =
"kg m^-2 second^-1",
622 external_units =
"kg m^-2 year^-1";
624 name =
"surface_runoff_rate";
626 accumulator_units =
"kg",
627 internal_units =
"kg second^-1";
628 external_units =
"Gt year^-1" ;
637 .
units(internal_units)
639 m_vars[0][
"cell_methods"] =
"time: mean";
648 double cell_area =
m_grid->cell_area();
652 for (
auto p :
m_grid->points()) {
653 const int i = p.i(), j = p.j();
659 return runoff_amount;
673 ?
"surface_accumulation_flux"
674 :
"surface_accumulation_rate",
681 name =
"surface_accumulation_flux",
682 long_name =
"accumulation (precipitation minus rain), averaged over the reporting interval",
683 accumulator_units =
"kg m^-2",
684 internal_units =
"kg m^-2 second^-1",
685 external_units =
"kg m^-2 year^-1";
687 name =
"surface_accumulation_rate";
688 accumulator_units =
"kg",
689 internal_units =
"kg second^-1";
690 external_units =
"Gt year^-1" ;
698 .
units(internal_units)
700 m_vars[0][
"cell_methods"] =
"time: mean";
709 double cell_area =
m_grid->cell_area();
713 for (
auto p :
m_grid->points()) {
714 const int i = p.i(), j = p.j();
720 return accumulation_amount;
733 auto grid = input.
grid();
735 double cell_area = grid->cell_area();
741 for (
auto p : grid->points()) {
742 const int i = p.i(), j = p.j();
744 result += input(i, j) * cell_area;
759 m_variable[
"long_name"] =
"surface accumulation rate";
776 m_variable[
"long_name"] =
"surface melt rate";
793 m_variable[
"long_name"] =
"surface runoff rate";
804 using namespace diagnostics;
807 {
"surface_accumulation_flux",
Diagnostic::Ptr(
new Accumulation(
this, AMOUNT))},
808 {
"surface_accumulation_rate",
Diagnostic::Ptr(
new Accumulation(
this, MASS))},
811 {
"surface_runoff_flux",
Diagnostic::Ptr(
new SurfaceRunoff(
this, AMOUNT))},
812 {
"surface_runoff_rate",
Diagnostic::Ptr(
new SurfaceRunoff(
this, MASS))},
813 {
"climatic_mass_balance",
Diagnostic::Ptr(
new PS_climatic_mass_balance(
this))},
815 {
"ice_surface_liquid_water_fraction",
Diagnostic::Ptr(
new PS_liquid_water_fraction(
this))},
817 {
"surface_layer_thickness",
Diagnostic::Ptr(
new PS_layer_thickness(
this))}
820 if (
m_config->get_flag(
"output.ISMIP6")) {
836 using namespace diagnostics;
839 {
"surface_accumulation_rate",
TSDiagnostic::Ptr(
new TotalSurfaceAccumulation(
this))},
std::shared_ptr< const Grid > grid() const
std::shared_ptr< const Config > m_config
configuration database used by this component
const std::shared_ptr< const Grid > m_grid
grid used by this component
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".
std::vector< VariableMetadata > m_vars
metadata corresponding to NetCDF variables
double m_fill_value
fill value (used often enough to justify storing it)
const units::System::Ptr m_sys
the unit system
std::shared_ptr< const Config > m_config
Configuration flags and parameters.
double to_internal(double x) const
std::shared_ptr< Diagnostic > Ptr
std::shared_ptr< const Grid > m_grid
the grid
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
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata 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)
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)
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 TSDiagnosticList scalar_diagnostics_impl() const
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)
virtual void write_state_impl(const OutputFile &output) const
The default (empty implementation).
void dummy_melt(const array::Scalar &smb, array::Scalar &result)
virtual std::set< VariableMetadata > state_impl() const
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 DiagnosticList spatial_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.
const array::Scalar & model_input()
SurfaceMelt(const SurfaceModel *m, AmountKind kind)
array::Scalar m_melt_mass
Report surface melt, averaged over the reporting interval.
const array::Scalar & model_input()
array::Scalar m_runoff_mass
SurfaceRunoff(const SurfaceModel *m, AmountKind kind)
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
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)