Magnetostatic Vector Potentials: Dipole and Loop Sources

Lindsey HeagyRowan Cockett

In this example, we plot the vector potential for a dipole and a loop source in a wholespace.

We can vary the magnetic permeability of the wholespace, location and orientation of the sources. For the dipole source, we can vary the moment, and for the loop source, we can vary the radius and current through the loop.

# Only run this cell in jupyterlite!
import micropip
await micropip.install('ipywidgets')
await micropip.install('https://cdn.curvenote.com/pypi/geoana-0.5.0-py3-none-any.whl')
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
from scipy.constants import mu_0, epsilon_0
from ipywidgets import interactive

from geoana import utils, spatial
from geoana.em import static

Setup

Define the location orientation and source, physical properties of the wholespace and source parameters

mu = mu_0  # permeability of free space (this is the default)
location=np.r_[0., 0., 0.]  # location of the dipole
orientation='Z'  # vertical dipole (can also be a unit-vector)

Magnetostatic Dipole and Loop

Here, we build the geoana magnetic dipole in a wholespace and circular loop in a wholespace using the parameters defined above. For a full list of the properties you can set on a dipole, see the :class:geoana.em.static.MagneticDipoleWholeSpace docs and for the circular loop source, see the :class:geoana.em.static.CircularLoopWholeSpace docs

# Evaluate vector potential
# --------------------------
#
# Next, we construct a grid where we want to plot the vector potential and
# evaluate

###############################################################################
#
# and define plotting code to plot an image of the amplitude of the vector
# field / flux as well as the streamlines

def plot_amplitude(ax, x, y, v):
    v = spatial.vector_magnitude(v)
    plt.colorbar(
        ax.pcolormesh(
            x, y, v.reshape(len(x), len(y), order='C'), norm=LogNorm()
        ), ax=ax
    )
    ax.axis('square')
    ax.set_xlabel('x (m)')
    ax.set_ylabel('y (m)')


# plot streamlines
def plot_streamlines(ax, x, y, v):
    vx = v[:, 0].reshape(len(x), len(y), order='F')
    vy = v[:, 1].reshape(len(x), len(y), order='F')
    ax.streamplot(x, y, vx.T, vy.T, color='k')


###############################################################################
# Create subplots for plotting the results. Loop over frequencies and plot the
# electric and magnetic fields along a slice through the center of the dipole.
def plot_fields(moment = 1, current = 1, radius = 20, location_x=0., location_y=0., location_z=0.,orientation_x=0.,orientation_y=0.,orientation_z=1.):

    mu = mu_0
    location=np.r_[location_x, location_y, location_z]  # location of the dipole
    orientation=np.r_[orientation_x, orientation_y, orientation_z]  # vertical dipole (can also be a unit-vector)

    dipole = static.MagneticDipoleWholeSpace(
        mu=mu, location=location,
        orientation=orientation , moment=moment
    )

    loop = static.CircularLoopWholeSpace(
        mu=mu, location=location,
        orientation=orientation, current=current,
        radius=radius
    )
    
    x = np.linspace(-50, 50, 100)
    y = np.linspace(-50, 50, 100)
    xyz = utils.ndgrid([x, y, np.r_[0]])

    # evaluate the vector potential
    a_dipole = dipole.vector_potential(xyz)
    a_loop = loop.vector_potential(xyz)

    fig, ax = plt.subplots(1, 2, figsize=(12, 5))

    # plot dipole vector potential
    plot_amplitude(ax[0], x, y, a_dipole)
    plot_streamlines(ax[0], x, y, a_dipole)

    # plot loop vector potential
    plot_amplitude(ax[1], x, y, a_loop)
    plot_streamlines(ax[1], x, y, a_loop)


    # set the titles
    ax[0].set_title("$\\vec{A}$: dipole")
    ax[1].set_title("$\\vec{A}$: loop")

    # format so text doesn't overlap
    fig.tight_layout()
    plt.show()
interactive(plot_fields, radius=(1.,40.,1.), location_x=(-40.,40.,1.),location_y=(-40.,40.,1.),location_z=(-40.,40.,1.), orientation_x=(0.,1.,0.1), orientation_y=(0.,1.,0.1), orientation_z=(0.,1.,0.1))
Loading...