熱門文章

2018年5月14日 星期一

電流的磁效應

作者:王一哲
日期:2018/5/14




選修物理下第8章電流的磁效應會介紹必歐 - 沙伐定律 (Biot–Savart law),用來計算一小段載流導線於空間中某處產生的磁場,方程式為

$$ d \vec B = \frac{\mu_0}{4\pi} \frac{I d \vec L \times \hat r}{r^2} ~\Rightarrow~ dB = \frac{\mu_0}{4\pi} \frac{I dL \sin \theta}{r^2} $$

利用必歐 - 沙伐定律可以算出長直載流導線垂直距離 r 處的磁場量值為

$$ B = \frac{\mu_0 I}{2 \pi r} $$

半徑為 r 的載流線圈圓心處的磁場量值為

$$ B = \frac{\mu_0 I}{2 r} $$

單位長度中有 n 匝線圈的的載流螺線管中心處的磁場量值為

$$ B = \mu_0 nI $$

磁場應該是分布在空間中的,但是書上的圖卻都是平面的,因此我想要藉由 VPython 將空間中的磁場強度、方向畫出來,成果如下圖。


載流螺線管產生的磁場示意圖





程式 25-1.長直載流導線產生的磁場


取得程式碼
GlowScript 網站動畫連結

"""
 VPython教學: 25-1.長直載流導線產生的磁場
 Ver. 1: 2018/4/20
 Ver. 2: 2019/9/19
 作者: 王一哲
"""
from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
size = 0.4            # 導線截面的半徑
n = 200               # 導線分割成 n 等份
L = 80                # 導線長度, 畫面寬度
d = L/n               # 導線分割後每段的長度
mu = 4*pi*1E-7        # 真空中的磁導率
current = 5E8         # 電流量值
direct = True         # 電流方向, True 為姆指向右, Fasle 為姆指向左, 改變 dr 計算方式
N = 9                 # 將顯示的空間每邊切成 N 等份

"""
 2. 畫面設定
"""
# 產生動畫視窗及導線
scene = canvas(title="Magnetic Field of Current Line", width=600, height=600, x=0, y=0, 
               center=vec(0, 0.1*L, 0), background=color.black)
line = cylinder(pos=vec(-0.5*L, 0, 0), axis=vec(L, 0, 0), radius=0.2*size, color=color.blue)

# 產生串列 segs, 用 for 迴圈產生導線分割後的小球並填入串列 segs 中
#segs = []
#for i in range(n+1):
#    segs.append(sphere(pos=line.pos + vec(i*d, 0, 0), radius=size, color=color.cyan))
segs = [sphere(pos=line.pos + vec(i*d, 0, 0), radius=size, color=color.cyan) for i in range(n+1)]

# 計算畫箭頭的位置並加到串列 locations 當中
locations = []
for i in range(N+1):
    for j in range(N+1):
        for k in range(N+1):
            location = vec(L/N*i - L/2, L/N*j - L/2, L/N*k - L/2)
            locations.append(location)

# 自訂函式 magnetic, 計算某個位置的磁場
def magnetic(loc, segments):
    field = vec(0, 0, 0)
    for segment in segments:
        axis = loc - segment.pos
        if(direct): dr = vec(1, 0, 0)
        else: dr = vec(-1, 0, 0)
        field += mu*current/(4*pi)*d*cross(dr, axis.norm())/axis.mag2
    return field

# 依序讀取串列 locations 的元素, 在對應的位置產生箭頭
#fields = []
#for location in locations:
#    fields.append(arrow(pos=location, axis=vec(0, 0, 0), color=color.green))
fields = [arrow(pos=location, axis=vec(0, 0, 0), color=color.green) for location in locations]

# 更新箭頭的長度及方向, 記錄磁場強度最大值, 量值接近最大值偏紅色, 量值接近 0 偏綠色
Bmax = 0
for field in fields:
    value = magnetic(field.pos, segs)
    if(value.mag >= Bmax): Bmax = value.mag
    field.axis = value

for field in fields:
    field.color = vec(field.axis.mag/Bmax, 1 - field.axis.mag/Bmax, 0)




參數設定


在此設定變數為 size、n、L、d、mu、current、direct、N,用途已寫在該行的註解當中。為了增加磁場量值,使箭頭的長度較為明顯,設定的電流量值非常地大。




畫面設定


  1. 產生動畫視窗及導線。
  2. 產生空白串列 segs,用 for 迴圈產生導線分割後的小球並填入串列 segs 中。以下兩種寫法的效果相同,第一種寫法行數較多但比較容易看懂,第二種寫法比較精簡但是不容易看懂。
    segs = []
    for i in range(n+1):
        segs.append(sphere(pos=line.pos + vec(i*d, 0, 0), radius=size, color=color.cyan))
    
    segs = [sphere(pos=line.pos + vec(i*d, 0, 0), radius=size, color=color.cyan) for i in range(n+1)]
    
  3. 產生空白串列 locations,使用 3 層的 for 迴圈計算畫箭頭的位置並加到串列 locations 當中,同樣有兩種寫法。
    fields = []
    for location in locations:
        fields.append(arrow(pos=location, axis=vec(0, 0, 0), color=color.green))
    
    fields = [arrow(pos=location, axis=vec(0, 0, 0), color=color.green) for location in locations]
  4. 自訂函式 magnetic,輸入的參數 loc 是要計算磁場的位置坐標,segments 儲存分割後導線資料的串列,利用必歐 - 沙伐定律計算磁場。
  5. 依序讀取串列 locations 的元素,在對應的位置產生箭頭。
  6. 更新箭頭的長度及方向,記錄磁場強度最大值 Bmax,量值接近最大值箭頭偏紅色, 量值接近 0 箭頭偏綠色。




模擬結果


試著修改 n、L、N 的數值,找出視覺效果較好的組合。有時候程式會出現錯誤,這是因為箭頭的位置正好在導線上,分母為0,如果要徹底避免這個錯誤,應該要加上一段程式碼,檢查箭頭與導線的位置是否重疊。


程式 25-1:n = 100, L = 40, N = 5 畫面截圖




程式 25-1:n = 200, L = 80, N = 9 畫面截圖




程式 25-1:n = 200, L = 80, N = 9, 電流向左畫面截圖



程式 25-2.載流線圈產生的磁場


取得程式碼
GlowScript 網站動畫連結

"""
 VPython教學: 25-2.載流線圈產生的磁場
 Ver. 1: 2018/4/10
 Ver. 2: 2018/4/20 可調整範圍
 Ver. 3: 2019/9/19
 作者: 王一哲
"""
from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
size = 0.4            # 線圈截面的半徑
r = 10                # 線圈的半徑
n = 100               # 線圈分割成 n 等份
part = 1.0            # 完整的線圈 part = 1
d = 2*pi*r*part/n     # 線圈分割後每段的長度
mu = 4*pi*1E-7        # 真空中的磁導率
current = 5E8         # 電流量值
direct = True         # 電流方向, True 為姆指向上, Fasle 為姆指向下, 改變 dr 計算方式
L = 40                # 畫面寬度
N = 5                 # 將顯示的空間每邊切成 N 等份
Bmax = 5              # 顯示的磁場最大值

"""
 2. 畫面設定
"""
# 產生動畫視窗及線圈
scene = canvas(title="Magnetic Field of Current Loop", width=600, height=600, x=0, y=0, 
               center=vec(0, 0.1*L, 0), background=color.black)
loop = ring(pos=vec(0, 0, 0), axis=vec(0, 1, 0), radius=r, thickness=0.2*size, color=color.blue)

# 產生串列 segs, 用 for 迴圈產生圓環分割後的小球並填入串列 segs 中
segs = [sphere(pos=vec(r*cos(i*2*pi*part/n), 0, -r*sin(i*2*pi*part/n)), radius=size, color=color.cyan) for i in range(n)]

# 計算畫箭頭的位置並加到串列 locations 當中
locations = []
for i in range(N+1):
    for j in range(N+1):
        for k in range(N+1):
            location = vec(L/N*i - L/2, L/N*j - L/2, L/N*k - L/2)
            locations.append(location)

# 自訂函式 magnetic, 計算某個位置的磁場
def magnetic(loc, segments):
    field = vec(0, 0, 0)
    for segment in segments:
        axis = loc - segment.pos
        if(direct): dr = norm(vec(segment.pos.z, 0, -segment.pos.x))
        else: dr = norm(vec(-segment.pos.z, 0, segment.pos.x))
        field += mu*current/(4*pi)*d*cross(dr, axis.norm())/axis.mag2
    return field

# 依序讀取串列 locations 的元素, 在對應的位置產生箭頭
fields = [arrow(pos=location, axis=vec(0, 0, 0), color=color.green) for location in locations]

# 更新箭頭的長度及方向, 若磁場量值 >= Bmax 則設定為 Bmax, 以避免箭頭蓋住其它東西
# 量值接近 Bmax 偏紅色, 量值接近 0 偏綠色
for field in fields:
    value = magnetic(field.pos, segs)
    if(value.mag >= Bmax): value = value.norm() * Bmax
    field.axis = value
    field.color = vec(value.mag/Bmax, 1 - value.mag/Bmax, 0)



程式設計部分


程式 25-2 與 25-1 非常相似,以下只說明不同之處。

  1. 在此設定變數為 size、r、n、part、d、mu、current、direct、L、N、Bmax。由於磁場量值差異很大,因此將 Bmax 直接設定好,而不是從計算得到的值當中找最大值。
  2. 使用 ring 物件產生線圈。
  3. 圓環分割後的小球由 (r, 0, 0) 開始擺放,若由 +y 軸向原點看去,擺放的方向為逆時鐘方向,因此位置設定為
    (r*cos(i*2*pi*part/n), 0, -*sin(i*2*pi*part/n))
    
  4. 在自訂函式中若電流為逆時鐘方向,也就是 direct = True,則 dr 設定為
    norm(vec(segment.pos.z, 0, -segment.pos.x))
    
    反之設定為
    norm(vec(-segment.pos.z, 0, segment.pos.x))
    




模擬結果


修改 part 的數值,可以畫出不同比例的載流線圈產生的磁場,例如 part = 0.25 代表 1/4 個線圈。也可以修改 direct 控制電流的方向,觀察電方向對磁場的影響。


程式 25-2: 1/4 個載流線圈磁場示意圖




程式 25-2: 半個載流線圈磁場示意圖




程式 25-2: 3/4 個載流線圈磁場示意圖




程式 25-2: 整個載流線圈磁場示意圖




程式 25-2: 整個載流線圈磁場示意圖(電流為順時鐘方向)



程式 25-3.2個載流線圈產生的磁場


取得程式碼
GlowScript 網站動畫連結

"""
 VPython教學: 25-3.2個載流線圈產生的磁場
 Ver. 1: 2018/4/11
 Ver. 2: 2018/4/20 可調整範圍
 Ver. 3: 2019/9/19
 作者: 王一哲
"""
from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
size = 0.4            # 線圈截面的半徑
r = 10                # 線圈的半徑
n = 100               # 線圈分割成 n 等份
part = 1.0            # 完整的線圈 part = 1
d = 2*pi*r*part/n     # 線圈分割後每段的長度
delta = r             # 線圈圓心之間的距離為 2*delta
mu = 4*pi*1E-7        # 真空中的磁導率
current = 5E8         # 電流量值
direct = True         # 電流方向, True 為姆指向上, Fasle 為姆指向下, 改變 dr 計算方式
L = 40                # 畫面寬度
N = 5                 # 將顯示的空間每邊切成 N 等份
Bmax = 5              # 顯示的磁場最大值

"""
 2. 畫面設定
"""
# 產生動畫視窗及線圈
scene = canvas(title="Magnetic Field of Two Current Loops", width=600, height=600, x=0, y=0, 
               center=vec(0, 0.1*L, 0), background=color.black)
loop1 = ring(pos=vec(0, delta, 0), axis=vec(0, 1, 0), radius=r, thickness=0.2*size, color=color.blue)
loop2 = ring(pos=vec(0, -delta, 0), axis=vec(0, 1, 0), radius=r, thickness=0.2*size, color=color.blue)

# 產生串列 segs, 用 for 迴圈產生圓環分割後的小球並填入串列 segs 中
segs1, segs2 = [], []
for i in range(n):
    segs1.append(sphere(pos=vec(r*cos(i*2*pi*part/n), delta, -r*sin(i*2*pi*part/n)), radius=size, color=color.cyan))
    segs2.append(sphere(pos=vec(r*cos(i*2*pi*part/n), -delta, -r*sin(i*2*pi*part/n)), radius=size, color=color.cyan))

# 計算畫箭頭的位置並加到串列 locations 當中
locations = []
for i in range(N+1):
    for j in range(N+1):
        for k in range(N+1):
            location = vec(L/N*i - L/2, L/N*j - L/2, L/N*k - L/2)
            locations.append(location)

# 自訂函式 magnetic, 計算某個位置的磁場
def magnetic(loc, segments):
    field = vec(0, 0, 0)
    for segment in segments:
        axis = loc - segment.pos
        if(direct): dr = norm(vec(segment.pos.z, 0, -segment.pos.x))
        else: dr = norm(vec(-segment.pos.z, 0, segment.pos.x))
        field += mu*current/(4*pi)*d*cross(dr, axis.norm())/axis.mag2
    return field

# 依序讀取串列 locations 的元素, 在對應的位置產生箭頭
fields = [arrow(pos = location, axis = vec(0, 0, 0), color = color.green) for location in locations]

# 更新箭頭的長度及方向, 若磁場量值 >= Bmax 則設定為 Bmax, 以避免箭頭蓋住其它東西
# 量值接近 Bmax 偏紅色, 量值接近 0 偏綠色
for field in fields:
    value1 = magnetic(field.pos, segs1)
    value2 = magnetic(field.pos, segs2)
    value = value1 + value2
    if(value.mag >= Bmax): value = value/value.mag * Bmax
    field.axis = value
    field.color = vec(value.mag/Bmax, 1 - value.mag/Bmax, 0)




程式設計部分


程式 25-3 主要是為了畫出亥姆霍茲線圈 (Helmholtz coil) 的磁場,以 25-2 為基礎再加上另一個線圈,以下只說明不同之處。

  1. 由於要再加上另一個線圈,需要多定義變數 delta,用來調整線圈之間的距離。兩個線圈分別位於 (0, delta, 0) 及 (0, -delta, 0) 處。
  2. 圓環分割後的小球擺放方式不變,但兩個線圈分割後的小球資料分別儲存於兩個串列中。
  3. 計算磁場時需要分別將 segs1 及 segs2 的資料代入自訂函式中,再算出磁場總合。



模擬結果


由於亥姆霍茲線圈通常是完整的圓周,因此只調整 delta 和電流方向,觀察磁場的變化。


程式 25-3: delta = r/2 磁場示意圖(電流為逆時鐘方向)




程式 25-3: delta = r/2 磁場示意圖(電流為順時鐘方向)




程式 25-3: delta = r 磁場示意圖(電流為逆時鐘方向)




程式 25-3: delta = r 磁場示意圖(電流為順時鐘方向)



程式 25-4.載流螺線管產生的磁場


取得程式碼
GlowScript 網站動畫連結

"""
 VPython教學: 25-4.載流螺線管產生的磁場
 Ver. 1: 2018/4/21
 Ver. 2: 2019/9/19
 作者: 王一哲
"""
from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
size = 0.4            # 螺線管截面的半徑
point_size = 0.2*size # 螺線管導線分割後標示位置用的小球半徑, 若要使小球較明顯設為1倍, 若要隱藏設為0.2倍
seg_size = 1.0*size   # 螺線管導線分割後每一小段導線的半徑, 若要使導線較明顯設為1倍, 若要隱藏設為0.2倍
r = 10                # 螺線管的半徑
n = 500               # 螺線管分割成 n 等份
num = 10              # 螺線管匝數
mu = 4*pi*1E-7        # 真空中的磁導率
current = 1E8         # 電流量值
direct = True         # 電流方向, True 為姆指向右, Fasle 為姆指向左, 改變 segment.axis 計算方式
L = 40                # 畫面寬度
N = 5                 # 將顯示的空間每邊切成 N 等份
Bmax = 5              # 顯示的磁場最大值

"""
 2. 畫面設定
"""
# 產生動畫視窗
scene = canvas(title="Magnetic Field of Current Solenoid", width=600, height=600, x=0, y=0, 
               center=vec(0, 0.1*L, 0), background=color.black)

# 產生空白串列 points, 在螺線管上等距離取點並填入 points 中
points = [sphere(pos=vec(L/2 - i*L/n, r*cos(2*pi/n*num*i), r*sin(2*pi/n*num*i)), radius=point_size, color=color.cyan) for i in range(n)]

# 產生空白串列 segs, 從 points 依序一次讀取兩個點, 計算軸向量, 中點位置, 將螺線管切成很多小圓柱並填入 segs 中
segs = []
for i in range(n-1):
    if(direct): dis = points[i+1].pos - points[i].pos
    else: dis = points[i].pos - points[i+1].pos
    mid = (points[i+1].pos + points[i].pos)/2
    segs.append(cylinder(pos = mid, axis = dis, radius = seg_size, color = color.yellow))

# 計算畫箭頭的位置並加到串列 locations 當中
locations = []
for i in range(N+1):
    for j in range(N+1):
        for k in range(N+1):
            location = vec(L/N*i - L/2, L/N*j - L/2, L/N*k - L/2)
            locations.append(location)

# 自訂函式 magnetic, 計算某個位置的磁場
def magnetic(loc, segments):
    field = vec(0, 0, 0)
    for segment in segments:
        axis = loc - segment.pos
        field += mu*current/(4*pi)*segment.axis.mag*cross(segment.axis, axis.norm())/axis.mag2
    return field

# 依序讀取串列 locations 的元素, 在對應的位置產生箭頭
fields = [arrow(pos=location, axis=vec(0, 0, 0), color=color.green) for location in locations]

# 更新箭頭的長度及方向, 若磁場量值 >= Bmax 則設定為 Bmax, 以避免箭頭蓋住其它東西
# 量值接近 Bmax 偏紅色, 量值接近 0 偏綠色
for field in fields:
    value = magnetic(field.pos, segs)
    if(value.mag >= Bmax): value = value/value.mag * Bmax
    field.axis = value
    field.color = vec(value.mag/Bmax, 1 - value.mag/Bmax, 0)




程式設計部分


程式 25-4 是以 25-2 為基礎修改而成,以下只說明不同之處。

  1. 新增變數為小球的半徑 point_size、導線的半徑 seg_size、螺線管的半徑 r、螺線管的匝數 num。
  2. 用 for 迴圈將 500 個小球排成縲旋線,將資料存入串列 points。
  3. 用 for 迴圈從串列 points 中一次讀取相鄰的兩個小球,計算兩球連線長度與方向,以兩球的中點為起點畫出導線,將資料存入串列 segs。




模擬結果


我只畫出兩種不同電流方向的磁場示意圖,可以試著改變其它參數,看看會有什麼變化。


程式25-4:螺線管中心處磁場向左,將小球半徑調大




程式25-4:螺線管中心處磁場向左,從側面看螺線管




程式25-4:螺線管中心處磁場向左,從左側開口處看螺線管




程式25-4:螺線管中心處磁場向右,從側面看螺線管




程式25-4:螺線管中心處磁場向右,從左側開口處看螺線管



結語


這是目前已經做好的 VPython 動畫講義的最後一篇,同學們可以試著依據這些動畫為基礎,修改成自己想要的樣子,解決自己想要研究的物理問題。




VPython官方說明書


  1. canvas: http://www.glowscript.org/docs/VPythonDocs/canvas.html
  2. sphere: http://www.glowscript.org/docs/VPythonDocs/sphere.html
  3. cylinder: http://www.glowscript.org/docs/VPythonDocs/cylinder.html
  4. ring: http://www.glowscript.org/docs/VPythonDocs/ring.html
  5. arrow: http://www.glowscript.org/docs/VPythonDocs/arrow.html



HackMD 版本連結:https://hackmd.io/@yizhewang/r1g8P0uf7

沒有留言:

張貼留言