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_const.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: constant flow. The rheology is
20 nonlinear (i.e. n=3 in the Glen flow law) and the basal shear stress is a
21 nonlinear function of velocity (peseudo-plastic flow with parameter q
22 specified at runtime).
23
24 The geometry consists of a constant surface slope in the positive
25 x-direction, and a constant velocity is specified as a Dirichlet condition
26 on the boundary that should lead to a constant solution in the interior.
27 Because the solution is constant, the nonzero terms in the SSA are only the
28 basal shear stress and the driving stress.
29 */
30
31#include <memory>
32static char help[] =
33 "\nSSA_TEST_CONST\n"
34 " Testing program for the finite element implementation of the SSA.\n"
35 " Does a time-independent calculation. Does not run IceModel or a derived\n"
36 " class thereof.Also may be used in a PISM\n"
37 " software (regression) test.\n\n";
38
39#include <cmath>
40
41#include "pism/basalstrength/basal_resistance.hh" // IceBasalResistancePlasticLaw
42#include "pism/stressbalance/ssa/SSAFD.hh"
43#include "pism/stressbalance/ssa/SSAFEM.hh"
44#include "pism/stressbalance/ssa/SSATestCase.hh"
45#include "pism/util/Mask.hh"
46#include "pism/util/Context.hh"
47#include "pism/util/VariableMetadata.hh"
48#include "pism/util/error_handling.hh"
49#include "pism/util/io/File.hh"
50#include "pism/util/petscwrappers/PetscInitializer.hh"
51#include "pism/util/pism_utilities.hh"
52#include "pism/util/pism_options.hh"
53#include "pism/verification/tests/exactTestsIJ.h"
54
55namespace pism {
56namespace stressbalance {
57
58std::shared_ptr<Grid> ssa_test_const_grid(std::shared_ptr<Context> ctx, int Mx, int My) {
59 return SSATestCase::grid(ctx, Mx, My, 50e3, 50e3, grid::CELL_CORNER, grid::NOT_PERIODIC);
60}
61
63{
64public:
65 SSATestCaseConst(std::shared_ptr<Context> ctx, std::shared_ptr<SSA> ssa) : SSATestCase(ssa) {
66 m_L = units::convert(m_sys, 50.0, "km", "m"); // 50km half-width
67 m_H0 = 500; // m
68 m_dhdx = 0.005; // pure number
69 m_nu0 = units::convert(m_sys, 30.0, "MPa year", "Pa s");
70 m_tauc0 = 1.e4; // Pa
71
72 auto config = ctx->config();
73 m_basal_q = config->get_number("basal_resistance.pseudo_plastic.q");
74 };
75
76protected:
78
79 void exactSolution(int i, int j, double x, double y, double *u, double *v);
80
81 double m_basal_q;
82 double m_L;
83 double m_H0;
84 double m_dhdx;
85 double m_nu0;
86 double m_tauc0;
87};
88
90
91 // Force linear rheology
92 m_ssa->strength_extension->set_notional_strength(m_nu0 * m_H0);
93 m_ssa->strength_extension->set_min_thickness(0.5*m_H0);
94
95 // Set constant thickness, tauc
96 m_bc_mask.set(0);
99
102
103 for (auto p = m_grid->points(); p; p.next()) {
104 const int i = p.i(), j = p.j();
105
106 double u, v;
107 const double x = m_grid->x(i), y=m_grid->y(j);
108
109 m_geometry.bed_elevation(i, j) = -x*(m_dhdx);
111
112 bool edge = ((j == 0) || (j == (int)m_grid->My() - 1) ||
113 (i == 0) || (i == (int)m_grid->Mx() - 1));
114 if (edge) {
115 m_bc_mask(i,j) = 1;
116 exactSolution(i, j, x, y, &u, &v);
117 m_bc_values(i, j).u = u;
118 m_bc_values(i, j).v = v;
119 }
120 }
121
126}
127
128
129void SSATestCaseConst::exactSolution(int /*i*/, int /*j*/,
130 double /*x*/, double /*y*/,
131 double *u, double *v) {
132 double earth_grav = m_config->get_number("constants.standard_gravity"),
133 tauc_threshold_velocity = m_config->get_number("basal_resistance.pseudo_plastic.u_threshold",
134 "m second-1"),
135 ice_rho = m_config->get_number("constants.ice.density");
136
137 *u = pow(ice_rho * earth_grav * m_H0 * m_dhdx / m_tauc0, 1./m_basal_q)*tauc_threshold_velocity;
138 *v = 0;
139}
140
141} // end of namespace stressbalance
142} // end of namespace pism
143
144int main(int argc, char *argv[]) {
145
146 using namespace pism;
147 using namespace pism::stressbalance;
148
149 MPI_Comm com = MPI_COMM_WORLD; // won't be used except for rank,size
150 petsc::Initializer petsc(argc, argv, help);
151
152 com = PETSC_COMM_WORLD;
153
154 /* This explicit scoping forces destructors to be called before PetscFinalize() */
155 try {
156 std::shared_ptr<Context> ctx = context_from_options(com, "ssa_test_const");
157 Config::Ptr config = ctx->config();
158
159 std::string usage = "\n"
160 "usage of SSA_TEST_CONST:\n"
161 " run ssa_test_const -Mx <number> -My <number> -ssa_method <fd|fem>\n"
162 "\n";
163
164 bool stop = show_usage_check_req_opts(*ctx->log(), "ssa_test_const", {}, usage);
165
166 if (stop) {
167 return 0;
168 }
169
170 // Parameters that can be overridden by command line options
171 unsigned int Mx = config->get_number("grid.Mx");
172 unsigned int My = config->get_number("grid.My");
173
174 double basal_q = 1.0;
175
176 auto method = config->get_string("stress_balance.ssa.method");
177 auto output_file = config->get_string("output.file");
178
179 bool write_output = config->get_string("output.size") != "none";
180
181 config->set_flag("basal_resistance.pseudo_plastic.enabled", true);
182 config->set_number("basal_resistance.pseudo_plastic.q", basal_q);
183
184 // Use a pseudo-plastic law with a constant q determined at run time
185 config->set_flag("basal_resistance.pseudo_plastic.enabled", true);
186
187 // The finite difference code uses the following flag to treat the non-periodic grid correctly.
188 config->set_flag("stress_balance.ssa.compute_surface_gradient_inward", true);
189
190 auto grid = ssa_test_const_grid(ctx, Mx, My);
191 SSATestCaseConst testcase(ctx, SSATestCase::solver(grid, method));
192 testcase.init();
193 testcase.run();
194 testcase.report("const");
195 if (write_output) {
196 testcase.write(output_file);
197 }
198 }
199 catch (...) {
200 handle_fatal_errors(com);
201 return 1;
202 }
203
204 return 0;
205}
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
void initializeSSACoefficients()
Set up the coefficient variables as appropriate for the test case.
SSATestCaseConst(std::shared_ptr< Context > ctx, std::shared_ptr< SSA > ssa)
void exactSolution(int i, int j, double x, double y, double *u, double *v)
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
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_const_grid(std::shared_ptr< Context > ctx, int Mx, int My)
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[]