|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 /* 00002 Copyright (C) 2004-2006 Jed Brown and Ed Bueler 00003 00004 This file is part of PISM. 00005 00006 PISM is free software; you can redistribute it and/or modify it under the 00007 terms of the GNU General Public License as published by the Free Software 00008 Foundation; either version 2 of the License, or (at your option) any later 00009 version. 00010 00011 PISM is distributed in the hope that it will be useful, but WITHOUT ANY 00012 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00013 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00014 details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with PISM; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <stdio.h> 00022 #include <math.h> 00023 #include "exactTestsABCDE.h" 00024 00025 #define pi 3.14159265358979 00026 #define SperA 31556926.0 /* seconds per year; 365.2422 days */ 00027 00028 int exactA(const double r, double *H, double *M) { 00029 /* NOTE: t is in seconds */ 00030 const double L = 750000.0; /* m; distance of margin from center */ 00031 const double M0 = 0.3 / SperA; /* 30 cm/year constant accumulation */ 00032 const double g = 9.81; /* m/s^2; accel of gravity */ 00033 const double rho = 910.0; /* kg/m^3; density */ 00034 const double n = 3.0; /* Glen exponent */ 00035 const double A = 1.0E-16/SperA; /* = 3.17e-24 1/(Pa^3 s); */ 00036 /* (EISMINT value) flow law parameter */ 00037 const double Gamma = 2 * pow(rho * g,n) * A / (n+2); 00038 00039 double m, p, C; 00040 00041 if (r < L) { 00042 m = 2.0 * n + 2.0; 00043 p = 1.0 + 1.0 / n; 00044 C = pow(pow(2.0, n - 1) * M0 / Gamma, 1.0 / m); 00045 *H = C * pow(pow(L, p) - pow(r, p), n / m); 00046 } else { 00047 *H = 0.0; 00048 } 00049 00050 *M = M0; 00051 00052 return 0; 00053 } 00054 00055 00056 int exactB(const double t, const double r, double *H, double *M) { 00057 /* NOTE: t and t0 are in seconds */ 00058 double alpha, beta, t0, Rmargin; 00059 const double n = 3.0, H0 = 3600.0, R0=750000.0; 00060 00061 /* lambda=0.0 case of Bueler et al (2005) family of similarity solns; 00062 is Halfar (1983) soln */ 00063 alpha=1.0/9.0; /* alpha=(2-(n+1)*lambda)/(5*n+3)=1/9 */ 00064 beta=1.0/18.0; /* beta=(1+(2*n+1)*lambda)/(5*n+3)=1/18 */ 00065 t0=422.45*SperA; /* t0 = (beta/Gamma) 00066 * pow((2n+1)/(n+1),n)*(pow(R0,n+1)/pow(H0,2n+1)) */ 00067 00068 Rmargin=R0*pow(t/t0,beta); 00069 if (r<Rmargin) 00070 *H = H0 * pow(t/t0,-alpha) 00071 * pow( 1.0-pow( pow(t/t0,-beta)*(r/R0), (n+1)/n ), n/(2*n+1) ); 00072 else 00073 *H = 0.0; 00074 00075 *M=0.0; 00076 return 0; 00077 } 00078 00079 00080 int exactC(const double t, const double r, double *H, double *M) { 00081 double lambda, alpha, beta, t0, Rmargin; 00082 const double n = 3.0, H0 = 3600.0, R0=750000.0; 00083 00084 lambda=5.0; 00085 alpha=-1.0; /* alpha=(2-(n+1)*lambda)/(5*n+3) */ 00086 beta=2.0; /* beta=(1+(2*n+1)*lambda)/(5*n+3) */ 00087 t0=15208.0*SperA; /* t0 = (beta/Gamma) 00088 * pow((2n+1)/(n+1),n)*(pow(R0,n+1)/pow(H0,2n+1)) */ 00089 00090 Rmargin=R0*pow(t/t0,beta); 00091 if (r<Rmargin) 00092 *H = H0 * pow(t/t0,-alpha) 00093 * pow( 1.0-pow( pow(t/t0,-beta)*(r/R0), (n+1)/n ), n/(2*n+1) ); 00094 else 00095 *H = 0.0; 00096 00097 if (t>0.1*SperA) 00098 *M = (lambda/t)* (*H); 00099 else { /* when less than 0.1 year, avoid division by time */ 00100 Rmargin=R0*pow(0.1*SperA/t0,beta); 00101 if (r<Rmargin) 00102 *M=5*H0/t0; /* constant value in disc of Rmargin radius */ 00103 else 00104 *M=0.0; 00105 } 00106 return 0; 00107 } 00108 00109 00110 int exactD(const double t, const double rin, double *H, double *M) { 00111 00112 /* parameters describing extent of sheet: */ 00113 const double H0=3600.0; /* m */ 00114 const double L=750000.0; /* m */ 00115 /* parameters for perturbation: */ 00116 const double Tp=5000.0*SperA; /* s */ 00117 const double Cp=200.0; /* m */ 00118 /* fundamental physical constants */ 00119 const double g=9.81; /* m/s^2; accel of gravity */ 00120 /* ice properties; parameters which appear in constitutive relation: */ 00121 const double rho=910.0; /* kg/m^3; density */ 00122 const double n=3.0; /* Glen exponent */ 00123 const double A=1.0E-16/SperA; /* = 3.17e-24 1/(Pa^3 s); */ 00124 /* (EISMINT value) flow law parameter */ 00125 00126 double r=rin; 00127 double Gamma, power, s, lamhat, f, Hs, temp, C, Ms, df, ddf, chi, dchi, 00128 ddchi, c1, dHs, ddHs, dH, ddH, divterms, Mc; 00129 00130 if (r < 0.0) r=-r; 00131 00132 if (r >= L - 0.01) { 00133 *H = 0.0; 00134 *M = -0.1 / SperA; 00135 } else { 00136 if (r < 0.01) r = 0.01; /* avoid r=0 singularity in formulas */ 00137 00138 /* important derived quantities */ 00139 Gamma = 2 * pow(rho * g,n) * A / (n+2); 00140 power = n / (2*n+2); 00141 s = r/L; 00142 00143 /* compute H from analytical steady state Hs plus perturbation */ 00144 lamhat = (1+1/n)*s - (1/n) + pow(1-s,1+1/n) - pow(s,1+1/n); 00145 if ((r>0.3*L) && (r<0.9*L)) f = pow( cos(pi*(r-0.6*L)/(0.6*L)) ,2.0); 00146 else f = 0.0; 00147 Hs = (H0 / pow(1-1/n,power)) * pow(lamhat,power); 00148 *H = Hs + Cp * sin(2.0*pi*t/Tp) * f; 00149 00150 /* compute steady part of accumulation */ 00151 temp = pow(s,1/n) + pow(1-s,1/n) - 1; 00152 C = Gamma * pow(H0,2*n+2) / pow(2.0 * L * (1-1/n),n); 00153 Ms = (C/r) * pow(temp,n-1) 00154 * ( 2*pow(s,1/n) + pow(1-s,(1/n)-1) * (1 - 2*s) - 1 ); 00155 00156 /* derivs of H */ 00157 if ((r>0.3*L) && (r<0.9*L)) { 00158 df = -(pi/(0.6*L)) * sin(pi*(r-0.6*L)/(0.3*L)); 00159 ddf = -(pi*pi/(0.18*L*L)) * cos(pi*(r-0.6*L)/(0.3*L)); 00160 chi = (4.0/3.0)*s - 1.0/3.0 + pow(1-s,4.0/3.0) - pow(s,4.0/3.0); 00161 dchi = -(4.0/(3.0*L)) * (pow(s,1.0/3.0) + pow(1-s,1.0/3.0) - 1); 00162 ddchi = -(4.0/(9.0*L*L)) * ( pow(s,-2.0/3.0) - pow(1-s,-2.0/3.0) ); 00163 c1 = (3.0*H0) / (8.0*pow(2.0/3.0,3.0/8.0)); 00164 dHs = c1 * pow(chi,-5.0/8.0) * dchi; 00165 ddHs = c1 * ( (-5.0/8.0) * pow(chi,-13.0/8.0) * dchi * dchi 00166 + pow(chi,-5.0/8.0) * ddchi ); 00167 dH = dHs + Cp * sin(2.0*pi*t/Tp) * df; 00168 ddH = ddHs + Cp * sin(2.0*pi*t/Tp) * ddf; 00169 divterms = Gamma * pow(*H,4.) * dH * dH 00170 * ( (1.0/r) * (*H) * dH + 5.0 * dH * dH + 3.0 * (*H) * ddH ); 00171 Mc = (2.0*pi*Cp/Tp) * cos(2.0*pi*t/Tp) * f - Ms - divterms; 00172 } else { 00173 Mc = 0.0; 00174 } 00175 00176 /* actual calculate total M */ 00177 *M = Ms + Mc; 00178 } 00179 return 0; 00180 } 00181 00182 00183 int exactE(const double xIN, const double yIN, 00184 double *H, double *M, double *mu, double *ub, double *vb) { 00185 00186 const double L = 750000.0; /* m; distance of margin from center */ 00187 const double M0 = 0.3 / SperA; /* 30 cm/year constant accumulation */ 00188 const double g = 9.81; /* m/s^2; accel of gravity */ 00189 const double rho = 910.0; /* kg/m^3; density */ 00190 const double n = 3.0; /* Glen exponent */ 00191 const double A = 1.0E-16/SperA; /* = 3.17e-24 1/(Pa^3 s); */ 00192 /* (EISMINT value) flow law parameter */ 00193 const double Gamma = 2 * pow(rho * g,n) * A / (n+2); 00194 00195 const double mu_max = 2.5e-11; /* Pa^-1 m s^-1; max sliding coeff */ 00196 const double r1 = 200e3, r2 = 700e3, /* define region of sliding */ 00197 theta1 = 10 * (pi/180), theta2 = 40 * (pi/180); 00198 const double rbot = (r2 - r1) * (r2 - r1), 00199 thetabot = (theta2 - theta1) * (theta2 - theta1); 00200 00201 /* note all features are reflected across coordinate axes */ 00202 double x = fabs(xIN), y = fabs(yIN), 00203 sgnx = 1.0, sgny = 1.0, r, theta; 00204 double m, q, C, chi; 00205 double mufactor, dchidr, P, dhdr, h_x, h_y, d2hdr2, dmudr, Mb; 00206 00207 r = sqrt(x * x + y * y); 00208 if (xIN < 0) sgnx = -1.0; 00209 if (yIN < 0) sgny = -1.0; 00210 00211 if (r < L) { 00212 m = 2.0 * n + 2.0; 00213 q = 1.0 + 1.0 / n; 00214 C = pow(pow(2.0, n - 1) * M0 / Gamma, 1.0 / m); 00215 chi = pow(L, q) - pow(r, q); 00216 *H = C * pow(chi, n / m); 00217 00218 if (x < 1.0) 00219 theta = pi / 2.0; 00220 else 00221 theta = atan(y / x); 00222 00223 if ( (r <= r1) || (r >= r2) || (theta <= theta1) || (theta >= theta2) ) { 00224 /* if outside sliding region but within ice cap, return as in test A */ 00225 *M = M0; 00226 *mu = 0.0; 00227 *ub = 0.0; 00228 *vb = 0.0; 00229 } else { 00230 /* if INSIDE sliding region */ 00231 mufactor = mu_max * (4.0 * (theta - theta1) * (theta2 - theta) / thetabot); 00232 *mu = mufactor * (4.0 * (r - r1) * (r2 - r) / rbot); 00233 00234 dchidr = -q * pow(r, 1.0/n); 00235 dhdr = ((n * C) / m) * pow(chi, (n - m) / m) * dchidr; 00236 /* also: dhdr = -(C / 2.0) * pow(r, 1.0 / n) * pow(chi, -(n + 2.0) / m) */ 00237 P = rho * g * (*H); 00238 h_x = dhdr * cos(theta); 00239 h_y = dhdr * sin(theta); 00240 *ub = sgnx * ( -(*mu) * P * h_x ); 00241 *vb = sgny * ( -(*mu) * P * h_y ); 00242 00243 d2hdr2 = dhdr * ( -((n + 2.0) / m) * dchidr / chi + 1.0 / (n * r) ); 00244 dmudr = mufactor * 4.0 * (r1 + r2 - 2.0 * r) / rbot; 00245 Mb = -P * ( ((*mu) / r) * (*H) * dhdr + dmudr * (*H) * dhdr 00246 + 2.0 * (*mu) * dhdr * dhdr + (*mu) * (*H) * d2hdr2 ); 00247 *M = M0 + Mb; 00248 } 00249 } else { /* outside of ice cap */ 00250 *H = 0.0; 00251 *M = M0; 00252 *mu = 0.0; 00253 *ub = 0.0; 00254 *vb = 0.0; 00255 } 00256 return 0; 00257 } 00258
1.7.3