20 #include "pism/verification/tests/exactTestL.hh"
24 #include <gsl/gsl_errno.h>
25 #include <gsl/gsl_matrix.h>
26 #include <gsl/gsl_math.h>
28 #include <gsl/gsl_version.h>
29 #if (defined GSL_MAJOR_VERSION) && (defined GSL_MINOR_VERSION) && \
30 ((GSL_MAJOR_VERSION >= 1 && GSL_MINOR_VERSION >= 15) || (GSL_MAJOR_VERSION >= 2))
31 #define PISM_USE_ODEIV2 1
32 #include <gsl/gsl_odeiv2.h>
35 #include "pism/util/error_handling.hh"
38 static const double SperA = 31556926.0;
40 static const double L = 750.0e3;
41 static const double b0 = 500.0;
42 static const double z0 = 1.2;
43 static const double g = 9.81;
44 static const double rho = 910.0;
45 static const double n = 3.0;
47 int funcL(
double r,
const double u[],
double f[],
void *params) {
55 const double Lsqr =
L *
L;
56 const double a0 = 0.3 /
SperA;
57 const double A = 1.0e-16 /
SperA;
58 const double Gamma = 2 * pow(
rho *
g,
n) * A / (
n+2);
59 const double tilGamma = Gamma * pow(
n,
n) / (pow(2.0 *
n + 2.0,
n));
60 const double C = a0 / (2.0 * Lsqr * tilGamma);
62 if (params == NULL) {}
64 if ((r >= 0.0) && (r <=
L)) {
65 const double freq =
z0 * M_PI /
L;
66 const double bprime =
b0 * freq * sin(freq * r);
67 f[0] = - (8.0/3.0) * bprime * pow(u[0], 5.0/8.0)
68 - pow(
C * r * (Lsqr - r * r), 1.0/3.0);
76 #define TESTL_NOT_DONE 8966
77 #define TESTL_NOT_DECREASING 8967
78 #define TESTL_INVALID_METHOD 8968
79 #define TESTL_NO_LIST 8969
81 #ifdef PISM_USE_ODEIV2
85 int getU(
const double *r,
int N,
double *u,
86 const double EPS_ABS,
const double EPS_REL,
const int ode_method) {
92 const gsl_odeiv2_step_type* Tpossible[4];
93 const gsl_odeiv2_step_type *T;
94 gsl_odeiv2_system sys = {
funcL, NULL, 1, NULL};
98 Tpossible[0] = gsl_odeiv2_step_rk8pd;
99 Tpossible[1] = gsl_odeiv2_step_rk2;
100 Tpossible[2] = gsl_odeiv2_step_rkf45;
101 Tpossible[3] = gsl_odeiv2_step_rkck;
102 if ((ode_method > 0) && (ode_method < 5))
103 T = Tpossible[ode_method-1];
117 if (
k == N)
return GSL_SUCCESS;
122 d = gsl_odeiv2_driver_alloc_y_new(&sys, T, hstart, EPS_ABS, EPS_REL);
129 while (rr > r[
count]) {
130 status = gsl_odeiv2_driver_apply(d, &rr, r[
count], &(u[
count]));
131 if (status != GSL_SUCCESS){
137 gsl_odeiv2_driver_free(d);
142 int getU(
const double *r,
int N,
double *u,
143 const double EPS_ABS,
const double EPS_REL,
const int ode_method) {
155 int exactL_list(
const double *r,
int N,
double *H,
double *b,
double *a) {
159 const double Lsqr =
L *
L;
160 const double a0 = 0.3 /
SperA;
163 std::vector<double> u(N);
167 stat =
getU(r,N,u.data(),1.0e-12,0.0,1);
168 if (stat != GSL_SUCCESS) {
172 for (i = 0; i < N; i++) {
173 H[i] = pow(u[i],3.0/8.0);
174 b[i] = -
b0 * cos(
z0 * M_PI * r[i] /
L);
175 a[i] = a0 * (1.0 - (2.0 * r[i] * r[i] / Lsqr));
182 : H(size), a(size), b(size) {
188 int error_code =
exactL_list(&r[0], r.size(), &result.
H[0], &result.
b[0], &result.
a[0]);
190 switch (error_code) {
192 throw RuntimeError::formatted(
PISM_ERROR_LOCATION,
"Test L ERROR: exactL_list() returns 'NOT_DONE' (%d) ...",
196 throw RuntimeError::formatted(
PISM_ERROR_LOCATION,
"Test L ERROR: exactL_list() returns 'NOT_DECREASING' (%d) ...",
200 throw RuntimeError::formatted(
PISM_ERROR_LOCATION,
"Test L ERROR: exactL_list() returns 'INVALID_METHOD' (%d) ...",
204 throw RuntimeError::formatted(
PISM_ERROR_LOCATION,
"Test L ERROR: exactL_list() returns 'NO_LIST' (%d) ...",
#define PISM_ERROR_LOCATION
#define TESTL_NOT_DECREASING
int funcL(double r, const double u[], double f[], void *params)
int exactL_list(const double *r, int N, double *H, double *b, double *a)
static const double SperA
int getU(const double *r, int N, double *u, const double EPS_ABS, const double EPS_REL, const int ode_method)
ExactLParameters exactL(const std::vector< double > &r)
#define TESTL_INVALID_METHOD
ExactLParameters(size_t n)