PISM, A Parallel Ice Sheet Model stable 0.4.1779

src/verif/tests/exactTestsIJ.c

Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines