123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- """Compute the magnetic field B in an iron cylinder,
- the copper wires, and the surrounding vacuum.
- Isolines of Az are also shown."""
- # https://fenicsproject.org/pub/tutorial/html/._ftut1015.html
- # conda install conda-forge::mshr
- from fenics import *
- from mshr import *
- from math import sin, cos, pi
- a = 1.0 # inner radius of iron cylinder
- b = 1.2 # outer radius of iron cylinder
- c_1 = 0.8 # radius for inner circle of copper wires
- c_2 = 1.4 # radius for outer circle of copper wires
- r = 0.1 # radius of copper wires
- R = 2.5 # radius of domain
- n = 5 # number of windings
- # Define geometry for background
- domain = Circle(Point(0, 0), R)
- # Define geometry for iron cylinder
- cylinder = Circle(Point(0, 0), b) - Circle(Point(0, 0), a)
- # Define geometry for wires (N = North (up), S = South (down))
- angles_N = [i*2*pi/n for i in range(n)]
- angles_S = [(i + 0.5)*2*pi/n for i in range(n)]
- wires_N = [Circle(Point(c_1*cos(v), c_1*sin(v)), r) for v in angles_N]
- wires_S = [Circle(Point(c_2*cos(v), c_2*sin(v)), r) for v in angles_S]
- # Set subdomain for iron cylinder
- domain.set_subdomain(1, cylinder)
- # Set subdomains for wires
- for (i, wire) in enumerate(wires_N):
- domain.set_subdomain(2 + i, wire)
- for (i, wire) in enumerate(wires_S):
- domain.set_subdomain(2 + n + i, wire)
- # Create mesh
- mesh = generate_mesh(domain, 64)
- # Define function space
- V = FunctionSpace(mesh, 'P', 1)
- # Define boundary condition
- bc = DirichletBC(V, Constant(0), 'on_boundary')
- # Define subdomain markers and integration measure
- markers = MeshFunction('size_t', mesh, 2, mesh.domains())
- dx = Measure('dx', domain=mesh, subdomain_data=markers)
- # Define current densities
- J_N = Constant(1.0)
- J_S = Constant(-1.0)
-
- # Define magnetic permeability
- class Permeability(UserExpression):
- def __init__(self, markers, **kwargs):
- self.markers = markers
- super().__init__(**kwargs)
- def eval_cell(self, values, x, cell):
- if self.markers[cell.index] == 0:
- values[0] = 4*pi*1e-7 # vacuum
- elif self.markers[cell.index] == 1:
- values[0] = 1e-5 # iron (should really be 6.3e-3)
- else:
- values[0] = 1.26e-6 # copper
- mu = Permeability(markers, degree=1)
- # Define variational problem
- A_z = TrialFunction(V)
- v = TestFunction(V)
- a = (1 / mu)*dot(grad(A_z), grad(v))*dx
- L_N = sum(J_N*v*dx(i) for i in range(2, 2 + n))
- L_S = sum(J_S*v*dx(i) for i in range(2 + n, 2 + 2*n))
- L = L_N + L_S
- # Solve variational problem
- A_z = Function(V)
- solve(a == L, A_z, bc)
- # Compute magnetic field (B = curl A)
- W = VectorFunctionSpace(mesh, 'P', 1)
- B = project(as_vector((A_z.dx(1), -A_z.dx(0))), W)
- # Plot solution
- from vedo.dolfin import plot
- plot(A_z, B,
- lw=0, # linewidth of mesh
- isolines={'n':10, 'lw':0, 'c':'black'},
- scalarbar=False,
- )
|