-
Notifications
You must be signed in to change notification settings - Fork 90
Expand file tree
/
Copy pathtesseroid_variable_density.py
More file actions
96 lines (77 loc) · 2.94 KB
/
tesseroid_variable_density.py
File metadata and controls
96 lines (77 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# Copyright (c) 2018 The Harmonica Developers.
# Distributed under the terms of the BSD 3-Clause License.
# SPDX-License-Identifier: BSD-3-Clause
#
# This code is part of the Fatiando a Terra project (https://www.fatiando.org)
#
"""
Tesseroids with variable density
================================
The :func:`harmonica.tesseroid_gravity` is capable of computing the
gravitational effects of tesseroids whose density is defined through
a continuous function of the radial coordinate. This is achieved by the
application of the method introduced in [Soler2021]_.
To do so we need to define a regular Python function for the density, which
should have a single argument (the ``radius`` coordinate) and return the
density of the tesseroids at that radial coordinate.
In addition, we need to decorate the density function with
:func:`numba.jit(nopython=True)` or ``numba.njit`` for short.
On this example we will show how we can compute the gravitational effect of
four tesseroids whose densities are given by a custom linear ``density``
function.
"""
import boule as bl
import pygmt
import verde as vd
from numba import njit
import harmonica as hm
# Use the WGS84 ellipsoid to obtain the mean Earth radius which we'll use to
# reference the tesseroid
ellipsoid = bl.WGS84
mean_radius = ellipsoid.mean_radius
# Define tesseroid with top surface at the mean Earth radius, a thickness of
# 10km and a linear density function
tesseroids = (
[-70, -60, -40, -30, mean_radius - 3e3, mean_radius],
[-70, -60, -30, -20, mean_radius - 5e3, mean_radius],
[-60, -50, -40, -30, mean_radius - 7e3, mean_radius],
[-60, -50, -30, -20, mean_radius - 10e3, mean_radius],
)
# Define a linear density function. We should use the jit decorator so Numba
# can run the forward model efficiently.
@njit
def density(radius):
"""Linear density function"""
top = mean_radius
bottom = mean_radius - 10e3
density_top = 2670
density_bottom = 3000
slope = (density_top - density_bottom) / (top - bottom)
return slope * (radius - bottom) + density_bottom
# Define computation points on a regular grid at 100km above the mean Earth
# radius
coordinates = vd.grid_coordinates(
region=[-80, -40, -50, -10],
shape=(80, 80),
extra_coords=100e3 + ellipsoid.mean_radius,
)
# Compute the radial component of the acceleration
gravity = hm.tesseroid_gravity(coordinates, tesseroids, density, field="g_z")
print(gravity)
grid = vd.make_xarray_grid(
coordinates, gravity, data_names="gravity", extra_coords_names="extra"
)
# Plot the gravitational field
fig = pygmt.Figure()
title = "Gravitational acceleration of variable density tesseroids"
with pygmt.config(FONT_TITLE="16p"):
fig.grdimage(
region=[-80, -40, -50, -10],
projection="M-60/-30/10c",
grid=grid.gravity,
frame=["a", f"+t{title}"],
cmap="viridis",
)
fig.colorbar(cmap=True, position="JMR", frame=["a200f50", "x+lmGal"])
fig.coast(shorelines="1p,black")
fig.show()