Note
Go to the end to download the full example code.
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]))

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)

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()

The inductance derived from the continous current density¶
Magnetic energy of a inductor is E = 0.5*L*I^2
For unit current I=1 the inductance is L=2*E
The total current of a stream function (sf) integrated over the from minimum to maximum is dsf = max(sf) - min(sf)
When discretized to N conductors the current per conductor is I = dsf / N
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)