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"
29 #include "pism/stressbalance/ssa/SSA_diagnostics.hh"
32 namespace stressbalance {
51 if (my_min_thickness <= 0.0) {
73 m_mask(m_grid,
"ssa_mask"),
74 m_taud(m_grid,
"taud"),
75 m_velocity_global(m_grid,
"bar")
84 .
long_name(
"ice-type (ice-free/grounded/floating/ocean) integer mask");
87 m_mask.
metadata()[
"flag_meanings"] =
"ice_free_bedrock grounded_ice floating_ice ice_free_ocean";
90 .
long_name(
"X-component of the driving shear stress at the base of ice")
93 .
long_name(
"Y-component of the driving shear stress at the base of ice")
125 m_log->message(2,
"* Initializing the SSA stress balance...\n");
127 " [using the %s flow law]\n",
m_flow_law->name().c_str());
134 if (
m_config->get_flag(
"stress_balance.ssa.read_initial_guess")) {
138 unsigned int start = input_file.
nrecords() - 1;
140 if (u_ssa_found and v_ssa_found) {
141 m_log->message(3,
"Reading u_ssa and v_ssa...\n");
157 const double H_threshold =
m_config->get_number(
"stress_balance.ice_free_thickness_standard");
190 double h_ij,
double h_n,
206 if ((
icy(M_ij) and
ice_free(M_n) and h_n > h_ij) or
220 if ((N_ij == 0 and N_n == 1) or (N_ij == 1 and N_n == 0)) {
241 bool cfbc =
m_config->get_flag(
"stress_balance.calving_front_stress_bc");
242 bool surface_gradient_inward =
m_config->get_flag(
"stress_balance.ssa.compute_surface_gradient_inward");
251 list.
add(*no_model_mask);
254 for (
auto p =
m_grid->points(); p; p.next()) {
255 const int i = p.i(), j = p.j();
257 const double pressure =
m_EC->pressure(ice_thickness(i, j));
258 if (pressure <= 0.0) {
264 if (surface_gradient_inward) {
266 h_x =
diff_x_p(surface_elevation, i, j),
267 h_y =
diff_y_p(surface_elevation, i, j);
268 result(i, j) = - pressure *
Vector2d(h_x, h_y);
289 auto M = cell_type.
star(i, j);
290 auto h = surface_elevation.
star(i, j);
301 west =
weight(cfbc, M.c, M.w, h.c, h.w, N.
c, N.
w),
302 east =
weight(cfbc, M.c, M.e, h.c, h.e, N.
c, N.
e);
304 if (east + west > 0) {
305 h_x = 1.0 / ((west + east) * dx) * (west * (h.c - h.w) + east * (h.e - h.c));
320 south =
weight(cfbc, M.c, M.s, h.c, h.s, N.
c, N.
s),
321 north =
weight(cfbc, M.c, M.n, h.c, h.n, N.
c, N.
n);
323 if (north + south > 0) {
324 h_y = 1.0 / ((south + north) * dy) * (south * (h.c - h.s) + north * (h.n - h.c));
335 result(i, j) = - pressure *
Vector2d(h_x, h_y);
356 for (
auto p =
m_grid->points(); p; p.next()) {
357 const int i = p.i(), j = p.j();
361 auto M = cell_type.
star(i, j);
418 m_vars[0].long_name(
"X-component of the driving shear stress at the base of ice");
419 m_vars[1].long_name(
"Y-component of the driving shear stress at the base of ice");
423 v[
"comment"] =
"this is the driving stress used by the SSA solver";
429 auto result = allocate<array::Vector>(
"taud");
431 result->copy_from(
model->driving_stress());
442 m_vars[0].long_name(
"magnitude of the driving shear stress at the base of ice").units(
"Pa");
443 m_vars[0][
"comment"] =
"this is the magnitude of the driving stress used by the SSA solver";
447 auto result = allocate<array::Scalar>(
"taud_mag");
#define ICE_GOLDSBY_KOHLSTEDT
const Config::ConstPtr m_config
configuration database used by this component
const Logger::ConstPtr m_log
logger (for easy access)
const std::shared_ptr< const Grid > m_grid
grid used by this component
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
A class for storing and accessing PISM configuration flags and parameters.
A template derived from Diagnostic, adding a "Model".
const units::System::Ptr m_sys
the unit system
std::vector< SpatialVariableMetadata > m_vars
metadata corresponding to NetCDF variables
std::shared_ptr< Diagnostic > Ptr
VariableLookupData find_variable(const std::string &short_name, const std::string &std_name) const
Find a variable using its standard name and/or short name.
unsigned int nrecords() const
Get the number of records. Uses the length of an unlimited dimension.
High-level PISM I/O class.
void compute_mask(const array::Scalar &sea_level, const array::Scalar &bed, const array::Scalar &thickness, array::Scalar &result) const
void set_icefree_thickness(double threshold)
array::Scalar1 sea_level_elevation
array::Scalar2 ice_thickness
array::Scalar2 bed_elevation
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
This class represents a 2D vector field (such as ice velocity) at a certain grid point.
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void copy_from(const Array2D< T > &source)
stencils::Star< T > star(int i, int j) const
void add(double alpha, const Array2D< T > &x)
void read(const std::string &filename, unsigned int time)
void define(const File &file, io::Type default_type) const
Define variables corresponding to an Array in a file opened using file.
void write(const std::string &filename) const
void set(double c)
Result: v[j] <- c for all j.
std::shared_ptr< petsc::DM > dm() const
void update_ghosts()
Updates ghost points.
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
bool next_to_ice(int i, int j) const
Ice-free margin (at least one of four neighbors has ice).
bool ice_free(int i, int j) const
stencils::Star< int > star_int(int i, int j) const
std::shared_ptr< FlowLaw > create()
void remove(const std::string &name)
double get_notional_strength() const
Returns strength = (viscosity times thickness).
void set_min_thickness(double my_min_thickness)
Set minimum thickness to trigger use of extension.
SSAStrengthExtension(const Config &c)
double get_min_thickness() const
Returns minimum thickness to trigger use of extension.
void set_notional_strength(double my_nuH)
Set strength = (viscosity times thickness).
Gives an extension coefficient to maintain ellipticity of SSA where ice is thin.
virtual std::shared_ptr< array::Array > compute_impl() const
SSA_taud_mag(const SSA *m)
Computes the magnitude of the driving shear stress at the base of ice (diagnostically).
virtual std::shared_ptr< array::Array > compute_impl() const
Computes the driving shear stress at the base of ice (diagnostically).
void set_initial_guess(const array::Vector &guess)
Set the initial guess of the SSA velocity.
virtual void update(const Inputs &inputs, bool full_update)
Update the SSA solution.
virtual DiagnosticList diagnostics_impl() const
virtual void solve(const Inputs &inputs)=0
SSA(std::shared_ptr< const Grid > g)
virtual void compute_driving_stress(const array::Scalar &ice_thickness, const array::Scalar1 &surface_elevation, const array::CellType1 &cell_type, const array::Scalar1 *no_model_mask, array::Vector &result) const
Compute the gravitational driving stress.
array::Vector m_velocity_global
void extrapolate_velocity(const array::CellType1 &cell_type, array::Vector1 &velocity) const
virtual void define_model_state_impl(const File &output) const
The default (empty implementation).
SSAStrengthExtension * strength_extension
virtual std::string stdout_report() const
Produce a report string for the standard output.
std::shared_ptr< petsc::DM > m_da
const array::Vector & driving_stress() const
virtual void write_model_state_impl(const File &output) const
The default (empty implementation).
virtual void init_impl()
Initialize a generic regular-grid SSA solver.
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.
array::Scalar m_basal_frictional_heating
virtual DiagnosticList diagnostics_impl() const
double m_e_factor
flow enhancement factor
std::shared_ptr< rheology::FlowLaw > m_flow_law
EnthalpyConverter::Ptr m_EC
array::Vector2 m_velocity
Shallow stress balance (such as the SSA).
#define PISM_ERROR_LOCATION
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
double sum(const array::Scalar &input)
Sums up all the values in an array::Scalar object. Ignores ghosts.
double diff_x_p(const array::Scalar &array, int i, int j)
Returns the x-derivative at i,j approximated using centered finite differences. Respects grid periodi...
void compute_magnitude(const array::Vector &input, array::Scalar &result)
double diff_y_p(const array::Scalar &array, int i, int j)
Returns the y-derivative at i,j approximated using centered finite differences. Respects grid periodi...
@ PISM_READONLY
open an existing file for reading only
bool icy(int M)
Ice-filled cell (grounded or floating).
bool ice_free_ocean(int M)
bool grounded(int M)
Grounded cell (grounded ice or ice-free).
bool ice_free(int M)
Ice-free cell (grounded or ocean).
static int weight(int M_ij, int M_n, double h_ij, double h_n)
InputOptions process_input_options(MPI_Comm com, Config::ConstPtr config)
std::map< std::string, Diagnostic::Ptr > DiagnosticList
Star stencil points (in the map-plane).