6 #include "pism/energy/BedThermalUnit.hh"
7 #include "pism/util/EnthalpyConverter.hh"
8 #include "pism/util/io/File.hh"
9 #include "pism/util/io/io_helpers.hh"
11 #include "pism/icebin/IBIceModel.hh"
12 #include "pism/icebin/IBSurfaceModel.hh"
13 #include "pism/coupler/ocean/Factory.hh"
14 #include "pism/energy/EnergyModel.hh"
19 static double const NaN = std::numeric_limits<double>::quiet_NaN();
31 ice_top_senth(grid,
"ice_top_senth"),
32 elevmask_ice(grid,
"elevmask_ice"),
33 elevmask_land(grid,
"elevmask_land") {
35 std::cout <<
"IBIceModel Conservation Formulas:" << std::endl;
57 m_log->message(2,
"# Allocating the icebin surface model...\n");
67 const double my_t0 =
m_grid.time->current();
68 const double my_dt = this->
dt;
78 const double my_t0 =
m_grid.time->current();
79 const double my_dt = this->
dt;
120 const auto &strain_heating3 =
m_stress_balance->volumetric_strain_heating();
127 printf(
"BEGIN IBIceModel::MassContExplicitStep()\n");
156 for (
auto p =
m_grid->points(); p; p.next()) {
157 const int i = p.i(), j = p.j();
172 double surface_mass_balance,
173 double basal_melt_rate,
176 double Href_to_H_flux,
177 double nonneg_rule_flux)
186 double p_basal = EC->pressure(ice_thickness(i, j));
187 double T = EC->melting_temperature(p_basal);
188 double specific_enth_basal = EC->enthalpy_permissive(T, 1.0, p_basal);
198 const int ks =
m_grid->kBelowHeight(ice_thickness(i, j));
199 const double *Enth = ice_enthalpy.get_column(i, j);
200 double specific_enth_top = Enth[ks];
224 double by_dt = 1.0 /
dt;
225 printf(
"IBIceModel::set_rate(dt=%f)\n",
dt);
234 for (; base_ii !=
base.
all_vecs.end(); ++base_ii, ++cur_ii, ++rate_ii) {
241 for (
auto p =
m_grid->points(); p; p.next()) {
242 const int i = p.i(), j = p.j();
246 vrate(i, j) = (vcur(i, j) - vbase(i, j)) * by_dt;
249 vrate(i, j) = vcur(i, j);
260 for (; base_ii !=
base.
all_vecs.end(); ++base_ii, ++cur_ii) {
267 for (
auto p =
m_grid->points(); p; p.next()) {
268 const int i = p.i(), j = p.j();
270 vbase(i, j) = vcur(i, j);
289 for (
int i =
m_grid->xs(); i < m_grid->xs() +
m_grid->xm(); ++i) {
290 for (
int j =
m_grid->ys(); j < m_grid->ys() +
m_grid->ym(); ++j) {
291 double const *Enth = ice_enthalpy.get_column(i, j);
294 auto ks =
m_grid->kBelowHeight(ice_thickness(i, j));
295 double senth = Enth[ks];
299 switch ((
int)cell_type(i, j)) {
324 m_ctx->pio_iosys_id());
338 m_log->message(2,
"* Run time: [%s, %s] (%s years, using the '%s' calendar)\n",
340 m_time->run_length().c_str(),
m_time->calendar().c_str());
357 for (; base_ii !=
base.
all_vecs.end(); ++base_ii, ++cur_ii) {
358 base_ii->vec.copy_from(cur_ii->vec);
374 double ice_density =
m_config->get_number(
"constants.ice.density",
"kg m-3");
382 for (
auto p =
m_grid->points(); p; p.next()) {
383 const int i = p.i(), j = p.j();
390 if (ice_thickness(i, j) > 0) {
391 int ks = (int)
m_grid->kBelowHeight(ice_thickness(i, j));
392 const auto *Enth = ice_enthalpy.get_column(i, j);
394 for (
int k = 0;
k < ks; ++
k) {
396 enth2(i, j) += Enth[
k] * dz;
400 double dz = (ice_thickness(i, j) -
m_grid->z(ks));
401 enth2(i, j) += Enth[ks] * dz;
404 enth2(i, j) *= ice_density;
405 mass2(i, j) = ice_thickness(i, j) * ice_density;
427 printf(
"BEGIN IBIceModel::merge_surface_temp default_val=%g\n", default_val);
430 double ice_density =
m_config->get_number(
"constants.ice.density");
438 for (
int i =
m_grid->xs(); i < m_grid->xs() +
m_grid->xm(); ++i) {
439 for (
int j =
m_grid->ys(); j < m_grid->ys() +
m_grid->ym(); ++j) {
440 double &surface_temp_ij(surface_temp(i, j));
441 double const &deltah_ij(deltah(i, j));
443 const auto *Enth = ice_enthalpy.get_column(i, j);
446 const int ks =
m_grid->kBelowHeight(ice_thickness(i, j));
447 double spec_enth3 = Enth[ks];
449 if (deltah_ij != default_val) {
451 double toplayer_dz = ice_thickness(i, j) -
m_grid->z(ks);
455 spec_enth3 = spec_enth3 + deltah_ij / (toplayer_dz * ice_density) * timestep_s;
460 const double p = 0.0;
461 surface_temp_ij = EC->temperature(spec_enth3, p);
466 printf(
"END IBIceModel::merge_surface_temp\n");
std::shared_ptr< EnthalpyConverter > Ptr
High-level PISM I/O class.
array::Scalar2 ice_surface_elevation
array::CellType2 cell_type
array::Scalar2 ice_thickness
std::map< std::string, const Component * > m_submodels
the list of sub-models, for writing model states and obtaining diagnostics
std::shared_ptr< stressbalance::StressBalance > m_stress_balance
VariableMetadata run_stats() const
virtual void energy_step()
Manage the solution of the energy equation, and related parallel communication.
std::shared_ptr< surface::SurfaceModel > m_surface
const Config::Ptr m_config
Configuration flags and parameters.
const Time::Ptr m_time
Time manager.
const std::shared_ptr< Context > m_ctx
Execution context.
virtual void misc_setup()
Miscellaneous initialization tasks plus tasks that need the fields that can come from regridding.
const Logger::Ptr m_log
Logger.
std::shared_ptr< energy::BedThermalUnit > m_btu
virtual void save_variables(const File &file, OutputKind kind, const std::set< std::string > &variables, double time, io::Type default_diagnostics_type=io::PISM_FLOAT) const
double t_TempAge
time of last update for enthalpy/temperature
std::shared_ptr< Context > ctx() const
Return the context this model is running in.
virtual void allocate_couplers()
virtual void write_metadata(const File &file, MappingTreatment mapping_flag, HistoryTreatment history_flag) const
Write time-independent metadata to a file.
std::unique_ptr< hydrology::Hydrology > m_subglacial_hydrology
double dt_TempAge
enthalpy/temperature and age time-steps
double m_dt
mass continuity time step, s
std::shared_ptr< energy::EnergyModel > m_energy_model
const std::shared_ptr< Grid > m_grid
Computational grid.
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void add(double alpha, const Array2D< T > &x)
pism::array::Scalar elevmask_ice
pism::array::Scalar ice_top_senth
void construct_surface_temp(pism::array::Scalar &deltah, double default_val, double timestep_s, pism::array::Scalar &surface_temp)
virtual void misc_setup()
Miscellaneous initialization tasks plus tasks that need the fields that can come from regridding.
void dumpToFile(const std::string &filename) const
virtual void time_setup()
Initialize time from an input file or command-line options.
virtual void accumulateFluxes_massContExplicitStep(int i, int j, double surface_mass_balance, double basal_melt_rate, double divQ_SIA, double divQ_SSA, double Href_to_H_flux, double nonneg_rule_flux)
virtual void allocate_couplers()
virtual void massContExplicitStep()
IBIceModel(std::shared_ptr< pism::Grid > grid, const std::shared_ptr< Context > &context, IBIceModel::Params const &_params)
void compute_enth2(pism::array::Scalar &enth2, pism::array::Scalar &mass2)
void prepare_outputs(double time_s)
void energy_step()
Manage the solution of the energy equation, and related parallel communication.
virtual void allocate_subglacial_hydrology()
Decide which subglacial hydrology model to use.
pism::icebin::IBSurfaceModel * ib_surface_model()
pism::array::Scalar elevmask_land
double m_meter_per_s_to_kg_per_m2
pism::array::Scalar enthxfer
pism::array::Scalar massxfer
pism::array::Scalar deltah
pism::array::Scalar href_to_h
SMB as seen by PISM in iMgeometry.cc massContExplicitSte(). Used to check icebin_smb....
pism::array::Scalar nonneg_rule
std::ostream & print_formulas(std::ostream &out)
pism::array::Scalar geothermal_flux
Total amount of geothermal energy [J/m^2].
MassEnthVec2S internal_advection
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
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)
pism::array::Scalar deltah
Change in enthalpy of top layer.
#define PISM_ERROR_LOCATION
void sum_columns(const Array3D &data, double A, double B, Scalar &output)
@ PISM_READWRITE_MOVE
create a file for writing, move foo.nc to foo.nc~ if present
io::Backend string_to_backend(const std::string &backend)
std::string printf(const char *format,...)
void write_run_stats(const File &file, const pism::VariableMetadata &stats)