25 #include <gsl/gsl_errno.h>
26 #include <gsl/gsl_matrix.h>
27 #include <gsl/gsl_odeiv.h>
28 #include "pism/verification/tests/exactTestM.h"
30 #define MAX(a, b) (a > b ? a : b)
31 #define MIN(a, b) (a > b ? b : a)
33 #define SperA 31556926.0
45 double F_M(
double x,
double alpha,
double r,
double Q) {
48 DD = x * x + x * aor + pow(aor, 2.0);
49 return Q * pow(DD, 1./3.) - 2.0 * r * x - alpha;
53 double dF_M(
double x,
double alpha,
double r,
double Q) {
56 DD = x * x + x * aor + pow(aor, 2.0);
57 return (1. / 3.) * Q * pow(DD, - 2./3.) * (2.0 * x + aor) - 2.0 * r;
61 int funcM_ode_G(
double r,
const double alpha[],
double f[],
void* params) {
71 guess = 0.15 * (pow(Q/r,
n) - alpha[0]/r);
74 double Old = guess, New;
77 for (i = 1; i < 100; i++) {
78 New = Old -
F_M(Old,alpha[0],r,Q) /
dF_M(Old,alpha[0],r,Q);
79 if (fabs((New-Old)/Old) < 1.0e-12)
break;
83 printf(
"exactTestM WARNING: Newton iteration not converged in funcM_ode_G!\n");
90 #define INVALID_METHOD 8968
91 #define NEGATIVE_R 8969
96 double *alpha,
double *Drr,
97 const double EPS_ABS,
const double EPS_REL,
const int ode_method) {
99 double ug = 100.0 /
SperA;
100 double DrrRg, xx, xA, nu, aa, rr, myalf,
step;
101 const gsl_odeiv_step_type* T;
104 gsl_odeiv_control* c;
106 gsl_odeiv_system sys = {
funcM_ode_G, NULL, 1, NULL};
110 }
else if (r <=
Rg/4.0) {
114 }
else if (r <=
Rg) {
121 nu = DrrRg * xA / ug;
122 aa = ug / pow(xA, nu);
124 *alpha = aa * pow(xx, nu);
125 *Drr = aa * nu * pow(xx, nu - 1);
127 }
else if (r >=
Rc + 1.0) {
134 switch (ode_method) {
136 T = gsl_odeiv_step_rkck;
139 T = gsl_odeiv_step_rk2;
142 T = gsl_odeiv_step_rk4;
145 T = gsl_odeiv_step_rk8pd;
148 printf(
"INVALID ode_method in exactM(): must be 1,2,3,4\n");
151 s = gsl_odeiv_step_alloc(T, (
size_t)1);
152 c = gsl_odeiv_control_y_new(EPS_ABS,EPS_REL);
153 e = gsl_odeiv_evolve_alloc((
size_t)1);
163 status = gsl_odeiv_evolve_apply(e, c, s, &sys, &rr, r, &
step, &myalf);
164 if (status != GSL_SUCCESS)
break;
168 gsl_odeiv_evolve_free(e);
169 gsl_odeiv_control_free(c);
170 gsl_odeiv_step_free(s);
178 double EPS_ABS, double EPS_REL, int ode_method) {
181 EPS_ABS, EPS_REL, ode_method);
double F_M(double x, double alpha, double r, double Q)
struct TestMParameters exactM(double r, double EPS_ABS, double EPS_REL, int ode_method)
double dF_M(double x, double alpha, double r, double Q)
int exactM_old(double r, double *alpha, double *Drr, const double EPS_ABS, const double EPS_REL, const int ode_method)
int funcM_ode_G(double r, const double alpha[], double f[], void *params)
static void step(double dt, const array::Staggered1 &velocity, const array::Scalar1 &x_old, array::Scalar &x)
std::string printf(const char *format,...)