Loading [MathJax]/jax/output/HTML-CSS/config.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ssa_test_linear.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: linear flow. The rheology is
20 linear (i.e. n=1 in the Glen flow law) and the basal shear stress is also
21 linear viscous flow. The geometry consists of a constant surface slope in
22 the positive x-direction, and dirichlet conditions leading to an exponential
23 solution are imposed along the entire boundary.
24*/
25
26
27#include <memory>
28static char help[] =
29 "\nSSA_TEST_EXP\n"
30 " Testing program for the finite element implementation of the SSA.\n"
31 " Does a time-independent calculation. Does not run IceModel or a derived\n"
32 " class thereof.Also may be used in a PISM\n"
33 " software (regression) test.\n\n";
34
35#include <cmath>
36
37#include "pism/stressbalance/ssa/SSAFD.hh"
38#include "pism/stressbalance/ssa/SSAFEM.hh"
39#include "pism/stressbalance/ssa/SSATestCase.hh"
40#include "pism/util/Context.hh"
41#include "pism/util/error_handling.hh"
42#include "pism/util/petscwrappers/PetscInitializer.hh"
43#include "pism/util/pism_options.hh"
44
45namespace pism {
46namespace stressbalance {
47
48std::shared_ptr<Grid> ssa_test_linear_grid(std::shared_ptr<Context> ctx, int Mx, int My) {
49 return SSATestCase::grid(ctx, Mx, My, 50e3, 50e3, grid::CELL_CORNER, grid::NOT_PERIODIC);
50}
51
53{
54public:
55 SSATestCaseExp(std::shared_ptr<SSA> ssa)
56 : SSATestCase(ssa) {
57 L = units::convert(m_sys, 50, "km", "m"); // 50km half-width
58 H0 = 500; // meters
59 dhdx = 0.005; // pure number
60 nu0 = units::convert(m_sys, 30.0, "MPa year", "Pa s");
61 tauc0 = 1.e4; // 1kPa
62 }
63
64protected:
65 virtual void initializeSSACoefficients();
66
67 virtual void exactSolution(int i, int j,
68 double x, double y, double *u, double *v);
69
70 double L, H0, dhdx, nu0, tauc0;
71};
72
74
75 // Force linear rheology
76 m_ssa->strength_extension->set_notional_strength(nu0 * H0);
77 m_ssa->strength_extension->set_min_thickness(4000*10);
78
79 // Set constants for most coefficients.
84
85
86 // Set boundary conditions (Dirichlet all the way around).
87 m_bc_mask.set(0.0);
88
90
91 for (auto p = m_grid->points(); p; p.next()) {
92 const int i = p.i(), j = p.j();
93
94 double myu, myv;
95 const double myx = m_grid->x(i), myy=m_grid->y(j);
96
97 bool edge = ((j == 0) || (j == (int)m_grid->My() - 1) ||
98 (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
109}
110
111
112void SSATestCaseExp::exactSolution(int /*i*/, int /*j*/, double x, double /*y*/,
113 double *u, double *v) {
114 double tauc_threshold_velocity = m_config->get_number("basal_resistance.pseudo_plastic.u_threshold",
115 "m second-1");
116 double v0 = units::convert(m_sys, 100.0, "m year^-1", "m second^-1");
117 // double alpha=log(2.)/(2*L);
118 double alpha = sqrt((tauc0/tauc_threshold_velocity) / (4*nu0*H0));
119 *u = v0*exp(-alpha*(x-L));
120 *v = 0;
121}
122
123} // end of namespace stressbalance
124} // end of namespace pism
125
126int main(int argc, char *argv[]) {
127
128 using namespace pism;
129 using namespace pism::stressbalance;
130
131 MPI_Comm com = MPI_COMM_WORLD; // won't be used except for rank,size
132 petsc::Initializer petsc(argc, argv, help);
133
134 com = PETSC_COMM_WORLD;
135
136 /* This explicit scoping forces destructors to be called before PetscFinalize() */
137 try {
138 std::shared_ptr<Context> ctx = context_from_options(com, "ssa_test_linear");
139 Config::Ptr config = ctx->config();
140
141 std::string usage = "\n"
142 "usage:\n"
143 " run ssa_test_linear -Mx <number> -My <number> -ssa_method <fd|fem>\n"
144 "\n";
145
146 bool stop = show_usage_check_req_opts(*ctx->log(), "ssa_test_linear", {}, usage);
147
148 if (stop) {
149 return 0;
150 }
151
152 // Parameters that can be overridden by command line options
153 unsigned int Mx = config->get_number("grid.Mx");
154 unsigned int My = config->get_number("grid.My");
155
156 auto method = config->get_string("stress_balance.ssa.method");
157 auto output_file = config->get_string("output.file");
158
159 bool write_output = config->get_string("output.size") != "none";
160
161 // Use a pseudo-plastic law with linear till
162 config->set_flag("basal_resistance.pseudo_plastic.enabled", true);
163 config->set_number("basal_resistance.pseudo_plastic.q", 1.0);
164
165 // The finite difference code uses the following flag to treat the non-periodic grid correctly.
166 config->set_flag("stress_balance.ssa.compute_surface_gradient_inward", true);
167
168 auto grid = ssa_test_linear_grid(ctx, Mx, My);
169 SSATestCaseExp testcase(SSATestCase::solver(grid, method));
170 testcase.init();
171 testcase.run();
172 testcase.report("linear");
173 if (write_output) {
174 testcase.write(output_file);
175 }
176 }
177 catch (...) {
178 handle_fatal_errors(com);
179 return 1;
180 }
181
182 return 0;
183}
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
SSATestCaseExp(std::shared_ptr< SSA > ssa)
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)
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_linear_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
static const double v0
Definition exactTestP.cc:50
int main(int argc, char *argv[])
static char help[]