22 #include "pism/util/Mask.hh"
23 #include "pism/util/ConfigInterface.hh"
24 #include "pism/util/Vars.hh"
25 #include "pism/util/error_handling.hh"
26 #include "pism/util/pism_utilities.hh"
27 #include "pism/util/IceModelVec2CellType.hh"
28 #include "pism/rheology/FlowLaw.hh"
29 #include "pism/rheology/FlowLawFactory.hh"
30 #include "pism/util/Context.hh"
33 namespace stressbalance {
61 if (
m_config->get_flag(
"output.ISMIP6")) {
82 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
86 {
m_sys, ismip6 ?
"yvelmean" :
"vbar"}};
88 set_attrs(
"vertical mean of horizontal ice velocity in the X direction",
89 "land_ice_vertical_mean_x_velocity",
90 "m s-1",
"m year-1", 0);
91 set_attrs(
"vertical mean of horizontal ice velocity in the Y direction",
92 "land_ice_vertical_mean_y_velocity",
93 "m s-1",
"m year-1", 1);
104 result->metadata(0) =
m_vars[0];
105 result->metadata(1) =
m_vars[1];
110 const int i = p.i(), j = p.j();
111 double thk = (*thickness)(i,j);
116 (*result)(i,j) /= thk;
118 (*result)(i,j) = 0.0;
131 set_attrs(
"magnitude of vertically-integrated horizontal velocity of ice",
"",
132 "m second-1",
"m year-1", 0);
135 m_vars[0][
"valid_min"] = {0.0};
141 result->metadata(0) =
m_vars[0];
164 set_attrs(
"Vertically integrated horizontal flux of ice in the X direction",
166 "m2 s-1",
"m2 year-1", 0);
167 set_attrs(
"Vertically integrated horizontal flux of ice in the Y direction",
169 "m2 s-1",
"m2 year-1", 1);
173 double H_threshold =
m_config->get_number(
"geometry.ice_free_thickness_standard");
176 result->metadata(0) =
m_vars[0];
177 result->metadata(1) =
m_vars[1];
183 &u3 =
model->velocity_u(),
184 &v3 =
model->velocity_v();
193 const int i = p.i(), j = p.j();
195 double H = (*thickness)(i,j);
198 if (H < H_threshold) {
199 (*result)(i, j) = 0.0;
206 auto v = v3.get_column(i, j);
211 int ks =
m_grid->kBelowHeight(H);
216 for (
int k = 1;
k <= ks; ++
k) {
220 Q += (z[
k] - z[
k - 1]) * 0.5 * (
v0 + v1);
227 Q += (H - z[ks]) *
Vector2(u[ks], v[ks]);
247 set_attrs(
"magnitude of vertically-integrated horizontal flux of ice",
"",
248 "m2 s-1",
"m2 year-1", 0);
251 m_vars[0][
"valid_min"] = {0.0};
260 result->metadata() =
m_vars[0];
265 const int i = p.i(), j = p.j();
267 (*result)(i,j) *= (*thickness)(i,j);
281 set_attrs(
"magnitude of horizontal velocity of ice at base of ice",
"",
282 "m s-1",
"m year-1", 0);
285 m_vars[0][
"valid_min"] = {0.0};
290 result->metadata(0) =
m_vars[0];
301 const int i = p.i(), j = p.j();
304 (*result)(i, j) = fill_value;
316 set_attrs(
"magnitude of horizontal velocity of ice at ice surface",
"",
317 "m s-1",
"m year-1", 0);
320 m_vars[0][
"valid_min"] = {0.0};
327 result->metadata(0) =
m_vars[0];
336 const int i = p.i(), j = p.j();
339 (*result)(i, j) = fill_value;
350 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
353 m_vars = {{
m_sys, ismip6 ?
"xvelsurf" :
"uvelsurf"},
354 {
m_sys, ismip6 ?
"yvelsurf" :
"vvelsurf"}};
356 set_attrs(
"x-component of the horizontal velocity of ice at ice surface",
357 "land_ice_surface_x_velocity",
358 "m s-1",
"m year-1", 0);
359 set_attrs(
"y-component of the horizontal velocity of ice at ice surface",
360 "land_ice_surface_y_velocity",
361 "m s-1",
"m year-1", 1);
365 m_vars[0][
"valid_range"] = {-large_number, large_number};
368 m_vars[1][
"valid_range"] = {-large_number, large_number};
376 result->metadata(0) =
m_vars[0];
377 result->metadata(1) =
m_vars[1];
383 &u3 =
model->velocity_u(),
384 &v3 =
model->velocity_v();
396 const int i = p.i(), j = p.j();
399 (*result)(i, j) = fill_value;
401 (*result)(i, j) = {u_surf(i, j), v_surf(i, j)};
414 set_attrs(
"vertical velocity of ice, relative to geoid",
"",
415 "m s-1",
"m year-1", 0);
419 m_vars[0][
"valid_range"] = {-large_number, large_number};
424 result3->metadata() =
m_vars[0];
427 bed =
m_grid->variables().get_2d_scalar(
"bedrock_altitude");
428 uplift =
m_grid->variables().get_2d_scalar(
"tendency_of_bedrock_altitude");
434 &u3 =
model->velocity_u(),
435 &v3 =
model->velocity_v(),
436 &w3 =
model->velocity_w();
440 const double ice_density =
m_config->get_number(
"constants.ice.density"),
441 sea_water_density =
m_config->get_number(
"constants.sea_water.density"),
442 R = ice_density / sea_water_density;
447 const int i = p.i(), j = p.j();
451 *v = v3.get_column(i, j),
452 *w = w3.get_column(i, j);
453 double *result = result3->get_column(i, j);
455 int ks =
m_grid->kBelowHeight(thickness(i,j));
462 uplift_ij = (*uplift)(i,j);
463 for (
int k = 0;
k <= ks ;
k++) {
464 result[
k] = w[
k] + uplift_ij + u[
k] * bed_dx + v[
k] * bed_dy;
469 z_sl = R * thickness(i,j),
470 w_sl = w3.interpolate(i, j, z_sl);
472 for (
int k = 0;
k <= ks ;
k++) {
473 result[
k] = w[
k] - w_sl;
481 for (
unsigned int k = ks+1;
k <
m_grid->Mz() ;
k++) {
486 for (
unsigned int k = ks+1;
k <
m_grid->Mz() ;
k++) {
487 result[
k] = result[ks];
507 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
510 m_vars = {{
m_sys, ismip6 ?
"zvelsurf" :
"wvelsurf"}};
512 set_attrs(
"vertical velocity of ice at ice surface, relative to the geoid",
513 "land_ice_surface_upward_velocity",
514 "m s-1",
"m year-1", 0);
518 m_vars[0][
"valid_range"] = {-large_number, large_number};
526 result->metadata() =
m_vars[0];
540 const int i = p.i(), j = p.j();
543 (*result)(i, j) = fill_value;
553 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
556 m_vars = {{
m_sys, ismip6 ?
"zvelbase" :
"wvelbase"}};
558 set_attrs(
"vertical velocity of ice at the base of ice, relative to the geoid",
559 "land_ice_basal_upward_velocity",
560 "m s-1",
"m year-1", 0);
564 m_vars[0][
"valid_range"] = {-large_number, large_number};
572 result->metadata() =
m_vars[0];
584 const int i = p.i(), j = p.j();
587 (*result)(i, j) = fill_value;
597 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
600 m_vars = {{
m_sys, ismip6 ?
"xvelbase" :
"uvelbase"},
601 {
m_sys, ismip6 ?
"yvelbase" :
"vvelbase"}};
603 set_attrs(
"x-component of the horizontal velocity of ice at the base of ice",
604 "land_ice_basal_x_velocity",
605 "m s-1",
"m year-1", 0);
606 set_attrs(
"y-component of the horizontal velocity of ice at the base of ice",
607 "land_ice_basal_y_velocity",
608 "m s-1",
"m year-1", 1);
613 m_vars[0][
"valid_range"] = {-large_number, large_number};
614 m_vars[1][
"valid_range"] = {-large_number, large_number};
616 m_vars[0][
"_FillValue"] = {fill_value};
617 m_vars[1][
"_FillValue"] = {fill_value};
624 result->metadata(0) =
m_vars[0];
625 result->metadata(1) =
m_vars[1];
631 &u3 =
model->velocity_u(),
632 &v3 =
model->velocity_v();
642 const int i = p.i(), j = p.j();
645 (*result)(i, j) = fill_value;
647 (*result)(i, j) = {u_base(i, j), v_base(i, j)};
661 set_attrs(
"basal frictional heating",
"",
662 "W m-2",
"W m-2", 0);
668 result->metadata() =
m_vars[0];
670 result->copy_from(
model->basal_frictional_heating());
682 set_attrs(
"horizontal velocity of ice in the X direction",
"land_ice_x_velocity",
683 "m s-1",
"m year-1", 0);
696 auto Mz = grid->Mz();
701 const int i = p.i(), j = p.j();
703 int ks = grid->kBelowHeight(H(i,j));
705 const double *F_ij =
F.get_column(i,j);
709 for (
int k = 0;
k <= ks ;
k++) {
710 F_out_ij[
k] = F_ij[
k];
713 for (
unsigned int k = ks+1;
k < Mz ;
k++) {
726 result->metadata() =
m_vars[0];
729 *
m_grid->variables().get_2d_scalar(
"land_ice_thickness"),
741 set_attrs(
"horizontal velocity of ice in the Y direction",
"land_ice_y_velocity",
742 "m s-1",
"m year-1", 0);
748 result->metadata() =
m_vars[0];
751 *
m_grid->variables().get_2d_scalar(
"land_ice_thickness"),
763 set_attrs(
"vertical velocity of ice, relative to base of ice directly below",
"",
764 "m s-1",
"m year-1", 0);
770 result->metadata() =
m_vars[0];
773 *
m_grid->variables().get_2d_scalar(
"land_ice_thickness"),
786 set_attrs(
"rate of strain heating in ice (dissipation heating)",
"",
787 "W m-3",
"mW m-3", 0);
792 result->metadata() =
m_vars[0];
794 result->copy_from(
model->volumetric_strain_heating());
804 set_attrs(
"first eigenvalue of the horizontal, vertically-integrated strain rate tensor",
805 "",
"s-1",
"s-1", 0);
806 set_attrs(
"second eigenvalue of the horizontal, vertically-integrated strain rate tensor",
807 "",
"s-1",
"s-1", 1);
815 result->metadata(0) =
m_vars[0];
816 result->metadata(1) =
m_vars[1];
835 set_attrs(
"deviatoric stress in X direction",
"",
"Pa",
"Pa", 0);
836 set_attrs(
"deviatoric stress in Y direction",
"",
"Pa",
"Pa", 1);
837 set_attrs(
"deviatoric shear stress",
"",
"Pa",
"Pa", 2);
844 "deviatoric_stresses",
846 result->metadata(0) =
m_vars[0];
847 result->metadata(1) =
m_vars[1];
848 result->metadata(2) =
m_vars[2];
864 velocity, hardness, cell_type, *result);
875 set_attrs(
"pressure in ice (hydrostatic)",
"",
"Pa",
"Pa", 0);
881 result->metadata(0) =
m_vars[0];
887 const double rg =
m_config->get_number(
"constants.ice.density") *
m_config->get_number(
"constants.standard_gravity");
892 const int i = p.i(), j = p.j();
894 unsigned int ks =
m_grid->kBelowHeight((*thickness)(i,j));
895 double *P_out_ij = result->get_column(i,j);
896 const double H = (*thickness)(i,j);
898 for (
unsigned int k = 0;
k <= ks; ++
k) {
899 P_out_ij[
k] = rg * (H -
m_grid->z(
k));
902 for (
unsigned int k = ks + 1;
k <
m_grid->Mz(); ++
k) {
921 set_attrs(
"shear stress xz component (in shallow ice approximation SIA)",
"",
935 result->metadata() =
m_vars[0];
939 thickness =
m_grid->variables().get_2d_scalar(
"land_ice_thickness");
940 surface =
m_grid->variables().get_2d_scalar(
"surface_altitude");
944 const double rg =
m_config->get_number(
"constants.ice.density") *
m_config->get_number(
"constants.standard_gravity");
949 const int i = p.i(), j = p.j();
951 unsigned int ks =
m_grid->kBelowHeight((*thickness)(i,j));
952 double *tauxz_out_ij = result->get_column(i, j);
954 H = (*thickness)(i,j),
958 for (
unsigned int k = 0;
k <= ks; ++
k) {
959 tauxz_out_ij[
k] = - rg * (H -
m_grid->z(
k)) * dhdx;
962 for (
unsigned int k = ks + 1;
k <
m_grid->Mz(); ++
k) {
963 tauxz_out_ij[
k] = 0.0;
981 set_attrs(
"shear stress yz component (in shallow ice approximation SIA)",
"",
995 result->metadata(0) =
m_vars[0];
1002 const double rg =
m_config->get_number(
"constants.ice.density") *
m_config->get_number(
"constants.standard_gravity");
1007 const int i = p.i(), j = p.j();
1009 unsigned int ks =
m_grid->kBelowHeight((*thickness)(i,j));
1010 double *tauyz_out_ij = result->get_column(i, j);
1012 H = (*thickness)(i,j),
1016 for (
unsigned int k = 0;
k <= ks; ++
k) {
1017 tauyz_out_ij[
k] = - rg * (H -
m_grid->z(
k)) * dhdy;
1020 for (
unsigned int k = ks + 1;
k <
m_grid->Mz(); ++
k) {
1021 tauyz_out_ij[
k] = 0.0;
1040 "Pascal",
"Pascal", 0);
1050 result->metadata(0) =
m_vars[0];
1060 const IceModelVec2S &ice_thickness = *
m_grid->variables().get_2d_scalar(
"land_ice_thickness");
1064 std::shared_ptr<const rheology::FlowLaw> flow_law;
1066 if (
m_config->get_flag(
"calving.vonmises_calving.use_custom_flow_law")) {
1069 flow_law = factory.
create();
1071 flow_law =
model->shallow()->flow_law();
1074 const double *z = &
m_grid->z()[0];
1076 double glen_exponent = flow_law->exponent();
1082 const int i = pt.i(), j = pt.j();
1084 if (mask.
icy(i, j)) {
1086 const double H = ice_thickness(i, j);
1087 const unsigned int k =
m_grid->kBelowHeight(H);
1090 *enthalpy_column = enthalpy->
get_column(i, j),
1092 eigen1 = strain_rates(i, j, 0),
1093 eigen2 = strain_rates(i, j, 1);
1096 const double effective_tensile_strain_rate = sqrt(0.5 * (pow(
max(0.0, eigen1), 2) +
1097 pow(
max(0.0, eigen2), 2)));
1099 vonmises_stress(i, j) = sqrt(3.0) * hardness * pow(effective_tensile_strain_rate,
1100 1.0 / glen_exponent);
1103 vonmises_stress(i, j) = 0.0;
Makes sure that we call begin_access() and end_access() for all accessed IceModelVecs.
const Config::ConstPtr m_config
configuration database used by this component
const StressBalance * model
A template derived from Diagnostic, adding a "Model".
IceModelVec::Ptr compute() const
Compute a diagnostic quantity and return a pointer to a newly-allocated IceModelVec.
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
IceGrid::ConstPtr m_grid
the grid
void set_attrs(const std::string &long_name, const std::string &standard_name, const std::string &units, const std::string &glaciological_units, unsigned int N=0)
A method for setting common variable attributes.
const Config::ConstPtr m_config
Configuration flags and parameters.
std::shared_ptr< EnthalpyConverter > Ptr
std::shared_ptr< const IceGrid > ConstPtr
bool icy(int i, int j) const
bool grounded(int i, int j) const
bool ice_free(int i, int j) const
"Cell type" mask. Adds convenience methods to IceModelVec2Int.
std::shared_ptr< IceModelVec2S > Ptr
std::shared_ptr< IceModelVec2V > Ptr
void copy_from(const IceModelVec2< T > &source)
std::shared_ptr< IceModelVec3 > Ptr
double * get_column(int i, int j)
A virtual class collecting methods common to ice and bedrock 3D fields.
std::shared_ptr< IceModelVec > Ptr
IceGrid::ConstPtr grid() const
void failed()
Indicates a failure of a parallel section.
This class represents a 2D vector field (such as ice velocity) at a certain grid point.
std::shared_ptr< FlowLaw > create()
virtual IceModelVec::Ptr compute_impl() const
PSB_bfrict(const StressBalance *m)
Computes basal frictional heating.
virtual IceModelVec::Ptr compute_impl() const
PSB_deviatoric_stresses(const StressBalance *m)
Reports the vertically-integrated (2D) deviatoric stresses.
virtual IceModelVec::Ptr compute_impl() const
PSB_flux_mag(const StressBalance *m)
Computes flux_mag, the magnitude of vertically-integrated horizontal flux of ice.
PSB_flux(const StressBalance *m)
virtual IceModelVec::Ptr compute_impl() const
Computes uflux and vflux, components of vertically-integrated horizontal flux of ice.
PSB_pressure(const StressBalance *m)
virtual IceModelVec::Ptr compute_impl() const
Reports the pressure within the ice (3D).
virtual IceModelVec::Ptr compute_impl() const
PSB_strain_rates(const StressBalance *m)
Reports the vertically-integrated (2D) principal strain rates.
virtual IceModelVec::Ptr compute_impl() const
PSB_strainheat(const StressBalance *m)
Reports the volumetric strain heating (3D).
PSB_tauxz(const StressBalance *m)
virtual IceModelVec::Ptr compute_impl() const
Reports the xz component of the shear stress within the ice (3D), according to the SIA formula.
virtual IceModelVec::Ptr compute_impl() const
PSB_tauyz(const StressBalance *m)
Reports the yz component of the shear stress within the ice (3D), according to the SIA formula.
PSB_uvel(const StressBalance *m)
virtual IceModelVec::Ptr compute_impl() const
Computes the x-component of the horizontal ice velocity.
virtual IceModelVec::Ptr compute_impl() const
PSB_velbar_mag(const StressBalance *m)
Computes velbar_mag, the magnitude of vertically-integrated horizontal velocity of ice and masks out ...
virtual IceModelVec::Ptr compute_impl() const
PSB_velbar(const StressBalance *m)
Computes the vertically-averaged ice velocity.
PSB_velbase_mag(const StressBalance *m)
virtual IceModelVec::Ptr compute_impl() const
Computes velbase_mag, the magnitude of horizontal velocity of ice at base of ice and masks out ice-fr...
PSB_velbase(const StressBalance *m)
virtual IceModelVec::Ptr compute_impl() const
Computes horizontal ice velocity at the base of ice.
virtual IceModelVec::Ptr compute_impl() const
PSB_velsurf_mag(const StressBalance *m)
Computes velsurf_mag, the magnitude of horizontal ice velocity at the surface.
virtual IceModelVec::Ptr compute_impl() const
PSB_velsurf(const StressBalance *m)
Computes velsurf, the horizontal velocity of ice at ice surface.
PSB_vonmises_stress(const StressBalance *m)
IceModelVec::Ptr compute_impl() const
virtual IceModelVec::Ptr compute_impl() const
PSB_vvel(const StressBalance *m)
Computes the y-component of the horizontal ice velocity.
PSB_wvel_rel(const StressBalance *m)
virtual IceModelVec::Ptr compute_impl() const
Computes vertical velocity of ice, relative to the bed directly below.
virtual IceModelVec::Ptr compute_impl() const
PSB_wvel(const StressBalance *m)
Computes vertical ice velocity (relative to the geoid).
virtual IceModelVec::Ptr compute_impl() const
PSB_wvelbase(const StressBalance *m)
Computes wvelbase, the vertical velocity of ice at the base of ice.
PSB_wvelsurf(const StressBalance *m)
virtual IceModelVec::Ptr compute_impl() const
Computes wvelsurf, the vertical velocity of ice at ice surface.
std::shared_ptr< SSB_Modifier > m_modifier
virtual TSDiagnosticList ts_diagnostics_impl() const
std::shared_ptr< ShallowStressBalance > m_shallow_stress_balance
virtual DiagnosticList diagnostics_impl() const
The class defining PISM's interface to the shallow stress balance code.
double averaged_hardness(const FlowLaw &ice, double thickness, int kbelowH, const double *zlevels, const double *enthalpy)
Computes vertical average of B(E, p) ice hardness, namely .
void averaged_hardness_vec(const FlowLaw &ice, const IceModelVec2S &thickness, const IceModelVec3 &enthalpy, IceModelVec2S &result)
void compute_2D_stresses(const rheology::FlowLaw &flow_law, const IceModelVec2V &velocity, const IceModelVec2S &hardness, const IceModelVec2CellType &cell_type, IceModelVec3 &result)
Compute 2D deviatoric stresses.
void compute_2D_principal_strain_rates(const IceModelVec2V &V, const IceModelVec2CellType &mask, IceModelVec3 &result)
Compute eigenvalues of the horizontal, vertically-integrated strain rate tensor.
static void zero_above_ice(const IceModelVec3 &F, const IceModelVec2S &H, IceModelVec3 &result)
void apply_mask(const IceModelVec2S &M, double fill, IceModelVec2S &result)
Masks out all the areas where by setting them to fill.
double max(const IceModelVec2S &input)
Finds maximum over all the values in an IceModelVec2S object. Ignores ghosts.
static double F(double SL, double B, double H, double alpha)
void compute_magnitude(const IceModelVec2S &v_x, const IceModelVec2S &v_y, IceModelVec2S &result)
Sets an IceModelVec2 to the magnitude of a 2D vector field with components v_x and v_y.
double diff_x_p(const IceModelVec2S &array, int i, int j)
Returns the x-derivative at i,j approximated using centered finite differences. Respects grid periodi...
void extract_surface(const IceModelVec3 &data, double z, IceModelVec2S &output)
Copies a horizontal slice at level z of an IceModelVec3 into an IceModelVec2S gslice.
std::map< std::string, TSDiagnostic::Ptr > TSDiagnosticList
std::map< std::string, Diagnostic::Ptr > DiagnosticList
T combine(const T &a, const T &b)
double diff_y_p(const IceModelVec2S &array, int i, int j)
Returns the y-derivative at i,j approximated using centered finite differences. Respects grid periodi...