This page was generated from unit-11.1-fmm/BiotSavart.ipynb.
11.1.4 Biot Savart¶
Let \(G(x,y) = \frac{1}{4 \pi} \frac{\exp (i k |x-y|)}{|x-y|}\) be Green’s function for the Helmholtz equation.
For a given current path \(j\) along a Curve \(C\), the magnetic field in vacuum on the full space \({\mathbb R}^3\) is
\[H(x) = \int_C j(y) \times \nabla_y G(x,y) dl_y\]
[1]:
from ngsolve import *
from netgen.occ import *
from ngsolve.webgui import Draw
vismesh = Mesh(OCCGeometry(Box((-5,-5,-5), (5,5,5))).GenerateMesh(maxh=1))
for l in range(0):
vismesh.Refine()
Draw (vismesh)
[1]:
BaseWebGuiScene
[2]:
from ngsolve.bem import BiotSavartCF, BiotSavartSingularMLCF, BiotSavartRegularMLCF
We evaluate the single layer integral using numerical integration on the surface mesh. Thus, we get a sum of many Green’s functions, which is compressed using a multilevel-multipole.
[3]:
kappa = 0.01*pi
mp = BiotSavartSingularMLCF((0,0,0), r=5, kappa=kappa)
mp.mlmp.AddCurrent( (1,0,-1), (1,0,1), 1, num=100)
mp.mlmp.AddCurrent( (1,0, 1), (-1,0,1), 1, num=100)
mp.mlmp.AddCurrent( (-1,0, 1), (-1,0,-1), 1, num=10)
mp.mlmp.AddCurrent( (-1,0, -1), (1,0,-1), 1, num=100)
regmp = mp.CreateRegularExpansion((0,0,0),r=5)
[4]:
clipping = { "function" : False, "pnt" : (0,0,0), "vec" : (0,0,-1) }
Draw (regmp.real, vismesh, min=0, max=1, order=2, vectors={"grid_size" : 40, "offset" : 0 }, clipping=clipping);
[5]:
visplane = WorkPlane(Axes( (0,0.2,0), Z, X)).RectangleC(5,5).Face()
vismesh2 = Mesh(OCCGeometry(visplane).GenerateMesh(maxh=0.5))
Draw (regmp.real[0], vismesh2, min=-0.1, max=0.1, order=10);
[6]:
kappa = 0.01*pi
mp = BiotSavartSingularMLCF((0,0,0), r=5, kappa=kappa)
coil = Cylinder((0,-1,0), Y, r=1, h=1, mantle="outer") - Cylinder((0,-1,0), Y, r=0.5, h=1)
coilmesh = Mesh(OCCGeometry(coil).GenerateMesh(maxh=0.3)).Curve(3)
Draw (coilmesh)
current = CF((z,0,-x))
current /= Norm(current)
mp.mlmp.AddCurrentDensity(current, coilmesh.Materials(".*"))
# mp.mlmp.AddCurrentDensity(current, coilmesh.Boundaries("outer"))
regmp = mp.CreateRegularExpansion((0,0,0),r=5)
[7]:
clipping = { "function" : False, "pnt" : (0,0,0), "vec" : (0,0,-1) }
Draw (regmp.real, vismesh, min=0, max=0.2, order=2, vectors={"grid_size" : 40, "offset" : 0 }, clipping=clipping);
[8]:
Draw (regmp.real[0], vismesh2, min=-0.1, max=0.1, order=10);
the spikes inside the coil domain stem from numerical integration of the current source.
[9]:
from ngsolve.webgui import FieldLines
N=14
fl = FieldLines(mp.real, vismesh.Materials('.*'), num_lines=N**3/20, length=1)
[10]:
clipping = { "function" : False, "pnt" : (0,0,0), "vec" : (0,0,-1) }
Draw (regmp.real, vismesh, min=0, max=0.5, order=2, vectors={"grid_size" : 40, "offset" : 0 }, clipping=clipping);
[11]:
settings = {"objects": { "Surface":False, "Wireframe":False}}
clipping = {"function" : False, "pnt" : (0,0,0), "vec" : (0,0,-1) }
vectors = {"grid_size" : 100, "offset": 0.2}
Draw (mp.real, vismesh, "X", objects=[fl], min=0, max=0.5, autoscale=False, settings=settings, vectors=vectors, clipping=clipping)
[11]:
BaseWebGuiScene