Loading [MathJax]/jax/output/HTML-CSS/config.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_plug.cc
Go to the documentation of this file.
1// Copyright (C) 2010--2018, 2021, 2022, 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
19/* This file implements a test case for the ssa: plug flow. The geometry
20 consists of a constant surface slope in the positive x-direction, and the
21 ice is pinned on the y-boundaries. There is no basal shear stress, and hence
22 the the only nonzero terms in the SSA are the "p-laplacian" and the driving
23 stress.
24*/
25
26static char help[] =
27 "\nSSA_TEST_PLUG\n"
28 " Testing program for the finite element implementation of the SSA.\n"
29 " Does a time-independent calculation. Does not run IceModel or a derived\n"
30 " class thereof.\n\n";
31
32#include <cmath>
33
34#include "pism/stressbalance/ssa/SSAFD.hh"
35#include "pism/stressbalance/ssa/SSAFEM.hh"
36#include "pism/stressbalance/ssa/SSATestCase.hh"
37#include "pism/util/Context.hh"
38#include "pism/util/error_handling.hh"
39#include "pism/util/petscwrappers/PetscInitializer.hh"
40#include "pism/util/pism_options.hh"
41
42namespace pism {
43namespace stressbalance {
44
45std::shared_ptr<Grid> ssa_test_plug_grid(std::shared_ptr<Context> ctx, int Mx, int My) {
46 return SSATestCase::grid(ctx, Mx, My, 50e3, 50e3, grid::CELL_CORNER, grid::NOT_PERIODIC);
47}
48
50public:
51 SSATestCasePlug(std::shared_ptr<SSA> ssa)
52 : SSATestCase(ssa) {
53 }
54
55 static const double H0; // Thickness, meters
56 static const double L; // Half-width, meters
57 static const double dhdx; // surface slope, pure number
58 static const double tauc0; // zero basal shear stress, Pa
59 static const double B0; // Pa s^{1/3}; hardness given on p. 239 of Schoof; why so big?
60
61protected:
62 virtual void initializeSSACoefficients();
63
64 virtual void exactSolution(int i, int j, double x, double y, double *u, double *v);
65};
66
67const double SSATestCasePlug::H0 = 2000.0;
68const double SSATestCasePlug::L = 50e3;
69const double SSATestCasePlug::dhdx = 0.001;
70const double SSATestCasePlug::tauc0 = 0.0;
71const double SSATestCasePlug::B0 = 3.7e8;
72
74
75 // Ensure we never use the strength extension.
76 m_ssa->strength_extension->set_min_thickness(H0 / 2);
77
78 // Set constant coefficients.
81
82 // Set boundary conditions (Dirichlet all the way around).
83 m_bc_mask.set(0.0);
84
87
88 for (auto p = m_grid->points(); p; p.next()) {
89 const int i = p.i(), j = p.j();
90
91 double myu, myv;
92 const double myx = m_grid->x(i), myy = m_grid->y(j);
93
94 m_geometry.bed_elevation(i, j) = -myx * (dhdx);
96
97 bool edge =
98 ((j == 0) || (j == (int)m_grid->My() - 1) || (i == 0) || (i == (int)m_grid->Mx() - 1));
99 if (edge) {
100 m_bc_mask(i, j) = 1;
101 exactSolution(i, j, myx, myy, &myu, &myv);
102 m_bc_values(i, j).u = myu;
103 m_bc_values(i, j).v = myv;
104 }
105 }
106
111}
112
113void SSATestCasePlug::exactSolution(int /*i*/, int /*j*/, double /*x*/, double y, double *u,
114 double *v) {
115 double earth_grav = m_config->get_number("constants.standard_gravity"),
116 ice_rho = m_config->get_number("constants.ice.density");
117 double f = ice_rho * earth_grav * H0 * dhdx;
118 double ynd = y / L;
119
120 *u = 0.5 * pow(f, 3) * pow(L, 4) / pow(B0 * H0, 3) * (1 - pow(ynd, 4));
121 *v = 0;
122}
123
124} // end of namespace stressbalance
125} // end of namespace pism
126
127int main(int argc, char *argv[]) {
128
129 using namespace pism;
130 using namespace pism::stressbalance;
131
132 MPI_Comm com = MPI_COMM_WORLD; // won't be used except for rank,size
133 petsc::Initializer petsc(argc, argv, help);
134
135 com = PETSC_COMM_WORLD;
136
137 /* This explicit scoping forces destructors to be called before PetscFinalize() */
138 try {
139 std::shared_ptr<Context> ctx = context_from_options(com, "ssa_test_plug");
140 Config::Ptr config = ctx->config();
141
142 std::string usage = "\n"
143 "usage of SSA_TEST_PLUG:\n"
144 " run ssa_test_plug -Mx <number> -My <number> -ssa_method <fd|fem>\n"
145 "\n";
146
147 bool stop = show_usage_check_req_opts(*ctx->log(), "ssa_test_plug", {}, usage);
148
149 if (stop) {
150 return 0;
151 }
152
153 // Parameters that can be overridden by command line options
154
155 unsigned int Mx = config->get_number("grid.Mx");
156 unsigned int My = config->get_number("grid.My");
157
158 auto method = config->get_string("stress_balance.ssa.method");
159 auto output_file = config->get_string("output.file");
160
161 bool write_output = config->get_string("output.size") != "none";
162
163 // we have to set parameters *before* `ssa` is allocated
164 //
165 // Use constant hardness
166 config->set_string("stress_balance.ssa.flow_law", "isothermal_glen");
167 config->set_number(
168 "flow_law.isothermal_Glen.ice_softness",
169 pow(SSATestCasePlug::B0, -config->get_number("stress_balance.ssa.Glen_exponent")));
170
171 // The finite difference code uses the following flag to treat the non-periodic grid correctly.
172 config->set_flag("stress_balance.ssa.compute_surface_gradient_inward", true);
173 config->set_number("stress_balance.ssa.epsilon", 0.0);
174
175 auto grid = ssa_test_plug_grid(ctx, Mx, My);
176 SSATestCasePlug testcase(SSATestCase::solver(grid, method));
177 testcase.init();
178 testcase.run();
179 testcase.report("plug");
180 if (write_output) {
181 testcase.write(output_file);
182 }
183 } catch (...) {
184 handle_fatal_errors(com);
185 return 1;
186 }
187
188 return 0;
189}
std::shared_ptr< Config > Ptr
array::Scalar2 ice_surface_elevation
Definition Geometry.hh:57
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
virtual void initializeSSACoefficients()
Set up the coefficient variables as appropriate for the test case.
virtual void exactSolution(int i, int j, double x, double y, double *u, double *v)
SSATestCasePlug(std::shared_ptr< SSA > ssa)
std::shared_ptr< const pism::Grid > m_grid
virtual void init()
Initialize the test case at the start of a run.
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
std::shared_ptr< SSA > m_ssa
virtual void write(const std::string &filename)
Save the computation and data to a file.
@ NOT_PERIODIC
Definition Grid.hh:54
@ CELL_CORNER
Definition Grid.hh:56
std::shared_ptr< Grid > ssa_test_plug_grid(std::shared_ptr< Context > ctx, int Mx, int My)
Stress balance models and related diagnostics.
Definition Isochrones.hh:31
int main(int argc, char *argv[])
static char help[]