Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add magnetic field forward modelling of rectangular prisms #369

Merged
merged 27 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ee8cfb6
Start drafting magnetic field of prisms
santisoler Nov 26, 2022
60b8032
Merge branch 'main' into magnetic-prisms
santisoler Dec 19, 2022
0de79e5
Add functions to compute magnetic field components
santisoler Dec 19, 2022
f418535
Update names of choclo magnetic functions
santisoler Jan 30, 2023
a37fb8f
Reduce number of magnetic forward functions
santisoler Feb 12, 2023
e08c67c
Merge branch 'main' into magnetic-prisms
santisoler Apr 4, 2023
566dff4
Move the file to private _forward module
santisoler Apr 4, 2023
b54da36
Add tests for magnetic forward modelling of prisms
santisoler Apr 24, 2023
2b4fba1
Fix style
santisoler Apr 24, 2023
30ebc7e
Use new Choclo's functions that take scalars only
santisoler May 5, 2023
f1d544a
Merge branch 'main' into magnetic-prisms
santisoler May 19, 2023
02e512f
Merge branch 'main' into magnetic-prisms
santisoler May 26, 2023
2e457d5
Fix description of coordinates
santisoler May 26, 2023
6c4ca37
Use row instead of line in docstring
santisoler May 26, 2023
c3636e0
Update comment
santisoler May 26, 2023
3135e64
Merge branch 'main' into magnetic-prisms
santisoler Jul 6, 2023
eb387bc
Merge branch 'main' into magnetic-prisms
santisoler Jul 19, 2023
d4ec887
Fix flake error on docstring
santisoler Aug 16, 2023
ca963d8
Add new functions to API reference
santisoler Aug 16, 2023
c24f76c
Remove duplicated line in setup.cfg
santisoler Aug 16, 2023
2767465
Add magnetic forward modelling to the user guide
santisoler Aug 16, 2023
e68c73f
Merge branch 'main' into magnetic-prisms
santisoler Aug 17, 2023
1e735fd
Merge branch 'main' into magnetic-prisms
santisoler Sep 20, 2023
5e150a3
Merge branch 'main' into magnetic-prisms
santisoler Sep 22, 2023
3e4fb75
Make use of the progressbar context manager function
santisoler Sep 22, 2023
ea6e468
Rename _forward/prism.py to _forward/prism_gravity.py
santisoler Sep 22, 2023
ece1af6
Update doc/user_guide/forward_modelling/prism.rst
LL-Geo Sep 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ Magnetic fields:

dipole_magnetic
dipole_magnetic_component
prism_magnetic
prism_magnetic_component

Layers and meshes:

Expand Down
122 changes: 117 additions & 5 deletions doc/user_guide/forward_modelling/prism.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ computation point:


Gravitational fields
^^^^^^^^^^^^^^^^^^^^
--------------------

The :func:`harmonica.prism_gravity` is able to compute the gravitational
potential (``"potential"``), the acceleration components (``"g_e"``, ``"g_n"``,
Expand Down Expand Up @@ -139,8 +139,9 @@ Plot the results:
plt.colorbar(tmp, ax=ax, label="Eotvos", orientation="horizontal", pad=0.08)
plt.show()


Passing multiple prisms
^^^^^^^^^^^^^^^^^^^^^^^
~~~~~~~~~~~~~~~~~~~~~~~

We can compute the gravitational field of a set of prisms by passing a list of
them, where each prism is defined as mentioned before, and then making
Expand Down Expand Up @@ -200,10 +201,123 @@ Lets plot this gravitational field:
fig.show()


Magnetic fields
---------------

The :func:`harmonica.prism_magnetic` and
:func:`harmonica.prism_magnetic_component` functions allows us to calculate the
magnetic fields generated by rectangular prisms on a set of observation points.
Each rectangular prism is defined in the same way we did for the gravity
forward modelling, although we now need to define a magnetization vector for
each one of them.

For example:

.. jupyter-execute::

import numpy as np

prisms = [
[-5e3, -3e3, -5e3, -2e3, -10e3, -1e3],
[3e3, 4e3, 4e3, 5e3, -9e3, -1e3],
]

magnetization = np.array([
[0.5, 0.5, -0.78989],
[-0.4, 0.3, 0.2],
])

Each row of the ``magnetization`` 2D vector corresponds to the easting,
northing and upward components of the magnetization vector of each prism in
``prisms``, provided in :math:`Am^2`.
LL-Geo marked this conversation as resolved.
Show resolved Hide resolved

With the :func:`harmonica.prism_magnetic` function we can compute the three
components of the magnetic field the prisms generates on any set of observation
points.

.. jupyter-execute::

region = (-10e3, 10e3, -10e3, 10e3)
shape = (51, 51)
height = 10
coordinates = vd.grid_coordinates(region, shape=shape, extra_coords=height)

.. jupyter-execute::

b_e, b_n, b_u = hm.prism_magnetic(coordinates, prisms, magnetization)

.. jupyter-execute::

fig, axes = plt.subplots(nrows=1, ncols=3, sharey=True, figsize=(12, 6))

for ax, mag_component, title in zip(axes, (b_e, b_n, b_u), ("Be", "Bn", "Bu")):
maxabs = vd.maxabs(mag_component)
tmp = ax.pcolormesh(
coordinates[0],
coordinates[1],
mag_component,
vmin=-maxabs,
vmax=maxabs,
cmap="RdBu_r",
)
ax.contour(
coordinates[0],
coordinates[1],
mag_component,
colors="k",
linewidths=0.5,
)
ax.set_title(title)
ax.set_aspect("equal")
plt.colorbar(
tmp,
ax=ax,
orientation="horizontal",
label="nT",
pad=0.08,
aspect=42,
shrink=0.8,
)

plt.show()


Alternatively, we can use :func:`harmonica.prism_magnetic_component` to
calculate only a single component of the magnetic field.

.. important::

Using :func:`harmonica.prism_magnetic_component` to compute several magnetic
components is less efficient that using :func:`harmonica.prism_magnetic`.
Use the former only when a single component is needed.

For example, we can calculate only the upward component of the magnetic field
generated by these two prisms:

.. jupyter-execute::

b_u = hm.prism_magnetic_component(
coordinates, prisms, magnetization, component="upward"
)

.. jupyter-execute::

maxabs = vd.maxabs(b_u)

tmp = plt.pcolormesh(
coordinates[0], coordinates[1], b_u, vmin=-maxabs, vmax=maxabs, cmap="RdBu_r"
)
plt.contour(coordinates[0], coordinates[1], b_u, colors="k", linewidths=0.5)
plt.title("Bu")
plt.gca().set_aspect("equal")
plt.colorbar(tmp, label="nT", pad=0.03, aspect=42, shrink=0.8)
plt.show()


.. _prism_layer:

Prism layer
^^^^^^^^^^^
-----------

One of the most common usage of prisms is to model geologic structures.
Harmonica offers the possibility to define a layer of prisms through the
Expand Down Expand Up @@ -241,8 +355,6 @@ sample a trigonometric function for this simple example:

.. jupyter-execute::

import numpy as np

wavelength = 24 * spacing
surface = np.abs(np.sin(easting * 2 * np.pi / wavelength))

Expand Down
3 changes: 2 additions & 1 deletion harmonica/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
from ._equivalent_sources.spherical import EquivalentSourcesSph
from ._forward.dipole import dipole_magnetic, dipole_magnetic_component
from ._forward.point import point_gravity
from ._forward.prism import prism_gravity
from ._forward.prism_gravity import prism_gravity
from ._forward.prism_layer import DatasetAccessorPrismLayer, prism_layer
from ._forward.prism_magnetic import prism_magnetic, prism_magnetic_component
from ._forward.tesseroid import tesseroid_gravity
from ._forward.tesseroid_layer import DatasetAccessorTesseroidLayer, tesseroid_layer
from ._gravity_corrections import bouguer_correction
Expand Down
1 change: 1 addition & 0 deletions harmonica/_forward/_tesseroid_variable_density.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ def _density_based_discretization(tesseroid, density):
tesseroids : list
List containing the boundaries of discretized tesseroids.
"""

# Define normalized density
def normalized_density(radius):
return (density(radius) - density_min) / (density_max - density_min)
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion harmonica/_forward/prism_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import xarray as xr

from ..visualization import prism_to_pyvista
from .prism import prism_gravity
from .prism_gravity import prism_gravity


def prism_layer(
Expand Down
Loading
Loading