# Source code for choclo.point._forward

# Copyright (c) 2022 The Choclo Developers.
#
# This code is part of the Fatiando a Terra project (https://www.fatiando.org)
#
"""
Forward modelling function for point sources
"""
from numba import jit

from ..constants import GRAVITATIONAL_CONST
from ..utils import distance_cartesian
from ._kernels import (
kernel_e,
kernel_ee,
kernel_en,
kernel_eu,
kernel_n,
kernel_nn,
kernel_nu,
kernel_pot,
kernel_u,
kernel_uu,
)

[docs]
@jit(nopython=True)
def gravity_pot(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Gravitational potential field due to a point source

Returns the gravitational potential field produced by a single point source
on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
potential : float
Gravitational potential field generated by the point source on the
observation point in :math:\text{J}/\text{kg}.

Notes
-----
Returns the gravitational potential field :math:V(\mathbf{p}) on the
observation point :math:\mathbf{p} = (x_p, y_p, z_p) generated by
a single point source located in :math:\mathbf{q} = (x_q, y_q, z_q) and
mass :math:m.

.. math::

V(\mathbf{p}) = G m \frac{1}{\lVert \mathbf{p} - \mathbf{q} \rVert_2^2}

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_pot(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel

[docs]
@jit(nopython=True)
def gravity_e(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Easting component of the gravitational acceleration due to a point source

Returns the easting component of the gravitational acceleration produced by
a single point source on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
g_e : float
Easting component of the gravitational acceleration generated by the
point source on the observation point in :math:\text{m}/\text{s}^2.

Notes
-----
Returns the easting component :math:g_x(\mathbf{p}) of the gravitational
acceleration :math:\mathbf{g} on the observation point :math:\mathbf{p}
= (x_p, y_p, z_p) generated by a single point source located in
:math:\mathbf{q} = (x_q, y_q, z_q) and mass :math:m.

.. math::

g_x(\mathbf{p}) = - G m
\frac{
x_p - x_q
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^2
}

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_e(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel

[docs]
@jit(nopython=True)
def gravity_n(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Northing component of the gravitational acceleration due to a point source

Returns the northing component of the gravitational acceleration produced
by a single point source on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
g_n : float
Northing component of the gravitational acceleration generated by the
point source on the observation point in :math:\text{m}/\text{s}^2.

Notes
-----
Returns the northing component :math:g_y(\mathbf{p}) of the gravitational
acceleration :math:\mathbf{g} on the observation point :math:\mathbf{p}
= (x_p, y_p, z_p) generated by a single point source located in
:math:\mathbf{q} = (x_q, y_q, z_q) and mass :math:m.

.. math::

g_y(\mathbf{p}) = - G m
\frac{
y_p - y_q
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^2
}

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_n(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel

[docs]
@jit(nopython=True)
def gravity_u(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Upward component of the gravitational acceleration due to a point source

Returns the upward component of the gravitational acceleration produced by
a single point source on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
g_u : float
Upward component of the gravitational acceleration generated by the
point source on the observation point in :math:\text{m}/\text{s}^2.

Notes
-----
Returns the upward component :math:g_z(\mathbf{p}) of the gravitational
acceleration :math:\mathbf{g} on the observation point :math:\mathbf{p}
= (x_p, y_p, z_p) generated by a single point source located in
:math:\mathbf{q} = (x_q, y_q, z_q) and mass :math:m.

.. math::

g_z(\mathbf{p}) = - G m
\frac{
z_p - z_q
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^2
}

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_u(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel

[docs]
@jit(nopython=True)
def gravity_ee(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Easting-easting component of the gravitational tensor due to a point source

Returns the easting-easting component of the gravitational tensor produced
by a single point source on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
g_ee : float
Easting-easting component of the gravitational tensor generated by the
point source on the observation point in :math:\text{s}^{-2}.

Notes
-----
Returns the easting-easting component :math:g_{xx}(\mathbf{p}) of the
gravitational tensor :math:\mathbf{T} on the observation point
:math:\mathbf{p} = (x_p, y_p, z_p) generated by a single point source
located in :math:\mathbf{q} = (x_q, y_q, z_q) and mass :math:m.

.. math::

g_{xx}(\mathbf{p}) = G m
\left[
\frac{
3 (x_p - x_q)^2
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^5
}
- \frac{
1
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^3
}
\right]

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_ee(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel

[docs]
@jit(nopython=True)
def gravity_nn(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Northing-northing component of the gravitational tensor due to point source

Returns the northing-northing component of the gravitational tensor
produced by a single point source on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
g_nn : float
Northing-northing component of the gravitational tensor generated by
the point source on the observation point in :math:\text{s}^{-2}.

Notes
-----
Returns the northing-northing component :math:g_{yy}(\mathbf{p}) of the
gravitational tensor :math:\mathbf{T} on the observation point
:math:\mathbf{p} = (x_p, y_p, z_p) generated by a single point source
located in :math:\mathbf{q} = (x_q, y_q, z_q) and mass :math:m.

.. math::

g_{yy}(\mathbf{p}) = G m
\left[
\frac{
3 (y_p - y_q)^2
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^5
}
- \frac{
1
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^3
}
\right]

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_nn(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel

[docs]
@jit(nopython=True)
def gravity_uu(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Upward-upward component of the gravitational tensor due to a point source

Returns the upward-upward component of the gravitational tensor
produced by a single point source on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
g_uu : float
Upward-upward component of the gravitational tensor generated by
the point source on the observation point in :math:\text{s}^{-2}.

Notes
-----
Returns the upward-upward component :math:g_{zz}(\mathbf{p}) of the
gravitational tensor :math:\mathbf{T} on the observation point
:math:\mathbf{p} = (x_p, y_p, z_p) generated by a single point source
located in :math:\mathbf{q} = (x_q, y_q, z_q) and mass :math:m.

.. math::

g_{zz}(\mathbf{p}) = G m
\left[
\frac{
3 (z_p - z_q)^2
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^5
}
- \frac{
1
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^3
}
\right]

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_uu(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel

[docs]
@jit(nopython=True)
def gravity_en(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Easting-northing component of the gravitational tensor due to point source

Returns the easting-northing component of the gravitational tensor
produced by a single point source on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
g_en : float
Easting-northing component of the gravitational tensor generated by
the point source on the observation point in :math:\text{s}^{-2}.

Notes
-----
Returns the easting-northing component :math:g_{xy}(\mathbf{p}) of the
gravitational tensor :math:\mathbf{T} on the observation point
:math:\mathbf{p} = (x_p, y_p, z_p) generated by a single point source
located in :math:\mathbf{q} = (x_q, y_q, z_q) and mass :math:m.

.. math::

g_{xy}(\mathbf{p}) = G m
\left[
\frac{
3 (x_p - x_q) (y_p - y_q)
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^5
}
\right]

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_en(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel

[docs]
@jit(nopython=True)
def gravity_eu(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Easting-upward component of the gravitational tensor due to point source

Returns the easting-upward component of the gravitational tensor
produced by a single point source on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
g_eu : float
Easting-upward component of the gravitational tensor generated by
the point source on the observation point in :math:\text{s}^{-2}.

Notes
-----
Returns the easting-upward component :math:g_{xz}(\mathbf{p}) of the
gravitational tensor :math:\mathbf{T} on the observation point
:math:\mathbf{p} = (x_p, y_p, z_p) generated by a single point source
located in :math:\mathbf{q} = (x_q, y_q, z_q) and mass :math:m.

.. math::

g_{xz}(\mathbf{p}) = G m
\left[
\frac{
3 (x_p - x_q) (z_p - z_q)
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^5
}
\right]

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_eu(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel

[docs]
@jit(nopython=True)
def gravity_nu(easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, mass):
r"""
Northing-upward component of the gravitational tensor due to point source

Returns the northing-upward component of the gravitational tensor
produced by a single point source on a single computation point

Parameters
----------
easting_p : float
Easting coordinate of the observation point in meters.
northing_p : float
Northing coordinate of the observation point in meters.
upward_p : float
Upward coordinate of the observation point in meters.
easting_q : float
Easting coordinate of the point source in meters.
northing_q : float
Northing coordinate of the point source in meters.
upward_q : float
Upward coordinate of the point source in meters.
mass : float
Mass of the point source in kilograms.

Returns
-------
g_nu : float
Northing-upward component of the gravitational tensor generated by the
point source on the observation point in :math:\text{s}^{-2}.

Notes
-----
Returns the northing-upward component :math:g_{yz}(\mathbf{p}) of the
gravitational tensor :math:\mathbf{T} on the observation point
:math:\mathbf{p} = (x_p, y_p, z_p) generated by a single point source
located in :math:\mathbf{q} = (x_q, y_q, z_q) and mass :math:m.

.. math::

g_{yz}(\mathbf{p}) = G m
\left[
\frac{
3 (y_p - y_q) (z_p - z_q)
}{
\lVert \mathbf{p} - \mathbf{q} \rVert_2^5
}
\right]

where :math:\lVert \cdot \rVert_2 refer to the :math:L_2 norm (the
Euclidean distance between :math:\mathbf{p} and :math:\mathbf{q})
and :math:G is the Universal Gravitational Constant.
"""
distance = distance_cartesian(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q
)
kernel = kernel_nu(
easting_p, northing_p, upward_p, easting_q, northing_q, upward_q, distance
)
return GRAVITATIONAL_CONST * mass * kernel