PISM, A Parallel Ice Sheet Model 2.3.0-79cae578d committed by Constantine Khrulev on 2026-03-22
Loading...
Searching...
No Matches
BedThermalUnit.cc
Go to the documentation of this file.
1// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2023, 2024, 2025 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 <memory>
20
21#include "pism/energy/BedThermalUnit.hh"
22#include "pism/util/Config.hh"
23#include "pism/util/Grid.hh"
24#include "pism/util/io/File.hh"
25
26#include "pism/energy/BTU_Full.hh"
27#include "pism/energy/BTU_Minimal.hh"
28#include "pism/util/Logger.hh"
29#include "pism/util/pism_utilities.hh"
30#include "pism/util/io/IO_Flags.hh"
31
32namespace pism {
33namespace energy {
34
35BTUGrid::BTUGrid(std::shared_ptr<const Context> ctx) {
36 Mbz = (unsigned int) ctx->config()->get_number("grid.Mbz");
37 Lbz = ctx->config()->get_number("grid.Lbz");
38}
39
40
41BTUGrid BTUGrid::FromOptions(std::shared_ptr<const Context> ctx) {
42 BTUGrid result(ctx);
43
44 auto config = ctx->config();
45 InputOptions opts = process_input_options(ctx->com(), config);
46
47 if (opts.type == INIT_RESTART) {
48 // If we're initializing from a file we need to get the number of bedrock
49 // levels and the depth of the bed thermal layer from it:
50 File input_file(ctx->com(), opts.filename, io::PISM_NETCDF3, io::PISM_READONLY);
51
52 if (input_file.variable_exists("litho_temp")) {
53 grid::InputGridInfo info(input_file, "litho_temp", ctx->unit_system(),
54 grid::CELL_CENTER); // grid registration is irrelevant
55
56 result.Mbz = info.z.size();
57 result.Lbz = -vector_min(info.z);
58 } else {
59 // override values we got using config.get_number() in the constructor
60 result.Mbz = 1;
61 result.Lbz = 0;
62 }
63
64 input_file.close();
65 } else {
66 // Bootstrapping or initializing without an input file.
67 result.Mbz = config->get_number("grid.Mbz");
68 result.Lbz = config->get_number("grid.Lbz");
69
70 if (result.Mbz == 1) {
71 result.Lbz = 0;
72 result.Mbz = 1;
73 }
74 }
75
76 return result;
77}
78
79/*! Allocate a complete or minimal bedrock thermal unit depending on the number of bedrock levels.
80 *
81 */
82std::shared_ptr<BedThermalUnit> BedThermalUnit::FromOptions(std::shared_ptr<const Grid> grid,
83 std::shared_ptr<const Context> ctx) {
84
85 auto bedrock_grid = BTUGrid::FromOptions(ctx);
86
87 if (bedrock_grid.Mbz > 1) {
88 return std::make_shared<energy::BTU_Full>(grid, bedrock_grid);
89 }
90
91 return std::make_shared<energy::BTU_Minimal>(grid);
92}
93
94
95BedThermalUnit::BedThermalUnit(std::shared_ptr<const Grid> g)
96 : Component(g),
97 m_bottom_surface_flux(m_grid, "bheatflx"),
98 m_top_surface_flux(m_grid, "heat_flux_from_bedrock") {
99
100 {
102 .long_name("upward geothermal flux at the top bedrock surface")
103 .units("W m^-2")
104 .output_units("mW m^-2")
105 .standard_name("upward_geothermal_heat_flux_at_ground_level_in_land_ice");
106 m_top_surface_flux.metadata()["comment"] = "positive values correspond to an upward flux";
107 }
108 {
109 // PROPOSED standard_name = lithosphere_upward_heat_flux
111 .long_name("upward geothermal flux at the bottom bedrock surface")
112 .units("W m^-2") // note: don't convert to "mW m^-2" when saving
113 .set_time_dependent(false);
114
115 m_bottom_surface_flux.metadata()["comment"] = "positive values correspond to an upward flux";
116 }
117}
118
120 this->init_impl(opts);
121}
122
123//! \brief Initialize the bedrock thermal unit.
125 auto input_file = m_config->get_string("energy.bedrock_thermal.file");
126
127 if (not input_file.empty()) {
128 m_log->message(2, " - Reading geothermal flux from '%s' ...\n",
129 input_file.c_str());
130
132 } else {
133 m_log->message(2,
134 " - Parameter %s is not set. Reading geothermal flux from '%s'...\n",
135 "energy.bedrock_thermal.file",
136 opts.filename.c_str());
137
138 switch (opts.type) {
139 case INIT_RESTART:
141 break;
142 case INIT_BOOTSTRAP:
144 "bootstrapping.defaults.geothermal_flux")));
145 break;
146 case INIT_OTHER:
147 default:
149 }
150 }
151
153}
154
156 const double heat_flux = m_config->get_number("bootstrapping.defaults.geothermal_flux");
157
158 m_log->message(2, " using constant geothermal flux %f W m-2 ...\n",
159 heat_flux);
160
161 m_bottom_surface_flux.set(heat_flux);
162}
163
164/** Returns the vertical spacing used by the bedrock grid.
165 *
166 */
168 return this->vertical_spacing_impl();
169}
170
171/*!
172 * Return the depth of the bedrock thermal layer.
173 */
174double BedThermalUnit::depth() const {
175 return this->depth_impl();
176}
177
178/*!
179 * Return the number of levels in the bedrock thermal layer.
180 */
181unsigned int BedThermalUnit::Mz() const {
182 return this->Mz_impl();
183}
184
185std::set<VariableMetadata> BedThermalUnit::state_impl() const {
187}
188
191}
192
194 DiagnosticList result = {
196 {"heat_flux_from_bedrock", Diagnostic::Ptr(new BTU_geothermal_flux_at_ground_level(this))}};
197
198 if (m_config->get_flag("output.ISMIP6")) {
199 result["hfgeoubed"] = Diagnostic::Ptr(new BTU_geothermal_flux_at_ground_level(this));
200 }
201 return result;
202}
203
204void BedThermalUnit::update(const array::Scalar &bedrock_top_temperature,
205 double t, double dt) {
206 this->update_impl(bedrock_top_temperature, t, dt);
207}
208
212
216
218 : Diag<BedThermalUnit>(m) {
219
220 auto ismip6 = m_config->get_flag("output.ISMIP6");
221 m_vars = { { m_sys, ismip6 ? "hfgeoubed" : "heat_flux_from_bedrock", *m_grid } };
222 m_vars[0]
223 .long_name("upward geothermal flux at the top bedrock surface")
224 .standard_name((ismip6 ? "upward_geothermal_heat_flux_in_land_ice" :
225 "upward_geothermal_heat_flux_at_ground_level_in_land_ice"))
226 .units("W m^-2")
227 .output_units("mW m^-2");
228 m_vars[0]["comment"] = "positive values correspond to an upward flux";
229}
230
231std::shared_ptr<array::Array> BTU_geothermal_flux_at_ground_level::compute_impl() const {
232 auto result = std::make_shared<array::Scalar>(m_grid, "hfgeoubed");
233 result->metadata() = m_vars[0];
234
235 result->copy_from(model->flux_through_top_surface());
236
237 return result;
238}
239
240} // end of namespace energy
241} // end of namespace pism
std::shared_ptr< const Grid > grid() const
Definition Component.cc:107
std::shared_ptr< const Config > m_config
configuration database used by this component
Definition Component.hh:160
void regrid(const std::string &module_name, array::Array &variable, RegriddingFlag flag=NO_REGRID_WITHOUT_REGRID_VARS)
Definition Component.cc:152
std::shared_ptr< const Logger > m_log
logger (for easy access)
Definition Component.hh:164
A class defining a common interface for most PISM sub-models.
Definition Component.hh:118
const BedThermalUnit * model
A template derived from Diagnostic, adding a "Model".
std::vector< VariableMetadata > m_vars
metadata corresponding to NetCDF variables
static Ptr wrap(const T &input)
const units::System::Ptr m_sys
the unit system
std::shared_ptr< const Config > m_config
Configuration flags and parameters.
std::shared_ptr< Diagnostic > Ptr
Definition Diagnostic.hh:67
std::shared_ptr< const Grid > m_grid
the grid
bool variable_exists(const std::string &short_name) const
Checks if a variable exists.
Definition File.cc:378
void close()
Definition File.cc:237
High-level PISM I/O class.
Definition File.hh:57
VariableMetadata & long_name(const std::string &input)
VariableMetadata & units(const std::string &input)
VariableMetadata & standard_name(const std::string &input)
VariableMetadata & output_units(const std::string &input)
VariableMetadata & set_time_dependent(bool flag)
void read(const std::string &filename, unsigned int time)
Definition Array.cc:753
void write(const OutputFile &file) const
Definition Array.cc:859
void set(double c)
Result: v[j] <- c for all j.
Definition Array.cc:659
void regrid(const std::string &filename, io::Default default_value)
Definition Array.cc:758
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata object containing metadata for the compoment N.
Definition Array.cc:467
virtual std::shared_ptr< array::Array > compute_impl() const
BedThermalUnit(std::shared_ptr< const Grid > g)
virtual void initialize_bottom_surface_flux()
void update(const array::Scalar &bedrock_top_temperature, double t, double dt)
const array::Scalar & flux_through_top_surface() const
Return the upward heat flux through the top surface of the bedrock thermal layer.
array::Scalar m_bottom_surface_flux
upward heat flux through the bottom surface of the bed thermal layer
virtual void init_impl(const InputOptions &opts)
Initialize the bedrock thermal unit.
void init(const InputOptions &opts)
virtual double depth_impl() const =0
static std::shared_ptr< BedThermalUnit > FromOptions(std::shared_ptr< const Grid > g, std::shared_ptr< const Context > ctx)
virtual double vertical_spacing_impl() const =0
virtual unsigned int Mz_impl() const =0
const array::Scalar & flux_through_bottom_surface() const
Return the upward heat flux through the bottom surface of the bedrock thermal layer.
virtual DiagnosticList spatial_diagnostics_impl() const
array::Scalar m_top_surface_flux
upward heat flux through the top surface of the bed thermal layer
virtual void update_impl(const array::Scalar &bedrock_top_temperature, double t, double dt)=0
virtual std::set< VariableMetadata > state_impl() const
virtual void write_state_impl(const OutputFile &output) const
The default (empty implementation).
Given the temperature of the top of the bedrock, for the duration of one time-step,...
std::vector< double > z
z coordinates: input grids may be 3-dimensional
Definition Grid.hh:82
static Default Nil()
Definition IO_Flags.hh:94
std::set< VariableMetadata > metadata(std::initializer_list< const Array * > vecs)
Definition Array.cc:1244
@ PISM_NETCDF3
Definition IO_Flags.hh:58
@ PISM_READONLY
open an existing file for reading only
Definition IO_Flags.hh:69
static const double g
Definition exactTestP.cc:36
@ INIT_BOOTSTRAP
Definition Component.hh:56
@ INIT_OTHER
Definition Component.hh:56
@ INIT_RESTART
Definition Component.hh:56
std::map< std::string, Diagnostic::Ptr > DiagnosticList
double vector_min(const std::vector< double > &input)
InputOptions process_input_options(MPI_Comm com, std::shared_ptr< const Config > config)
Definition Component.cc:45
InitializationType type
initialization type
Definition Component.hh:61
std::string filename
name of the input file (if applicable)
Definition Component.hh:63
unsigned int record
index of the record to re-start from
Definition Component.hh:65
static BTUGrid FromOptions(std::shared_ptr< const Context > ctx)
BTUGrid(std::shared_ptr< const Context > ctx)