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
exactTestsIJ.c
Go to the documentation of this file.
1/*
2 Copyright (C) 2007-2008, 2011, 2014, 2015, 2016, 2023 Ed Bueler and Constantine Khroulev
3
4 This file is part of PISM.
5
6 PISM is free software; you can redistribute it and/or modify it under the
7 terms of the GNU General Public License as published by the Free Software
8 Foundation; either version 3 of the License, or (at your option) any later
9 version.
10
11 PISM is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 details.
15
16 You should have received a copy of the GNU General Public License
17 along with PISM; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <math.h>
24#include <gsl/gsl_math.h> /* M_PI */
25#include "pism/verification/tests/exactTestsIJ.h"
26
27#define secpera 31556926.0 /* seconds per year; 365.2422 days */
28
29struct TestIParameters exactI(const double m, const double x, const double y) {
30 /* see exact solution for an ice stream sliding over plastic till described
31 on pages 237 and 238 of C. Schoof 2006 "A variational approach to ice streams"
32 J Fluid Mech 556 pp 227--251 */
33 /* const double n = 3.0, p = 1.0 + 1.0/n; // p = 4/3 */
34
35 struct TestIParameters result;
36
37 const double L = 40e3; /* = 40km; y in [-3L,3L]; full width is 6L = 240 km */
38 const double aspect = 0.05;
39 const double h0 = aspect * L; /* if aspect = 0.05 and L = 40km then h0 = 2000 m */
40 const double theta = atan(0.001); /* a slope of 1/1000, a la Siple streams */
41 const double rho = 910, g = 9.81; /* kg/m^3 and m/s^2, resp. */
42 const double f = rho * g * h0 * tan(theta); /* about 18 kPa given above
43 values for rho,g,theta,aspect,L */
44 const double W = pow(m+1.0,1.0/m) * L; /* e.g. W = 1.2 * L if m = 10 */
45 const double B = 3.7e8; /* Pa s^{1/3}; hardness given on p. 239 of Schoof;
46 why so big? */
47
48 const double s = fabs(y/L);
49
50 double C0, C1, C2, C3, C4, z1, z2, z3, z4;
51
52 result.tauc = f * pow(s,m);
53
54 /* to compute bed, assume bed(x=0)=0 and bed is sloping down for increasing x;
55 if tan(theta) = 0.001 and -Lx < x < Lx with Lx = 240km then bed(x=Lx) = -240 m */
56 result.bed = - x * tan(theta);
57
58 /* formula (4.3) in Schoof; note u is indep of aspect because f/h0 ratio gives C0 */
59 if (fabs(y) < W) {
60 C0 = 2.0 * pow(f / (B * h0),3.0) * pow(L,4.0);
61 /* printf(" C0*secpera = %10.5e\n",C0*secpera); */
62 C1 = pow(m + 1.0, 4.0/m);
63 C2 = (m+1.0) * C1;
64 C3 = (m+1.0) * C2;
65 C4 = (m+1.0) * C3;
66 z1 = (pow(s,4.0) - C1) / 4.0;
67 z2 = (pow(s,m+4.0) - C2) / ((m+1.0) * (m+4.0));
68 z3 = (pow(s,2.0*m+4.0) - C3) / ((m+1.0)*(m+1.0) * (2.0*m+4.0));
69 z4 = (pow(s,3.0*m+4.0) - C4) / (pow((m+1.0),3.0) * (3.0*m+4.0));
70 /* printf(" u / C0 = %10.5e\n",- (z1 - 3.0 * z2 + 3.0 * z3 - z4)); */
71 result.u = - C0 * (z1 - 3.0 * z2 + 3.0 * z3 - z4); /* comes out positive */
72 } else {
73 result.u = 0.0;
74 }
75 result.v = 0.0; /* no transverse flow */
76 return result;
77}
78
79
80struct TestJParameters exactJ(const double x, const double y) {
81 /* documented only in preprint by Bueler */
82
83 struct TestJParameters result;
84
85 const double L = 300.0e3; /* 300 km half-width */
86 const double H0 = 500.0; /* 500 m typical thickness */
87 /* use Ritz et al (2001) value of 30 MPa year for typical
88 vertically-averaged viscosity */
89 const double nu0 = 30.0 * 1.0e6 * secpera; /* = 9.45e14 Pa s */
90 const double rho_ice = 910.0; /* kg/m^3 */
91 const double rho_sw = 1028.0; /* kg/m^3 */
92 const double g = 9.81; /* m/s^2 */
93 const double C = rho_ice * g * (1.0 - rho_ice/rho_sw) * H0 / (2.0 * nu0);
94 const double my_gamma[3][3] = {{1.0854, 0.108, 0.0027},
95 {0.402 , 0.04 , 0.001 },
96 {0.0402, 0.004, 0.0001}};
97 const double A = L / (4.0 * M_PI);
98 double uu = 0.0, vv = 0.0, denom, trig, kx, ly, B;
99 int k,l;
100
101 result.H = H0 * (1.0 + 0.4 * cos(M_PI * x / L)) * (1.0 + 0.1 * cos(M_PI * y / L));
102 result.nu = (nu0 * H0) / result.H; /* so \nu(x,y) H(x,y) = \nu_0 H_0 */
103 for (k=-2; k<=2; k++) {
104 for (l=-2; l<=2; l++) {
105 if ((k != 0) || (l != 0)) { /* note alpha_00 = beta_00 = 0 */
106 denom = (double)(k * k + l * l);
107 kx = (double)(k) * M_PI * x / L;
108 ly = (double)(l) * M_PI * y / L;
109 trig = cos(kx) * sin(ly) + sin(kx) * cos(ly);
110 B = (A / denom) * (C * my_gamma[abs(k)][abs(l)]) * trig;
111 uu += B * (double)(k);
112 vv += B * (double)(l);
113 }
114 }
115 }
116 result.u = uu;
117 result.v = vv;
118
119 return result;
120}
121
const double rho_ice
Definition exactTestK.c:31
static const double L
Definition exactTestL.cc:40
#define g
Definition exactTestM.c:34
#define H0
Definition exactTestM.c:39
#define rho
Definition exactTestM.c:35
#define secpera
Definition exactTestN.c:24
struct TestJParameters exactJ(const double x, const double y)
struct TestIParameters exactI(const double m, const double x, const double y)