Mutual inductance of wire loops

In this example, we demonstrate how to compute the mutual inductance between two sets of polyline wire loops.

import pyvista as pv

pv.set_plot_theme("document")


from bfieldtools.line_conductor import LineConductor
from bfieldtools.mesh_conductor import StreamFunction
from bfieldtools.suhtools import SuhBasis
from bfieldtools.utils import load_example_mesh

import numpy as np

We create a set of wire loops by picking a single (arbitrary) surface-harmonic mode from a plane mesh. Finally, we discretize the mode into a set of wire loops, which we plot.

mesh = load_example_mesh("10x10_plane")
mesh.apply_scale(0.1)  # Downsize from 10 meters to 1 meter
N_contours = 20

sb = SuhBasis(mesh, 10)  # Construct surface-harmonics basis
sf = StreamFunction(
    sb.basis[:, 1], sb.mesh_conductor
)  # Turn single mode into a stream function
c = LineConductor(
    mesh=mesh, scalars=sf, N_contours=N_contours
)  # Discretize the stream function into wire loops


# Plot loops for testing
c.plot_loops(origin=np.array([0, -100, 0]))
line conductor inductance
Calculating surface harmonics expansion...
Computing the laplacian matrix...
Computing the mass matrix...
Processing contour, value: -2.0487448636242185
Processing contour, value: -1.8330897283127965
Processing contour, value: -1.6174345930013745
Processing contour, value: -1.4017794576899525
Processing contour, value: -1.1861243223785305
Processing contour, value: -0.9704691870671087
Processing contour, value: -0.7548140517556867
Processing contour, value: -0.539158916444265
Processing contour, value: -0.32350378113284295
Processing contour, value: -0.10784864582142095
Processing contour, value: 0.10780648949000105
Processing contour, value: 0.3234616248014226
Processing contour, value: 0.5391167601128446
Processing contour, value: 0.7547718954242666
Processing contour, value: 0.9704270307356886
Processing contour, value: 1.1860821660471106
Processing contour, value: 1.4017373013585321
Processing contour, value: 1.6173924366699541
Processing contour, value: 1.8330475719813761
Processing contour, value: 2.0487027072927977

<pyvista.plotting.plotter.Plotter object at 0x7f1299f90910>

Now, we create a shifted copy of the wire loops, and the calculate the mutual_inductance between two sets of line conductors

mesh2 = mesh.copy()
mesh2.vertices[:, 1] += 1
c2 = LineConductor(mesh=mesh2, scalars=sf, N_contours=N_contours)
fig = c.plot_loops(origin=np.array([0, -100, 0]))
c2.plot_loops(figure=fig, origin=np.array([0, -100, 0]))

Mself = c.line_mutual_inductance(c, separate_loops=True, radius=1e-3)
M2 = c.line_mutual_inductance(c2, separate_loops=True)
line conductor inductance
Processing contour, value: -2.0487448636242185
Processing contour, value: -1.8330897283127965
Processing contour, value: -1.6174345930013745
Processing contour, value: -1.4017794576899525
Processing contour, value: -1.1861243223785305
Processing contour, value: -0.9704691870671087
Processing contour, value: -0.7548140517556867
Processing contour, value: -0.539158916444265
Processing contour, value: -0.32350378113284295
Processing contour, value: -0.10784864582142095
Processing contour, value: 0.10780648949000105
Processing contour, value: 0.3234616248014226
Processing contour, value: 0.5391167601128446
Processing contour, value: 0.7547718954242666
Processing contour, value: 0.9704270307356886
Processing contour, value: 1.1860821660471106
Processing contour, value: 1.4017373013585321
Processing contour, value: 1.6173924366699541
Processing contour, value: 1.8330475719813761
Processing contour, value: 2.0487027072927977

Now, we plot the inductance matrices

import matplotlib.pyplot as plt

ff, ax = plt.subplots(1, 2, figsize=(12, 8))
plt.sca(ax[0])
plt.matshow(Mself, fignum=0)
plt.title("Inductance matrix of the first set of wire loops")
plt.sca(ax[1])
plt.matshow(M2, fignum=0)
plt.title("Mutual inductance matrix between the sets of wire loops")

ff.tight_layout()
Inductance matrix of the first set of wire loops, Mutual inductance matrix between the sets of wire loops

The inductance derived from the continous current density

  1. Magnetic energy of a inductor is E = 0.5*L*I^2

  2. For unit current I=1 the inductance is L=2*E

  3. The total current of a stream function (sf) integrated over the from minimum to maximum is dsf = max(sf) - min(sf)

  4. When discretized to N conductors the current per conductor is I = dsf / N

  5. When sf is normalized such that I=1, i.e., dsf = N the inductance approximated by the continous stream function is L = 2*sf.magnetic_energy

scaling = N_contours / (sf.max() - sf.min())
L_approx = 2 * sf.magnetic_energy * (scaling**2)

print("Inductance based on the continuous current density", L_approx)
print("Inductance based on r=1mm wire", np.sum(Mself))

# Display the assembled scene (Sphinx-Gallery captures it during docs builds).
if "plotter" in globals() and not plotter._closed:
    plotter.show()
Computing the inductance matrix...
Computing self-inductance matrix using rough quadrature (degree=2).              For higher accuracy, set quad_degree to 4 or more.
Estimating 2432 MiB required for 676 by 676 vertices...
Computing inductance matrix in 20 chunks (14188 MiB memory free),              when approx_far=True using more chunks is faster...
Computing triangle-coupling matrix
Inductance matrix computation took 1.40 seconds.
Inductance based on the continuous current density 8.693078122415806e-05
Inductance based on r=1mm wire 9.793656532367407e-05

Total running time of the script: (0 minutes 9.746 seconds)

Gallery generated by Sphinx-Gallery