|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 /* 00002 Copyright (C) 2007-2008, 2011 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 <stdlib.h> 00023 #include <math.h> 00024 #include "exactTestsIJ.h" 00025 00026 #define pi 3.14159265358979 00027 #define secpera 31556926.0 /* seconds per year; 365.2422 days */ 00028 00029 int exactI(const double m, const double x, const double y, 00030 double *bed, double *tauc, double *u, double *v) { 00031 /* see exact solution for an ice stream sliding over plastic till described 00032 on pages 237 and 238 of C. Schoof 2006 "A variational approach to ice streams" 00033 J Fluid Mech 556 pp 227--251 */ 00034 /* const double n = 3.0, p = 1.0 + 1.0/n; // p = 4/3 */ 00035 00036 const double L = 40e3; /* = 40km; y in [-3L,3L]; full width is 6L = 240 km */ 00037 const double aspect = 0.05; 00038 const double h0 = aspect * L; /* if aspect = 0.05 and L = 40km then h0 = 2000 m */ 00039 const double theta = atan(0.001); /* a slope of 1/1000, a la Siple streams */ 00040 const double rho = 910, g = 9.81; /* kg/m^3 and m/s^2, resp. */ 00041 const double f = rho * g * h0 * tan(theta); /* about 18 kPa given above 00042 values for rho,g,theta,aspect,L */ 00043 const double W = pow(m+1.0,1.0/m) * L; /* e.g. W = 1.2 * L if m = 10 */ 00044 const double B = 3.7e8; /* Pa s^{1/3}; hardness given on p. 239 of Schoof; 00045 why so big? */ 00046 00047 const double s = fabs(y/L); 00048 00049 double C0, C1, C2, C3, C4, z1, z2, z3, z4; 00050 00051 *tauc = f * pow(s,m); 00052 00053 /* to compute bed, assume bed(x=0)=0 and bed is sloping down for increasing x; 00054 if tan(theta) = 0.001 and -Lx < x < Lx with Lx = 240km then bed(x=Lx) = -240 m */ 00055 *bed = - x * tan(theta); 00056 00057 /* formula (4.3) in Schoof; note u is indep of aspect because f/h0 ratio gives C0 */ 00058 if (fabs(y) < W) { 00059 C0 = 2.0 * pow(f / (B * h0),3.0) * pow(L,4.0); 00060 /* printf(" C0*secpera = %10.5e\n",C0*secpera); */ 00061 C1 = pow(m + 1.0, 4.0/m); 00062 C2 = (m+1.0) * C1; 00063 C3 = (m+1.0) * C2; 00064 C4 = (m+1.0) * C3; 00065 z1 = ( pow(s,4.0) - C1 ) / 4.0; 00066 z2 = ( pow(s,m+4.0) - C2 ) / ( (m+1.0) * (m+4.0) ); 00067 z3 = ( pow(s,2.0*m+4.0) - C3 ) / ( (m+1.0)*(m+1.0) * (2.0*m+4.0) ); 00068 z4 = ( pow(s,3.0*m+4.0) - C4 ) / ( pow((m+1.0),3.0) * (3.0*m+4.0) ); 00069 /* printf(" u / C0 = %10.5e\n",- (z1 - 3.0 * z2 + 3.0 * z3 - z4)); */ 00070 *u = - C0 * (z1 - 3.0 * z2 + 3.0 * z3 - z4); /* comes out positive */ 00071 } else { 00072 *u = 0.0; 00073 } 00074 *v = 0.0; /* no transverse flow */ 00075 return 0; 00076 } 00077 00078 00079 int exactJ(const double x, const double y, 00080 double *H, double *nu, double *u, double *v) { 00081 /* documented only in preprint by Bueler */ 00082 /* return 0 if successful */ 00083 00084 const double L = 300.0e3; /* 300 km half-width */ 00085 const double H0 = 500.0; /* 500 m typical thickness */ 00086 /* use Ritz et al (2001) value of 30 MPa yr for typical 00087 vertically-averaged viscosity */ 00088 const double nu0 = 30.0 * 1.0e6 * secpera; /* = 9.45e14 Pa s */ 00089 const double rho_ice = 910.0; /* kg/m^3 */ 00090 const double rho_sw = 1028.0; /* kg/m^3 */ 00091 const double g = 9.81; /* m/s^2 */ 00092 const double C = rho_ice * g * (1.0 - rho_ice/rho_sw) * H0 / (2.0 * nu0); 00093 const double my_gamma[3][3] = {{1.0854, 0.108, 0.0027}, 00094 {0.402 , 0.04 , 0.001 }, 00095 {0.0402, 0.004, 0.0001}}; 00096 const double A = L / (4.0 * pi); 00097 double uu = 0.0, vv = 0.0, denom, trig, kx, ly, B; 00098 int k,l; 00099 00100 *H = H0 * (1.0 + 0.4 * cos(pi * x / L)) * (1.0 + 0.1 * cos(pi * y / L)); 00101 *nu = (nu0 * H0) / *H; /* so \nu(x,y) H(x,y) = \nu_0 H_0 */ 00102 for (k=-2; k<=2; k++) { 00103 for (l=-2; l<=2; l++) { 00104 if ((k != 0) || (l != 0)) { /* note alpha_00 = beta_00 = 0 */ 00105 denom = (double)(k * k + l * l); 00106 kx = (double)(k) * pi * x / L; 00107 ly = (double)(l) * pi * y / L; 00108 trig = cos(kx) * sin(ly) + sin(kx) * cos(ly); 00109 B = (A / denom) * (C * my_gamma[abs(k)][abs(l)]) * trig; 00110 uu += B * (double)(k); 00111 vv += B * (double)(l); 00112 } 00113 } 00114 } 00115 *u = uu; *v = vv; 00116 return 0; 00117 } 00118
1.7.3