While studying at Masaryk University in Brno, I wrote my bachelor thesis - Electrostatics and magnetostatics on the hypersphere. The title says it all. My task was to solve scalar and vector Poisson equations for electrostatic and magnetostatic potentials. I managed to find a solution for the electrostatic potential. Still, unfortunately, the magnetostatic (vector) potential was too much of a task and would require extra time, which I did not have at the time. I managed to defend my thesis with the grade A in June of 2024. If you are interested in the Thesis, you can download it here or here.
I wrote some code for my bachelor thesis which I share here for anyone interested.
What do I mean by hypersphere? In my thesis by hypersphere I mean 3-sphere
where
Cartesian coordinates are not the best coordinates for describing the hypersphere (trust me...) and more "natrual" choice of coordinates can make the work with the hypersphere a lot easier. One of the more "natural" coordinate system that I used in my thesis is hyperspherical coordinate system represented by the map
where
which will be useful later :).
For the human mind, the hypersphere
where
Now we can visualize the functions on the hypersphere
N_fig = 120 # Grid number defines the "resolution" of the Figures
x_values = np.linspace(-2,2,N_fig) # Defiing the grid for the plotting
y_values = np.linspace(-2,2,N_fig)
z_values = np.linspace(-2,2,N_fig)
x,y,z = np.meshgrid(x_values, y_values, z_values)
Then, using the inverse map R3_R4
and R4_S3
like this
def R3_R4(x_values, y_values, z_values): # Inverse stereographic projection
X = (2*x_values)/(x_values**2+y_values**2+z_values**2+1)
Y = (2*y_values)/(x_values**2+y_values**2+z_values**2+1)
Z = (2*z_values)/(x_values**2+y_values**2+z_values**2+1)
W = (x_values**2+y_values**2+z_values**2-1)/(x_values**2+y_values**2+z_values**2+1)
return(X,Y,Z,W)
def R4_S3(X,Y,Z,W): # Inverse hyperspherical map
zeta = np.arctan2(W,Z)
theta = np.arctan2(np.sqrt(Z**2+W**2),Y)
phi = np.arctan2(np.sqrt(W**2+Z**2+Y**2),X)
return(phi, theta, zeta)
To confuse the reader - the code denotes the coordinates in X
, Y
, Z
, W
and in x_values
, y_values
, z_values
instead of
Now, we can assign the hyperspherical coordinate to each point of the grid in the subspace
Now the only thing that remains to do is to plot the function. I decided to use the isosurfaces (surfaces with constant function value) to be plotted and used Plotly graphing library to plot the figure of the isosurfaces of the function.
func_values_g = np.real(func_g(zeta_g,theta_g,phi_g)) # Evaluation of the func_g for each point of the plot grid
fig = go.Figure(layout=layout, data = go.Volume( # Making the plot
x=x.flatten(),
y=y.flatten(),
z=z.flatten(),
value = func_values_g.flatten(),
isomin = np.min(func_values_g),
isomax = np.max(func_values_g),
# isomin = -1,
# isomax = 1,
surface_count = 10,
opacity = 0.5,
#surface_fill = 0.9,
colorscale = "plasma",
caps = dict(x_show = False, y_show = False, z_show = False)
))
fig.update_layout(scene_camera=camera)
fig.show()
I selected a few simple functions as examples to show the output image. You may see them below.
|
|
|
|
As I said in the beginning, I managed to only solve electrostatic part of the problem but I generalized both electrostatic and magnetostatic Poisson equations to the hypersphere
In the hyperspherical coordinates the Laplace operator applied on the function
The classic Poisson equation for the eletrostatic potential
where
From now on I will omit the index in
With the assumption of separation of variables
I was able to find eigenfunctions of the Laplace operator
You may be interested in how does the hyperspherical harmonic function
where $C_n^{\alpha,n} are associated Gegenbauer polynomials which are disccused in the appendix B of my thesis. The constant in the front is normalization consstant which ensures that the hyperspherical harmonic function is normalized with respect to the inner product (integral over the hypersphere)
where
Now that I have the eigenfunctions of the Laplace operator we can finally solve some problems! How? Lets assume that we know the chrage density function
So why did we bother with finding the eigenfunctions of the Laplace operator? If the results of the Sturm--Liouville theory are applied on our set of eigenfunctions
where
Now we will use the important property of the Laplace operator - is is self-adjoint operator.
Now we have all the instruments we need to express our electrostatic potential
These equations follow from the things that have been said earlier. How would the Fourier series of the electrostatic function
and if we look closely we can see, that we expressed the coefficients
Becuase I cannot sum all of the terms in the infinite series in my solutions I ommited the terms with
def components_simps(n,l,m): # Calculation of the Fourier coefficient for the input function
function_values = np.conjugate(eigen_func(zeta,theta,phi,n,l,m))*func_g(zeta,theta,phi)
jacobian = (np.sin(phi))**2*np.sin(theta)
result = simpson(simpson(simpson(function_values*jacobian,zeta_values, axis = 2), theta_values, axis = 1),phi_values, axis = 0)
return(result)
The script then multiplies this component by