PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
MassEnergyBudget.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include "pism/util/array/Scalar.hh"
4 #include <memory>
5 
6 namespace pism {
7 namespace icebin {
8 
9 /** Encapsulates mass and enthalpy together. Used to tabulate total
10 enthalpy of a bunch of advected H2O based on its mass and specific
11 enthalpy. This allows us to have only one C++ variable per advected
12 quantity, instead of two. */
16 
17  MassEnthVec2S(std::shared_ptr<const pism::Grid> grid, const std::string &name);
18 
19  void set_attrs(const std::string &long_name, const std::string &units);
20 
21  virtual void begin_access() const {
24  }
25 
26  virtual void end_access() const {
27  mass.end_access();
28  enth.end_access();
29  }
30 
31 #if 0
32  /** @param mass [kg m-2]
33  @param specific_enthalpy [J kg-1] */
34  void add_mass(int i, int j, double mass, double specific_enthalpy) {
35  mass(i,j) += mass;
36  enthalpy(i,j) += mass * specific_enthalpy;
37  }
38 
39  void clear() {
40  mass.set(0);
41  enth.set(0);
42  }
43 #endif
44 };
45 
46 struct VecWithFlags {
48  int flags;
49 
50  /** IF this variable is used directly as a contractual ice model
51  output, the name of that contract entry. */
52  std::string contract_name;
53 
54  VecWithFlags(pism::array::Scalar &_vec, int _flags, std::string const &_contract_name)
55  : vec(_vec), flags(_flags), contract_name(_contract_name) {
56  }
57 };
58 
60 public:
61  // ============================================================
62  // Total State
63 
64  // ------------ Enthalpy State
65  MassEnthVec2S total; // Total mass [kg m-2] and enthalpy [J m-2] of the ice sheet
66 
67  // =============================================================
68  // Cumulative Fluxes
69 
70  // ======================= Variables to accumulate PISM output
71  // These are accumulated as [kg m-2] or [J m-2]
72  // They are accumulated for the life of the simulation, and never zeroed.
73  // Other instances of MassEnergyBudget are used to compute differences.
74 
75  // ----------- Heat generation of flows [vertical]
76  pism::array::Scalar basal_frictional_heating; //!< Total amount of basal friction heating [J/m^2]
77  pism::array::Scalar strain_heating; //!< Total amount of strain heating [J/m^2]
78  pism::array::Scalar geothermal_flux; //!< Total amount of geothermal energy [J/m^2]
79  pism::array::Scalar upward_geothermal_flux; //!< Total amount of geothermal energy [J/m^2]
80 
81  // ----------- Mass advection, with accompanying enthalpy change
82  // The enthalpy reported for these mass fluxes are the enthalpies
83  // AS REPORTED TO ICEBIN! That is not necessarily the same as the enthalpy
84  // that PISM sees internally.
85  MassEnthVec2S calving; //!< Equal to IceModel::discharge_flux_2D_cumulative
86 
87  // Let's not use basal_runoff (which would be derived from the variables
88  // in NullTransportHydrology).
89  //
90  // 1. It is derived directly from
91  // bmelt/basal_meltrate/melt_grounded/meltrate_grounded, which is
92  // already computed here.
93  //
94  // 2. bmelt plays directly into removal of mass from the ice sheet (see
95  // accumulateFluxes_massContExplicitStep() in iMgeometry.cc).
96  // Including basal_runoff would be double-counting it.
97  // MassEnthVec2S basal_runoff; //!< Enthalpy here is predictable, since runoff is 0C 100% water fraction.
98 
99  MassEnthVec2S smb; //!< accumulation / ablation, as provided by Icebin
100  pism::array::Scalar deltah; //!< Change in enthalpy of top layer
102  pism_smb; //! SMB as seen by PISM in iMgeometry.cc massContExplicitSte(). Used to check icebin_smb.mass, but does not figure into contract.
105  MassEnthVec2S melt_grounded; //!< basal melt (grounded) (from summing meltrate_grounded)
106  MassEnthVec2S melt_floating; //!< sub-shelf melt (from summing meltrate_floating)
107 
108  // ----------- Mass advection WITHIN the ice sheet
110  // MassEnthVec2S divQ_SIA;
111  // MassEnthVec2S divQ_SSA; //!< flux divergence
112 
113  // ======================= Balance the Budget
114  // At each step, we set epsilon as follows:
115  // total - (sum of fluxes) + epsilon = 0
116  // ==> epsilon = (sum of fluxes) - total
118 
119  // ======================== Different sets (flags)
120  static const int MASS = 1;
121  static const int ENTH = 2;
122 
123  // No post-processing: Value written to NetCDF is same as accumulated value.
124  // Good for things taht are set once.
125  // (eg: total.mass and total.enth, which are not wrten to NetCDF).
126  static const int TOTAL = 4;
127  // Variable to be accumulated, differenced and /dt at end;
128  // and also go into computation of epsilon
129  static const int DELTA = 8;
130  // Do NOT include in computation of epsilon, since this flag IS
131  // for the varaiable epsilon (and also pism_smb)
132  static const int EPSILON = 16; // To be differenced at the end.
133  static const int ADVECTION =
134  32; // This energy term is due to advection of a related mass term (not acted upon)
135 
136  // ======================== Summary of above variables
137  // This makes it easy to difference two MassEnergyBudget instances.
138  std::vector<VecWithFlags> all_vecs;
139 
140 
141  // =====================================================================
142  std::ostream &print_formulas(std::ostream &out);
143 
144 protected:
145  void add_mass(pism::array::Scalar &vec, int flags, std::string const &contract_name) {
146  all_vecs.push_back(VecWithFlags(vec, MASS | flags, contract_name));
147  }
148 
149  /** @param contract_name The name of this variable in the ice model's output contract. */
150  void add_enth(pism::array::Scalar &vec, int flags, std::string const &contract_name) {
151  all_vecs.push_back(VecWithFlags(vec, ENTH | flags, contract_name));
152  }
153 
154  void add_massenth(MassEnthVec2S &massenth, int flags, std::string const &contract_name_mass,
155  std::string const &contract_name_enth) {
156  all_vecs.push_back(VecWithFlags(massenth.mass, MASS | flags, contract_name_mass));
157  all_vecs.push_back(VecWithFlags(massenth.enth, ENTH | ADVECTION | flags, contract_name_enth));
158  }
159 
160 public:
161  MassEnergyBudget(std::shared_ptr<const pism::Grid> grid, std::string const &prefix);
162 
163  void set_epsilon();
164 };
165 
166 } // end of namespace icebin
167 } // end of namespace pism
virtual void end_access() const
Checks if an Array is allocated and calls DAVecRestoreArray.
Definition: Array.cc:667
virtual void begin_access() const
Checks if an Array is allocated and calls DAVecGetArray.
Definition: Array.cc:646
void set(double c)
Result: v[j] <- c for all j.
Definition: Array.cc:707
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.
virtual void begin_access() const
void set_attrs(const std::string &long_name, const std::string &units)
MassEnthVec2S(std::shared_ptr< const pism::Grid > grid, const std::string &name)
virtual void end_access() const
VecWithFlags(pism::array::Scalar &_vec, int _flags, std::string const &_contract_name)
pism::array::Scalar & vec