PISM, A Parallel Ice Sheet Model stable 0.4.1779

src/verif/tests/exactTestsABCDE.c

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