Overview of the routines in biosspheres.quadratures#
[1]:
import biosspheres.quadratures.sphere as quadratures
/opt/hostedtoolcache/Python/3.12.15/x64/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
This module has the implementation of functions that return
Points and weights for doing the Gauss-Legendre quadrature with a composite trapezoidal quadrature rule on the surface of a sphere. See
sphere.gauss_legendre_trapezoidal_2d,sphere.gauss_legendre_trapezoidal_1d.Evaluation of real and complex spherical harmonics in the points of the Gauss-Legendre and composite trapezoidal quadrature. See
sphere.gauss_legendre_trapezoidal_real_sh_mapping_2d,sphere.gauss_legendre_trapezoidal_complex_sh_mapping_2d.Arrays for implementing a slow spherical harmonic transform (real or complex) on the surface of a sphere. See
sphere.real_spherical_harmonic_transform_1d,sphere.complex_spherical_harmonic_transform_1d.Translations from a coordinate system to another. See
sphere.from_sphere_s_cartesian_to_j_spherical_2d,sphere.from_sphere_s_cartesian_to_j_spherical_1d,sphere.from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_2d,sphere.from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_1d.
[2]:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm, colors
Preliminaries#
Spherical coordinate system#
A vector is written as \(\mathbf{r}=\left(r,\varphi,\theta\right)^t\), with \(r \in [0,\infty)\), \(\varphi \in [0,2\pi)\) and \(\theta \in [0,\pi]\), which in Cartesian coordinates is equivalent to \(\mathbf{r}=r\left(\sin \theta \cos \varphi,\sin \theta \sin \varphi,\cos \theta\right)^t\). The unitary vectors of the spherical coordinate system can be written in Cartesian coordinates as
The gradient operator in spherical coordinates:
Spherical harmonics#
Associated Legendre functions#
\(P_l^m\) are the associated Legendre functions of degree \(l\) and order \(m\) defined as:
Here, the term \((-1)^m\) is the Condon-Shortley phase factor.
Real spherical harmonics#
Real spherical harmonics of degree \(l\) and order \(m\) are defined using spherical coordinates:
with \(l\in \mathbb{N}_0\), \(m\in \mathbb{Z}\) such that \(0\leq m\leq l\). If \(m=0\), then \(\delta_{m,0}=1\), and it is zero otherwise.
Complex spherical harmonics#
Complex spherical harmonics of degree \(l\) and order \(m\) are defined using spherical coordinates:
with \(l\in \mathbb{N}_0\), \(m\in \mathbb{Z}\) such that \(0\leq m\leq l\). If \(m=0\), then \(\delta_{m,0}=1\), and it is zero otherwise.
Reference systems in a geometry with \(N\) spheres#
\(N\) disjoint spheres in \(\mathbb{R}^3\):
Position vectors of the sphere centers: \(\mathbf{p_j} \in \mathbb{R}^3\), with \(j \in \{1,...,N\}\).
Radii: \(\tilde{r}_j\in \mathbb{R}^+\), with \(j \in \{1,...,N\}\).
Interior of sphere \(j\): \(\Omega_j:=\{ \mathbf{x} \in \mathbb{R}^3:||\mathbf{x}-\mathbf{p_j}||_2<\tilde{r}_j \}\).
Boundary of sphere \(j\): \(\Gamma_j:=\partial \Omega_j\).
Exterior medium, \(\Omega_0\): defined as \(\mathbb{R}^3\) without the spheres and their boundaries.
Let be \(j\in \{1,...,N\}\). We define the reference system \(j\) as the one centered at \(\mathbf{p_j}\) with the same orientation that the reference system centered in the origin.
Suppose that we have a vector written in cartesian coordinates of the reference system \(s\) (\(s\) an integer indicating the origin of the coordinate system being the same than the position of the center of the sphere \(s\)), we will call it \(\mathbf{x_s} = (x_s, y_s, z_s)\). We want to write this vector in the cartesian coordinates of the reference system \(j\), for this we can write
sphere.gauss_legendre_trapezoidal_2d#
This function is for obtaining the quadratures points to approximate numerically the integral in a surface of a sphere. In this case they are given in a two dimensional array (three dimensional if we add the dimension needed to represent a vector). It returns the weights and vectors for the Gauss-Legendre and composite trapezoidal quadrature rule.
Docstring and some comments#
[3]:
print(quadratures.gauss_legendre_trapezoidal_2d.__doc__)
It returns the weights and vectors for the Gauss-Legendre quadrature
rule and a composite trapezoidal quadrature rule to approximate
numerically the integral in a surface of a sphere.
Notes
-----
Gauss-legendre quadrature in theta. This one uses the package
pyshtools for obtaining the points and weights.
Integral on theta are (big_l_c + 1) quadrature points.
The weights returned correspond to the integral on this variable.
Composite trapezoidal rule in phi.
Integral on phi are (2 * big_l_c + 1) quadrature points.
This function does not return any weight for the phi variable,
because it is a trapezoidal rule equally spaced.
The integral in this variable can be solved using the fast fourier
transform.
Without considering errors produced by the approximation by finite
numbers, the quadrature must be exact for functions consisting in
polynomials of big_l_c degree times an exponential power to (m times
i), with |m| <= big_l_c.
Parameters
----------
big_l_c : int
>= 0. It's the parameter used to compute the points of the
quadrature.
Returns
-------
quantity_theta_points : int
how many points for the integral in theta, (big_l_c + 1).
quantity_phi_points : int
how many points for the integral in phi, (2 * big_l_c + 1).
weights : np.ndarray
of floats, with the weights for the integral quadrature in
theta. Length (big_l_c + 1).
pre_vector : np.ndarray
of floats. Represents the vectors of the quadrature points.
Shape (3, quantity_theta_points, quantity_phi_points).
See Also
--------
gauss_legendre_trapezoidal_1d
pre_vector_2d_init
We use the points used by the library SHTOOLS to be able to use fast spherical harmonic transform that the library provides. See Grid formats shtools.
This function needs only one parameter big_l_c. Without considering errors produced by the approximation by finite numbers, the quadrature must be exact for functions consisting in polynomials of big_l_c degree times \(e^{im}\), with \(|m| <=\) big_l_c.
See the section notes of the dosctring for more details.
Example#
[4]:
big_l_c = 15
quantity_theta_points, quantity_phi_points, weights, pre_vector = quadratures.gauss_legendre_trapezoidal_2d(big_l_c)
[5]:
print('big_l_c : ', big_l_c)
print('Quantity of points for the quadrature in the theta variable: ', quantity_theta_points)
print('Quantity of points for the quadrature in the phi variable: ', quantity_phi_points)
big_l_c : 15
Quantity of points for the quadrature in the theta variable: 16
Quantity of points for the quadrature in the phi variable: 31
[6]:
print('Gauss-Legendre Weights:\n', weights)
Gauss-Legendre Weights:
[0.02715246 0.06225352 0.09515851 0.12462897 0.14959599 0.16915652
0.18260342 0.18945061 0.18945061 0.18260342 0.16915652 0.14959599
0.12462897 0.09515851 0.06225352 0.02715246]
Quadrature points are given in the variable pre_vector:
[7]:
vector = pre_vector
fig = plt.figure(figsize=(4,4),dpi=75., layout='constrained')
ax_1 = fig.add_subplot(111, projection='3d')
ax_1.scatter3D(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
)
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
ax_1.set_title('Quadrature points')
plt.show()
sphere.gauss_legendre_trapezoidal_1d#
This function is almost the same than gauss_legendre_trapezoidal_2d, with the difference that the vectors are given in an array of one dimension (two if we add the dimension needed for represent a vector).
Docstring and some comments#
[8]:
print(quadratures.gauss_legendre_trapezoidal_1d.__doc__)
It returns the weights and vectors for the Gauss-Legendre quadrature
rule and a composite trapezoidal quadrature rule to approximate
numerically the integral in a surface of a sphere.
Notes
-----
Gauss-legendre quadrature in theta. This one uses the package
pyshtools for obtaining the points and weights.
Integral on theta are (big_l_c + 1) quadrature points.
Composite trapezoidal rule in phi.
Integral on phi are (2 * big_l_c + 1) quadrature points.
The weight for the variable phi (which is the same for
all points) is considered in the return array total_weights along
with the weights for the theta variable and the jacobian of the
surface integral.
The ordering of the arrays given by this function is not suited for
fast fourier transform algorithms. The returns of this function is
for using the simpler algorithm for obtaining integrals on the
sphere.
Without considering errors produced by the approximation by finite
numbers, the quadrature must be exact for functions consisting in
polynomials of big_l_c degree times an exponential power to (m times
i), with |m| <= big_l_c.
Parameters
----------
big_l_c : int
>= 0. It's the parameter used to compute the points of the
quadrature.
Returns
-------
final_length : int
how many points for the surface integral,
= (big_l_c + 1) * (2 * big_l_c + 1).
total_weights : np.ndarray
of floats, with the weights for the integral quadrature and
length final_length.
pre_vector : np.ndarray
of floats. Represents the vectors of the quadrature points.
Shape (3, final_length).
See Also
--------
gauss_legendre_trapezoidal_2d
See the section Notes of the docstring for details related to the weights that this function returns, and for more details.
The returns of this function is for using the simpler algorithm for obtaining integrals on the sphere.
Example#
[9]:
big_l_c = 15
final_length, total_weights, pre_vector = quadratures.gauss_legendre_trapezoidal_1d(big_l_c)
[10]:
print('big_l_c : ', big_l_c)
print('Quantity of points for the quadrature: ', final_length)
big_l_c : 15
Quantity of points for the quadrature: 496
In pre_vector the quadrature points are saved.
[11]:
vector = pre_vector
fig = plt.figure(figsize=(4,4),dpi=75., layout='constrained')
ax_1 = fig.add_subplot(111, projection='3d')
ax_1.scatter3D(
vector[0, :],
vector[1, :],
vector[2, :],
)
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
ax_1.set_title('Quadrature points')
plt.show()
sphere.gauss_legendre_trapezoidal_real_sh_mapping_2d#
This functions does the same than the function gauss_legendre_trapezoidal_2d and it also returns the evaluation of the real spherical harmonics in those points.
Docstring and some comments#
[12]:
print(quadratures.gauss_legendre_trapezoidal_real_sh_mapping_2d.__doc__)
This function is for obtaining the quadratures points to
approximate numerically the integral in a surface of a sphere, and
it also returns the evaluation of the real spherical harmonics in
those points.
It returns the weights and vectors for the Gauss-Legendre and
composite trapezoidal quadrature rule. The real spherical
harmonics evaluated are of degree l and order m, with l <= big_l.
See the shape of the returns.
Notes
-----
Gauss-legendre quadrature in theta. This one uses the package
pyshtools.
Composite trapezoidal rule in phi.
Integral on theta are (big_l_c + 1) quadrature points.
Integral on phi are (2 * big_l_c + 1) quadrature points.
Without considering errors produced by the approximation by finite
numbers, the quadrature must be exact for functions consisting in
polynomials of big_l_c degree times an exponential power to (m times
i), with |m| <= big_l_c.
Legendre's functions are computed used pyshtools.
Parameters
----------
big_l : int
>= 0, max degree.
big_l_c : int
>= 0. It's the parameter used to compute the points of the
quadrature.
Returns
-------
quantity_theta_points : int
how many points for the integral in theta, (big_l_c + 1).
quantity_phi_points : int
how many points for the integral in phi, (2 * big_l_c + 1)
weights : np.ndarray
of floats, with the weights for the integral quadrature in
theta. Length (big_l_c + 1).
pre_vector : np.ndarray
of floats. Represents the vectors of the quadrature points.
Shape (3, quantity_theta_points, quantity_phi_points).
spherical_harmonics : np.ndarray
of floats, represent the real spherical harmonics of degree and
order l and m evaluated in the points given by pre_vector. Shape
((big_l + 1)**2, quantity_theta_points, quantity_phi_points)
Now, the variable big_l indicates the maximum degree of spherical harmonics to be evaluated in the quadrature points.
Also, there are auxiliary parameters needed, which need to be obtained using biosspheres.miscella.auxindexes.pes_y_kus(big_l). Notice that they depend on big_l.
Example#
[13]:
big_l = 1
Auxiliar parameters needed:
[14]:
from biosspheres.utils.auxindexes import pes_y_kus
pesykus, p2_plus_p_plus_q, p2_plus_p_minus_q = pes_y_kus(big_l)
[15]:
big_l_c = 40
quantity_theta_points, quantity_phi_points, weights, pre_vector, spherical_harmonics = quadratures.gauss_legendre_trapezoidal_real_sh_mapping_2d(big_l, big_l_c)
Plottings of the spherical harmonics:
[16]:
vector = pre_vector
fig = plt.figure(figsize=plt.figaspect(0.20), dpi=68., layout='constrained')
ax_1 = fig.add_subplot(141, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[0, :, :]))
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1,
cstride=1,
facecolors=cm.coolwarm(spherical_harmonics[0, :, :] / surface_max),
)
ax_1.view_init(30, 135, 0)
ax_1.set_title('$l = 0$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(
cm.ScalarMappable(
norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm
),
ax=ax_1,
shrink=0.6,
orientation='vertical',
location='left',
)
ax_1 = fig.add_subplot(142, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[1, :, :]))
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1,
cstride=1,
facecolors=cm.coolwarm(spherical_harmonics[1, :, :] / surface_max),
)
ax_1.view_init(30, 135, 0)
ax_1.set_title('$l = 1$, $m = -1$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(
cm.ScalarMappable(
norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm
),
ax=ax_1,
shrink=0.6,
orientation='vertical',
location='left',
)
ax_1 = fig.add_subplot(143, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[2, :, :]))
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1,
cstride=1,
facecolors=cm.coolwarm(spherical_harmonics[2, :, :] / surface_max),
)
ax_1.view_init(30, 135, 0)
ax_1.set_title('$l = 1$, $m = 0$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(
cm.ScalarMappable(
norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm
),
ax=ax_1,
shrink=0.6,
orientation='vertical',
location='left'
)
ax_1 = fig.add_subplot(144, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[3, :, :]))
ax_1.view_init(30, 135, 0)
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1,
cstride=1,
facecolors=cm.coolwarm(spherical_harmonics[3, :, :] / surface_max),
)
ax_1.set_title('$l = 1$, $m = 1$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(
cm.ScalarMappable(
norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm
),
ax=ax_1,
shrink=0.6,
orientation='vertical',
location='left',
)
plt.show()
sphere.gauss_legendre_trapezoidal_complex_sh_mapping_2d#
This functions does the same than gauss_legendre_trapezoidal_complex_sh_mapping_2d, with the difference that this time the complex spherical harmonics are evaluated.
Docstring and comments#
[17]:
print(quadratures.gauss_legendre_trapezoidal_complex_sh_mapping_2d.__doc__)
This function is for obtaining the quadratures points to
approximate numerically the integral in a surface of a sphere, and
it also returns the evaluation of the complex spherical harmonics in
those points.
It returns the weights and vectors for the Gauss-Legendre and
composite trapezoidal quadrature rule. The complex spherical
harmonics evaluated are of degree l and order m, with l <= big_l.
See the shape of the returns.
Notes
-----
Gauss-legendre quadrature in theta. This one uses the package
pyshtools.
Composite trapezoidal rule in phi.
Integral on theta are (big_l_c + 1) quadrature points.
Integral on phi are (2 * big_l_c + 1) quadrature points.
Without considering errors produced by the approximation by finite
numbers, the quadrature must be exact for functions consisting in
polynomials of big_l_c degree times an exponential power to (m times
i), with |m| <= big_l_c.
Legendre's functions are computed used pyshtools.
Parameters
----------
big_l : int
>= 0, max degree.
big_l_c : int
>= 0. It's the parameter used to compute the points of the
quadrature.
pesykus : np.ndarray
dtype int, shape ((big_l+1) * big_l // 2, 2).
Used for the vectorization of some computations.
Comes from the function
biosspheres.miscella.auxindexes.pes_y_kus(big_l)
p2_plus_p_plus_q : np.ndarray
dtype int, length (big_l+1) * big_l // 2.
Used for the vectorization of some computations.
Comes from the function
biosspheres.miscella.auxindexes.pes_y_kus(big_l)
p2_plus_p_minus_q : np.ndarray
dtype int, length (big_l+1) * big_l // 2.
Used for the vectorization of some computations.
Comes from the function
biosspheres.miscella.auxindexes.pes_y_kus(big_l)
Returns
-------
quantity_theta_points : int
how many points for the integral in theta, (big_l_c + 1).
quantity_phi_points : int
how many points for the integral in phi, (2 * big_l_c + 1)
weights : np.ndarray
of floats, with the weights for the integral quadrature in
theta. Length (big_l_c + 1).
pre_vector : np.ndarray
of floats. Represents the vectors of the quadrature points.
Shape (3, quantity_theta_points, quantity_phi_points).
spherical_harmonics : np.ndarray
of complex numbers, represent the real spherical harmonics of
degree and order l and m evaluated in the points given by
pre_vector. Shape
((big_l + 1)**2, quantity_theta_points, quantity_phi_points)
Example#
[18]:
big_l_c = 40
big_l = 1
Auxiliary parameters:
[19]:
from biosspheres.utils.auxindexes import pes_y_kus
pesykus, p2_plus_p_plus_q, p2_plus_p_minus_q = pes_y_kus(big_l)
[20]:
quantity_theta_points, quantity_phi_points, weights, pre_vector, spherical_harmonics = quadratures.gauss_legendre_trapezoidal_complex_sh_mapping_2d(big_l, big_l_c, pesykus, p2_plus_p_plus_q, p2_plus_p_minus_q)
Plotting of the real part of the spherical harmonics.
[21]:
fig = plt.figure(figsize=plt.figaspect(0.25), dpi=68., layout='constrained')
ax_1 = fig.add_subplot(141, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[0, :, :]))
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1,
cstride=1,
facecolors=cm.coolwarm(
np.real(spherical_harmonics[0, :, :]) / surface_max
),
)
ax_1.view_init(30, 135, 0)
ax_1.set_title('$l = 0$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(
cm.ScalarMappable(
norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm
),
ax=ax_1,
shrink=0.6,
orientation='vertical',
location='left',
)
ax_1 = fig.add_subplot(142, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[1, :, :]))
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1,
cstride=1,
facecolors=cm.coolwarm(
np.real(spherical_harmonics[1, :, :]) / surface_max
),
)
ax_1.view_init(30, 135, 0)
ax_1.set_title('$l = 1$, $m = -1$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(
cm.ScalarMappable(
norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm
),
ax=ax_1,
shrink=0.6,
orientation='vertical',
location='left',
)
ax_1 = fig.add_subplot(143, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[2, :, :]))
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1,
cstride=1,
facecolors=cm.coolwarm(
np.real(spherical_harmonics[2, :, :]) / surface_max
),
)
ax_1.view_init(30, 135, 0)
ax_1.set_title('$l = 1$, $m = 0$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(cm.ScalarMappable(norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm), ax=ax_1, shrink=0.6, orientation='vertical', location='left')
ax_1 = fig.add_subplot(144, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[3, :, :]))
ax_1.view_init(30, 135, 0)
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1, cstride=1,
facecolors=cm.coolwarm(np.real(spherical_harmonics[3, :, :])/surface_max))
ax_1.set_title('$l = 1$, $m = 1$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(cm.ScalarMappable(norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm), ax=ax_1, shrink=0.6, orientation='vertical', location='left')
plt.show()
Plotting of the imaginary part of the spherical harmonics:
[22]:
fig = plt.figure(figsize=plt.figaspect(0.25), dpi=68., layout='constrained')
ax_1 = fig.add_subplot(141, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[0, :, :]))
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1, cstride=1,
facecolors=cm.coolwarm(np.imag(spherical_harmonics[0, :, :])/surface_max))
ax_1.view_init(30, 135, 0)
ax_1.set_title('$l = 0$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(cm.ScalarMappable(norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm), ax=ax_1, shrink=0.6, orientation='vertical', location='left')
ax_1 = fig.add_subplot(142, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[1, :, :]))
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1, cstride=1,
facecolors=cm.coolwarm(np.imag(spherical_harmonics[1, :, :])/surface_max))
ax_1.view_init(30, 135, 0)
ax_1.set_title('$l = 1$, $m = -1$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(cm.ScalarMappable(norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm), ax=ax_1, shrink=0.6, orientation='vertical', location='left')
ax_1 = fig.add_subplot(143, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[2, :, :]))
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1, cstride=1,
facecolors=cm.coolwarm(np.imag(spherical_harmonics[2, :, :])/surface_max))
ax_1.view_init(30, 135, 0)
ax_1.set_title('$l = 1$, $m = 0$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(cm.ScalarMappable(norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm), ax=ax_1, shrink=0.6, orientation='vertical', location='left')
ax_1 = fig.add_subplot(144, projection='3d')
surface_max = np.max(np.abs(spherical_harmonics[3, :, :]))
ax_1.view_init(30, 135, 0)
ax_1.plot_surface(
vector[0, :, :],
vector[1, :, :],
vector[2, :, :],
rstride=1, cstride=1,
facecolors=cm.coolwarm(np.imag(spherical_harmonics[3, :, :])/surface_max))
ax_1.set_title('$l = 1$, $m = 1$')
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
fig.colorbar(cm.ScalarMappable(norm=colors.CenteredNorm(halfrange=surface_max), cmap=cm.coolwarm), ax=ax_1, shrink=0.6, orientation='vertical', location='left')
plt.show()
sphere.real_spherical_harmonic_transform_1d#
It returns the same than sphere.gauss_legendre_trapezoidal_1d and a vector that can be used to calculate the real spherical harmonic transform on the surface of a sphere of radius equal to one.
Docstring and some comments#
[23]:
print(quadratures.real_spherical_harmonic_transform_1d.__doc__)
It returns the vectors for the Gauss-Legendre and trapezoidal
quadrature rule for computing a numerical integral in the surface
of a sphere. It also returns a vector that can be used to calculate
the real spherical harmonic transform on the surface of a sphere of
radius equal to one.
The use of the results of this routine is for SLOW routines, because
the vector used for the spherical harmonic transform does not have
any performance improvements.
Notes
-----
Gauss-legendre quadrature in theta. This one uses the package
pyshtools.
Composite trapezoidal rule in phi.
Integral on theta are (big_l_c + 1) quadrature points.
Integral on phi are (2 * big_l_c + 1) quadrature points.
Parameters
----------
big_l : int
>= 0.
big_l_c: int
>= 0. It's the parameter used to compute the points of the
quadrature.
Returns
-------
final_length : int
how many points for the surface integral,
= (big_l_c + 1) * (2 * big_l_c + 1).
pre_vector : np.ndarray
of floats. Represents the vectors of the quadrature points.
Shape (3, final_length).
transform : np.ndarray
of floats. Vector that can be used to calculate the real
spherical transform. Shape ((big_l+1)**2, final_length)
See Also
--------
gauss_legendre_trapezoidal_1d
Example#
[24]:
big_l = 1
big_l_c = 40
final_length, pre_vector, transform = quadratures.real_spherical_harmonic_transform_1d(big_l, big_l_c)
Now we are going to check the orthonormality of the spherical harmonics that are being used.
We obtain the spherical harmonics evaluated in the quadrature points:
[25]:
from biosspheres.utils.auxindexes import pes_y_kus
pesykus, p2_plus_p_plus_q, p2_plus_p_minus_q = pes_y_kus(big_l)
quantity_theta_points, quantity_phi_points, weights, pre_vector, spherical_harmonics = (
quadratures.gauss_legendre_trapezoidal_real_sh_mapping_2d(
big_l, big_l_c))
Check of the property:
[26]:
integral = np.sum(spherical_harmonics[0, :, :].flatten('F') * transform[0, :])
print(integral)
integral = np.sum(spherical_harmonics[1, :, :].flatten('F') * transform[1, :])
print(integral)
integral = np.sum(spherical_harmonics[2, :, :].flatten('F') * transform[2, :])
print(integral)
integral = np.sum(spherical_harmonics[3, :, :].flatten('F') * transform[3, :])
print(integral)
0.999999999999999
0.9999999999999997
0.9999999999999978
0.9999999999999997
Which is near to one, the expected result.
sphere.complex_spherical_harmonic_transform_1d#
It returns the same than sphere.gauss_legendre_trapezoidal_1d and a vector that can be used to calculate the complex spherical harmonic transform on the surface of a sphere of radius equal to one.
Docstring and some comments#
[27]:
print(quadratures.complex_spherical_harmonic_transform_1d.__doc__)
It returns the vectors for the Gauss-Legendre and trapezoidal
quadrature rule for computing a numerical integral in the surface
of a sphere. It also returns a vector that can be used to calculate
the complex spherical harmonic transform on the surface of a sphere of
radius equal to one.
The use of the results of this routine is for SLOW routines, because
the vector used for the spherical harmonic transform does not have
any performance improvements.
Notes
-----
Gauss-legendre quadrature in theta. This one uses the package
pyshtools.
Composite trapezoidal rule in phi.
Integral on theta are (big_l_c + 1) quadrature points.
Integral on phi are (2 * big_l_c + 1) quadrature points.
Parameters
----------
big_l : int
>= 0.
big_l_c: int
>= 0. It's the parameter used to compute the points of the
quadrature.
Returns
-------
final_length : int
how many points for the surface integral,
= (big_l_c + 1) * (2 * big_l_c + 1).
pre_vector : np.ndarray
of floats. Represents the vectors of the quadrature points.
Shape (3, final_length).
transform : np.ndarray
of complex numbers. Vector that can be used to calculate the
complex spherical transform. Shape ((big_l+1)**2, final_length)
See Also
--------
gauss_legendre_trapezoidal_1d
Example#
[28]:
big_l_c = 15
big_l = 1
final_length, pre_vector, transform = quadratures.complex_spherical_harmonic_transform_1d(big_l, big_l_c)
[29]:
from biosspheres.utils.auxindexes import pes_y_kus
pesykus, p2_plus_p_plus_q, p2_plus_p_minus_q = pes_y_kus(big_l)
(quantity_theta_points, quantity_phi_points, weights, pre_vector,
spherical_harmonics) = (
quadratures.gauss_legendre_trapezoidal_complex_sh_mapping_2d(
big_l, big_l_c, pesykus, p2_plus_p_plus_q, p2_plus_p_minus_q))
[30]:
integral = np.sum(spherical_harmonics[0, :, :].flatten('F') * transform[0, :])
print(integral)
integral = np.sum(spherical_harmonics[1, :, :].flatten('F') * transform[1, :])
print(integral)
integral = np.sum(spherical_harmonics[2, :, :].flatten('F') * transform[2, :])
print(integral)
integral = np.sum(spherical_harmonics[3, :, :].flatten('F') * transform[3, :])
print(integral)
(0.9999999999999977+0j)
(0.9999999999999996-3.4805253436693944e-18j)
(0.9999999999999934+0j)
(0.9999999999999996-1.334086267133296e-18j)
sphere.from_sphere_s_cartesian_to_j_spherical_2d#
Given points in the cartesian coordinate system \(s\), this algorithm writes them in the spherical coordinate system \(j\). See the following subsection for the format of the inputs.
Docstring and some comments#
[31]:
print(quadratures.from_sphere_s_cartesian_to_j_spherical_2d.__doc__)
Given points in the cartesian coordinate system "s", this algorithm
writes them in the spherical coordinate system "j". The "j" has its
center in a different point than the center of the coordinate system
"s".
Notes
-----
Input:
x_s = r_s sin(theta) cos(varphi) ,
y_s = r_s sin(theta) sin(varphi) ,
z_s = r_s cos(theta) ,
To the cartesian coordinate system j:
x_j = x_s + (p_s - p_j)_x ,
y_j = y_s + (p_s - p_j)_y ,
z_j = z_s + (p_s - p_j)_z ,
To the spherical coordinate system j:
r_j = sqrt{x^2_j + y^2_j + z^2_j} ,
cos theta = r_j / z_j ,
varphi = arctan2 (y_j / x_j)
Parameters
----------
r_s : float
> 0, radius of the sphere s.
p_j : np.ndarray
of floats of dimension 1, length 3, represents the position
vector of the center of the sphere j.
p_s : np.ndarray
of floats of dimension 1, length 3, represents the position
vector of the center of the sphere s.
quantity_theta_points : int
how many points in theta.
quantity_phi_points : int
how many points in phi.
pre_vector : np.ndarray
of floats. Represents the vectors. Shape
(3, quantity_theta_points, quantity_phi_points).
Returns
-------
r_coord : np.ndarray
Two dimensional array of floats with the spherical coordinate r
of the points in the coordinate system s. Shape equals to
(quantity_theta_points, quantity_phi_points).
phi_coord : np.ndarray
Two dimensional array of floats with the phi coordinate r of the
points in the coordinate system s. Shape equals to
(quantity_theta_points, quantity_phi_points).
cos_theta_coord : np.ndarray
Two dimensional array of floats with the cosine of the spherical
coordinate theta of the points in the coordinate system s.
Shape equals to (quantity_theta_points, quantity_phi_points).
See Also
--------
from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_2d
from_sphere_s_cartesian_to_j_spherical_1d
As long as the input points are given in the cartesian coordinate system \(s\), the function will do what it is supposed to.
Example#
[32]:
radio_1 = 1.2
radio_2 = 1.7
[33]:
p_1 = np.asarray([2., 1., 2.5])
p_2 = -p_1
[34]:
big_l_c = 4
[35]:
quantity_theta_points, quantity_phi_points, weights, pre_vector = quadratures.gauss_legendre_trapezoidal_2d(big_l_c)
[36]:
r_coord, phi_coord, cos_theta_coord = quadratures.from_sphere_s_cartesian_to_j_spherical_2d(
radio_2, p_1, p_2, quantity_theta_points, quantity_phi_points, pre_vector)
[37]:
fig = plt.figure(figsize=plt.figaspect(1.), dpi=68., layout='constrained')
ax_1 = fig.add_subplot(111, projection='3d')
vector = radio_1 * pre_vector
ax_1.scatter3D(
vector[0, :],
vector[1, :],
vector[2, :])
sin_theta = np.sqrt(1-cos_theta_coord**2)
ax_1.scatter3D(
r_coord * sin_theta * np.cos(phi_coord),
r_coord * sin_theta * np.sin(phi_coord),
r_coord * cos_theta_coord)
for i in np.arange(0, quantity_theta_points):
for j in np.arange(0, quantity_phi_points):
ax_1.quiver(
np.zeros_like(vector[0, i, j]),
np.zeros_like(vector[0, i, j]),
np.zeros_like(vector[0, i, j]),
sin_theta[i, j] * np.cos(phi_coord[i, j]),
sin_theta[i, j] * np.sin(phi_coord[i, j]),
cos_theta_coord[i, j],
pivot='tail', length=r_coord[i, j], arrow_length_ratio=0.0625, alpha=0.325)
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
plt.show()
sphere.from_sphere_s_cartesian_to_j_spherical_1d#
Same than sphere.from_sphere_s_cartesian_to_j_spherical_2d, but with different format input and output.
Docstring and some comments#
[38]:
print(quadratures.from_sphere_s_cartesian_to_j_spherical_1d.__doc__)
Given points in the cartesian coordinate system "s", this algorithm
writes them in the spherical coordinate system "j". The "j" has its
center in a different point than the center of the coordinate system
"s".
This one is for a slow routine.
Notes
-----
put:
x_s = r_s sin(theta) cos(varphi) ,
y_s = r_s sin(theta) sin(varphi) ,
z_s = r_s cos(theta) ,
To the cartesian coordinate system j:
x_j = x_s + (p_s - p_j)_x ,
y_j = y_s + (p_s - p_j)_y ,
z_j = z_s + (p_s - p_j)_z ,
To the spherical coordinate system j:
r_j = sqrt{x^2_j + y^2_j + z^2_j} ,
cos theta = r_j / z_j ,
varphi = arctan2 (y_j / x_j)
Parameters
----------
r_s : float
> 0, radius of the sphere s.
p_j : np.ndarray
of floats of dimension 1, length 3, represents the position
vector of the center of the sphere j.
p_s : np.ndarray
of floats of dimension 1, length 3, represents the position
vector of the center of the sphere s.
final_length : int
how many points.
pre_vector : np.ndarray
of floats. Represents the vectors. Shape (3, final_length).
Returns
-------
r_coord : np.ndarray
One dimensional array of floats with the spherical coordinate r
of the points in the coordinate system s. Length equals to
final_length.
phi_coord : np.ndarray
One dimensional array of floats with the phi coordinate r of the
points in the coordinate system s. Length equals to
final_length.
cos_theta_coord : np.ndarray
One dimensional array of floats with the cosine of the spherical
coordinate theta of the points in the coordinate system s.
Length equals to final_length.
See Also
--------
from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_1d
from_sphere_s_cartesian_to_j_spherical_2d
As long as the input points are given in the cartesian coordinate system \(s\), the function will do what it is supposed to.
Example#
[39]:
radio_1 = 1.2
radio_2 = 1.7
[40]:
p_1 = np.asarray([2., 1., 2.5])
p_2 = -p_1
[41]:
big_l_c = 3
[42]:
final_length, total_weights, pre_vector = quadratures.gauss_legendre_trapezoidal_1d(big_l_c)
[43]:
r_coord, phi_coord, cos_theta_coord = quadratures.from_sphere_s_cartesian_to_j_spherical_1d(
radio_2, p_1, p_2, final_length, pre_vector)
[44]:
fig = plt.figure(figsize=plt.figaspect(1.), dpi=68., layout='constrained')
ax_1 = fig.add_subplot(111, projection='3d')
vector = radio_1 * pre_vector
ax_1.scatter3D(
vector[0, :],
vector[1, :],
vector[2, :])
sin_theta = np.sqrt(1-cos_theta_coord**2)
ax_1.scatter3D(
r_coord * sin_theta * np.cos(phi_coord),
r_coord * sin_theta * np.sin(phi_coord),
r_coord * cos_theta_coord)
for i in np.arange(0, final_length):
ax_1.quiver(
np.zeros_like(vector[0, i]),
np.zeros_like(vector[0, i]),
np.zeros_like(vector[0, i]),
sin_theta[i] * np.cos(phi_coord[i]),
sin_theta[i] * np.sin(phi_coord[i]),
cos_theta_coord[i],
pivot='tail', length=r_coord[i], arrow_length_ratio=0.0625, alpha=0.325)
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
plt.show()
sphere.from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_2d#
Given points in the cartesian coordinate system \(s\), this algorithm writes them in the spherical coordinate system \(j\), and also gives the dot product between the unitary vectors of the spherical system obtained times the normal of the unitary sphere. See the following subsection for the format of the inputs.
Docstring and some comments#
[45]:
print(quadratures.from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_2d.__doc__)
Given points in the cartesian coordinate system "s", this algorithm
writes them in the spherical coordinate system "j", and also gives
the dot product between the unitary vectors of the spherical system
obtained times the normal of the unitary sphere.
The "j" has its center in a different point than the center of the
coordinate system "s".
Notes
-----
put:
x_s = r_s sin(theta) cos(varphi) ,
y_s = r_s sin(theta) sin(varphi) ,
z_s = r_s cos(theta) ,
To the cartesian coordinate system j:
x_j = x_s + (p_s - p_j)_x ,
y_j = y_s + (p_s - p_j)_y ,
z_j = z_s + (p_s - p_j)_z ,
To the spherical coordinate system j:
r_j = sqrt{x^2_j + y^2_j + z^2_j} ,
cos theta = r_j / z_j ,
varphi = arctan2 (y_j / x_j)
Unitary vectors:
hat{mathbf{e}}_r = sin(theta) cos(varphi) hat{mathbf{e}}_x
+ sin(theta) sin(varphi) hat{mathbf{e}}_y
+ cos(theta) hat{mathbf{e}}_z
hat{mathbf{e}}_theta = cos(theta) cos(varphi) hat{mathbf{e}}_x
+ cos(theta) sin(varphi) hat{mathbf{e}}_y
- sin(theta) hat{mathbf{e}}_z
hat{mathbf{e}}_{varphi} = -sin(varphi) hat{mathbf{e}}_x
+ cos(varphi) hat{mathbf{e}}_y
Parameters
----------
r_s : float
> 0, radius of the sphere s.
p_j : np.ndarray
of floats of dimension 1, length 3, represents the position
vector of the center of the sphere j.
p_s : np.ndarray
of floats of dimension 1, length 3, represents the position
vector of the center of the sphere s.
quantity_theta_points : int
how many points in theta.
quantity_phi_points : int
how many points in phi.
pre_vector : np.ndarray
of floats. Represents the vectors. Shape
(3, quantity_theta_points, quantity_phi_points).
Returns
-------
r_coord : np.ndarray
Two dimensional array of floats with the spherical coordinate r
of the points in the coordinate system s. Shape equals to
(quantity_theta_points, quantity_phi_points).
phi_coord : np.ndarray
Two dimensional array of floats with the phi coordinate r of the
points in the coordinate system s. Shape equals to
(quantity_theta_points, quantity_phi_points).
cos_theta_coord : np.ndarray
Two dimensional array of floats with the cosine of the spherical
coordinate theta of the points in the coordinate system s.
Shape equals to (quantity_theta_points, quantity_phi_points).
er_times_n : np.ndarray
Two dimensional array of floats with the dot product of the
canonical vector of the spherical coordinate r in the points
in the coordinate system s and the normal of a sphere. Shape
equals to (quantity_theta_points, quantity_phi_points).
etheta_times_n : np.ndarray
Two dimensional array of floats with the dot product of the
canonical vector of the spherical coordinate theta in the points
in the coordinate system s and the normal of a sphere. Shape
equals to (quantity_theta_points, quantity_phi_points).
ephi_times_n : np.ndarray
Two dimensional array of floats with the dot product of the
canonical vector of the spherical coordinate phi in the points
in the coordinate system s and the normal of a sphere. Shape
equals to (quantity_theta_points, quantity_phi_points).
See Also
--------
from_sphere_s_cartesian_to_j_spherical_2d
from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_1d
As long as the input points are given in the cartesian coordinate system \(s\), the function will do what it is supposed to.
Example#
[46]:
radio_1 = 1.2
radio_2 = 1.7
[47]:
p_1 = np.asarray([2., 1., 2.5])
p_2 = -p_1
[48]:
big_l_c = 30
[49]:
quantity_theta_points, quantity_phi_points, weights, pre_vector = quadratures.gauss_legendre_trapezoidal_2d(big_l_c)
[50]:
r_coord, phi_coord, cos_theta_coord, er_times_n, etheta_times_n, ephi_times_n = quadratures.from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_2d(
radio_2, p_1, p_2, quantity_theta_points, quantity_phi_points, pre_vector)
Projections in the other sphere:
[51]:
fig = plt.figure(figsize=plt.figaspect(.3), dpi=68., layout='constrained')
ax_1 = fig.add_subplot(131, projection='3d')
vector = radio_1 * pre_vector
ax_1.scatter3D(
vector[0, :],
vector[1, :],
vector[2, :])
sin_theta = np.sqrt(1-cos_theta_coord**2)
ax_1.scatter3D(
r_coord * sin_theta * np.cos(phi_coord),
r_coord * sin_theta * np.sin(phi_coord),
r_coord * cos_theta_coord)
for i in np.arange(0, quantity_theta_points):
for j in np.arange(0, quantity_phi_points):
ax_1.quiver(
np.zeros_like(vector[0, i, j]),
np.zeros_like(vector[0, i, j]),
np.zeros_like(vector[0, i, j]),
sin_theta[i, j] * np.cos(phi_coord[i, j]),
sin_theta[i, j] * np.sin(phi_coord[i, j]),
cos_theta_coord[i, j],
pivot='tail', length=r_coord[i, j], arrow_length_ratio=0.0625, alpha=0.005)
ax_1.plot_surface(
r_coord * sin_theta * np.cos(phi_coord),
r_coord * sin_theta * np.sin(phi_coord),
r_coord * cos_theta_coord,
rstride=1, cstride=1,
facecolors=cm.coolwarm(er_times_n))
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
ax_1.set_title('Projection of the unitary vector corresponding to the radius')
ax_1 = fig.add_subplot(132, projection='3d')
vector = radio_1 * pre_vector
ax_1.scatter3D(
vector[0, :],
vector[1, :],
vector[2, :])
sin_theta = np.sqrt(1-cos_theta_coord**2)
ax_1.scatter3D(
r_coord * sin_theta * np.cos(phi_coord),
r_coord * sin_theta * np.sin(phi_coord),
r_coord * cos_theta_coord)
for i in np.arange(0, quantity_theta_points):
for j in np.arange(0, quantity_phi_points):
ax_1.quiver(
np.zeros_like(vector[0, i, j]),
np.zeros_like(vector[0, i, j]),
np.zeros_like(vector[0, i, j]),
sin_theta[i, j] * np.cos(phi_coord[i, j]),
sin_theta[i, j] * np.sin(phi_coord[i, j]),
cos_theta_coord[i, j],
pivot='tail', length=r_coord[i, j], arrow_length_ratio=0.0625, alpha=0.005)
ax_1.plot_surface(
r_coord * sin_theta * np.cos(phi_coord),
r_coord * sin_theta * np.sin(phi_coord),
r_coord * cos_theta_coord,
rstride=1, cstride=1,
facecolors=cm.coolwarm(etheta_times_n))
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
ax_1.set_title('Projection of the unitary vector $\\theta$')
ax_1 = fig.add_subplot(133, projection='3d')
vector = radio_1 * pre_vector
ax_1.scatter3D(
vector[0, :],
vector[1, :],
vector[2, :])
sin_theta = np.sqrt(1-cos_theta_coord**2)
ax_1.scatter3D(
r_coord * sin_theta * np.cos(phi_coord),
r_coord * sin_theta * np.sin(phi_coord),
r_coord * cos_theta_coord)
for i in np.arange(0, quantity_theta_points):
for j in np.arange(0, quantity_phi_points):
ax_1.quiver(
np.zeros_like(vector[0, i, j]),
np.zeros_like(vector[0, i, j]),
np.zeros_like(vector[0, i, j]),
sin_theta[i, j] * np.cos(phi_coord[i, j]),
sin_theta[i, j] * np.sin(phi_coord[i, j]),
cos_theta_coord[i, j],
pivot='tail', length=r_coord[i, j], arrow_length_ratio=0.0625, alpha=0.005)
ax_1.plot_surface(
r_coord * sin_theta * np.cos(phi_coord),
r_coord * sin_theta * np.sin(phi_coord),
r_coord * cos_theta_coord,
rstride=1, cstride=1,
facecolors=cm.coolwarm(ephi_times_n))
ax_1.set_xlabel('$x$')
ax_1.set_ylabel('$y$')
ax_1.set_zlabel('$z$')
ax_1.set_aspect('equal')
ax_1.set_title('Projection of the unitary vector $\\phi$')
plt.show()
sphere.from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_1d#
Given points in the cartesian coordinate system \(s\), this algorithm writes them in the spherical coordinate system \(j\), and also gives the dot product between the unitary vectors of the spherical system obtained times the normal of the unitary sphere. See the following subsection for the format of the inputs.
Docstring and some comments#
[52]:
print(quadratures.from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_1d.__doc__)
Given points in the cartesian coordinate system "s", this algorithm
writes them in the spherical coordinate system "j", and also gives
the dot product between the unitary vectors of the spherical system
obtained times the normal of the unitary sphere.
The "j" has its center in a different point than the center of the
coordinate system "s".
Notes
-----
put:
x_s = r_s sin(theta) cos(varphi) ,
y_s = r_s sin(theta) sin(varphi) ,
z_s = r_s cos(theta) ,
To the cartesian coordinate system j:
x_j = x_s + (p_s - p_j)_x ,
y_j = y_s + (p_s - p_j)_y ,
z_j = z_s + (p_s - p_j)_z ,
To the spherical coordinate system j:
r_j = sqrt{x^2_j + y^2_j + z^2_j} ,
cos theta = r_j / z_j ,
varphi = arctan2 (y_j / x_j)
Unitary vectors:
hat{mathbf{e}}_r = sin(theta) cos(varphi) hat{mathbf{e}}_x
+ sin(theta) sin(varphi) hat{mathbf{e}}_y
+ cos(theta) hat{mathbf{e}}_z
hat{mathbf{e}}_theta = cos(theta) cos(varphi) hat{mathbf{e}}_x
+ cos(theta) sin(varphi) hat{mathbf{e}}_y
- sin(theta) hat{mathbf{e}}_z
hat{mathbf{e}}_{varphi} = -sin(varphi) hat{mathbf{e}}_x
+ cos(varphi) hat{mathbf{e}}_y
Parameters
----------
r_s : float
> 0, radius of the sphere s.
p_j : np.ndarray
of floats. Length 3, represents the
position vector of the center of the sphere j.
p_s : np.ndarray
of floats. Length 3, represents the
position vector of the center of the sphere s.
final_length : int
how many points.
pre_vector : np.ndarray
of floats. Represents the vectors. Shape (3, final_length).
Returns
-------
r_coord : np.ndarray
One dimensional array of floats with the spherical coordinate r
of the points in the coordinate system s. Length equals to
final_length.
phi_coord : np.ndarray
One dimensional array of floats with the phi coordinate r of the
points in the coordinate system s. Length equals to
final_length.
cos_theta_coord : np.ndarray
One dimensional array of floats with the cosine of the spherical
coordinate theta of the points in the coordinate system s.
Length equals to final_length.
er_times_n : np.ndarray
One dimensional array of floats with the dot product of the
canonical vector of the spherical coordinate r in the points
in the coordinate system s and the normal of a sphere.
Length final_length.
etheta_times_n : np.ndarray
One dimensional array of floats with the dot product of the
canonical vector of the spherical coordinate theta in the points
in the coordinate system s and the normal of a sphere.
Length final_length.
ephi_times_n : np.ndarray
One dimensional array of floats with the dot product of the
canonical vector of the spherical coordinate phi in the points
in the coordinate system s and the normal of a sphere.
Length final_length.
As long as the input points are given in the cartesian coordinate system \(s\), the function will do what it is supposed to.
Example#
[53]:
radio_1 = 1.2
radio_2 = 1.7
[54]:
p_1 = np.asarray([2., 1., 2.5])
p_2 = -p_1
[55]:
big_l = 1
big_l_c = 10
[56]:
final_length, total_weights, pre_vector = quadratures.gauss_legendre_trapezoidal_1d(big_l_c)
[57]:
r_coord, phi_coord, cos_theta_coord, er_times_n, etheta_times_n, ephi_times_n = quadratures.from_sphere_s_cartesian_to_j_spherical_and_spherical_vectors_1d(
radio_2, p_1, p_2, final_length, pre_vector)
[ ]: