PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
energy.cc
Go to the documentation of this file.
1 // Copyright (C) 2004-2011, 2013, 2014, 2015, 2016, 2017, 2018, 2021, 2023 Jed Brown, Ed Bueler and Constantine Khroulev
2 //
3 // This file is part of PISM.
4 //
5 // PISM is free software; you can redistribute it and/or modify it under the
6 // terms of the GNU General Public License as published by the Free Software
7 // Foundation; either version 3 of the License, or (at your option) any later
8 // version.
9 //
10 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with PISM; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #include <cassert>
20 
21 #include "pism/icemodel/IceModel.hh"
22 
23 #include "pism/energy/BedThermalUnit.hh"
24 #include "pism/util/Grid.hh"
25 #include "pism/util/ConfigInterface.hh"
26 #include "pism/util/error_handling.hh"
27 #include "pism/coupler/SurfaceModel.hh"
28 #include "pism/util/EnthalpyConverter.hh"
29 #include "pism/util/Profiling.hh"
30 
31 #include "pism/energy/EnergyModel.hh"
32 
33 namespace pism {
34 
35 //! \file energy.cc Methods of IceModel which address conservation of energy.
36 //! Common to enthalpy (polythermal) and temperature (cold-ice) methods.
37 
39 
40  const Profiling &profiling = m_ctx->profiling();
41 
42  array::Scalar &basal_enthalpy = *m_work2d[2];
43 
44  extract_surface(m_energy_model->enthalpy(), 0.0, basal_enthalpy);
45 
50  basal_enthalpy,
51  m_surface->temperature(),
52  m_bedtoptemp);
53 
54  profiling.begin("btu");
56  profiling.end("btu");
57 }
58 
59 //! Manage the solution of the energy equation, and related parallel communication.
61 
62  // operator-splitting occurs here (ice and bedrock energy updates are split):
63  // tell BedThermalUnit* btu that we have an ice base temp; it will return
64  // the z=0 value of geothermal flux when called inside temperatureStep() or
65  // enthalpyStep()
67 
69 
70  m_stdout_flags = m_energy_model->stdout_flags() + m_stdout_flags;
71 }
72 
73 //! @brief Combine basal melt rate in grounded and floating areas.
74 /**
75  * Grounded basal melt rate is computed as a part of the energy
76  * (enthalpy or temperature) step; floating basal melt rate is
77  * provided by an ocean model.
78  *
79  * This method updates IceModel::basal_melt_rate (in meters per second
80  * ice-equivalent).
81  *
82  * The sub shelf mass flux provided by an ocean model is in [kg m-2
83  * s-1], so we divide by the ice density to convert to [m second-1].
84  */
86  const array::Scalar &shelf_base_mass_flux,
87  const array::Scalar &grounded_basal_melt_rate,
88  array::Scalar &result) {
89 
90  const bool sub_gl = (m_config->get_flag("geometry.grounded_cell_fraction") and
91  m_config->get_flag("energy.basal_melt.use_grounded_cell_fraction"));
92 
94  &grounded_basal_melt_rate, &shelf_base_mass_flux, &result};
95  if (sub_gl) {
97  }
98 
99  double ice_density = m_config->get_number("constants.ice.density");
100 
101  for (auto p = m_grid->points(); p; p.next()) {
102  const int i = p.i(), j = p.j();
103 
104  double lambda = 1.0; // 1.0 corresponds to the grounded case
105  // Note: here we convert shelf base mass flux from [kg m-2 s-1] to [m s-1]:
106  const double
107  M_shelf_base = shelf_base_mass_flux(i,j) / ice_density;
108 
109  // Use the fractional floatation mask to adjust the basal melt
110  // rate near the grounding line:
111  if (sub_gl) {
112  lambda = geometry.cell_grounded_fraction(i,j);
113  } else if (geometry.cell_type.ocean(i,j)) {
114  lambda = 0.0;
115  }
116  result(i,j) = lambda * grounded_basal_melt_rate(i, j) + (1.0 - lambda) * M_shelf_base;
117  }
118 }
119 
120 //! @brief Compute the temperature seen by the top of the bedrock thermal layer.
122  const array::CellType &cell_type,
123  const array::Scalar &bed_topography,
124  const array::Scalar &ice_thickness,
125  const array::Scalar &basal_enthalpy,
126  const array::Scalar &ice_surface_temperature,
127  array::Scalar &result) {
128 
129  auto grid = result.grid();
130  auto config = grid->ctx()->config();
131 
132  const double
133  T0 = config->get_number("constants.fresh_water.melting_point_temperature"),
134  beta_CC_grad_sea_water = (config->get_number("constants.ice.beta_Clausius_Clapeyron") *
135  config->get_number("constants.sea_water.density") *
136  config->get_number("constants.standard_gravity")); // K m-1
137 
138  EnthalpyConverter::Ptr EC = grid->ctx()->enthalpy_converter();
139 
140  array::AccessScope list{&cell_type, &bed_topography, &sea_level, &ice_thickness,
141  &ice_surface_temperature, &basal_enthalpy, &result};
142  ParallelSection loop(grid->com);
143  try {
144  for (auto p = grid->points(); p; p.next()) {
145  const int i = p.i(), j = p.j();
146 
147  if (cell_type.grounded(i,j)) {
148  if (cell_type.ice_free(i,j)) { // no ice: sees air temp
149  result(i,j) = ice_surface_temperature(i,j);
150  } else { // ice: sees temp of base of ice
151  const double pressure = EC->pressure(ice_thickness(i,j));
152  result(i,j) = EC->temperature(basal_enthalpy(i,j), pressure);
153  }
154  } else { // floating: apply pressure melting temp as top of bedrock temp
155  result(i,j) = T0 - (sea_level(i, j) - bed_topography(i,j)) * beta_CC_grad_sea_water;
156  }
157  }
158  } catch (...) {
159  loop.failed();
160  }
161  loop.check();
162 }
163 
164 } // end of namespace pism
std::shared_ptr< EnthalpyConverter > Ptr
array::Scalar1 sea_level_elevation
Definition: Geometry.hh:48
array::Scalar cell_grounded_fraction
Definition: Geometry.hh:56
array::CellType2 cell_type
Definition: Geometry.hh:55
array::Scalar2 ice_thickness
Definition: Geometry.hh:51
array::Scalar2 bed_elevation
Definition: Geometry.hh:47
virtual energy::Inputs energy_model_inputs()
Definition: IceModel.cc:356
const Geometry & geometry() const
Definition: IceModel.cc:893
virtual void energy_step()
Manage the solution of the energy equation, and related parallel communication.
Definition: energy.cc:60
std::shared_ptr< surface::SurfaceModel > m_surface
Definition: IceModel.hh:286
const Config::Ptr m_config
Configuration flags and parameters.
Definition: IceModel.hh:243
Geometry m_geometry
Definition: IceModel.hh:295
const std::shared_ptr< Context > m_ctx
Execution context.
Definition: IceModel.hh:245
array::Scalar m_bedtoptemp
temperature at the top surface of the bedrock thermal layer
Definition: IceModel.hh:304
std::vector< std::shared_ptr< array::Scalar2 > > m_work2d
Definition: IceModel.hh:393
std::string m_stdout_flags
Definition: IceModel.hh:328
virtual void combine_basal_melt_rate(const Geometry &geometry, const array::Scalar &shelf_base_mass_flux, const array::Scalar &grounded_basal_melt_rate, array::Scalar &result)
Combine basal melt rate in grounded and floating areas.
Definition: energy.cc:85
virtual void bedrock_thermal_model_step()
Definition: energy.cc:38
std::shared_ptr< energy::BedThermalUnit > m_btu
Definition: IceModel.hh:266
double t_TempAge
time of last update for enthalpy/temperature
Definition: IceModel.hh:320
double dt_TempAge
enthalpy/temperature and age time-steps
Definition: IceModel.hh:322
std::shared_ptr< energy::EnergyModel > m_energy_model
Definition: IceModel.hh:267
const std::shared_ptr< Grid > m_grid
Computational grid.
Definition: IceModel.hh:241
void failed()
Indicates a failure of a parallel section.
void begin(const char *name) const
Definition: Profiling.cc:75
void end(const char *name) const
Definition: Profiling.cc:91
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition: Array.hh:65
void add(double alpha, const Array2D< T > &x)
Definition: Array2D.hh:65
std::shared_ptr< const Grid > grid() const
Definition: Array.cc:132
bool ice_free(int i, int j) const
Definition: CellType.hh:54
bool ocean(int i, int j) const
Definition: CellType.hh:34
bool grounded(int i, int j) const
Definition: CellType.hh:38
"Cell type" mask. Adds convenience methods to array::Scalar.
Definition: CellType.hh:30
void extract_surface(const Array3D &data, double z, Scalar &output)
Copies a horizontal slice at level z of an Array3D into output.
Definition: Array3D.cc:135
void bedrock_surface_temperature(const array::Scalar &sea_level, const array::CellType &cell_type, const array::Scalar &bed_topography, const array::Scalar &ice_thickness, const array::Scalar &basal_enthalpy, const array::Scalar &ice_surface_temperature, array::Scalar &result)
Compute the temperature seen by the top of the bedrock thermal layer.
Definition: energy.cc:121