multipoles is a Python package for multipole expansions of the solutions of the Poisson equation (e.g. electrostatic or gravitational potentials). It can handle discrete and continuous charge or mass distributions.
Simply use pip
:
pip install --upgrade multipoles
The documentation is available here.
For a given function
Examples of this are the electrostatic and Newtonian gravitational potential.
If you need to evaluate
for a exterior expansion, or
for an interior expansion; where
The multipole moments for the exterior expansion are:
and the multipole moments for the interior expansion are:
This approach is usually much faster because the contributions
Some literature considers the
As example for a discrete charge distribution we model two point charges with positive and negative unit charge located on the z-axis:
from multipoles import MultipoleExpansion
# Prepare the charge distribution dict for the MultipoleExpansion object:
charge_dist = {
'discrete': True, # point charges are discrete charge distributions
'charges': [
{'q': 1, 'xyz': (0, 0, 1)},
{'q': -1, 'xyz': (0, 0, -1)},
]
}
l_max = 2 # where to stop the infinite multipole sum; here we expand up to the quadrupole (l=2)
Phi = MultipoleExpansion(charge_dist, l_max)
# We can evaluate the multipole expanded potential at a given point like this:
x, y, z = 30.5, 30.6, 30.7
value = Phi(x, y, z)
# The multipole moments are stored in a dict, where the keys are (l, m) and the values q_lm:
Phi.multipole_moments
As an example for a continuous charge distribution, we smear out the point charges from the previous example:
from multipoles import MultipoleExpansion
import numpy as np
# First we set up our grid, a cube of length 10 centered at the origin:
npoints = 101
edge = 10
x, y, z = [np.linspace(-edge/2., edge/2., npoints)]*3
XYZ = np.meshgrid(x, y, z, indexing='ij')
# We model our smeared out charges as gaussian functions:
def gaussian(XYZ, xyz0, sigma):
g = np.ones_like(XYZ[0])
for k in range(3):
g *= np.exp(-(XYZ[k] - xyz0[k])**2 / sigma**2)
g *= (sigma**2*np.pi)**-1.5
return g
sigma = 1.5 # the width of our gaussians
# Initialize the charge density rho, which is a 3D numpy array:
rho = gaussian(XYZ, (0, 0, 1), sigma) - gaussian(XYZ, (0, 0, -1), sigma)
# Prepare the charge distribution dict for the MultipoleExpansion object:
charge_dist = {
'discrete': False, # we have a continuous charge distribution here
'rho': rho,
'xyz': XYZ
}
# The rest is the same as for the discrete case:
l_max = 2 # where to stop the infinite multipole sum; here we expand up to the quadrupole (l=2)
Phi = MultipoleExpansion(charge_dist, l_max)
x, y, z = 30.5, 30.6, 30.7
value = Phi(x, y, z)