Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
27namespace pism {
28namespace bed {
29
30double 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
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.
88struct 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 */
100double 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 */
135double 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 rho_ice
Definition exactTestK.c:31
const double G
Definition exactTestK.c:40
#define H0
Definition exactTestM.c:39
#define rho
Definition exactTestM.c:35
static const double grav
Definition exactTestO.c:26
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