Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.1-cd005eec8 committed by Constantine Khrulev on 2025-03-07
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ssa_test_cfbc.cc
Go to the documentation of this file.
1// Copyright (C) 2010--2018, 2021, 2022, 2023, 2024 Ed Bueler, Constantine Khroulev, and David Maxwell
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
19static char help[] =
20 "\nSSA_TESTCFBC\n"
21 " Testing program for PISM's implementations of the SSA.\n"
22 " Does a time-independent calculation. Does not run IceModel or a derived\n"
23 " class thereof. Uses the van der Veen flow-line shelf geometry. Also may be\n"
24 " used in a PISM software (regression) test.\n\n";
25
26#include "pism/stressbalance/ssa/SSATestCase.hh"
27#include "pism/util/Context.hh"
28#include "pism/util/error_handling.hh"
29#include "pism/util/petscwrappers/PetscInitializer.hh"
30#include "pism/util/pism_options.hh"
31
32#include "pism/stressbalance/ssa/SSAFD.hh"
33#include "pism/stressbalance/ssa/SSAFEM.hh"
34
35namespace pism {
36namespace stressbalance {
37
38// thickness profile in the van der Veen solution
39static double H_exact(double V0, double H0, double C, double x) {
40 const double Q0 = V0*H0;
41 return pow(4 * C / Q0 * x + 1/pow(H0, 4), -0.25);
42}
43
44// velocity profile; corresponds to constant flux
45static double u_exact(double V0, double H0, double C, double x) {
46 const double Q0 = V0*H0;
47 return Q0 / H_exact(V0, H0, C, x);
48}
49
50std::shared_ptr<Grid> ssa_test_cfbc_grid(std::shared_ptr<Context> ctx, int Mx, int My) {
51 return SSATestCase::grid(ctx, Mx, My, 250e3, 250e3, grid::CELL_CENTER, grid::Y_PERIODIC);
52}
53
55public:
56 SSATestCaseCFBC(std::shared_ptr<SSA> ssa)
57 : SSATestCase(ssa) {
58 m_V0 = units::convert(m_sys, 300.0, "m year^-1", "m second^-1");
59 m_H0 = 600.0; // meters
60 m_C = 2.45e-18;
61
63 // 0.01 water fraction
64 m_ice_enthalpy.set(EC.enthalpy(273.15, 0.01, 0.0));
65 }
66
67protected:
69
70 void exactSolution(int i, int j, double x, double y, double *u, double *v);
71
72 double m_V0, //!< grounding line vertically-averaged velocity
73 m_H0, //!< grounding line thickness (meters)
74 m_C; //!< "typical constant ice parameter"
75};
76
78
79 m_tauc.set(0.0); // irrelevant
80 m_geometry.bed_elevation.set(-1000.0); // assures shelf is floating
81
84
85 const double x_min = m_grid->x(0);
86
87 for (auto p = m_grid->points(); p; p.next()) {
88 const int i = p.i(), j = p.j();
89
90 const double x = m_grid->x(i);
91
92 if (i != (int)m_grid->Mx() - 1) {
93 m_geometry.ice_thickness(i, j) = H_exact(m_V0, m_H0, m_C, x - x_min);
94 } else {
95 m_geometry.ice_thickness(i, j) = 0.0;
96 }
97
98 if (i == 0) {
99 m_bc_mask(i, j) = 1;
100 m_bc_values(i, j) = {m_V0, 0.0};
101 } else {
102 m_bc_mask(i, j) = 0;
103 m_bc_values(i, j) = {0.0, 0.0};
104 }
105 }
106
107 // communicate what we have set
109
112}
113
114void SSATestCaseCFBC::exactSolution(int i, int /*j*/,
115 double x, double /*y*/,
116 double *u, double *v) {
117 const double x_min = m_grid->x(0);
118
119 if (i != (int)m_grid->Mx() - 1) {
120 *u = u_exact(m_V0, m_H0, m_C, x - x_min);
121 } else {
122 *u = 0;
123 }
124
125 *v = 0;
126}
127
128} // end of namespace stressbalance
129} // end of namespace pism
130
131int main(int argc, char *argv[]) {
132
133 using namespace pism;
134 using namespace pism::stressbalance;
135
136 MPI_Comm com = MPI_COMM_WORLD;
137 petsc::Initializer petsc(argc, argv, help);
138
139 com = PETSC_COMM_WORLD;
140
141 /* This explicit scoping forces destructors to be called before PetscFinalize() */
142 try {
143 std::shared_ptr<Context> ctx = context_from_options(com, "ssa_test_cfbc");
144 Config::Ptr config = ctx->config();
145
146 std::string usage = "\n"
147 "usage of SSA_TEST_CFBC:\n"
148 " run ssa_test_cfbc -Mx <number> -My <number>\n"
149 "\n";
150
151 bool stop = show_usage_check_req_opts(*ctx->log(), "ssa_test_cfbc", {}, usage);
152
153 if (stop) {
154 return 0;
155 }
156
157 // Parameters that can be overridden by command line options
158 unsigned int Mx = config->get_number("grid.Mx");
159 unsigned int My = config->get_number("grid.My");
160
161 auto method = config->get_string("stress_balance.ssa.method");
162 auto output_file = config->get_string("output.file");
163
164 bool write_output = config->get_string("output.size") != "none";
165
166 // we have to set parameters *before* `ssa` is allocated
167 config->set_number("flow_law.isothermal_Glen.ice_softness",
168 pow(1.9e8, -config->get_number("stress_balance.ssa.Glen_exponent")));
169 config->set_flag("stress_balance.ssa.compute_surface_gradient_inward", false);
170 config->set_flag("stress_balance.calving_front_stress_bc", true);
171 config->set_flag("stress_balance.ssa.fd.flow_line_mode", true);
172 config->set_flag("stress_balance.ssa.fd.extrapolate_at_margins", false);
173 config->set_string("stress_balance.ssa.flow_law", "isothermal_glen");
174
175 auto grid = ssa_test_cfbc_grid(ctx, Mx, My);
176 SSATestCaseCFBC testcase(SSATestCase::solver(grid, method));
177 testcase.init();
178 testcase.run();
179 testcase.report("V");
180 if (write_output) {
181 testcase.write(output_file);
182 }
183 }
184 catch (...) {
185 handle_fatal_errors(com);
186 return 1;
187 }
188
189 return 0;
190}
std::shared_ptr< Config > Ptr
double enthalpy(double T, double omega, double P) const
Compute enthalpy from absolute temperature, liquid water fraction, and pressure.
Converts between specific enthalpy and temperature or liquid content.
void ensure_consistency(double ice_free_thickness_threshold)
Definition Geometry.cc:114
array::Scalar2 ice_surface_elevation
Definition Geometry.hh:57
array::CellType2 cell_type
Definition Geometry.hh:55
array::Scalar2 ice_thickness
Definition Geometry.hh:51
array::Scalar2 bed_elevation
Definition Geometry.hh:47
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition Array.hh:64
void set(double c)
Result: v[j] <- c for all j.
Definition Array.cc:629
void update_ghosts()
Updates ghost points.
Definition Array.cc:615
double m_V0
grounding line vertically-averaged velocity
void exactSolution(int i, int j, double x, double y, double *u, double *v)
SSATestCaseCFBC(std::shared_ptr< SSA > ssa)
double m_H0
grounding line thickness (meters)
void initializeSSACoefficients()
Set up the coefficient variables as appropriate for the test case.
double m_C
"typical constant ice parameter"
std::shared_ptr< const pism::Grid > m_grid
virtual void init()
Initialize the test case at the start of a run.
const units::System::Ptr m_sys
static std::shared_ptr< Grid > grid(std::shared_ptr< Context > ctx, int Mx, int My, double Lx, double Ly, grid::Registration registration, grid::Periodicity periodicity)
virtual void report(const std::string &testname)
Report on the generated solution.
virtual void run()
Solve the SSA.
const Config::ConstPtr m_config
virtual void write(const std::string &filename)
Save the computation and data to a file.
#define H0
Definition exactTestM.c:39
@ Y_PERIODIC
Definition Grid.hh:54
@ CELL_CENTER
Definition Grid.hh:56
static double H_exact(double V0, double H0, double C, double x)
std::shared_ptr< Grid > ssa_test_cfbc_grid(std::shared_ptr< Context > ctx, int Mx, int My)
static double u_exact(double V0, double H0, double C, double x)
Stress balance models and related diagnostics.
Definition Isochrones.hh:31
double convert(System::Ptr system, double input, const std::string &spec1, const std::string &spec2)
Convert a quantity from unit1 to unit2.
Definition Units.cc:70
int main(int argc, char *argv[])
static char help[]