File:Ringmagnet compasses.svg

Summary

{{Information

|description=

English: Pointings of magnetic compasses around a cylindrical ringmagnet. The direction of each compass needle is computed with the exact formula, given in the source code. The magnet consists of a flat cylinder of R/L=2 with a cylindrical hole of radius r/R=1/2 and is homogeneously magnetized along the cylinder axis. The north-half of the magnet is painted red, whereas the south-half is green.

|date=2022-12-16 |source=Own work |author=Geek3 |permission= |other versions= |other fields={{Igen|Python|v|+|s1=Python svgwrite code|code=

  1. !/usr/bin/python3
  2. -*- coding: utf8 -*-

try:

   import svgwrite

except ImportError:

   print('requires svgwrite library: https://pypi.org/project/svgwrite/')
   # documentation at https://svgwrite.readthedocs.io/
   exit(1)


import numpy as np from scipy.integrate import solve_ivp from scipy.optimize import minimize from math import *


name = 'Ringmagnet_compasses' size = 600, 600 R1 = 100 R2 = 200 - 1e-6 L = 100 needles_d = 40. needle_w = 6. needle_l = 16. needle_c = 2.5


def cel(kc, p, a, b):

   """
   Bulirsch complete elliptic integral
   """
   
   if kc == 0.:
       return nan
   
   tol = 1e-9 # actual relative error will be tol**2
   k = kc = fabs(kc)
   m = 1.
   
   if p > 0.:
       p = sqrt(p)
       b /= p
   else:
       f = kc * kc
       g = 1. - p
       q = (1. - f) * (b - a * p)
       f -= p
       p = sqrt(f / g)
       a = (a - b) / g
       b = a * p - q / (g * g * p)
   
   for i in range(11):
       f = a
       a += b / p
       g = k / p
       b = 2. * (b + f * g)
       p += g
       g = m
       m += kc
       
       if fabs(g - kc) <= g * tol:
           break
       
       kc = 2. * sqrt(k)
       k = kc * m
   
   return pi * .5 * (a * m + b) / (m * (m + p))


def Bfield_barmagnet(xy, R, L, M):

   # www.doi.org/10.1119/1.3256157
   rho, z = xy
   rho0 = 1.
   if rho < 0.:
       rho = -rho
       rho0 = -1.
   Rm, Rp = R - rho, R + rho
   zm, zp = z - L / 2, z + L / 2
   Rmzm = hypot(Rm, zm)
   Rmzp = hypot(Rm, zp)
   Rpzm = hypot(Rp, zm)
   Rpzp = hypot(Rp, zp)
   g = Rm / Rp
   km = Rmzm / Rpzm
   kp = Rmzp / Rpzp
   Frhom = cel(km, 1., 1., -1.) / Rpzm
   Frhop = cel(kp, 1., 1., -1.) / Rpzp
   Fzm = cel(km, g * g, 1., g) * zm / Rpzm
   Fzp = cel(kp, g * g, 1., g) * zp / Rpzp
   return M * R / pi * np.array((rho0 * (Frhop - Frhom), (Fzp - Fzm) / Rp))


def Bfield(xy):

   return Bfield_barmagnet(xy, R2, L, 1.) - Bfield_barmagnet(xy, R1, L, 1.)


  1. draw the magnet

doc = svgwrite.Drawing(name + '.svg', profile='full', size=size) doc.set_desc(name, 'https://commons.wikimedia.org/wiki/File:' + name +

   '.svg\nrights: Creative Commons Attribution ShareAlike license')

clip = doc.defs.add(doc.clipPath(id='image_clip')) clip.add(doc.rect(insert=(-size[0]/2., -size[1]/2.), size=size)) doc.add(doc.rect(id='background', insert=(0, 0), size=size, fill='#ffffff', stroke='none')) g = doc.add(doc.g(id='image', clip_path='url(#image_clip)',

   transform='translate({:.0f}, {:.0f}) scale(1,-1)'.format(size[0]/2., size[1]/2.)))

needle = doc.defs.add(doc.g(id='needle')) needle.add(doc.path(d='M {:.3f},{:.3f} L {:.3f},{:.3f} L {:.3f},{:.3f} L {:.3f},{:.3f} Z'.format(

   -needle_w, 0, 0, needle_l, needle_w, 0, 0, -needle_l),
   fill='#00cc00', stroke='none'))

needle.add(doc.path(d='M {:.3f},{:.3f} L {:.3f},{:.3f} L {:.3f},{:.3f} Z'.format(

   -needle_w, 0, 0, needle_l, needle_w, 0),
   fill='#ff0000', stroke='none'))

needle.add(doc.path(d='M {:.3f},{:.3f} L {:.3f},{:.3f} L {:.3f},{:.3f} L {:.3f},{:.3f} Z'.format(

   -needle_w, 0, 0, needle_l, needle_w, 0, 0, -needle_l),
   fill='none', stroke='#000000', stroke_width=2,
   stroke_linejoin='miter', stroke_miterlimit=10))

needle.add(doc.circle(center=(0, 0), r='{:.3f}'.format(needle_c),

   fill='#ffffff', stroke='#000000', stroke_width=2))

magnet_back = g.add(doc.g(id='magnet_back')) needles = g.add(doc.g(id='needles')) magnet_front = g.add(doc.g(id='magnet_front')) mgrad = doc.defs.add(doc.linearGradient(id="magnetGrad",

   start=(0,0), end=(1,0), gradientUnits="objectBoundingBox"))

for c, of, op in [['#000000', '0', '0.33'], ['#ffffff', '0.4', '0.2'],

       ['#ffffff', '0.75', '0.5'], ['#ffffff', '0.93', '0.125'],
       ['#000000', '1', '0.125']]:
   mgrad.add_stop_color(of, c, op)

for x0, x1, isbg in [[-R2, -R1, False], [-R1, R1, True], [R1, R2, False]]:

   if isbg:
       magnet = magnet_back
       fill = 'url(#magnetGrad)'
       colors = ['#00cc00', '#ff0000']
   else:
       magnet = magnet_front
       fill = 'none'
       colors = ['#49da49', '#ff4949']
   for i in [0, 1]:
       magnet.add(doc.rect(insert=(x0, [-L/2, 0][i]), size=(x1-x0, [L, L/2][i]),
           fill=colors[i], stroke='none'))
   magnet.add(doc.rect(insert=(x0, -L/2), size=(x1 - x0, L), fill=fill,
           stroke='#000000', stroke_width=4, stroke_linejoin='miter'))


needles_nx = round(size[0] / needles_d) needles_ny = round(size[1] / needles_d) needles_x = (np.arange(needles_nx) + 0.5) * needles_d - size[0] / 2. needles_y = (np.arange(needles_ny) + 0.5) * needles_d - size[1] / 2.

for y in needles_y:

   for x in needles_x:
       B = Bfield([x, y])
       direction = atan2(B[1], B[0])
       needles.add(doc.use(href='#needle', insert=(0, 0),
           transform='translate({:.3f},{:.3f}) rotate({:.2f})'.format(
           x, y, degrees(direction-pi/2))))


doc.save(pretty=True) }}}}

Licensing

I, the copyright holder of this work, hereby publish it under the following license:
w:en:Creative Commons
attribution share alike
This file is licensed under the Creative Commons Attribution-Share Alike 4.0 International license.
You are free:
  • to share – to copy, distribute and transmit the work
  • to remix – to adapt the work
Under the following conditions:
  • attribution – You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
  • share alike – If you remix, transform, or build upon the material, you must distribute your contributions under the same or compatible license as the original.
Category:CC-BY-SA-4.0#Ringmagnet%20compasses.svgCategory:Self-published work
Category:Field lines around magnets Category:Compass needles in magnetic fields
Category:CC-BY-SA-4.0 Category:Compass needles in magnetic fields Category:Field lines around magnets Category:Self-published work Category:Valid SVG created with Python code