日期: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,用途已寫在該行的註解當中。為了增加磁場量值,使箭頭的長度較為明顯,設定的電流量值非常地大。
畫面設定
- 產生動畫視窗及導線。
- 產生空白串列 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,使用 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]
- 自訂函式 magnetic,輸入的參數 loc 是要計算磁場的位置坐標,segments 儲存分割後導線資料的串列,利用必歐 - 沙伐定律計算磁場。
- 依序讀取串列 locations 的元素,在對應的位置產生箭頭。
- 更新箭頭的長度及方向,記錄磁場強度最大值 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 非常相似,以下只說明不同之處。
- 在此設定變數為 size、r、n、part、d、mu、current、direct、L、N、Bmax。由於磁場量值差異很大,因此將 Bmax 直接設定好,而不是從計算得到的值當中找最大值。
- 使用 ring 物件產生線圈。
- 圓環分割後的小球由 (r, 0, 0) 開始擺放,若由 +y 軸向原點看去,擺放的方向為逆時鐘方向,因此位置設定為
(r*cos(i*2*pi*part/n), 0, -*sin(i*2*pi*part/n))
- 在自訂函式中若電流為逆時鐘方向,也就是 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 為基礎再加上另一個線圈,以下只說明不同之處。
- 由於要再加上另一個線圈,需要多定義變數 delta,用來調整線圈之間的距離。兩個線圈分別位於 (0, delta, 0) 及 (0, -delta, 0) 處。
- 圓環分割後的小球擺放方式不變,但兩個線圈分割後的小球資料分別儲存於兩個串列中。
- 計算磁場時需要分別將 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 為基礎修改而成,以下只說明不同之處。
- 新增變數為小球的半徑 point_size、導線的半徑 seg_size、螺線管的半徑 r、螺線管的匝數 num。
- 用 for 迴圈將 500 個小球排成縲旋線,將資料存入串列 points。
- 用 for 迴圈從串列 points 中一次讀取相鄰的兩個小球,計算兩球連線長度與方向,以兩球的中點為起點畫出導線,將資料存入串列 segs。
模擬結果
我只畫出兩種不同電流方向的磁場示意圖,可以試著改變其它參數,看看會有什麼變化。
程式25-4:螺線管中心處磁場向左,將小球半徑調大
程式25-4:螺線管中心處磁場向左,從側面看螺線管
程式25-4:螺線管中心處磁場向左,從左側開口處看螺線管
程式25-4:螺線管中心處磁場向右,從側面看螺線管
程式25-4:螺線管中心處磁場向右,從左側開口處看螺線管
結語
這是目前已經做好的 VPython 動畫講義的最後一篇,同學們可以試著依據這些動畫為基礎,修改成自己想要的樣子,解決自己想要研究的物理問題。
VPython官方說明書
- canvas: http://www.glowscript.org/docs/VPythonDocs/canvas.html
- sphere: http://www.glowscript.org/docs/VPythonDocs/sphere.html
- cylinder: http://www.glowscript.org/docs/VPythonDocs/cylinder.html
- ring: http://www.glowscript.org/docs/VPythonDocs/ring.html
- arrow: http://www.glowscript.org/docs/VPythonDocs/arrow.html
HackMD 版本連結:https://hackmd.io/@yizhewang/r1g8P0uf7
沒有留言:
張貼留言