PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
greens.cc
Go to the documentation of this file.
1 // Copyright (C) 2004-2007, 2015, 2017, 2018, 2019, 2023 Jed Brown and Ed Bueler and Constantine Khroulev
2 //
3 // This file is part of PISM.
4 //
5 // PISM is free software; you can redistribute it and/or modify it under the
6 // terms of the GNU General Public License as published by the Free Software
7 // Foundation; either version 3 of the License, or (at your option) any later
8 // version.
9 //
10 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with PISM; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #include "pism/earth/greens.hh"
20 #include <gsl/gsl_integration.h> // for gsl_integration_qag, gsl_integratio...
21 #include <gsl/gsl_math.h> // for gsl_function
22 #include <gsl/gsl_sf_bessel.h> // for gsl_sf_bessel_J0, gsl_sf_bessel_J1
23 #include <cassert> // for assert
24 #include <cmath> // for pow, exp, sqrt
25 #include <vector> // for vector
26 
27 namespace pism {
28 namespace bed {
29 
30 double ge_integrand(unsigned ndim, const double* args, void* data) {
31 
32  assert(ndim == 2);
33  (void) ndim;
34 
35  struct ge_data* d = (struct ge_data*) data;
36 
37  const double
38  dx = d->dx,
39  dy = d->dy,
40  xi = args[0],
41  eta = args[1],
42  xi_shift = d->p * dx - xi,
43  eta_shift = d->q * dy - eta,
44  r = sqrt(xi_shift * xi_shift + eta_shift * eta_shift);
45 
46  greens_elastic &G = *d->G;
47 
48  return G(r);
49 }
50 
52  acc = gsl_interp_accel_alloc();
53  spline = gsl_spline_alloc(gsl_interp_linear, N);
54  gsl_spline_init(spline, rmkm, GE, N);
55 }
56 
58  gsl_spline_free(spline);
59  gsl_interp_accel_free(acc);
60 }
61 
62 double greens_elastic::operator()(double r) {
63  if (r < 0.01) {
64  return GE[0] / (rmkm[1] * 1.0e3 * 1.0e12);
65  }
66  if (r > rmkm[N - 1] * 1.0e3) {
67  return 0.0;
68  }
69  return gsl_spline_eval(spline, r / 1.0e3, acc) / (r * 1.0e12);
70 }
71 
73  {0.0, 0.011, 0.111, 1.112, 2.224, 3.336, 4.448, 6.672, 8.896, 11.12,
74  17.79, 22.24, 27.80, 33.36, 44.48, 55.60, 66.72, 88.96, 111.2, 133.4,
75  177.9, 222.4, 278.0, 333.6, 444.8, 556.0, 667.2, 778.4, 889.6, 1001.0,
76  1112.0, 1334.0, 1779.0, 2224.0, 2780.0, 3336.0, 4448.0, 5560.0, 6672.0, 7784.0,
77  8896.0, 10008.0};
78 
80  {-33.6488, -33.64, -33.56, -32.75, -31.86, -30.98, -30.12, -28.44, -26.87, -25.41,
81  -21.80, -20.02, -18.36, -17.18, -15.71, -14.91, -14.41, -13.69, -13.01, -12.31,
82  -10.95, -9.757, -8.519, -7.533, -6.131, -5.237, -4.660, -4.272, -3.999, -3.798,
83  -3.640, -3.392, -2.999, -2.619, -2.103, -1.530, -0.292, 0.848, 1.676, 2.083,
84  2.057, 1.643};
85 
86 //! @brief Parameters used to describe the response of the viscous
87 //! half-space model to a disc load.
88 struct vd_params {
89  double t, R0, rk, rho, grav, D, eta;
90 };
91 
92 
93 //! @brief Integrand defining the response of the viscous half-space
94 //! model to a disc load.
95 /*!
96  * For the solution of the disc load case of the viscous half-space
97  * model, see appendix B of \ref BLK2006earth. See also \ref
98  * LingleClark and \ref BLKfastearth.
99  */
100 double vd_integrand (double kappa, void* parameters) {
101  // Matlab: function y=integrand(kappa,rg,D,t,eta,R0,rk)
102  // beta=rg + D*kappa.^4;
103  // expdiff=exp(-beta*t./(2*eta*kappa))-ones(size(kappa));
104  // y=expdiff.*besselj(1.0,kappa*R0).*besselj(0.0,kappa*rk)./beta;
105 
106  struct vd_params* p = (struct vd_params*) parameters;
107 
108  const double
109  t = p->t,
110  R0 = p->R0,
111  rk = p->rk,
112  rho = p->rho,
113  grav = p->grav,
114  D = p->D,
115  eta = p->eta,
116  beta = rho * grav + D * pow(kappa, 4.0),
117  expdiff = exp(-beta * t / (2.0 * eta * kappa)) - 1.0;
118 
119  return expdiff * gsl_sf_bessel_J1(kappa * R0) * gsl_sf_bessel_J0(kappa * rk) / beta;
120 }
121 
122 /*!
123  * Compute the response of the viscous half-space model in [@ref LingleClark] to a disc load.
124  *
125  * @param[in] t time in seconds
126  * @param[in] H0 thickness of the disc load, meters
127  * @param[in] R0 radius of the disc load, meters
128  * @param[in] r radius, meters
129  * @param[in] rho mantle density, kg/m3
130  * @param[in] rho_ice ice (load) density, kg/m3
131  * @param[in] grav acceleration due to gravity, m/s2
132  * @param[in] D lithosphere flexural rigidity, N meter
133  * @param[in] eta mantle viscosity, Pascal second
134  */
135 double viscDisc(double t, double H0, double R0, double r,
136  double rho, double rho_ice, double grav, double D, double eta) {
137  // t in seconds; H0, R0, r in meters
138 
139  const double ABSTOL = 1.0e-10;
140  const double RELTOL = 1.0e-14;
141  const int N_gsl_workspace = 1000;
142  const int lengthpts = 142;
143 
144  gsl_integration_workspace* w = gsl_integration_workspace_alloc(N_gsl_workspace);
145 
146  // Matlab: pts=[10.^(-3:-0.05:-10) 1.0e-14];
147  std::vector<double> pts(lengthpts);
148  for (int j=0; j < lengthpts-1; j++) {
149  pts[j] = pow(10.0, -3.0 - 0.05 * j);
150  }
151  pts[lengthpts-1] = 1.0e-14;
152 
153  // result=quadl(@integrand,pts(1),100.0*pts(1),TOL,0,rg,D,t,eta,R0,rk); % kap->infty tail
154  gsl_function F;
155  struct vd_params params = { t, R0, r, rho, grav, D, eta };
156  double result, error;
157  F.function = &vd_integrand;
158  F.params = &params;
159  // regarding tolerance: request is for convergence of all digits and relative tolerance RELTOL
160  gsl_integration_qag (&F, pts[1], 100.0*pts[1], ABSTOL, RELTOL, N_gsl_workspace,
161  GSL_INTEG_GAUSS21, w, &result, &error);
162 
163  double sum = result;
164  // for j=1:length(pts)-1
165  // result=result+quadl(@integrand,pts(j+1),pts(j),TOL,0,rg,D,t,eta,R0,rk);
166  // end
167  for (int j = 0; j < lengthpts - 1; j++) {
168  gsl_integration_qag (&F, pts[j+1], pts[j], ABSTOL, RELTOL, N_gsl_workspace,
169  GSL_INTEG_GAUSS21, w, &result, &error);
170  sum += result;
171  }
172 
173  gsl_integration_workspace_free(w);
174  // u(k)=rhoi*g*H0*R0*result;
175  return rho_ice * grav * H0 * R0 * sum;
176 }
177 
178 } // end of namespace bed
179 } // end of namespace pism
static const double rmkm[N]
Definition: greens.hh:43
double operator()(double r)
Definition: greens.cc:62
gsl_spline * spline
Definition: greens.hh:47
static const int N
Definition: greens.hh:42
static const double GE[N]
Definition: greens.hh:44
gsl_interp_accel * acc
Definition: greens.hh:46
const double H0
Definition: exactTestK.c:37
const double rho_ice
Definition: exactTestK.c:31
const double G
Definition: exactTestK.c:40
#define rho
Definition: exactTestM.c:35
static const double grav
Definition: exactTestO.c:26
double sum(const array::Scalar &input)
Sums up all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:150
double vd_integrand(double kappa, void *parameters)
Integrand defining the response of the viscous half-space model to a disc load.
Definition: greens.cc:100
double ge_integrand(unsigned ndim, const double *args, void *data)
The integrand in defining the elastic Green's function from the [Farrell] earth model.
Definition: greens.cc:30
double viscDisc(double t, double H0, double R0, double r, double rho, double rho_ice, double grav, double D, double eta)
Actually compute the response of the viscous half-space model in LingleClark, to a disc load.
Definition: greens.cc:135
static double F(double SL, double B, double H, double alpha)
greens_elastic * G
Definition: greens.hh:59
Parameters used to access elastic Green's function from the [Farrell] earth model.
Definition: greens.hh:56
Parameters used to describe the response of the viscous half-space model to a disc load.
Definition: greens.cc:88