23 #include "pism/age/AgeModel.hh"
24 #include "pism/energy/EnergyModel.hh"
25 #include "pism/energy/utilities.hh"
26 #include "pism/geometry/grounded_cell_fraction.hh"
27 #include "pism/geometry/part_grid_threshold_thickness.hh"
28 #include "pism/icemodel/IceModel.hh"
29 #include "pism/rheology/FlowLaw.hh"
30 #include "pism/stressbalance/SSB_Modifier.hh"
31 #include "pism/stressbalance/ShallowStressBalance.hh"
32 #include "pism/stressbalance/StressBalance.hh"
33 #include "pism/util/Diagnostic.hh"
34 #include "pism/util/EnthalpyConverter.hh"
35 #include "pism/util/error_handling.hh"
36 #include "pism/util/pism_utilities.hh"
37 #include "pism/util/projection.hh"
39 #if (Pism_USE_PROJ == 1)
40 #include "pism/util/Proj.hh"
45 namespace diagnostics {
58 std::string name =
"tendency_of_ice_amount", long_name =
"rate of change of the ice amount",
59 internal_units =
"kg m-2 second-1", external_units =
"kg m-2 year-1";
61 name =
"tendency_of_ice_mass";
62 long_name =
"rate of change of the ice mass";
63 internal_units =
"kg second-1";
64 external_units =
"Gt year-1";
69 m_vars[0].long_name(long_name).units(internal_units).output_units(external_units);
72 m_vars[0][
"valid_range"] = { -large_number, large_number };
74 m_vars[0][
"cell_methods"] =
"time: mean";
77 .
long_name(
"ice amount at the time of the last report of " + name)
78 .
units(internal_units +
" second");
84 auto result = std::make_shared<array::Scalar>(
m_grid,
"");
85 result->metadata() =
m_vars[0];
88 double ice_density =
m_config->get_number(
"constants.ice.density");
90 auto cell_area =
m_grid->cell_area();
97 for (
auto p =
m_grid->points(); p; p.next()) {
98 const int i = p.i(), j = p.j();
101 double amount = (thickness(i, j) + area_specific_volume(i, j)) * ice_density;
107 (*result)(i, j) *= cell_area;
123 double ice_density =
m_config->get_number(
"constants.ice.density");
127 for (
auto p =
m_grid->points(); p; p.next()) {
128 const int i = p.i(), j = p.j();
131 m_last_amount(i, j) = (thickness(i, j) + area_specific_volume(i, j)) * ice_density;
152 kind ==
AMOUNT ?
"tendency_of_ice_amount_due_to_flow" :
153 "tendency_of_ice_mass_due_to_flow",
157 std::string name =
"tendency_of_ice_amount_due_to_flow",
158 long_name =
"rate of change of ice amount due to flow",
159 accumulator_units =
"kg m-2", internal_units =
"kg m-2 second-1",
160 external_units =
"kg m-2 year-1";
163 name =
"tendency_of_ice_mass_due_to_flow";
164 long_name =
"rate of change of ice mass due to flow";
165 accumulator_units =
"kg";
166 internal_units =
"kg second-1";
167 external_units =
"Gt year-1";
175 m_vars[0].long_name(long_name).units(internal_units).output_units(external_units);
176 m_vars[0][
"cell_methods"] =
"time: mean";
178 m_vars[0][
"comment"] =
"positive flux corresponds to ice gain";
186 auto cell_area =
m_grid->cell_area();
190 for (
auto p =
m_grid->points(); p; p.next()) {
191 const int i = p.i(), j = p.j();
209 "tendency_of_ice_amount_due_to_surface_mass_flux" :
210 "tendency_of_ice_mass_due_to_surface_mass_flux",
215 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
217 std::string name = ismip6 ?
"acabf" :
"tendency_of_ice_amount_due_to_surface_mass_flux",
218 accumulator_units =
"kg m-2",
219 long_name =
"average surface mass flux over reporting interval",
220 standard_name =
"land_ice_surface_specific_mass_balance_flux",
221 internal_units =
"kg m-2 s-1", external_units =
"kg m-2 year-1";
223 name =
"tendency_of_ice_mass_due_to_surface_mass_flux", accumulator_units =
"kg",
224 long_name =
"average surface mass flux over reporting interval", standard_name =
"",
225 internal_units =
"kg second-1", external_units =
"Gt year-1";
232 .long_name(long_name)
233 .standard_name(standard_name)
234 .units(internal_units)
235 .output_units(external_units);
237 m_vars[0][
"cell_methods"] =
"time: mean";
238 m_vars[0][
"comment"] =
"positive flux corresponds to ice gain";
245 auto cell_area =
m_grid->cell_area();
249 for (
auto p =
m_grid->points(); p; p.next()) {
250 const int i = p.i(), j = p.j();
267 kind ==
AMOUNT ?
"tendency_of_ice_amount_due_to_basal_mass_flux" :
268 "tendency_of_ice_mass_due_to_basal_mass_flux",
273 std::string name =
"tendency_of_ice_amount_due_to_basal_mass_flux",
274 accumulator_units =
"kg m-2",
275 long_name =
"average basal mass flux over reporting interval", standard_name,
276 internal_units =
"kg m-2 second-1", external_units =
"kg m-2 year-1";
278 name =
"tendency_of_ice_mass_due_to_basal_mass_flux", accumulator_units =
"kg",
279 long_name =
"average basal mass flux over reporting interval",
280 standard_name =
"tendency_of_land_ice_mass_due_to_basal_mass_balance",
281 internal_units =
"kg second-1", external_units =
"Gt year-1";
287 .long_name(long_name)
288 .standard_name(standard_name)
289 .units(internal_units)
290 .output_units(external_units);
292 m_vars[0][
"cell_methods"] =
"time: mean";
293 m_vars[0][
"comment"] =
"positive flux corresponds to ice gain";
300 auto cell_area =
m_grid->cell_area();
304 for (
auto p =
m_grid->points(); p; p.next()) {
305 const int i = p.i(), j = p.j();
322 "tendency_of_ice_amount_due_to_conservation_error" :
323 "tendency_of_ice_mass_due_to_conservation_error",
328 std::string name =
"tendency_of_ice_amount_due_to_conservation_error",
329 accumulator_units =
"kg m-2",
330 long_name =
"average mass conservation error flux over reporting interval",
331 internal_units =
"kg m-2 second-1", external_units =
"kg m-2 year-1";
333 name =
"tendency_of_ice_mass_due_to_conservation_error", accumulator_units =
"kg",
334 long_name =
"average mass conservation error flux over reporting interval",
335 internal_units =
"kg second-1", external_units =
"Gt year-1";
342 .long_name(long_name)
343 .units(internal_units)
344 .output_units(external_units);
346 m_vars[0][
"cell_methods"] =
"time: mean";
347 m_vars[0][
"comment"] =
"positive flux corresponds to ice gain";
357 auto cell_area =
m_grid->cell_area();
359 for (
auto p =
m_grid->points(); p; p.next()) {
360 const int i = p.i(), j = p.j();
377 const auto &calving = model->
calving();
381 auto grid = accumulator.
grid();
391 if (add_frontal_melt) {
392 scope.add(frontal_melt);
394 if (add_forced_retreat) {
395 scope.add(forced_retreat);
398 for (
auto p = grid->points(); p; p.next()) {
399 const int i = p.i(), j = p.j();
402 accumulator(i, j) += factor * calving(i, j);
404 if (add_frontal_melt) {
405 accumulator(i, j) += factor * frontal_melt(i, j);
407 if (add_forced_retreat) {
408 accumulator(i, j) += factor * forced_retreat(i, j);
419 kind ==
AMOUNT ?
"tendency_of_ice_amount_due_to_discharge" :
420 "tendency_of_ice_mass_due_to_discharge",
426 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
428 std::string name = ismip6 ?
"lifmassbf" :
"tendency_of_ice_amount_due_to_discharge",
429 long_name =
"discharge flux (calving, frontal melt, forced retreat)",
430 accumulator_units =
"kg m-2",
431 standard_name =
"land_ice_specific_mass_flux_due_to_calving_and_ice_front_melting",
432 internal_units =
"kg m-2 s-1", external_units =
"kg m-2 year-1";
434 name =
"tendency_of_ice_mass_due_to_discharge";
435 long_name =
"discharge flux (calving, frontal melt, forced retreat)";
436 accumulator_units =
"kg";
438 internal_units =
"kg second-1";
439 external_units =
"Gt year-1";
446 .long_name(long_name)
447 .standard_name(standard_name)
448 .units(internal_units)
449 .output_units(external_units);
450 m_vars[0][
"cell_methods"] =
"time: mean";
452 m_vars[0][
"comment"] =
"positive flux corresponds to ice gain";
474 ?
"tendency_of_ice_amount_due_to_calving"
475 :
"tendency_of_ice_mass_due_to_calving",
481 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
484 name = ismip6 ?
"licalvf" :
"tendency_of_ice_amount_due_to_calving",
485 long_name =
"calving flux",
486 accumulator_units =
"kg m-2",
487 standard_name =
"land_ice_specific_mass_flux_due_to_calving",
488 internal_units =
"kg m-2 s-1",
489 external_units =
"kg m-2 year-1";
491 name =
"tendency_of_ice_mass_due_to_calving";
492 long_name =
"calving flux";
493 accumulator_units =
"kg";
495 internal_units =
"kg second-1";
496 external_units =
"Gt year-1";
503 .long_name(long_name)
504 .standard_name(standard_name)
505 .units(internal_units)
506 .output_units(external_units);
507 m_vars[0][
"cell_methods"] =
"time: mean";
510 m_vars[0][
"comment"] =
"positive flux corresponds to ice gain";
533 ?
"tendency_of_ice_amount_due_to_frontal_melt"
534 :
"tendency_of_ice_mass_due_to_frontal_melt",
540 std::string name =
"tendency_of_ice_amount_due_to_frontal_melt", accumulator_units =
"kg m-2",
541 internal_units =
"kg m-2 s-1", external_units =
"kg m-2 year-1";
543 name =
"tendency_of_ice_mass_due_to_frontal_melt";
544 accumulator_units =
"kg";
545 internal_units =
"kg second-1";
546 external_units =
"Gt year-1";
552 m_vars[0].long_name(
"frontal melt flux").units(internal_units).output_units(external_units);
553 m_vars[0][
"cell_methods"] =
"time: mean";
555 m_vars[0][
"comment"] =
"positive flux corresponds to ice gain";
577 kind ==
AMOUNT ?
"tendency_of_ice_amount_due_to_forced_retreat" :
578 "tendency_of_ice_mass_due_to_forced_retreat",
584 std::string name =
"tendency_of_ice_amount_due_to_forced_retreat", accumulator_units =
"kg m-2",
585 internal_units =
"kg m-2 s-1", external_units =
"kg m-2 year-1";
587 name =
"tendency_of_ice_mass_due_to_forced_retreat";
588 accumulator_units =
"kg";
589 internal_units =
"kg second-1";
590 external_units =
"Gt year-1";
597 .long_name(
"forced (prescribed) retreat flux")
598 .units(internal_units)
599 .output_units(external_units);
600 m_vars[0][
"cell_methods"] =
"time: mean";
602 m_vars[0][
"comment"] =
"positive flux corresponds to ice gain";
628 namespace diagnostics {
647 m_vars = { {
m_sys,
"ice_margin_pressure_difference" } };
651 "vertically-averaged pressure difference at ice margins (including calving fronts)")
657 auto result = allocate<array::Scalar>(
"ice_margin_pressure_difference");
666 const double H_threshold =
m_config->get_number(
"stress_balance.ice_free_thickness_standard");
674 rho_ocean =
m_config->get_number(
"constants.sea_water.density"),
675 g =
m_config->get_number(
"constants.standard_gravity");
681 for (
auto p =
m_grid->points(); p; p.next()) {
682 const int i = p.i(), j = p.j();
684 double delta_p = 0.0;
688 double P_ice = 0.5 *
rho_ice *
g * H(i, j),
692 delta_p = P_ice - P_water;
697 (*result)(i, j) = delta_p;
714 m, flag ==
GROUNDED ?
"basal_mass_flux_grounded" :
"basal_mass_flux_floating",
717 assert(flag !=
BOTH);
719 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
721 std::string name, description, standard_name;
723 name = ismip6 ?
"libmassbfgr" :
"basal_mass_flux_grounded";
724 description =
"average basal mass flux over the reporting interval (grounded areas)";
725 standard_name = ismip6 ?
"land_ice_basal_specific_mass_balance_flux" :
"";
727 name = ismip6 ?
"libmassbffl" :
"basal_mass_flux_floating";
728 description =
"average basal mass flux over the reporting interval (floating areas)";
729 standard_name = ismip6 ?
"land_ice_basal_specific_mass_balance_flux" :
"";
736 .long_name(description)
737 .standard_name(standard_name)
739 .output_units(
"kg m-2 year-1");
740 m_vars[0][
"cell_methods"] =
"time: mean";
742 m_vars[0][
"comment"] =
"positive flux corresponds to ice gain";
751 double ice_density =
m_config->get_number(
"constants.ice.density");
759 for (
auto p =
m_grid->points(); p; p.next()) {
760 const int i = p.i(), j = p.j();
764 }
else if (
m_kind ==
SHELF and cell_type.ocean(i, j)) {
781 virtual std::shared_ptr<array::Array>
compute_impl()
const;
789 .long_name(
"vertical average of ice hardness")
790 .set_units_without_validation(
792 m_vars[0][
"valid_min"] = { 0.0 };
794 m_vars[0][
"comment"] =
"units depend on the Glen exponent used by the flow law";
801 if (flow_law == NULL) {
803 if (flow_law == NULL) {
805 "Can't compute vertically-averaged hardness: no flow law is used.");
809 auto result = std::make_shared<array::Scalar>(
m_grid,
"hardav");
810 result->metadata() =
m_vars[0];
820 for (
auto p =
m_grid->points(); p; p.next()) {
821 const int i = p.i(), j = p.j();
823 const double *Eij = ice_enthalpy.
get_column(i, j);
824 const double H = ice_thickness(i, j);
825 if (cell_type.icy(i, j)) {
846 virtual std::shared_ptr<array::Array>
compute_impl()
const;
852 .long_name(
"processor rank")
854 .set_time_independent(
true)
860 auto result = std::make_shared<array::Scalar>(
m_grid,
"rank");
861 result->metadata() =
m_vars[0];
865 for (
auto p =
m_grid->points(); p; p.next()) {
866 (*result)(p.i(), p.j()) =
m_grid->rank();
878 virtual std::shared_ptr<array::Array>
compute_impl()
const;
884 .long_name(
"cts = E/E_s(p), so cold-temperate transition surface is at cts = 1")
891 result->metadata() =
m_vars[0];
905 virtual std::shared_ptr<array::Array>
compute_impl()
const;
911 .long_name(
"ice temperature")
912 .standard_name(
"land_ice_temperature")
914 m_vars[0][
"valid_min"] = { 0.0 };
919 std::shared_ptr<array::Array3D> result(
921 result->metadata() =
m_vars[0];
929 const double *Enthij;
935 for (
auto p =
m_grid->points(); p; p.next()) {
936 const int i = p.i(), j = p.j();
938 Tij = result->get_column(i,j);
939 Enthij = enthalpy.get_column(i,j);
940 for (
unsigned int k=0;
k <
m_grid->Mz(); ++
k) {
941 const double depth = thickness(i,j) -
m_grid->z(
k);
942 Tij[
k] = EC->temperature(Enthij[
k], EC->pressure(depth));
960 virtual std::shared_ptr<array::Array>
compute_impl()
const;
968 .long_name(
"pressure-adjusted ice temperature (degrees above pressure-melting point)")
970 m_vars[0][
"valid_max"] = {0};
974 bool cold_mode =
m_config->get_flag(
"energy.temperature_based");
975 double melting_point_temp =
m_config->get_number(
"constants.fresh_water.melting_point_temperature");
978 result->metadata() =
m_vars[0];
986 const double *Enthij;
992 for (
auto pt =
m_grid->points(); pt; pt.next()) {
993 const int i = pt.i(), j = pt.j();
995 Tij = result->get_column(i,j);
996 Enthij = enthalpy.get_column(i,j);
997 for (
unsigned int k=0;
k <
m_grid->Mz(); ++
k) {
998 const double depth = thickness(i,j) -
m_grid->z(
k),
999 p = EC->pressure(depth);
1000 Tij[
k] = EC->pressure_adjusted_temperature(Enthij[
k], p);
1004 if (EC->is_temperate_relaxed(Enthij[
k],p) && (thickness(i,j) > 0)) {
1005 Tij[
k] = melting_point_temp;
1016 result->shift(-melting_point_temp);
1027 virtual std::shared_ptr<array::Array>
compute_impl()
const;
1033 m_vars[0].long_name(
"pressure-adjusted ice temperature at the base of ice").units(
"Celsius");
1038 bool cold_mode =
m_config->get_flag(
"energy.temperature_based");
1039 double melting_point_temp =
m_config->get_number(
"constants.fresh_water.melting_point_temperature");
1041 auto result = std::make_shared<array::Scalar>(
m_grid,
"temp_pa_base");
1042 result->metadata() =
m_vars[0];
1053 for (
auto pt =
m_grid->points(); pt; pt.next()) {
1054 const int i = pt.i(), j = pt.j();
1056 auto Enthij = enthalpy.get_column(i,j);
1058 const double depth = thickness(i,j),
1059 p = EC->pressure(depth);
1060 (*result)(i,j) = EC->pressure_adjusted_temperature(Enthij[0], p);
1064 if (EC->is_temperate_relaxed(Enthij[0],p) && (thickness(i,j) > 0)) {
1065 (*result)(i,j) = melting_point_temp;
1074 result->shift(-melting_point_temp);
1085 virtual std::shared_ptr<array::Array>
compute_impl()
const;
1091 m_vars[0].long_name(
"ice enthalpy at 1m below the ice surface").units(
"J kg-1");
1097 auto result = std::make_shared<array::Scalar>(
m_grid,
"enthalpysurf");
1098 result->metadata() =
m_vars[0];
1107 for (
auto p =
m_grid->points(); p; p.next()) {
1108 const int i = p.i(), j = p.j();
1110 (*result)(i,j) =
std::max(ice_thickness(i,j) - 1.0, 0.0);
1115 for (
auto p =
m_grid->points(); p; p.next()) {
1116 const int i = p.i(), j = p.j();
1118 if (ice_thickness(i,j) <= 1.0) {
1132 virtual std::shared_ptr<array::Array>
compute_impl()
const;
1138 m_vars[0].long_name(
"ice enthalpy at the base of ice").units(
"J kg-1");
1144 auto result = std::make_shared<array::Scalar>(
m_grid,
"enthalpybase");
1145 result->metadata() =
m_vars[0];
1168 std::string name, long_name, standard_name;
1169 switch (area_type) {
1171 name =
"litempbotgr";
1172 long_name =
"ice temperature at the bottom surface of grounded ice";
1173 standard_name =
"temperature_at_base_of_ice_sheet_model";
1176 name =
"litempbotfl";
1177 long_name =
"ice temperature at the bottom surface of floating ice";
1178 standard_name =
"temperature_at_base_of_ice_sheet_model";
1182 long_name =
"ice temperature at the base of ice";
1183 standard_name =
"land_ice_basal_temperature";
1188 m_vars[0].long_name(long_name).standard_name(standard_name).units(
"K");
1194 auto result = allocate<array::Scalar>(
"basal_temperature");
1209 for (
auto p =
m_grid->points(); p; p.next()) {
1210 const int i = p.i(), j = p.j();
1212 double depth = thickness(i, j), pressure = EC->pressure(depth),
1213 T = EC->temperature((*result)(i, j), pressure);
1218 (*result)(i, j) = T;
1237 virtual std::shared_ptr<array::Array>
compute_impl()
const;
1243 .long_name(
"ice temperature at 1m below the ice surface")
1244 .standard_name(
"temperature_at_ground_level_in_snow_or_firn")
1254 auto result = array::cast<array::Scalar>(enth);
1263 double depth = 1.0, pressure = EC->pressure(depth);
1266 for (
auto p =
m_grid->points(); p; p.next()) {
1267 const int i = p.i(), j = p.j();
1269 if (thickness(i, j) > 1) {
1270 (*result)(i, j) = EC->temperature((*result)(i, j), pressure);
1280 result->metadata(0) =
m_vars[0];
1290 virtual std::shared_ptr<array::Array>
compute_impl()
const;
1295 m_vars[0].long_name(
"liquid water fraction in ice (between 0 and 1)").units(
"1");
1296 m_vars[0][
"valid_range"] = { 0.0, 1.0 };
1301 std::shared_ptr<array::Array3D> result(
1303 result->metadata(0) =
m_vars[0];
1305 bool cold_mode =
m_config->get_flag(
"energy.temperature_based");
1323 virtual std::shared_ptr<array::Array>
compute_impl()
const;
1328 m_vars[0].long_name(
"temperate ice thickness (total column content)").units(
"m");
1334 auto result = allocate<array::Scalar>(
"tempicethk");
1346 for (
auto p =
m_grid->points(); p; p.next()) {
1347 const int i = p.i(), j = p.j();
1349 if (cell_type.icy(i, j)) {
1350 const double *Enth = ice_enthalpy.get_column(i, j);
1351 double H_temperate = 0.0;
1352 const double H = ice_thickness(i, j);
1353 const unsigned int ks =
m_grid->kBelowHeight(H);
1355 for (
unsigned int k = 0;
k < ks; ++
k) {
1356 double pressure = EC->pressure(H -
m_grid->z(
k));
1358 if (EC->is_temperate_relaxed(Enth[
k], pressure)) {
1363 double pressure = EC->pressure(H -
m_grid->z(ks));
1364 if (EC->is_temperate_relaxed(Enth[ks], pressure)) {
1365 H_temperate += H -
m_grid->z(ks);
1368 (*result)(i, j) = H_temperate;
1388 virtual std::shared_ptr<array::Array>
compute_impl()
const;
1393 m_vars[0].long_name(
"thickness of the basal layer of temperate ice").units(
"m");
1402 auto result = allocate<array::Scalar>(
"tempicethk_basal");
1414 for (
auto p =
m_grid->points(); p; p.next()) {
1415 const int i = p.i(), j = p.j();
1417 double H = ice_thickness(i, j);
1421 if (cell_type.ice_free(i, j)) {
1426 const double *Enth = ice_enthalpy.get_column(i, j);
1428 unsigned int ks =
m_grid->kBelowHeight(H);
1431 double pressure = EC->pressure(H -
m_grid->z(
k));
1433 pressure = EC->pressure(H -
m_grid->z(
k));
1435 if (EC->is_temperate_relaxed(Enth[
k], pressure)) {
1446 (*result)(i, j) = 0.0;
1453 (*result)(i, j) =
m_grid->z(ks);
1458 slope1 = (Enth[
k] - Enth[
k - 1]) / dz,
1459 slope2 = (EC->enthalpy_cts(pressure) - EC->enthalpy_cts(pressure_0)) / dz;
1461 if (slope1 != slope2) {
1463 m_grid->z(
k - 1) + (EC->enthalpy_cts(pressure_0) - Enth[
k - 1]) / (slope1 - slope2);
1470 "Linear interpolation of the thickness of"
1471 " the basal temperate layer failed:\n"
1472 "(i=%d, j=%d, k=%d, ks=%d)\n",
1494 m_variable[
"long_name"] =
"volume of the ice in glacierized areas";
1499 m_config->get_number(
"output.ice_free_thickness_standard"));
1509 m_variable[
"long_name"] =
"volume of the ice, including seasonal cover";
1525 m_variable[
"long_name"] =
"the sea level rise that would result if all the ice were melted";
1531 m_config->get_number(
"output.ice_free_thickness_standard"));
1542 m_variable[
"long_name"] =
"rate of change of the ice volume in glacierized areas";
1547 m_config->get_number(
"output.ice_free_thickness_standard"));
1558 m_variable[
"long_name"] =
"rate of change of the ice volume, including seasonal cover";
1573 m_variable[
"long_name"] =
"glacierized area";
1589 m_variable[
"long_name"] =
"mass of the ice not displacing sea water";
1590 m_variable[
"standard_name"] =
"land_ice_mass_not_displacing_sea_water";
1596 const double thickness_standard =
m_config->get_number(
"output.ice_free_thickness_standard"),
1597 ice_density =
m_config->get_number(
"constants.ice.density"),
1613 m_variable[
"long_name"] =
"mass of the ice in glacierized areas";
1618 double ice_density =
m_config->get_number(
"constants.ice.density"),
1619 thickness_standard =
m_config->get_number(
"output.ice_free_thickness_standard");
1629 if (
m_config->get_flag(
"output.ISMIP6")) {
1634 m_variable[
"long_name"] =
"mass of the ice, including seasonal cover";
1635 m_variable[
"standard_name"] =
"land_ice_mass";
1651 m_variable[
"long_name"] =
"rate of change of the ice mass in glacierized areas";
1655 double ice_density =
m_config->get_number(
"constants.ice.density"),
1656 thickness_threshold =
m_config->get_number(
"output.ice_free_thickness_standard");
1672 m_variable[
"long_name"] =
"rate of change of the mass of ice due to flow"
1673 " (i.e. prescribed ice thickness)";
1678 const double ice_density =
m_config->get_number(
"constants.ice.density");
1683 auto cell_area =
m_grid->cell_area();
1687 double volume_change = 0.0;
1688 for (
auto p =
m_grid->points(); p; p.next()) {
1689 const int i = p.i(), j = p.j();
1691 volume_change += (dH(i, j) + dV(i, j)) * cell_area;
1705 m_variable[
"long_name"] =
"rate of change of the mass of ice, including seasonal cover";
1709 const double ice_density =
m_config->get_number(
"constants.ice.density");
1722 m_variable[
"long_name"] =
"volume of temperate ice in glacierized areas";
1738 m_variable[
"long_name"] =
"volume of temperate ice, including seasonal cover";
1754 m_variable[
"long_name"] =
"volume of cold ice in glacierized areas";
1769 m_variable[
"long_name"] =
"volume of cold ice, including seasonal cover";
1785 m_variable[
"long_name"] =
"glacierized area where basal ice is temperate";
1801 m_variable[
"long_name"] =
"glacierized area where basal ice is cold";
1817 m_variable[
"long_name"] =
"enthalpy of the ice in glacierized areas";
1834 m_variable[
"long_name"] =
"enthalpy of the ice, including seasonal cover";
1850 if (
m_config->get_flag(
"output.ISMIP6")) {
1855 m_variable[
"long_name"] =
"area of grounded ice in glacierized areas";
1856 m_variable[
"standard_name"] =
"grounded_ice_sheet_area";
1862 m_config->get_number(
"output.ice_free_thickness_standard"));
1872 if (
m_config->get_flag(
"output.ISMIP6")) {
1877 m_variable[
"long_name"] =
"area of ice shelves in glacierized areas";
1878 m_variable[
"standard_name"] =
"floating_ice_shelf_area";
1884 m_config->get_number(
"output.ice_free_thickness_standard"));
1895 m_variable[
"long_name"] =
"volume of grounded ice in glacierized areas";
1904 const double thickness_threshold =
m_config->get_number(
"output.ice_free_thickness_standard"),
1905 cell_area =
m_grid->cell_area();
1909 double volume = 0.0;
1910 for (
auto p =
m_grid->points(); p; p.next()) {
1911 const int i = p.i(), j = p.j();
1913 const double H = ice_thickness(i, j);
1915 if (cell_type.grounded(i, j) and H >= thickness_threshold) {
1916 volume += cell_area * H;
1931 m_variable[
"long_name"] =
"volume of ice shelves in glacierized areas";
1940 const double thickness_threshold =
m_config->get_number(
"output.ice_free_thickness_standard"),
1941 cell_area =
m_grid->cell_area();
1945 double volume = 0.0;
1946 for (
auto p =
m_grid->points(); p; p.next()) {
1947 const int i = p.i(), j = p.j();
1949 const double H = ice_thickness(i, j);
1951 if (cell_type.ocean(i, j) and H >= thickness_threshold) {
1952 volume += cell_area * H;
1966 m_variable[
"long_name"] =
"mass continuity time step";
1981 m_variable[
"long_name"] =
"ratio of max. allowed time steps "
1982 "according to CFL and SIA diffusivity criteria";
1992 auto cfl_3d = stress_balance->max_timestep_cfl_3d();
1997 m_config->get_number(
"time_stepping.adaptive_ratio"));
1999 auto dt_cfl =
std::min(cfl_2d.dt_max, cfl_3d.dt_max);
2001 if (dt_cfl.finite() and dt_diff.finite() and dt_diff.value() > 0.0) {
2002 return dt_cfl.value() / dt_diff.value();
2015 m_variable[
"long_name"] =
"maximum diffusivity of the flow (usually from the SIA model)";
2041 m_variable[
"long_name"] =
"max(max(abs(u)), max(abs(v))) for the horizontal velocity of ice"
2042 " over volume of the ice in last time step during time-series reporting interval";
2079 const Config &config = *grid.
ctx()->config();
2081 const double ice_density = config.
get_number(
"constants.ice.density"),
2115 double volume_change = 0.0;
2117 const int i = p.i(), j = p.j();
2119 if ((area ==
BOTH) or (area ==
GROUNDED and cell_type.grounded(i, j)) or
2120 (area ==
SHELF and cell_type.ocean(i, j))) {
2122 double dV = term ==
FLOW ? dV_flow(i, j) : 0.0;
2125 volume_change += cell_area * ((*thickness_change)(i, j) + dV);
2130 return ice_density *
GlobalSum(grid.
com, volume_change);
2139 if (
m_config->get_flag(
"output.ISMIP6")) {
2144 m_variable[
"long_name"] =
"total over ice domain of bottom surface ice mass flux";
2145 m_variable[
"standard_name"] =
"tendency_of_land_ice_mass_due_to_basal_mass_balance";
2146 m_variable[
"comment"] =
"positive means ice gain";
2160 if (
m_config->get_flag(
"output.ISMIP6")) {
2165 m_variable[
"long_name"] =
"total over ice domain of top surface ice mass flux";
2166 m_variable[
"standard_name"] =
"tendency_of_land_ice_mass_due_to_surface_mass_balance";
2167 m_variable[
"comment"] =
"positive means ice gain";
2182 m_variable[
"long_name"] =
"total over grounded ice domain of basal mass flux";
2183 m_variable[
"standard_name"] =
"tendency_of_land_ice_mass_due_to_basal_mass_balance";
2184 m_variable[
"comment"] =
"positive means ice gain";
2198 if (
m_config->get_flag(
"output.ISMIP6")) {
2203 m_variable[
"long_name"] =
"total sub-shelf ice flux";
2204 m_variable[
"standard_name"] =
"tendency_of_land_ice_mass_due_to_basal_mass_balance";
2205 m_variable[
"comment"] =
"positive means ice gain";
2221 m_variable[
"long_name"] =
"total numerical flux needed to preserve non-negativity"
2222 " of ice thickness";
2223 m_variable[
"comment"] =
"positive means ice gain";
2237 if (
m_config->get_flag(
"output.ISMIP6")) {
2242 m_variable[
"long_name"] =
"discharge flux (frontal melt, calving, forced retreat)";
2243 m_variable[
"standard_name"] =
"tendency_of_land_ice_mass_due_to_calving_and_ice_front_melting";
2244 m_variable[
"comment"] =
"positive means ice gain";
2248 const double ice_density =
m_config->get_number(
"constants.ice.density");
2254 auto cell_area =
m_grid->cell_area();
2256 double volume_change = 0.0;
2260 for (
auto p =
m_grid->points(); p; p.next()) {
2261 const int i = p.i(), j = p.j();
2263 volume_change += cell_area * (calving(i, j) + frontal_melt(i, j) + forced_retreat(i, j));
2277 if (
m_config->get_flag(
"output.ISMIP6")) {
2283 m_variable[
"standard_name"] =
"tendency_of_land_ice_mass_due_to_calving";
2284 m_variable[
"comment"] =
"positive means ice gain";
2288 const double ice_density =
m_config->get_number(
"constants.ice.density");
2292 auto cell_area =
m_grid->cell_area();
2294 double volume_change = 0.0;
2298 for (
auto p =
m_grid->points(); p; p.next()) {
2299 const int i = p.i(), j = p.j();
2301 volume_change += cell_area * calving(i, j);
2315 if (
m_config->get_flag(
"output.ISMIP6")) {
2317 m_variable[
"standard_name"] =
"tendency_of_grounded_ice_mass";
2321 m_variable[
"long_name"] =
"total ice flux across the grounding line";
2322 m_variable[
"comment"] =
"negative flux corresponds to ice loss into the ocean";
2340 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
2343 m_vars = { {
m_sys, ismip6 ?
"dlithkdt" :
"dHdt" } };
2345 .long_name(
"ice thickness rate of change")
2346 .standard_name(
"tendency_of_land_ice_thickness")
2348 .output_units(
"m year-1");
2352 m_vars[0][
"valid_range"] = { -large_number, large_number };
2354 m_vars[0][
"cell_methods"] =
"time: mean";
2358 "ice thickness at the time of the last report of the rate of change of ice thickness")
2366 auto result = std::make_shared<array::Scalar>(
m_grid,
"dHdt");
2367 result->metadata() =
m_vars[0];
2399 virtual std::shared_ptr<array::Array>
compute_impl()
const;
2405 const std::string &proj_string)
2407 assert(var_name ==
"lat" || var_name ==
"lon");
2412 m_vars[0].z().clear().set_name(
"nv4");
2414 m_vars[0].set_time_independent(
true);
2416 m_vars[0].long_name(
"longitude bounds").units(
"degree_east");
2417 m_vars[0][
"valid_range"] = { -180, 180 };
2419 m_vars[0].long_name(
"latitude bounds").units(
"degree_north");
2420 m_vars[0][
"valid_range"] = { -90, 90 };
2425 #if (Pism_USE_PROJ == 1)
2437 result->metadata(0) =
m_vars[0];
2453 virtual std::shared_ptr<array::Array>
compute_impl()
const;
2459 .long_name(
"fraction of a grid cell covered by ice (grounded or floating)")
2460 .standard_name(
"land_ice_area_fraction")
2474 array::AccessScope list{ &thickness, &surface_elevation, &bed_topography, &cell_type,
2477 const bool do_part_grid =
m_config->get_flag(
"geometry.part_grid.enabled");
2486 for (
auto p =
m_grid->points(); p; p.next()) {
2487 const int i = p.i(), j = p.j();
2489 if (cell_type.
icy(i, j)) {
2491 (*result)(i, j) = 1.0;
2496 double H_reference = do_part_grid ? Href(i, j) : 0.0;
2498 if (H_reference > 0.0) {
2499 const double H_threshold =
2501 surface_elevation.star(i, j), bed_topography(i, j));
2503 if (H_threshold > 0.0) {
2504 (*result)(i, j) =
std::min(H_reference / H_threshold, 1.0);
2506 (*result)(i, j) = 1.0;
2510 (*result)(i, j) = 0.0;
2514 (*result)(i, j) = 0.0;
2530 virtual std::shared_ptr<array::Array>
compute_impl()
const;
2536 .long_name(
"fraction of a grid cell covered by grounded ice")
2537 .standard_name(
"grounded_ice_sheet_area_fraction")
2543 result->metadata() =
m_vars[0];
2545 const double ice_density =
m_config->get_number(
"constants.ice.density"),
2546 ocean_density =
m_config->get_number(
"constants.sea_water.density");
2555 bed_topography, *result);
2564 for (
auto p =
m_grid->points(); p; p.next()) {
2565 const int i = p.i(), j = p.j();
2566 if (cell_type.ice_free(i, j)) {
2567 (*result)(i, j) = 0.0;
2583 virtual std::shared_ptr<array::Array>
compute_impl()
const;
2589 .long_name(
"fraction of a grid cell covered by floating ice")
2590 .standard_name(
"floating_ice_shelf_area_fraction")
2599 auto result = ice_area_fraction;
2600 result->metadata() =
m_vars[0];
2614 virtual std::shared_ptr<array::Array>
compute_impl()
const;
2621 m_vars[0].long_name(
"ice thickness in excess of the maximum floating ice thickness").units(
"m");
2623 m_vars[0][
"comment"] =
"shows how close to floatation the ice is at a given location";
2628 auto result = allocate<array::Scalar>(
"height_above_flotation");
2632 const double ice_density =
m_config->get_number(
"constants.ice.density"),
2633 ocean_density =
m_config->get_number(
"constants.sea_water.density");
2639 array::AccessScope list{ &cell_type, result.get(), &ice_thickness, &bed_topography, &sea_level };
2643 for (
auto p =
m_grid->points(); p; p.next()) {
2644 const int i = p.i(), j = p.j();
2646 const double thickness = ice_thickness(i, j), bed = bed_topography(i, j),
2647 ocean_depth = sea_level(i, j) - bed;
2649 if (cell_type.icy(i, j) and ocean_depth > 0.0) {
2650 const double max_floating_thickness = ocean_depth * (ocean_density / ice_density);
2651 (*result)(i, j) = thickness - max_floating_thickness;
2670 virtual std::shared_ptr<array::Array>
compute_impl()
const;
2675 m_vars[0].long_name(
"ice mass per cell").units(
"kg");
2681 auto result = allocate<array::Scalar>(
"ice_mass");
2685 const double ice_density =
m_config->get_number(
"constants.ice.density");
2689 auto cell_area =
m_grid->cell_area();
2695 for (
auto p =
m_grid->points(); p; p.next()) {
2696 const int i = p.i(), j = p.j();
2700 if (ice_thickness(i, j) > 0.0) {
2701 (*result)(i, j) = ice_density * ice_thickness(i, j) * cell_area;
2713 if (
m_config->get_flag(
"geometry.part_grid.enabled")) {
2716 for (
auto p =
m_grid->points(); p; p.next()) {
2717 const int i = p.i(), j = p.j();
2719 if (ice_thickness(i, j) <= 0.0 and Href(i, j) > 0.0) {
2720 (*result)(i, j) = ice_density * Href(i, j) * cell_area;
2740 m_vars[0].long_name(
"sea-level adjusted bed topography (zero is at sea level)").units(
"meters");
2745 auto result = allocate<array::Scalar>(
"topg_sl_adjusted");
2752 for (
auto p =
m_grid->points(); p; p.next()) {
2753 const int i = p.i(), j = p.j();
2755 (*result)(i, j) = bed(i, j) - sea_level(i, j);
2773 .long_name(
"ice hardness computed using the SIA flow law")
2774 .set_units_without_validation(
2776 m_vars[0][
"comment"] =
"units depend on the Glen exponent used by the flow law";
2781 std::shared_ptr<array::Array3D> result(
2783 result->metadata(0) =
m_vars[0];
2794 const unsigned int Mz =
m_grid->Mz();
2798 for (
auto p =
m_grid->points(); p; p.next()) {
2799 const int i = p.i(), j = p.j();
2800 const double *E = ice_enthalpy.
get_column(i, j);
2801 const double H = ice_thickness(i, j);
2803 double *hardness = result->get_column(i, j);
2805 for (
unsigned int k = 0;
k < Mz; ++
k) {
2806 const double depth = H -
m_grid->z(
k);
2809 const double pressure = EC->pressure(depth);
2811 hardness[
k] = flow_law.
hardness(E[
k], pressure);
2834 .long_name(
"effective viscosity of ice")
2835 .units(
"Pascal second")
2836 .output_units(
"kPascal second");
2837 m_vars[0][
"valid_min"] = { 0.0 };
2847 std::shared_ptr<array::Array3D> result(
2849 result->metadata(0) =
m_vars[0];
2868 const unsigned int Mz =
m_grid->Mz();
2870 const std::vector<double> &z =
m_grid->z();
2874 array::AccessScope list{ &U, &V, &W, &ice_enthalpy, &ice_thickness, &mask, result.get() };
2878 for (
auto p =
m_grid->points(); p; p.next()) {
2879 const int i = p.i(), j = p.j();
2881 const double *E = ice_enthalpy.
get_column(i, j);
2882 const double H = ice_thickness(i, j);
2884 const double *u = U.get_column(i, j), *u_n = U.get_column(i, j + 1),
2885 *u_e = U.get_column(i + 1, j), *u_s = U.get_column(i, j - 1),
2886 *u_w = U.get_column(i - 1, j);
2888 const double *v = V.get_column(i, j), *v_n = V.get_column(i, j + 1),
2889 *v_e = V.get_column(i + 1, j), *v_s = V.get_column(i, j - 1),
2890 *v_w = V.get_column(i - 1, j);
2897 const unsigned int east =
ice_free(m.e) ? 0 : 1, west =
ice_free(m.w) ? 0 : 1,
2900 double *viscosity = result->get_column(i, j);
2907 for (
unsigned int k = 0;
k < Mz; ++
k) {
2908 const double depth = H - z[
k];
2916 const double pressure = EC->pressure(depth);
2918 const double hardness = flow_law.
hardness(E[
k], pressure);
2920 double u_x = 0.0, v_x = 0.0, w_x = 0.0;
2921 if (west + east > 0) {
2922 const double D = 1.0 / (dx * (west + east));
2923 u_x =
D * (west * (u[
k] - u_w[
k]) + east * (u_e[
k] - u[
k]));
2924 v_x =
D * (west * (v[
k] - v_w[
k]) + east * (v_e[
k] - v[
k]));
2925 w_x =
D * (west * (w[
k] - w_w[
k]) + east * (w_e[
k] - w[
k]));
2928 double u_y = 0.0, v_y = 0.0, w_y = 0.0;
2929 if (south + north > 0) {
2930 const double D = 1.0 / (dy * (south + north));
2931 u_y =
D * (south * (u[
k] - u_s[
k]) + north * (u_n[
k] - u[
k]));
2932 v_y =
D * (south * (v[
k] - v_s[
k]) + north * (v_n[
k] - v[
k]));
2933 w_y =
D * (south * (w[
k] - w_s[
k]) + north * (w_n[
k] - w[
k]));
2936 double u_z = 0.0, v_z = 0.0, w_z = 0.0;
2939 const double dz = z[1] - z[0];
2940 u_z = (u[1] - u[0]) / dz;
2941 v_z = (v[1] - v[0]) / dz;
2942 w_z = (w[1] - w[0]) / dz;
2943 }
else if (
k == Mz - 1) {
2944 const double dz = z[Mz - 1] - z[Mz - 2];
2945 u_z = (u[Mz - 1] - u[Mz - 2]) / dz;
2946 v_z = (v[Mz - 1] - v[Mz - 2]) / dz;
2947 w_z = (w[Mz - 1] - w[Mz - 2]) / dz;
2949 const double dz_p = z[
k + 1] - z[
k], dz_m = z[
k] - z[
k - 1];
2950 u_z = 0.5 * ((u[
k + 1] - u[
k]) / dz_p + (u[
k] - u[
k - 1]) / dz_m);
2951 v_z = 0.5 * ((v[
k + 1] - v[
k]) / dz_p + (v[
k] - v[
k - 1]) / dz_m);
2952 w_z = 0.5 * ((w[
k + 1] - w[
k]) / dz_p + (w[
k] - w[
k - 1]) / dz_m);
2956 const double eps_xx = u_x, eps_yy = v_y, eps_zz = w_z, eps_xy = 0.5 * (u_y + v_x),
2957 eps_xz = 0.5 * (u_z + w_x), eps_yz = 0.5 * (v_z + w_y);
2986 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
2990 m_vars[0].long_name(
"land ice thickness").standard_name(
"land_ice_thickness").units(
"m");
2991 m_vars[0][
"valid_min"] = { 0.0 };
2997 auto result = allocate<array::Scalar>(
"thk");
3010 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
3012 m_vars = { {
m_sys, ismip6 ?
"base" :
"ice_base_elevation" } };
3013 m_vars[0].long_name(
"ice bottom surface elevation").units(
"m");
3019 auto result = allocate<array::Scalar>(
"ice_base_elevation");
3032 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
3034 m_vars = { {
m_sys, ismip6 ?
"orog" :
"usurf" } };
3035 m_vars[0].long_name(
"ice top surface elevation").standard_name(
"surface_altitude").units(
"m");
3040 auto result = allocate<array::Scalar>(
"usurf");
3055 auto ismip6 =
m_config->get_flag(
"output.ISMIP6");
3057 m_vars = { {
m_sys, ismip6 ?
"ligroundf" :
"grounding_line_flux" } };
3060 .long_name(
"grounding line flux")
3061 .units(
"kg m-2 second-1")
3062 .output_units(
"kg m-2 year-1");
3063 m_vars[0][
"cell_methods"] =
"time: mean";
3067 "Positive flux corresponds to mass moving from the ocean to"
3068 " an icy grounded area. This convention makes it easier to compare"
3069 " grounding line flux to the total discharge into the ocean";
3074 bool add_values =
true;
3090 using namespace diagnostics;
3097 {
"height_above_flotation", f(
new HeightAboveFloatation(
this))},
3099 {
"ice_mass", f(
new IceMass(
this))},
3103 {
"thk", f(
new IceThickness(
this))},
3104 {
"topg_sl_adjusted", f(
new BedTopographySeaLevelAdjusted(
this))},
3105 {
"usurf", f(
new IceSurfaceElevation(
this))},
3106 {
"ice_base_elevation", f(
new IceBottomSurfaceElevation(
this))},
3112 {
"enthalpybase", f(
new IceEnthalpyBasal(
this))},
3113 {
"enthalpysurf", f(
new IceEnthalpySurface(
this))},
3115 {
"cts", f(
new CTS(
this))},
3116 {
"liqfrac", f(
new LiquidFraction(
this))},
3117 {
"temp", f(
new Temperature(
this))},
3118 {
"temp_pa", f(
new TemperaturePA(
this))},
3119 {
"tempbase", f(
new TemperatureBasal(
this,
BOTH))},
3120 {
"temppabase", f(
new TemperaturePABasal(
this))},
3121 {
"tempsurf", f(
new TemperatureSurface(
this))},
3124 {
"tempicethk", f(
new TemperateIceThickness(
this))},
3125 {
"tempicethk_basal", f(
new TemperateIceThicknessBasal(
this))},
3126 {
"hardav", f(
new HardnessAverage(
this))},
3127 {
"hardness", f(
new IceHardness(
this))},
3128 {
"effective_viscosity", f(
new IceViscosity(
this))},
3133 {
"ice_margin_pressure_difference", f(
new IceMarginPressureDifference(
this))},
3147 {
"tendency_of_ice_amount", f(
new TendencyOfIceAmount(
this,
AMOUNT))},
3148 {
"tendency_of_ice_amount_due_to_flow", f(
new TendencyOfIceAmountDueToFlow(
this,
AMOUNT))},
3149 {
"tendency_of_ice_amount_due_to_conservation_error", f(
new ConservationErrorFlux(
this,
AMOUNT))},
3150 {
"tendency_of_ice_amount_due_to_surface_mass_flux", f(
new SurfaceFlux(
this,
AMOUNT))},
3151 {
"tendency_of_ice_amount_due_to_basal_mass_flux", f(
new BasalFlux(
this,
AMOUNT))},
3152 {
"tendency_of_ice_amount_due_to_discharge", f(
new DischargeFlux(
this,
AMOUNT))},
3153 {
"tendency_of_ice_amount_due_to_calving", f(
new CalvingFlux(
this,
AMOUNT))},
3154 {
"tendency_of_ice_amount_due_to_frontal_melt", f(
new FrontalMeltFlux(
this,
AMOUNT))},
3155 {
"tendency_of_ice_amount_due_to_forced_retreat", f(
new ForcedRetreatFlux(
this,
AMOUNT))},
3168 {
"tendency_of_ice_mass", f(
new TendencyOfIceAmount(
this,
MASS))},
3169 {
"tendency_of_ice_mass_due_to_flow", f(
new TendencyOfIceAmountDueToFlow(
this,
MASS))},
3170 {
"tendency_of_ice_mass_due_to_conservation_error", f(
new ConservationErrorFlux(
this,
MASS))},
3171 {
"tendency_of_ice_mass_due_to_surface_mass_flux", f(
new SurfaceFlux(
this,
MASS))},
3172 {
"tendency_of_ice_mass_due_to_basal_mass_flux", f(
new BasalFlux(
this,
MASS))},
3173 {
"tendency_of_ice_mass_due_to_discharge", f(
new DischargeFlux(
this,
MASS))},
3174 {
"tendency_of_ice_mass_due_to_calving", f(
new CalvingFlux(
this,
MASS))},
3175 {
"tendency_of_ice_mass_due_to_frontal_melt", f(
new FrontalMeltFlux(
this,
MASS))},
3176 {
"tendency_of_ice_mass_due_to_forced_retreat", f(
new ForcedRetreatFlux(
this,
MASS))},
3179 {
"basal_mass_flux_grounded", f(
new BMBSplit(
this,
GROUNDED))},
3180 {
"basal_mass_flux_floating", f(
new BMBSplit(
this,
SHELF))},
3181 {
"dHdt", f(
new ThicknessRateOfChange(
this))},
3183 {
"grounding_line_flux", f(
new GroundingLineFlux(
this))},
3186 {
"rank", f(
new Rank(
this))},
3189 #if (Pism_USE_PROJ==1)
3190 std::string proj =
m_grid->get_mapping_info().proj;
3191 if (not proj.empty()) {
3192 m_diagnostics[
"lat_bnds"] = f(
new LatLonBounds(
this,
"lat", proj));
3193 m_diagnostics[
"lon_bnds"] = f(
new LatLonBounds(
this,
"lon", proj));
3198 if (
m_config->get_flag(
"output.ISMIP6")) {
3216 {
"ice_area_glacierized", s(
new scalar::IceAreaGlacierized(
this))},
3217 {
"ice_area_glacierized_cold_base", s(
new scalar::IceAreaGlacierizedColdBase(
this))},
3218 {
"ice_area_glacierized_grounded", s(
new scalar::IceAreaGlacierizedGrounded(
this))},
3219 {
"ice_area_glacierized_floating", s(
new scalar::IceAreaGlacierizedShelf(
this))},
3220 {
"ice_area_glacierized_temperate_base", s(
new scalar::IceAreaGlacierizedTemperateBase(
this))},
3222 {
"ice_mass_glacierized", s(
new scalar::IceMassGlacierized(
this))},
3223 {
"ice_mass", s(
new scalar::IceMass(
this))},
3224 {
"tendency_of_ice_mass_glacierized", s(
new scalar::IceMassRateOfChangeGlacierized(
this))},
3225 {
"limnsw", s(
new scalar::IceMassNotDisplacingSeaWater(
this))},
3227 {
"ice_volume_glacierized", s(
new scalar::IceVolumeGlacierized(
this))},
3228 {
"ice_volume_glacierized_cold", s(
new scalar::IceVolumeGlacierizedCold(
this))},
3229 {
"ice_volume_glacierized_grounded", s(
new scalar::IceVolumeGlacierizedGrounded(
this))},
3230 {
"ice_volume_glacierized_floating", s(
new scalar::IceVolumeGlacierizedShelf(
this))},
3231 {
"ice_volume_glacierized_temperate", s(
new scalar::IceVolumeGlacierizedTemperate(
this))},
3232 {
"ice_volume", s(
new scalar::IceVolume(
this))},
3233 {
"ice_volume_cold", s(
new scalar::IceVolumeCold(
this))},
3234 {
"ice_volume_temperate", s(
new scalar::IceVolumeTemperate(
this))},
3235 {
"tendency_of_ice_volume_glacierized", s(
new scalar::IceVolumeRateOfChangeGlacierized(
this))},
3236 {
"tendency_of_ice_volume", s(
new scalar::IceVolumeRateOfChange(
this))},
3237 {
"sea_level_rise_potential", s(
new scalar::SeaLevelRisePotential(
this))},
3239 {
"ice_enthalpy_glacierized", s(
new scalar::IceEnthalpyGlacierized(
this))},
3240 {
"ice_enthalpy", s(
new scalar::IceEnthalpy(
this))},
3242 {
"max_diffusivity", s(
new scalar::MaxDiffusivity(
this))},
3243 {
"max_horizontal_vel", s(
new scalar::MaxHorizontalVelocity(
this))},
3244 {
"dt", s(
new scalar::TimeStepLength(
this))},
3245 {
"dt_ratio", s(
new scalar::TimeStepRatio(
this))},
3247 {
"tendency_of_ice_mass", s(
new scalar::IceMassRateOfChange(
this))},
3248 {
"tendency_of_ice_mass_due_to_flow", s(
new scalar::IceMassRateOfChangeDueToFlow(
this))},
3249 {
"tendency_of_ice_mass_due_to_conservation_error", s(
new scalar::IceMassFluxConservationError(
this))},
3250 {
"tendency_of_ice_mass_due_to_basal_mass_flux", s(
new scalar::IceMassFluxBasal(
this))},
3251 {
"tendency_of_ice_mass_due_to_surface_mass_flux", s(
new scalar::IceMassFluxSurface(
this))},
3252 {
"tendency_of_ice_mass_due_to_discharge", s(
new scalar::IceMassFluxDischarge(
this))},
3253 {
"tendency_of_ice_mass_due_to_calving", s(
new scalar::IceMassFluxCalving(
this))},
3255 {
"basal_mass_flux_grounded", s(
new scalar::IceMassFluxBasalGrounded(
this))},
3256 {
"basal_mass_flux_floating", s(
new scalar::IceMassFluxBasalFloating(
this))},
3257 {
"grounding_line_flux", s(
new scalar::IceMassFluxAtGroundingLine(
this))},
3261 if (
m_config->get_flag(
"output.ISMIP6")) {
3280 typedef std::map<std::string, std::vector<VariableMetadata>>
Metadata;
3283 for (
const auto &d : list) {
3284 const std::string &name = d.first;
3285 log.
message(1,
" Name: %s\n", name.c_str());
3287 for (
const auto &v : d.second) {
3290 var_name = v.get_name(),
3292 output_units = v[
"output_units"],
3293 long_name = v[
"long_name"],
3294 comment = v[
"comment"];
3296 if (not output_units.empty()) {
3297 units = output_units;
3300 log.
message(1,
" %s [%s]\n", var_name.c_str(), units.c_str());
3301 log.
message(1,
" %s\n", long_name.c_str());
3302 if (not comment.empty()) {
3303 log.
message(1,
" %s\n", comment.c_str());
3312 bool first_diagnostic =
true;
3313 for (
const auto &d : list) {
3315 if (not first_diagnostic) {
3318 first_diagnostic =
false;
3321 log.
message(1,
"\"%s\" : [\n", d.first.c_str());
3323 bool first_variable =
true;
3324 for (
const auto &variable : d.second) {
3327 var_name = variable.get_name(),
3328 units = variable[
"units"],
3329 output_units = variable[
"output_units"],
3330 long_name = variable[
"long_name"],
3331 standard_name = variable[
"standard_name"],
3332 comment = variable[
"comment"];
3334 if (not output_units.empty()) {
3335 units = output_units;
3338 if (not first_variable) {
3341 first_variable =
false;
3344 log.
message(1,
"[\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"]",
3345 var_name.c_str(), units.c_str(), long_name.c_str(), standard_name.c_str(), comment.c_str());
3358 for (
const auto& f : diags) {
3361 for (
unsigned int k = 0;
k < diag->n_variables(); ++
k) {
3362 result[f.first].push_back(diag->metadata(
k));
3375 for (
auto d : ts_diags) {
3377 result[d.first] = {d.second->metadata()};
3385 if (list_type ==
"json") {
3386 m_log->message(1,
"{\n");
3388 m_log->message(1,
"\"spatial\" :\n");
3391 m_log->message(1,
",\n");
3393 m_log->message(1,
"\"scalar\" :\n");
3396 m_log->message(1,
"}\n");
3401 if (
member(list_type, {
"all",
"spatial"})) {
3402 m_log->message(1,
"\n");
3403 m_log->message(1,
"======== Available 2D and 3D diagnostics ========\n");
3408 if (
member(list_type, {
"all",
"scalar"})) {
3410 m_log->message(1,
"======== Available time-series ========\n");
3425 auto cell_area =
m_grid->cell_area();
3427 double result = 0.0, meltarea = 0.0;
3434 for (
auto p =
m_grid->points(); p; p.next()) {
3435 const int i = p.i(), j = p.j();
3442 if (EC->is_temperate_relaxed(E_basal, pressure)) {
3443 meltarea += cell_area;
3458 if (total_ice_area > 0.0) {
3459 result = result / total_ice_area;
3473 double result = -1.0;
3479 const double a =
m_grid->cell_area() * 1e-3 * 1e-3,
3480 currtime =
m_time->current();
3487 double original_ice_volume = 0.0;
3492 for (
auto p =
m_grid->points(); p; p.next()) {
3493 const int i = p.i(), j = p.j();
3497 const double *age = ice_age.
get_column(i, j);
3499 for (
int k = 1;
k <= ks;
k++) {
3501 if (0.5 * (age[
k - 1] + age[
k]) > currtime - one_year) {
3502 original_ice_volume += a * 1.0e-3 * (
m_grid->z(
k) -
m_grid->z(
k - 1));
3517 if (total_ice_volume > 0.0) {
3518 result = result / total_ice_volume;
3531 double thickness_threshold) {
3535 auto EC =
ctx->enthalpy_converter();
3537 auto cell_area =
grid->cell_area();
3538 const auto& z =
grid->z();
3540 double volume = 0.0;
3550 auto volume_counter = [EC, kind, cell_area](
double z_min,
double z_max,
double H,
double E) {
3551 double depth = H - z_min;
3552 double P = EC->pressure(depth);
3553 double V = cell_area * (z_max - z_min);
3554 bool temperate = EC->is_temperate_relaxed(E, P);
3558 return temperate ? V : 0.0;
3561 return (not temperate) ? V : 0.0;
3568 for (
auto p =
grid->points(); p; p.next()) {
3569 const int i = p.i(), j = p.j();
3571 double H = ice_thickness(i, j);
3573 if (H >= thickness_threshold) {
3574 const int ks =
grid->kBelowHeight(H);
3575 const double *E = ice_enthalpy.
get_column(i, j);
3577 for (
int k = 0;
k < ks; ++
k) {
3578 volume += volume_counter(z[
k], z[
k + 1], H, E[
k]);
3581 volume += volume_counter(z[ks], H, H, E[ks]);
3595 double thickness_threshold) {
3599 auto EC =
ctx->enthalpy_converter();
3601 auto cell_area =
grid->cell_area();
3608 for (
auto p =
grid->points(); p; p.next()) {
3609 const int i = p.i(), j = p.j();
3611 double thickness = ice_thickness(i, j);
3613 if (thickness >= thickness_threshold) {
3614 double basal_enthalpy = ice_enthalpy.
get_column(i, j)[0];
3616 bool temperate = EC->is_temperate_relaxed(basal_enthalpy,
3617 EC->pressure(thickness));
3621 area += temperate ? cell_area : 0.0;
3625 area += (not temperate) ? cell_area : 0.0;
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
A class for storing and accessing PISM configuration flags and parameters.
array::Scalar m_accumulator
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
std::shared_ptr< array::Array > compute() const
Compute a diagnostic quantity and return a pointer to a newly-allocated Array.
const Config::ConstPtr m_config
Configuration flags and parameters.
Class representing diagnostic computations in PISM.
std::shared_ptr< EnthalpyConverter > Ptr
void compute_mask(const array::Scalar &sea_level, const array::Scalar &bed, const array::Scalar &thickness, array::Scalar &result) const
void set_icefree_thickness(double threshold)
const array::Scalar & thickness_change_due_to_flow() const
const array::Scalar & bottom_surface_mass_balance() const
const array::Scalar & top_surface_mass_balance() const
const array::Scalar & area_specific_volume_change_due_to_flow() const
const array::Scalar & conservation_error() const
const array::Staggered1 & flux_staggered() const
array::Scalar1 sea_level_elevation
array::Scalar cell_grounded_fraction
array::Scalar2 ice_surface_elevation
array::Scalar1 ice_area_specific_volume
array::CellType2 cell_type
array::Scalar2 ice_thickness
array::Scalar2 bed_elevation
PointsWithGhosts points(unsigned int stencil_width=0) const
std::shared_ptr< const Context > ctx() const
Return execution context this grid corresponds to.
Describes the PISM grid and the distribution of data across processors.
std::map< std::string, const Component * > m_submodels
the list of sub-models, for writing model states and obtaining diagnostics
virtual double compute_temperate_base_fraction(double ice_area)
const Geometry & geometry() const
double ice_volume_temperate(double thickness_threshold) const
Computes the temperate ice volume, in m^3.
std::map< std::string, TSDiagnostic::Ptr > m_ts_diagnostics
Requested scalar diagnostics.
const Config::Ptr m_config
Configuration flags and parameters.
double cold_base_area(double thickness_threshold) const
Computes area of basal ice which is cold, in m^2.
const Time::Ptr m_time
Time manager.
const GeometryEvolution & geometry_evolution() const
const stressbalance::StressBalance * stress_balance() const
double temperate_base_area(double thickness_threshold) const
Computes area of basal ice which is temperate, in m^2.
virtual double compute_original_ice_fraction(double ice_volume)
array::Scalar m_basal_melt_rate
rate of production of basal meltwater (ice-equivalent); no ghosts
std::shared_ptr< Grid > grid() const
Return the grid used by this model.
const std::shared_ptr< Context > m_ctx
Execution context.
const Logger::Ptr m_log
Logger.
array::Scalar m_bedtoptemp
temperature at the top surface of the bedrock thermal layer
double ice_volume_cold(double thickness_threshold) const
Computes the cold ice volume, in m^3.
const energy::EnergyModel * energy_balance_model() const
const array::Scalar & frontal_melt() const
const array::Scalar & forced_retreat() const
array::Scalar2 m_velocity_bc_mask
mask to determine Dirichlet boundary locations for the sliding velocity
array::Scalar1 m_ice_thickness_bc_mask
Mask prescribing locations where ice thickness is held constant.
std::shared_ptr< AgeModel > m_age_model
const units::System::Ptr m_sys
Unit system.
array::Vector2 m_velocity_bc_values
Dirichlet boundary velocities.
void list_diagnostics(const std::string &list_type) const
std::map< std::string, Diagnostic::Ptr > m_diagnostics
Requested spatially-variable diagnostics.
const array::Scalar & calving() const
std::shared_ptr< Context > ctx() const
Return the context this model is running in.
virtual void init_diagnostics()
std::shared_ptr< energy::EnergyModel > m_energy_model
const std::shared_ptr< Grid > m_grid
Computational grid.
void message(int threshold, const char format[],...) const __attribute__((format(printf
Print a message to the log.
void failed()
Indicates a failure of a parallel section.
A wrapper for PJ that makes sure pj_destroy is called.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
void set_units(const std::string &units, const std::string &output_units)
VariableMetadata m_variable
const Config::ConstPtr m_config
Configuration flags and parameters.
std::shared_ptr< const Grid > m_grid
the grid
std::shared_ptr< TSDiagnostic > Ptr
Scalar diagnostic reporting a "flux".
Scalar diagnostic reporting the rate of change of a quantity modeled by PISM.
Scalar diagnostic reporting a snapshot of a quantity modeled by PISM.
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void copy_from(const Array2D< T > &source)
stencils::Star< T > star(int i, int j) const
void add(double alpha, const Array2D< T > &x)
void copy_from(const Array3D &input)
double * get_column(int i, int j)
A virtual class collecting methods common to ice and bedrock 3D fields.
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.
stencils::Star< int > star_int(int i, int j) const
bool next_to_ice_free_ocean(int i, int j) const
bool ice_free_ocean(int i, int j) const
bool grounded_ice(int i, int j) const
bool icy(int i, int j) const
BMBSplit(const IceModel *m, AreaType flag)
void update_impl(double dt)
Report average basal mass balance flux over the reporting interval (grounded or floating areas)
BasalFlux(const IceModel *m, AmountKind kind)
void update_impl(double dt)
Report basal mass balance flux, averaged over the reporting interval.
BedTopographySeaLevelAdjusted(const IceModel *m)
std::shared_ptr< array::Array > compute_impl() const
Sea-level adjusted bed topography (zero at sea level).
virtual std::shared_ptr< array::Array > compute_impl() const
Computes CTS, CTS = E/E_s(p).
void update_impl(double dt)
CalvingFlux(const IceModel *m, AmountKind kind)
void update_impl(double dt)
ConservationErrorFlux(const IceModel *m, AmountKind kind)
void update_impl(double dt)
DischargeFlux(const IceModel *m, AmountKind kind)
Report discharge (calving and frontal melt) flux.
ForcedRetreatFlux(const IceModel *m, AmountKind kind)
void update_impl(double dt)
Report the frontal melt flux.
FrontalMeltFlux(const IceModel *m, AmountKind kind)
void update_impl(double dt)
Report the frontal melt flux.
void update_impl(double dt)
GroundingLineFlux(const IceModel *m)
Report grounding line flux.
HardnessAverage(const IceModel *m)
virtual std::shared_ptr< array::Array > compute_impl() const
Computes vertically-averaged ice hardness.
Computes vertically-averaged ice hardness.
HeightAboveFloatation(const IceModel *m)
virtual std::shared_ptr< array::Array > compute_impl() const
Computes the 2D height above flotation.
IceAreaFractionFloating(const IceModel *m)
virtual std::shared_ptr< array::Array > compute_impl() const
IceAreaFractionGrounded(const IceModel *m)
virtual std::shared_ptr< array::Array > compute_impl() const
IceAreaFraction(const IceModel *m)
virtual std::shared_ptr< array::Array > compute_impl() const
IceBottomSurfaceElevation(const IceModel *m)
std::shared_ptr< array::Array > compute_impl() const
Report ice top surface elevation.
virtual std::shared_ptr< array::Array > compute_impl() const
IceEnthalpyBasal(const IceModel *m)
Computes enthalpy at the base of the ice.
IceEnthalpySurface(const IceModel *m)
virtual std::shared_ptr< array::Array > compute_impl() const
Computes surface values of ice enthalpy.
IceHardness(const IceModel *m)
std::shared_ptr< array::Array > compute_impl() const
Ice hardness computed using the SIA flow law.
std::shared_ptr< array::Array > compute_impl() const
IceMarginPressureDifference(IceModel *m)
Ocean pressure difference at calving fronts. Used to debug CF boundary conditins.
IceMass(const IceModel *m)
virtual std::shared_ptr< array::Array > compute_impl() const
Computes the mass per cell.
IceSurfaceElevation(const IceModel *m)
std::shared_ptr< array::Array > compute_impl() const
Report ice top surface elevation.
std::shared_ptr< array::Array > compute_impl() const
IceThickness(const IceModel *m)
std::shared_ptr< array::Array > compute_impl() const
IceViscosity(IceModel *m)
Effective viscosity of ice (3D).
LatLonBounds(const IceModel *m, const std::string &var_name, const std::string &proj_string)
std::string m_proj_string
virtual std::shared_ptr< array::Array > compute_impl() const
Computes latitude and longitude bounds.
virtual std::shared_ptr< array::Array > compute_impl() const
LiquidFraction(const IceModel *m)
Computes the liquid water fraction.
virtual std::shared_ptr< array::Array > compute_impl() const
Computes a diagnostic field filled with processor rank values.
SurfaceFlux(const IceModel *m, AmountKind kind)
void update_impl(double dt)
Report surface mass balance flux, averaged over the reporting interval.
TemperateIceThicknessBasal(const IceModel *m)
virtual std::shared_ptr< array::Array > compute_impl() const
Computes the thickness of the basal layer of temperate ice.
TemperateIceThickness(const IceModel *m)
virtual std::shared_ptr< array::Array > compute_impl() const
Computes the total thickness of temperate ice in a column.
std::shared_ptr< array::Array > compute_impl() const
TemperatureBasal(const IceModel *m, AreaType flag)
Computes ice temperature at the base of the ice.
virtual std::shared_ptr< array::Array > compute_impl() const
TemperaturePABasal(const IceModel *m)
Computes basal values of the pressure-adjusted temperature.
virtual std::shared_ptr< array::Array > compute_impl() const
TemperaturePA(const IceModel *m)
Compute the pressure-adjusted temperature in degrees C corresponding to ice temperature.
virtual std::shared_ptr< array::Array > compute_impl() const
TemperatureSurface(const IceModel *m)
Computes ice temperature at the surface of the ice.
virtual std::shared_ptr< array::Array > compute_impl() const
Temperature(const IceModel *m)
Computes ice temperature from enthalpy.
void update_impl(double dt)
TendencyOfIceAmountDueToFlow(const IceModel *Model, AmountKind kind)
Computes tendency_of_ice_amount_due_to_flow, the rate of change of ice amount due to flow.
std::shared_ptr< array::Array > compute_impl() const
void update_impl(double dt)
TendencyOfIceAmount(const IceModel *Model, AmountKind kind)
array::Scalar m_last_amount
Computes tendency_of_ice_amount, the ice amount rate of change.
array::Scalar m_last_thickness
ThicknessRateOfChange(const IceModel *m)
void update_impl(double dt)
std::shared_ptr< array::Array > compute_impl() const
Computes dHdt, the ice thickness rate of change.
IceAreaGlacierizedColdBase(IceModel *m)
Computes the total area of the cold ice.
IceAreaGlacierizedGrounded(IceModel *m)
Computes the total grounded ice area.
IceAreaGlacierizedShelf(IceModel *m)
Computes the total floating ice area.
IceAreaGlacierizedTemperateBase(IceModel *m)
Computes the total area of the temperate ice.
IceAreaGlacierized(IceModel *m)
Computes the total ice area.
IceEnthalpyGlacierized(IceModel *m)
Computes the total ice enthalpy in glacierized areas.
Computes the total ice enthalpy.
IceMassFluxAtGroundingLine(const IceModel *m)
Reports the total flux across the grounding line.
IceMassFluxBasalFloating(const IceModel *m)
Reports the total sub-shelf ice flux.
IceMassFluxBasalGrounded(const IceModel *m)
Reports the total basal ice flux over the grounded region.
IceMassFluxBasal(const IceModel *m)
Reports the total bottom surface ice flux.
IceMassFluxCalving(const IceModel *m)
Reports the total calving flux.
IceMassFluxConservationError(const IceModel *m)
Reports the total numerical mass flux needed to preserve non-negativity of ice thickness.
IceMassFluxDischarge(const IceModel *m)
Reports the total discharge flux.
IceMassFluxSurface(const IceModel *m)
Reports the total top surface ice flux.
IceMassGlacierized(IceModel *m)
Computes the total ice mass in glacierized areas.
IceMassNotDisplacingSeaWater(const IceModel *m)
Computes the total mass of the ice not displacing sea water.
IceMassRateOfChangeDueToFlow(IceModel *m)
Computes the rate of change of the total ice mass due to flow (influx due to prescribed constant-in-t...
IceMassRateOfChangeGlacierized(IceModel *m)
Computes the rate of change of the total ice mass in glacierized areas.
IceMassRateOfChange(IceModel *m)
Computes the rate of change of the total ice mass.
Computes the total ice mass.
IceVolumeCold(IceModel *m)
Computes the total volume of the cold ice.
IceVolumeGlacierizedCold(IceModel *m)
Computes the total volume of the cold ice in glacierized areas.
IceVolumeGlacierizedGrounded(IceModel *m)
Computes the total grounded ice volume.
IceVolumeGlacierizedShelf(IceModel *m)
Computes the total floating ice volume.
IceVolumeGlacierizedTemperate(IceModel *m)
Computes the total volume of the temperate ice in glacierized areas.
IceVolumeGlacierized(IceModel *m)
Computes the total ice volume in glacierized areas.
IceVolumeRateOfChangeGlacierized(IceModel *m)
Computes the rate of change of the total ice volume in glacierized areas.
IceVolumeRateOfChange(IceModel *m)
Computes the rate of change of the total ice volume.
IceVolumeTemperate(IceModel *m)
Computes the total volume of the temperate ice.
Computes the total ice volume.
MaxDiffusivity(const IceModel *m)
Reports maximum diffusivity.
MaxHorizontalVelocity(const IceModel *m)
Reports the maximum horizontal absolute velocity component over the grid.
SeaLevelRisePotential(const IceModel *m)
Computes the total ice volume which is relevant for sea-level.
TimeStepLength(const IceModel *m)
Reports the mass continuity time step.
TimeStepRatio(const IceModel *m)
Reports the mass continuity time step.
const array::Array3D & enthalpy() const
void effective_viscosity(double hardness, double gamma, double *nu, double *dnu) const
Computes the regularized effective viscosity and its derivative with respect to the second invariant ...
double hardness(double E, double p) const
std::shared_ptr< const rheology::FlowLaw > flow_law() const
std::shared_ptr< const rheology::FlowLaw > flow_law() const
CFLData max_timestep_cfl_3d() const
const array::Array3D & velocity_w() const
const SSB_Modifier * modifier() const
Returns a pointer to a stress balance modifier implementation.
const array::Array3D & velocity_u() const
Get components of the the 3D velocity field.
CFLData max_timestep_cfl_2d() const
double max_diffusivity() const
Get the max diffusivity (for the adaptive time-stepping).
const ShallowStressBalance * shallow() const
Returns a pointer to a shallow stress balance solver implementation.
const array::Array3D & velocity_v() const
#define PISM_ERROR_LOCATION
void extract_surface(const Array3D &data, double z, Scalar &output)
Copies a horizontal slice at level z of an Array3D into output.
void apply_mask(const array::Scalar &M, double fill, array::Scalar &result)
Masks out all the areas where by setting them to fill.
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
double min(const array::Scalar &input)
Finds minimum over all the values in an array::Scalar object. Ignores ghosts.
static double ice_volume(const array::Scalar &ice_thickness, const array::Array3D &ice_enthalpy, IceKind kind, double thickness_threshold)
static double base_area(const array::Scalar &ice_thickness, const array::Array3D &ice_enthalpy, IceKind kind, double thickness_threshold)
double mass_change(const IceModel *model, TermType term, AreaType area)
static double square(double x)
static void accumulate_changes(const IceModel *model, double factor, ChangeKind kind, array::Scalar &accumulator)
void compute_liquid_water_fraction(const array::Array3D &enthalpy, const array::Scalar &ice_thickness, array::Array3D &result)
Compute the liquid fraction corresponding to enthalpy and ice_thickness.
void compute_cts(const array::Array3D &ice_enthalpy, const array::Scalar &ice_thickness, array::Array3D &result)
Compute the CTS field, CTS = E/E_s(p), from ice_enthalpy and ice_thickness, and put in result.
double total_ice_enthalpy(double thickness_threshold, const array::Array3D &ice_enthalpy, const array::Scalar &ice_thickness)
Computes the total ice enthalpy in J.
bool domain_edge(const Grid &grid, int i, int j)
bool ice_free(int M)
Ice-free cell (grounded or ocean).
double averaged_hardness(const FlowLaw &ice, double thickness, unsigned int kbelowH, const double *zlevels, const double *enthalpy)
Computes vertical average of B(E, p) ice hardness, namely .
double convert(System::Ptr system, double input, const std::string &spec1, const std::string &spec2)
Convert a quantity from unit1 to unit2.
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.
double grounded_area_fraction(double a, double b, double c)
static const char * grounded_ice_sheet_area_fraction_name
static Metadata diag_metadata(const std::map< std::string, Diagnostic::Ptr > &diags)
double average_water_column_pressure(double ice_thickness, double bed, double floatation_level, double rho_ice, double rho_water, double g)
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 part_grid_threshold_thickness(stencils::Star< int > cell_type, stencils::Star< double > ice_thickness, stencils::Star< double > surface_elevation, double bed_elevation)
Compute threshold thickness used when deciding if a partially-filled cell should be considered 'full'...
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.
double total_grounding_line_flux(const array::CellType1 &cell_type, const array::Staggered1 &flux, double dt)
static void print_diagnostics_json(const Logger &log, const Metadata &list)
double ice_volume(const Geometry &geometry, double thickness_threshold)
Computes the ice volume, in m^3.
void grounding_line_flux(const array::CellType1 &cell_type, const array::Staggered1 &flux, double dt, bool add_values, array::Scalar &output)
void ice_bottom_surface(const Geometry &geometry, array::Scalar &result)
bool member(const std::string &string, const std::set< std::string > &set)
MaxTimestep max_timestep_diffusivity(double D_max, double dx, double dy, double adaptive_timestepping_ratio)
static Metadata ts_diag_metadata(const std::map< std::string, TSDiagnostic::Ptr > &ts_diags)
static void print_diagnostics(const Logger &log, const Metadata &list)
double ice_area_grounded(const Geometry &geometry, double thickness_threshold)
Computes grounded ice area, in m^2.
T combine(const T &a, const T &b)
void compute_lat_bounds(const std::string &projection, array::Array3D &result)
void GlobalSum(MPI_Comm comm, double *local, double *result, int count)
void compute_lon_bounds(const std::string &projection, array::Array3D &result)
std::map< std::string, std::vector< VariableMetadata > > Metadata
static const char * land_ice_area_fraction_name
static const char * floating_ice_sheet_area_fraction_name