Loading [MathJax]/extensions/tex2jax.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
exactTestsABCD.c
Go to the documentation of this file.
1/*
2 Copyright (C) 2004-2006, 2014, 2016, 2023 Jed Brown and Ed Bueler
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 <math.h>
23#include <gsl/gsl_math.h> /* M_PI */
24#include "pism/verification/tests/exactTestsABCD.h"
25
26#define SperA 31556926.0 /* seconds per year; 365.2422 days */
27
28int exactA_old(const double r, double *H, double *M) {
29 /* NOTE: t is in seconds */
30 const double L = 750000.0; /* m; distance of margin from center */
31 const double M0 = 0.3 / SperA; /* 30 cm year-1 constant accumulation */
32 const double g = 9.81; /* m/s^2; accel of gravity */
33 const double rho = 910.0; /* kg/m^3; density */
34 const double n = 3.0; /* Glen exponent */
35 const double A = 1.0E-16/SperA; /* = 3.17e-24 1/(Pa^3 s); */
36 /* (EISMINT value) flow law parameter */
37 const double Gamma = 2 * pow(rho * g,n) * A / (n+2);
38
39 double m, p, C;
40
41 if (r < L) {
42 m = 2.0 * n + 2.0;
43 p = 1.0 + 1.0 / n;
44 C = pow(pow(2.0, n - 1) * M0 / Gamma, 1.0 / m);
45 *H = C * pow(pow(L, p) - pow(r, p), n / m);
46 } else {
47 *H = 0.0;
48 }
49
50 *M = M0;
51
52 return 0;
53}
54
56 struct TestABCDParameters result;
57
58 result.error_code = exactA_old(r, &result.H, &result.M);
59
60 return result;
61}
62
63int exactB_old(const double t, const double r, double *H, double *M) {
64 /* NOTE: t and t0 are in seconds */
65 double alpha, beta, t0, Rmargin;
66 const double n = 3.0, H0 = 3600.0, R0=750000.0;
67
68 /* lambda=0.0 case of Bueler et al (2005) family of similarity solns;
69 is Halfar (1983) soln */
70 alpha=1.0/9.0; /* alpha=(2-(n+1)*lambda)/(5*n+3)=1/9 */
71 beta=1.0/18.0; /* beta=(1+(2*n+1)*lambda)/(5*n+3)=1/18 */
72 t0=422.45*SperA; /* t0 = (beta/Gamma)
73 * pow((2n+1)/(n+1),n)*(pow(R0,n+1)/pow(H0,2n+1)) */
74
75 Rmargin=R0*pow(t/t0,beta);
76 if (r<Rmargin)
77 *H = H0 * pow(t/t0,-alpha)
78 * pow(1.0-pow(pow(t/t0,-beta)*(r/R0), (n+1)/n), n/(2*n+1));
79 else
80 *H = 0.0;
81
82 *M=0.0;
83 return 0;
84}
85
86struct TestABCDParameters exactB(const double t, const double r) {
87 struct TestABCDParameters result;
88
89 result.error_code = exactB_old(t, r, &result.H, &result.M);
90
91 return result;
92}
93
94int exactC_old(const double t, const double r, double *H, double *M) {
95 double lambda, alpha, beta, t0, Rmargin;
96 const double n = 3.0, H0 = 3600.0, R0=750000.0;
97
98 lambda=5.0;
99 alpha=-1.0; /* alpha=(2-(n+1)*lambda)/(5*n+3) */
100 beta=2.0; /* beta=(1+(2*n+1)*lambda)/(5*n+3) */
101 t0=15208.0*SperA; /* t0 = (beta/Gamma)
102 * pow((2n+1)/(n+1),n)*(pow(R0,n+1)/pow(H0,2n+1)) */
103
104 Rmargin=R0*pow(t/t0,beta);
105 if (r<Rmargin)
106 *H = H0 * pow(t/t0,-alpha)
107 * pow(1.0-pow(pow(t/t0,-beta)*(r/R0), (n+1)/n), n/(2*n+1));
108 else
109 *H = 0.0;
110
111 if (t>0.1*SperA)
112 *M = (lambda/t)* (*H);
113 else { /* when less than 0.1 year, avoid division by time */
114 Rmargin=R0*pow(0.1*SperA/t0,beta);
115 if (r<Rmargin)
116 *M=5*H0/t0; /* constant value in disc of Rmargin radius */
117 else
118 *M=0.0;
119 }
120 return 0;
121}
122
123struct TestABCDParameters exactC(const double t, const double r) {
124 struct TestABCDParameters result;
125
126 result.error_code = exactC_old(t, r, &result.H, &result.M);
127
128 return result;
129}
130
131int exactD_old(const double t, const double rin, double *H, double *M) {
132
133 /* parameters describing extent of sheet: */
134 const double H0=3600.0; /* m */
135 const double L=750000.0; /* m */
136 /* parameters for perturbation: */
137 const double Tp=5000.0*SperA; /* s */
138 const double Cp=200.0; /* m */
139 /* fundamental physical constants */
140 const double g=9.81; /* m/s^2; accel of gravity */
141 /* ice properties; parameters which appear in constitutive relation: */
142 const double rho=910.0; /* kg/m^3; density */
143 const double n=3.0; /* Glen exponent */
144 const double A=1.0E-16/SperA; /* = 3.17e-24 1/(Pa^3 s); */
145 /* (EISMINT value) flow law parameter */
146
147 double r=rin;
148 double Gamma, power, s, lamhat, f, Hs, temp, C, Ms, df, ddf, chi, dchi,
149 ddchi, c1, dHs, ddHs, dH, ddH, divterms, Mc;
150
151 if (r < 0.0) r=-r;
152
153 if (r >= L - 0.01) {
154 *H = 0.0;
155 *M = -0.1 / SperA;
156 } else {
157 if (r < 0.01) r = 0.01; /* avoid r=0 singularity in formulas */
158
159 /* important derived quantities */
160 Gamma = 2 * pow(rho * g,n) * A / (n+2);
161 power = n / (2*n+2);
162 s = r/L;
163
164 /* compute H from analytical steady state Hs plus perturbation */
165 lamhat = (1+1/n)*s - (1/n) + pow(1-s,1+1/n) - pow(s,1+1/n);
166 if ((r>0.3*L) && (r<0.9*L)) f = pow(cos(M_PI*(r-0.6*L)/(0.6*L)) ,2.0);
167 else f = 0.0;
168 Hs = (H0 / pow(1-1/n,power)) * pow(lamhat,power);
169 *H = Hs + Cp * sin(2.0*M_PI*t/Tp) * f;
170
171 /* compute steady part of accumulation */
172 temp = pow(s,1/n) + pow(1-s,1/n) - 1;
173 C = Gamma * pow(H0,2*n+2) / pow(2.0 * L * (1-1/n),n);
174 Ms = (C/r) * pow(temp,n-1)
175 * (2*pow(s,1/n) + pow(1-s,(1/n)-1) * (1 - 2*s) - 1);
176
177 /* derivs of H */
178 if ((r>0.3*L) && (r<0.9*L)) {
179 df = -(M_PI/(0.6*L)) * sin(M_PI*(r-0.6*L)/(0.3*L));
180 ddf = -(M_PI*M_PI/(0.18*L*L)) * cos(M_PI*(r-0.6*L)/(0.3*L));
181 chi = (4.0/3.0)*s - 1.0/3.0 + pow(1-s,4.0/3.0) - pow(s,4.0/3.0);
182 dchi = -(4.0/(3.0*L)) * (pow(s,1.0/3.0) + pow(1-s,1.0/3.0) - 1);
183 ddchi = -(4.0/(9.0*L*L)) * (pow(s,-2.0/3.0) - pow(1-s,-2.0/3.0));
184 c1 = (3.0*H0) / (8.0*pow(2.0/3.0,3.0/8.0));
185 dHs = c1 * pow(chi,-5.0/8.0) * dchi;
186 ddHs = c1 * ((-5.0/8.0) * pow(chi,-13.0/8.0) * dchi * dchi
187 + pow(chi,-5.0/8.0) * ddchi);
188 dH = dHs + Cp * sin(2.0*M_PI*t/Tp) * df;
189 ddH = ddHs + Cp * sin(2.0*M_PI*t/Tp) * ddf;
190 divterms = Gamma * pow(*H,4.) * dH * dH
191 * ((1.0/r) * (*H) * dH + 5.0 * dH * dH + 3.0 * (*H) * ddH);
192 Mc = (2.0*M_PI*Cp/Tp) * cos(2.0*M_PI*t/Tp) * f - Ms - divterms;
193 } else {
194 Mc = 0.0;
195 }
196
197 /* actual calculate total M */
198 *M = Ms + Mc;
199 }
200 return 0;
201}
202
203struct TestABCDParameters exactD(const double t, const double r) {
204 struct TestABCDParameters result;
205
206 result.error_code = exactD_old(t, r, &result.H, &result.M);
207
208 return result;
209}
static const double L
Definition exactTestL.cc:40
#define g
Definition exactTestM.c:34
#define H0
Definition exactTestM.c:39
#define n
Definition exactTestM.c:37
#define rho
Definition exactTestM.c:35
int exactD_old(const double t, const double rin, double *H, double *M)
#define SperA
int exactB_old(const double t, const double r, double *H, double *M)
struct TestABCDParameters exactB(const double t, const double r)
struct TestABCDParameters exactD(const double t, const double r)
int exactC_old(const double t, const double r, double *H, double *M)
int exactA_old(const double r, double *H, double *M)
struct TestABCDParameters exactA(double r)
struct TestABCDParameters exactC(const double t, const double r)