21 #include "pism/verification/tests/exactTestsFG.hh"
28 static double p3(
double x) {
30 return -6.0 + x*(6.0 + x*(-3.0 + x));
33 static double p4(
double x) {
35 return 24.0 + x*(-24.0 + x*(12.0 + x*(-4.0 + x)));
40 const double SperA = 31556926.0;
43 const double H0 = 3000.0;
44 const double L = 750000.0;
47 const double Tp = 2000.0*
SperA;
50 const double g = 9.81;
51 const double Rgas = 8.314;
54 const double rho = 910.0;
56 const double cpheat = 2009.0;
60 const double A = 3.615E-13;
61 const double Q = 6.0E4;
64 const double Ggeo = 0.042;
65 const double ST = 1.67E-5;
66 const double Tmin = 223.15;
67 const double Kcond =
k / (
rho*cpheat);
69 const size_t Mz = z.size();
82 std::vector<double> I3(Mz);
84 if ((r <= 0) or (r >=
L)) {
85 throw std::runtime_error(
"exactFG(): code and derivation assume 0 < r < L !");
89 const double power =
n / (2*
n + 2);
90 const double Hconst =
H0 / pow(1 - 1 /
n, power);
91 const double s = r /
L;
92 const double lamhat = (1 + 1 /
n)*s - (1 /
n) + pow(1 - s, 1 + 1 /
n) - pow(s, 1 + 1 /
n);
95 if ((r > 0.3*
L) and (r < 0.9*
L)) {
96 f = pow(cos(M_PI*(r - 0.6*
L) / (0.6*
L)) , 2.0);
101 const double goft = Cp*sin(2.0*M_PI*t / Tp);
103 H = Hconst*pow(lamhat, power) + goft*f;
107 const double nusqrt = sqrt(1 + (4.0*H*Ggeo) / (
k*
Ts));
108 const double nu = (
k*
Ts / (2.0*Ggeo))*(1 + nusqrt);
109 for (
size_t i = 0; i < Mz; i++) {
111 T[i] =
Ts * (nu + H) / (nu + z[i]);
119 const double lamhatr = ((1 + 1 /
n) /
L)*(1 - pow(1 - s, 1 /
n) - pow(s, 1 /
n));
122 if ((r > 0.3*
L) and (r < 0.9*
L)) {
123 fr = - (M_PI / (0.6*
L)) * sin(2.0*M_PI*(r - 0.6*
L) / (0.6*
L));
128 const double Hr = Hconst * power * pow(lamhat, power - 1) * lamhatr + goft*fr;
130 throw std::runtime_error(
"exactFG(): assumes H_r negative for all 0 < r < L !");
133 const double mu = Q / (Rgas*
Ts*(nu + H));
134 const double surfArr = exp(-Q / (Rgas*
Ts));
135 const double Uconst = 2.0 * pow(
rho*
g,
n) * A;
136 const double omega = Uconst * pow( - Hr,
n) * surfArr * pow(mu, -
n - 1);
138 for (
size_t i = 0; i < Mz; i++) {
140 I3[i] =
p3(mu*H) * exp(mu*H) -
p3(mu*(H - z[i])) * exp(mu*(H - z[i]));
141 U[i] = omega * I3[i];
143 I3[i] =
p3(mu*H) * exp(mu*H) -
p3(0.0);
144 U[i] = omega * I3[i];
149 for (
size_t i = 0; i < Mz; i++) {
151 const double Sigmu = - (Q*(nu + z[i])) / (Rgas*
Ts*(nu + H));
152 Sig[i] = (Uconst*
g / cpheat) * exp(Sigmu) * pow(fabs(Hr)*(H - z[i]) ,
n + 1);
159 const double lamhatrr = ((1 + 1 /
n) / (
n*
L*
L)) * (pow(1 - s, (1 /
n) - 1) - pow(s, (1 /
n) - 1));
162 if ((r > 0.3*
L) and (r < 0.9*
L)) {
163 frr = - (2.0*M_PI*M_PI / (0.36*
L*
L)) * cos(2.0*M_PI*(r - 0.6*
L) / (0.6*
L));
168 const double Hrr = Hconst*power*(power - 1)*pow(lamhat, power - 2.0) * pow(lamhatr, 2.0) +
169 Hconst*power*pow(lamhat, power - 1)*lamhatrr + goft*frr;
170 const double Tsr =
ST;
171 const double nur = (
k*Tsr / (2.0*Ggeo)) * (1 + nusqrt) + (1 /
Ts) * (Hr*
Ts - H*Tsr) / nusqrt;
172 const double mur = ( - Q / (Rgas*
Ts*
Ts*pow(nu + H, 2.0))) * (Tsr*(nu + H) +
Ts*(nur + Hr));
173 const double phi = 1 / r +
n*Hrr / Hr + Q*Tsr / (Rgas*
Ts*
Ts) - (
n + 1)*mur / mu;
174 const double gam = pow(mu,
n) * exp(mu*H) * (mur*H + mu*Hr) * pow(H,
n);
175 for (
size_t i = 0; i < Mz; i++) {
176 const double I4 =
p4(mu*H) * exp(mu*H) -
p4(mu*(H - z[i])) * exp(mu*(H - z[i]));
177 w[i] = omega * ((mur / mu -
phi)*I4 / mu + (
phi*(H - z[i]) + Hr)*I3[i] - gam*z[i]);
181 const double I4H =
p4(mu*H) * exp(mu*H) - 24.0;
182 const double divQ = - omega * (mur / mu -
phi) * I4H / mu + omega * gam * H;
183 const double Ht = (Cp*2.0*M_PI / Tp) * cos(2.0*M_PI*t / Tp) * f;
187 const double nut = Ht / nusqrt;
188 for (
size_t i = 0; i < Mz; i++) {
190 const double dTt =
Ts * ((nut + Ht)*(nu + z[i]) - (nu + H)*nut) * pow(nu + z[i], - 2.0);
191 const double Tr = Tsr*(nu + H) / (nu + z[i])
192 +
Ts * ((nur + Hr)*(nu + z[i]) - (nu + H)*nur) * pow(nu + z[i], - 2.0);
193 const double Tz = -
Ts * (nu + H) * pow(nu + z[i], - 2.0);
194 const double Tzz = 2.0 *
Ts * (nu + H) * pow(nu + z[i], - 3.0);
195 Sigc[i] = dTt + U[i]*Tr + w[i]*Tz - Kcond*Tzz - Sig[i];
static double p4(double x)
static double p3(double x)
static const double SperA
TestFGParameters exactFG(double t, double r, const std::vector< double > &z, double Cp)
std::vector< double > Sig
std::vector< double > Sigc