Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MassEnergyBudget.cc
Go to the documentation of this file.
1#include <iostream>
2
3#include "pism/icebin/MassEnergyBudget.hh"
4#include "pism/util/VariableMetadata.hh"
5
6namespace pism {
7namespace icebin {
8
9MassEnthVec2S::MassEnthVec2S(std::shared_ptr<const pism::Grid> grid, const std::string &name)
10 : mass(grid, name + ".mass"), enth(grid, name + ".enth") {
11}
12
13void MassEnthVec2S::set_attrs(const std::string &long_name, const std::string &units) {
14 mass.metadata().long_name(long_name + " (mass portion)").units("kg " + units);
15 enth.metadata().long_name(long_name + " (enthalpy portion)").units("J " + units);
16}
17
18MassEnergyBudget::MassEnergyBudget(std::shared_ptr<const pism::Grid> grid,
19 std::string const &prefix)
20 : total(grid, prefix + "total"),
21 basal_frictional_heating(grid, prefix + "basal_frictional_heating"),
22 strain_heating(grid, prefix + "strain_heating"),
23 geothermal_flux(grid, prefix + "geothermal_flux"),
24 upward_geothermal_flux(grid, prefix + "upward_geothermal_flux"),
25 calving(grid, prefix + "calving"),
26 smb(grid, prefix + "smb"),
27 deltah(grid, prefix + "deltah"),
28 pism_smb(grid, prefix + "pism_smb"),
29 href_to_h(grid, prefix + "href_to_h"),
30 nonneg_rule(grid, prefix + "nonneg_rule"),
31 melt_grounded(grid, prefix + "melt_grounded"),
32 melt_floating(grid, prefix + "melt_floating"),
33 internal_advection(grid, prefix + "internal_advection"),
34 epsilon(grid, prefix + "epsilon") {
35
36 // ----------- Mass and Enthalpy State of the Ice Sheet
37
38 total.set_attrs("State of the ice sheet (NOT a difference between time steps)", "m-2");
39 add_massenth(total, TOTAL, "", "");
40
41 // ----------- Heat generation of flows [vertical]
42 // Postive means heat is flowing INTO the ice sheet.
43
44 basal_frictional_heating.metadata(0).long_name("Basal frictional heating").units("W m^-2");
45 add_enth(basal_frictional_heating, DELTA, "basal_frictional_heating");
46
47 strain_heating.metadata(0).long_name("Strain heating").units("W m^-2");
48 add_enth(strain_heating, DELTA, "strain_heating"); //!< Total amount of strain heating [J/m^2]
49
51 .long_name("Geothermal energy through (compare to upward_geothermal_flux?)")
52 .units("W m^-2");
53 add_enth(geothermal_flux, 0, "geothermal_flux"); //!< Total amount of geothermal energy [J/m^2]
54
56 .long_name("Geothermal energy through (compare to geothermal_flux?)")
57 .units("W m^-2");
58 // Total amount of geothermal energy [J/m^2]
59 add_enth(upward_geothermal_flux, DELTA, "upward_geothermal_flux");
60
61 // ----------- Mass advection, with accompanying enthalpy change
62 // Postive means mass/enthalpy is flowing INTO the ice sheet.
63 calving.set_attrs("Mass/Enthalpy gain from calving. Should be negative.",
64 "m-2 s-1");
65 add_massenth(calving, DELTA, "calving.mass", "calving.enth");
66
67 // SMB as seen by PISM in iMgeometry.cc massContExplicitSte().
68 // Used to check icebin_smb.mass, but does not figure into
69 // contract.
70 pism_smb.set_attrs("pism_smb", "m-2 s-1");
71 // No DELTA< does not participate in epsilon computation
72 add_massenth(pism_smb, EPSILON, "pism_smb.mass", "pism_smb.enth");
73
74 // accumulation / ablation, as provided by Icebin
75 smb.set_attrs("smb", "m-2 s-1");
76 add_massenth(smb, DELTA, "smb.mass", "smb.enth");
77
78 deltah.metadata(0).long_name("deltah").units("J m^-2 s^-1");
79 add_enth(deltah, DELTA, "");
80
81 href_to_h.metadata(0).long_name("href_to_h").units("kg m^-2 s^-1");
82 add_mass(href_to_h, 0, "");
83
84 nonneg_rule.metadata(0).long_name("nonneg_rule").units("kg m^-2 s^-1");
85 add_mass(nonneg_rule, 0, "");
86
87
88 melt_grounded.set_attrs("Basal melting of grounded ice (negative)", "m-2 s-1");
89 add_massenth(melt_grounded, DELTA, "melt_grounded.mass", "melt_grounded.enth");
90
91 melt_floating.set_attrs("Sub-shelf melting (negative)", "m-2 s-1");
92 add_massenth(melt_floating, DELTA, "melt_floating.mass", "melt_floating.enth");
93
94 // ----------- Advection WITHIN the ice sheet
95 internal_advection.set_attrs("Advection within the ice sheet", "m-2 s-1");
96 add_massenth(internal_advection, DELTA, "internal_advection.mass", "internal_advection.enth");
97
98 // ----------- Balance the Budget
99 epsilon.set_attrs("Unaccounted-for changes", "m-2 s-1");
100 add_massenth(epsilon, EPSILON, "epsilon.mass", "epsilon.enth");
101}
102
103std::ostream &MassEnergyBudget::print_formulas(std::ostream &out) {
104 // MASS
105 out << "epsilon.mass = total.mass -" << std::endl;
106 out << " (";
107 for (auto ii = all_vecs.begin(); ii != all_vecs.end(); ++ii) {
108 if ((ii->flags & (DELTA | MASS)) != (DELTA | MASS)) {
109 continue;
110 }
111 char str[20];
112 sprintf(str, "%p", (void *)&ii->vec);
113 out << ii->vec.get_name() << " + ";
114 }
115 out << ")" << std::endl;
116
117 // Energy
118 out << "epsilon.enth = total.enth -" << std::endl;
119 out << " (";
120 for (auto ii = all_vecs.begin(); ii != all_vecs.end(); ++ii) {
121 if ((ii->flags & (DELTA | ENTH)) != (DELTA | ENTH)) {
122 continue;
123 }
124 char str[20];
125 sprintf(str, "%p", (void *)&ii->vec);
126 out << ii->vec.get_name() << " + ";
127 }
128 out << ")" << std::endl;
129
130 return out;
131}
132
133
135 auto grid = epsilon.mass.grid();
136 // ==> epsilon = (sum of fluxes) - total
137
138 // -------- Mass
141 for (int i = grid->xs(); i < grid->xs() + grid->xm(); ++i) {
142 for (int j = grid->ys(); j < grid->ys() + grid->ym(); ++j) {
143 epsilon.mass(i, j) = total.mass(i, j);
144 }
145 }
147
148 for (auto &ii : all_vecs) {
149 // This normally does not include things marked EPSILON
150 // (which is mutually exclusive with DELTA)
151 // This excluded epsilon (ourself), as well as redundant pism_smb
152 if ((ii.flags & (DELTA | MASS)) != (DELTA | MASS)) {
153 continue;
154 }
155
156 ii.vec.begin_access();
157 for (int i = grid->xs(); i < grid->xs() + grid->xm(); ++i) {
158 for (int j = grid->ys(); j < grid->ys() + grid->ym(); ++j) {
159 epsilon.mass(i, j) -= ii.vec(i, j);
160 }
161 }
162 ii.vec.end_access();
163 }
165
166 // -------- Energy
169 for (int i = grid->xs(); i < grid->xs() + grid->xm(); ++i) {
170 for (int j = grid->ys(); j < grid->ys() + grid->ym(); ++j) {
171 epsilon.enth(i, j) = total.enth(i, j);
172 }
173 }
175
176#if 1
177 for (auto &ii : all_vecs) {
178 if ((ii.flags & (DELTA | ENTH)) != (DELTA | ENTH)) {
179 continue;
180 }
181
182 printf("epsilon.energy: %s\n", ii.vec.get_name().c_str());
183
184 ii.vec.begin_access();
185 for (int i = grid->xs(); i < grid->xs() + grid->xm(); ++i) {
186 for (int j = grid->ys(); j < grid->ys() + grid->ym(); ++j) {
187 epsilon.enth(i, j) -= ii.vec(i, j);
188 }
189 }
190 ii.vec.end_access();
191 }
192#endif
194}
195
196} // namespace icebin
197} // namespace pism
VariableMetadata & long_name(const std::string &input)
VariableMetadata & units(const std::string &input)
virtual void end_access() const
Checks if an Array is allocated and calls DAVecRestoreArray.
Definition Array.cc:589
virtual void begin_access() const
Checks if an Array is allocated and calls DAVecGetArray.
Definition Array.cc:568
petsc::Vec & vec() const
Definition Array.cc:310
std::shared_ptr< const Grid > grid() const
Definition Array.cc:131
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
Definition Array.cc:476
pism::array::Scalar href_to_h
SMB as seen by PISM in iMgeometry.cc massContExplicitSte(). Used to check icebin_smb....
MassEnergyBudget(std::shared_ptr< const pism::Grid > grid, std::string const &prefix)
std::ostream & print_formulas(std::ostream &out)
MassEnthVec2S calving
Equal to IceModel::discharge_flux_2D_cumulative.
pism::array::Scalar geothermal_flux
Total amount of geothermal energy [J/m^2].
MassEnthVec2S smb
accumulation / ablation, as provided by Icebin
pism::array::Scalar basal_frictional_heating
Total amount of basal friction heating [J/m^2].
std::vector< VecWithFlags > all_vecs
void add_enth(pism::array::Scalar &vec, int flags, std::string const &contract_name)
pism::array::Scalar strain_heating
Total amount of strain heating [J/m^2].
MassEnthVec2S melt_grounded
basal melt (grounded) (from summing meltrate_grounded)
pism::array::Scalar upward_geothermal_flux
Total amount of geothermal energy [J/m^2].
MassEnthVec2S melt_floating
sub-shelf melt (from summing meltrate_floating)
void add_massenth(MassEnthVec2S &massenth, int flags, std::string const &contract_name_mass, std::string const &contract_name_enth)
void add_mass(pism::array::Scalar &vec, int flags, std::string const &contract_name)
pism::array::Scalar deltah
Change in enthalpy of top layer.
std::string printf(const char *format,...)
void set_attrs(const std::string &long_name, const std::string &units)
MassEnthVec2S(std::shared_ptr< const pism::Grid > grid, const std::string &name)