23 #include <gsl/gsl_errno.h>
24 #include <gsl/gsl_math.h>
25 #include <gsl/gsl_roots.h>
26 #include "pism/verification/tests/exactTestK.h"
28 const double SperA = 31556926.0;
37 const double H0 = 3000.0;
38 const double B0 = 1000.0;
39 const double Ts = 223.15;
40 const double G = 0.042;
41 const double phi = 0.0125;
47 static int exactK_old(
const double t,
const double z,
double *TT,
double *FF,
const int bedrockIsIce_p) {
50 double ZZ, alpha, lambda, beta, my_gamma, XkSQR, Xk,
51 theta, dthetakdz, P, dPdz,
52 Ck, I1, I2, aH, bB, mI, mR;
53 double c_p_bedrock, rho_bedrock, k_bedrock;
55 double alf[
Nsum] = {3.350087528822397e-04, 1.114576827617396e-03, 1.953590840303518e-03,
56 2.684088585781064e-03, 3.371114869333445e-03, 4.189442265117592e-03,
57 5.008367405382524e-03, 5.696044031764593e-03, 6.425563506942886e-03,
58 7.264372872913219e-03, 8.044853066396166e-03, 8.714877612414516e-03,
59 9.493529164160654e-03, 1.033273985210279e-02, 1.106421822502108e-02,
60 1.175060460132703e-02, 1.256832682090360e-02, 1.338784224692084e-02,
61 1.407617951778051e-02, 1.480472324161026e-02, 1.564331999062109e-02,
62 1.642470780103220e-02, 1.709475346624607e-02, 1.787248418996684e-02,
63 1.871188358061674e-02, 1.944434477688470e-02, 2.013010181370026e-02,
64 2.094721145334310e-02, 2.176730968036079e-02, 2.245631776169424e-02};
71 alf[
k] = (2.0 *
k + 1.0) * M_PI / (2.0 * (
H0 +
B0));
94 my_gamma = sin(alpha *
H0) / cos(beta *
B0);
95 XkSQR = (rho_bedrock * c_p_bedrock * my_gamma * my_gamma *
B0 +
rho_ice *
c_p_ice *
H0) / 2.0;
98 theta = (z > 0) ? sin(alpha * (
H0 - z))
99 : my_gamma * cos(beta * (
B0 + z));
101 dthetakdz = (z > 0) ? - alpha * cos(alpha * (
H0 - z))
102 : - beta * my_gamma * sin(beta * (
B0 + z));
108 aH = alpha *
H0; bB = beta *
B0;
109 I1 = - mI * (sin(aH) - aH * cos(aH)) / (alpha * alpha);
110 I2 = mR * (cos(bB) - 1.0 + bB * sin(bB)) / (beta * beta)
111 - (
B0 * mR +
H0 * mI) * sin(bB) / beta;
112 Ck = (
rho_ice *
c_p_ice * I1 + rho_bedrock * c_p_bedrock * my_gamma * I2) / Xk;
114 *TT += Ck * exp(- lambda * t) * theta;
115 *FF += - ((z > 0) ?
k_ice : k_bedrock) * Ck * exp(- lambda * t) * dthetakdz;
121 dPdz = 1.0 / ((z > 0) ?
k_ice : k_bedrock);
123 *FF += ((z > 0) ?
k_ice : k_bedrock) *
G * dPdz;
137 #define ALPHA_RELTOL 1.0e-14
138 #define ITER_MAXED_OUT 999
156 int status = 0, iter = 0,
k = 0, max_iter = 200;
157 double Z = 0.0, A = 0.0;
158 double alpha = 0.0, alpha_lo = 0.0, alpha_hi = 0.0, temp_lo = 0.0;
159 const gsl_root_fsolver_type *solvT;
160 gsl_root_fsolver *solv;
166 params.
Afrac = (A - 1.0) / (A + 1.0);
172 solvT = gsl_root_fsolver_brent;
173 solv = gsl_root_fsolver_alloc(solvT);
175 for (
k = 0;
k < N;
k++) {
177 alpha_lo = ((double)(
k) * M_PI) / params.
HZBsum;
178 alpha_hi = ((
double)(
k + 1) * M_PI) / params.
HZBsum;
179 gsl_root_fsolver_set(solv, &
F, alpha_lo, alpha_hi);
185 status = gsl_root_fsolver_iterate(solv);
186 if (status != GSL_SUCCESS) {
190 alpha = gsl_root_fsolver_root(solv);
191 alpha_lo = gsl_root_fsolver_x_lower(solv);
192 alpha_hi = gsl_root_fsolver_x_upper(solv);
193 temp_lo = (alpha_lo > 0) ? alpha_lo : (alpha_hi/2.0);
195 status = gsl_root_test_interval(temp_lo, alpha_hi, 0,
ALPHA_RELTOL);
196 }
while ((status == GSL_CONTINUE) && (iter < max_iter));
198 if (iter >= max_iter) {
199 printf(
"!!!ERROR: root finding iteration reached maximum iterations; QUITTING!\n");
203 printf(
"%19.15e,\n",alpha);
207 gsl_root_fsolver_free(solv);
static int exactK_old(const double t, const double z, double *TT, double *FF, const int bedrockIsIce_p)
struct TestKParameters exactK(double t, double z, int bedrock_is_ice)
double coscross(double alpha, void *params)
int print_alpha_k(const int N)
static double F(double SL, double B, double H, double alpha)
std::string printf(const char *format,...)