PISM, A Parallel Ice Sheet Model 2.3.0-79cae578d committed by Constantine Khrulev on 2026-03-22
Loading...
Searching...
No Matches
SSA.cc
Go to the documentation of this file.
1// Copyright (C) 2004--2019, 2021, 2022, 2023, 2024, 2025 Constantine Khroulev, Ed Bueler, Jed Brown, Torsten Albrecht
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 "pism/stressbalance/ssa/SSA.hh"
20#include "pism/util/EnthalpyConverter.hh"
21#include "pism/rheology/FlowLawFactory.hh"
22#include "pism/util/Mask.hh"
23#include "pism/util/error_handling.hh"
24#include "pism/util/io/File.hh"
25#include "pism/util/array/CellType.hh"
26#include "pism/stressbalance/StressBalance.hh"
27#include "pism/geometry/Geometry.hh"
28#include "pism/util/Logger.hh"
29#include "pism/util/io/IO_Flags.hh"
30
31namespace pism {
32namespace stressbalance {
33
35 m_min_thickness = config.get_number("stress_balance.ssa.strength_extension.min_thickness");
36 m_constant_nu = config.get_number("stress_balance.ssa.strength_extension.constant_nu");
37}
38
39//! Set strength = (viscosity times thickness).
40/*! Determines nu by input strength and current min_thickness. */
42 if (my_nuH <= 0.0) {
43 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "nuH must be positive, got %f", my_nuH);
44 }
46}
47
48//! Set minimum thickness to trigger use of extension.
49/*! Preserves strength (nuH) by also updating using current nu. */
50void SSAStrengthExtension::set_min_thickness(double my_min_thickness) {
51 if (my_min_thickness <= 0.0) {
52 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "min_thickness must be positive, got %f",
53 my_min_thickness);
54 }
55 double nuH = m_constant_nu * m_min_thickness;
56 m_min_thickness = my_min_thickness;
58}
59
60//! Returns strength = (viscosity times thickness).
64
65//! Returns minimum thickness to trigger use of extension.
69
70
71SSA::SSA(std::shared_ptr<const Grid> g)
73 m_velocity_global(m_grid, "bar")
74{
75
76 m_e_factor = m_config->get_number("stress_balance.ssa.enhancement_factor");
77
79
80 // override velocity metadata
81 m_velocity.metadata(0).set_name("u_ssa");
82 m_velocity.metadata(0).long_name("SSA model ice velocity in the X direction");
83
84 m_velocity.metadata(1).set_name("v_ssa");
85 m_velocity.metadata(1).long_name("SSA model ice velocity in the Y direction");
86
87 {
89 ice_factory.remove(ICE_GOLDSBY_KOHLSTEDT);
90 m_flow_law = ice_factory.create(m_config->get_string("stress_balance.ssa.flow_law"),
91 m_config->get_number("stress_balance.ssa.Glen_exponent"));
92 }
93}
94
96 if (strength_extension != NULL) {
97 delete strength_extension;
98 strength_extension = NULL;
99 }
100}
101
102
103//! \brief Initialize a generic regular-grid SSA solver.
105
107
108 m_log->message(2, "* Initializing the SSA stress balance...\n");
109 m_log->message(2,
110 " [using the %s flow law]\n", m_flow_law->name().c_str());
111
113
114 // Check if PISM is being initialized from an output file from a previous run
115 // and read the initial guess (unless asked not to).
116 if (opts.type == INIT_RESTART) {
117 if (m_config->get_flag("stress_balance.ssa.read_initial_guess")) {
118 File input_file(m_grid->com, opts.filename, io::PISM_GUESS, io::PISM_READONLY);
119 bool u_ssa_found = input_file.variable_exists("u_ssa");
120 bool v_ssa_found = input_file.variable_exists("v_ssa");
121 unsigned int start = input_file.nrecords() - 1;
122
123 if (u_ssa_found and v_ssa_found) {
124 m_log->message(3, "Reading u_ssa and v_ssa...\n");
125
126 m_velocity.read(input_file, start);
127 }
128 }
129 } else {
130 m_velocity.set(0.0); // default initial guess
131 }
132}
133
134//! \brief Update the SSA solution.
135void SSA::update(const Inputs &inputs, bool full_update) {
136
137 if (full_update) {
138 solve(inputs);
140 *inputs.basal_yield_stress,
141 inputs.geometry->cell_type,
143 }
144}
145
146
147/*!
148 * Estimate velocity at ice-free cells near the ice margin using interpolation from
149 * immediate neighbors that are icy.
150 *
151 * This is used to improve the initial guess of ice viscosity at marginal locations when
152 * ice advances: otherwise we would use the *zero* velocity (if CFBC is "on"), and that is
153 * a poor estimate at best.
154 *
155 * Note: icy cells of `velocity` are treated as read-only, and ice-free marginal cells are
156 * write-only. This means that it's okay for `velocity` to be a input-output argument: we
157 * don't use of the values modified by this method.
158 */
160 array::Vector1 &velocity) const {
161 array::AccessScope list{&cell_type, &velocity};
162
163 for (auto p : m_grid->points()) {
164 const int i = p.i(), j = p.j();
165
166 if (cell_type.ice_free(i, j) and cell_type.next_to_ice(i, j)) {
167
168 auto M = cell_type.star_int(i, j);
169 auto vel = velocity.star(i, j);
170
171 Vector2d sum{0.0, 0.0};
172 int N = 0;
173 for (auto d : {North, East, South, West}) {
174 if (mask::icy(M[d])) {
175 sum += vel[d];
176 ++N;
177 }
178 }
179 velocity(i, j) = sum / std::max(N, 1);
180 }
181 }
183}
184
185
186std::string SSA::stdout_report() const {
187 return m_stdout_ssa;
188}
189
190std::set<VariableMetadata> SSA::state_impl() const {
191 return array::metadata({ &m_velocity });
192}
193
194void SSA::write_state_impl(const OutputFile &output) const {
195 m_velocity.write(output);
196}
197
198} // end of namespace stressbalance
199} // end of namespace pism
#define ICE_GOLDSBY_KOHLSTEDT
std::shared_ptr< const Config > m_config
configuration database used by this component
Definition Component.hh:160
const std::shared_ptr< const Grid > m_grid
grid used by this component
Definition Component.hh:158
std::shared_ptr< const Logger > m_log
logger (for easy access)
Definition Component.hh:164
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
Definition Config.cc:188
A class for storing and accessing PISM configuration flags and parameters.
Definition Config.hh:56
unsigned int nrecords() const
Get the number of records. Uses the length of an unlimited dimension.
Definition File.cc:280
bool variable_exists(const std::string &short_name) const
Checks if a variable exists.
Definition File.cc:378
High-level PISM I/O class.
Definition File.hh:57
array::CellType2 cell_type
Definition Geometry.hh:55
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
VariableMetadata & long_name(const std::string &input)
VariableMetadata & set_name(const std::string &name)
This class represents a 2D vector field (such as ice velocity) at a certain grid point.
Definition Vector2d.hh:29
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition Array.hh:66
stencils::Star< T > star(int i, int j) const
Definition Array2D.hh:107
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 update_ghosts()
Updates ghost points.
Definition Array.cc:645
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata object containing metadata for the compoment N.
Definition Array.cc:467
bool next_to_ice(int i, int j) const
Ice-free margin (at least one of four neighbors has ice).
Definition CellType.hh:87
stencils::Star< int > star_int(int i, int j) const
Definition Scalar.hh:72
bool ice_free(int i, int j) const
Definition CellType.hh:54
void remove(const std::string &name)
std::shared_ptr< FlowLaw > create(const std::string &type_name, double exponent)
const array::Scalar * basal_yield_stress
double get_notional_strength() const
Returns strength = (viscosity times thickness).
Definition SSA.cc:61
void set_min_thickness(double my_min_thickness)
Set minimum thickness to trigger use of extension.
Definition SSA.cc:50
SSAStrengthExtension(const Config &c)
Definition SSA.cc:34
double get_min_thickness() const
Returns minimum thickness to trigger use of extension.
Definition SSA.cc:66
void set_notional_strength(double my_nuH)
Set strength = (viscosity times thickness).
Definition SSA.cc:41
Gives an extension coefficient to maintain ellipticity of SSA where ice is thin.
Definition SSA.hh:57
virtual void update(const Inputs &inputs, bool full_update)
Update the SSA solution.
Definition SSA.cc:135
virtual void solve(const Inputs &inputs)=0
SSA(std::shared_ptr< const Grid > g)
Definition SSA.cc:71
virtual void write_state_impl(const OutputFile &output) const
The default (empty implementation).
Definition SSA.cc:194
void extrapolate_velocity(const array::CellType1 &cell_type, array::Vector1 &velocity) const
Definition SSA.cc:159
virtual std::set< VariableMetadata > state_impl() const
Definition SSA.cc:190
SSAStrengthExtension * strength_extension
Definition SSA.hh:104
virtual std::string stdout_report() const
Produce a report string for the standard output.
Definition SSA.cc:186
std::string m_stdout_ssa
Definition SSA.hh:120
virtual void init_impl()
Initialize a generic regular-grid SSA solver.
Definition SSA.cc:104
const array::Vector1 & velocity() const
Get the thickness-advective 2D velocity.
void compute_basal_frictional_heating(const array::Vector &velocity, const array::Scalar &tauc, const array::CellType &mask, array::Scalar &result) const
Compute the basal frictional heating.
std::shared_ptr< rheology::FlowLaw > m_flow_law
std::shared_ptr< EnthalpyConverter > m_EC
Shallow stress balance (such as the SSA).
#define PISM_ERROR_LOCATION
std::set< VariableMetadata > metadata(std::initializer_list< const Array * > vecs)
Definition Array.cc:1244
@ PISM_GUESS
Definition IO_Flags.hh:57
@ PISM_READONLY
open an existing file for reading only
Definition IO_Flags.hh:69
bool icy(int M)
Ice-filled cell (grounded or floating).
Definition Mask.hh:48
static const double g
Definition exactTestP.cc:36
@ INIT_RESTART
Definition Component.hh:56
@ North
Definition stencils.hh:24
@ East
Definition stencils.hh:24
@ South
Definition stencils.hh:24
@ West
Definition stencils.hh:24
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