熱門文章

2018年5月11日 星期五

速度選擇器

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




速度選擇器是用來篩選具有特定速度帶電粒子的裝置,基本的構造如下圖。用兩塊平行帶電板製造向下的電場,再加上垂直射入紙面的磁場,若帶正電的粒子由左側以水平速度 v 進入速度選擇器,粒子會受到向下的靜電力以及向上的磁力,當合力為零時粒子等速度前進,此時

$$ qE = qvB ~\Rightarrow~ v = \frac{E}{B} = \frac{V}{Bd} $$

如果在右側加上只有一個小孔的擋板,只有向右直線前進的粒子可以通過,就可以藉由改變電場、磁場的量值控制通過裝置的粒子速度量值。以下共有兩個程式:

  1. 程式20-1:畫電場、磁場、平行帶電板、粒子運動軌跡出來,粒子撞到平行帶電板後停止運動。
  2. 程式20-2:以20-1為基礎,於出口處加上擋板。





速度選擇器構造示意圖





程式 20-1.速度選擇器


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

"""
 VPython教學: 20-1.速度選擇器
 Ver. 1: 2018/4/7
 Ver. 2: 2019/9/16
 作者: 王一哲
"""
from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
size, m, v0, q = 0.005, 1E-10, 10, 1E-9  # 粒子半徑, 質量, 水平速度, 電量
V, d, L, B = 1, 0.1, 0.2, 1 # 平行帶電板間的電壓, 距離, 長度, 外加磁場強度
E_field = vec(0, -V/d, 0)   # 電場
B_field = vec(0, 0, -B)     # 磁場
t, dt = 0, 1E-5             # 時間, 時間間隔

"""
 2. 畫面設定
"""
# 產生動畫視窗、平行帶電板、水平線、帶電粒子
scene = canvas(title="Velocity Selector", width=800, height=600, x=0, y=0, center=vec(0, 0, 0), background=color.black)
p1 = box(pos=vec(0, d/2, 0), size=vec(L, 0.01*L, L), color=color.blue)
p2 = box(pos=vec(0, -d/2, 0), size=vec(L, 0.01*L, L), color=color.blue)
line = cylinder(pos=vec(-L, 0, 0), radius=0.1*size, axis=vec(2*L, 0, 0), color=color.yellow)
charge = sphere(pos=vec(-L, 0, 0), v=vec(v0, 0, 0), radius=size, color=color.red, m=m, make_trail=True)
# 產生表示電場、磁場的箭頭及標籤
arrow_E = arrow(pos=vec(-L/2, d/2, 0), axis=vec(0, -0.1, 0), shaftwidth=size, color=color.green)
arrow_B = arrow(pos=vec(-L/2, 0, d/2), axis=vec(0, 0, -0.1), shaftwidth=size, color=color.orange)
label_E = label(pos=vec(-L/2, d/2, 0), text="E", xoffset=-25, yoffset=25, color=color.green, font="sans")
label_B = label(pos=vec(-L/2, 0, d/2), text="B", xoffset=-25, yoffset=-25, color=color.orange, font="sans")
# 產生表示速度、加速度的箭頭
arrow_v = arrow(pos=charge.pos, shaftwidth=0.3*size, color=color.cyan)
arrow_a = arrow(pos=charge.pos, shaftwidth=0.3*size, color=color.magenta)

"""
 3. 物體運動部分, 當帶電粒子到達畫面最右側或撞到平行帶電板時停止
"""
while(charge.pos.x < L and abs(charge.pos.y) < d/2 - p1.height - size):
    rate(500)
# 計算帶電粒子所受合力, 在平行帶電板間才有電場、磁場
    if(-L/2 <= charge.pos.x <= L/2): F = q*(E_field + cross(charge.v, B_field))
    else: F = vec(0, 0, 0)
# 更新帶電粒子加速度、速度、位置
    charge.a = F/charge.m
    charge.v += charge.a*dt
    charge.pos += charge.v*dt
# 更新表示速度、加速度的箭頭, 只畫出方向以避免動畫自動縮小
    arrow_v.pos = charge.pos
    arrow_a.pos = charge.pos
    arrow_v.axis = charge.v.norm()*0.05
    arrow_a.axis = charge.a.norm()*0.05
# 更新時間
    t += dt




參數設定


在此設定變數為size、m、v0、q、V、d、L、B、E_field、B_field、t、dt,用途已寫在該行的註解當中。為了使動畫較為順暢,粒子的加速度不能太大,因此粒子的質量比真實的原子核質量大很多。




畫面設定


  1. 生動畫視窗、平行帶電板、水平線、帶電粒子。
  2. 產生表示速度、加速度的箭頭。
  3. 產生表示電場、磁場的箭頭及標籤。標籤的語法為
    [標籤名稱] = label(pos=[位置向量], text="[標籤內容]", xoffset=[x方向位移量], yoffset=[y方向位移量], color=[顏色名稱或RGB值], font="[字體名稱]")
    []中的內容請換成自己需要的參數。
  4. 開啟繪圖視窗,畫小球的位置、速度、加速度與時間關係圖。




物體運動


  1. 為了使動畫在帶電粒子到達畫面最右側或撞到平行帶電板時停止,將 while 迴圈當中的條件設定為 charge.pos.x < L and abs(charge.pos.y) < d/2 - p1.height - size
  2. 計算帶電粒子所受合力,由於平行帶電板間才有電場、磁場,在平行帶電板外設為零。計算帶電粒子所受合力的數學式為 $\vec F = q(\vec E + \vec v \times \vec B)$,對應的程式碼為
    F = q*(E_field + cross(charge.v, B_field))
  3. 更新帶電粒子加速度、速度、位置。
  4. 更新表示速度、加速度的箭頭,只畫出方向以避免動畫自動縮小。
  5. 更新時間。




模擬結果


以下是5種不同的數據組合及測試結果:

  1. v0 = 10, V = 1, d = 0.1, B = 1 ⇒ 等速度直線運動
  2. q > 0, v0 = 20 其它條件與組合1相同 ⇒ 向上偏移
  3. q > 0, d = 0.2 其它條件與組合1相同 ⇒ 向上偏移
  4. q > 0, V = 2 其它條件與組合1相同 ⇒ 向下偏移
  5. q > 0, B = 5 其它條件與組合1相同 ⇒ 向上偏移




程式 20-1 數據組合1畫面截圖




程式 20-1 數據組合2畫面截圖




程式 20-1 數據組合3畫面截圖




程式 20-1 數據組合4畫面截圖




程式 20-1 數據組合5畫面截圖



程式 20-2.速度選擇器, 加上出口處的擋板


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

"""
 VPython教學: 20-2.速度選擇器, 加上出口處的擋板
 Ver. 1: 2018/5/10
 Ver. 2: 201/9/16
 作者: 王一哲
"""
from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
size, m, v0, q = 0.005, 1E-10, 10, 1E-9  # 粒子半徑, 質量, 水平速度, 電量
V, d, L, B = 1, 0.1, 0.2, 1 # 平行帶電板間的電壓, 距離, 長度, 外加磁場強度
E_field = vec(0, -V/d, 0)   # 電場
B_field = vec(0, 0, -B)     # 磁場
t, dt = 0, 1E-5             # 時間, 時間間隔

"""
 2. 畫面設定
"""
# 產生動畫視窗、平行帶電板、出口處的擋板、水平線、帶電粒子
scene = canvas(title="Velocity Selector", width=800, height=600, x=0, y=0, center=vec(0, 0, 0), background=color.black)
p1 = box(pos=vec(0, d/2, 0), size=vec(L, 0.01*L, L), color=color.blue)
p2 = box(pos=vec(0, -d/2, 0), size=vec(L, 0.01*L, L), color=color.blue)
b1 = box(pos=vec(L/2, d/4 + size, 0), size=vec(0.01*L, 0.5*d, L), color = color.gray(0.7))
b2 = box(pos=vec(L/2, -d/4 - size, 0), size=vec(0.01*L, 0.5*d, L), color = color.gray(0.7))
line = cylinder(pos=vec(-L, 0, 0), radius=0.1*size, axis=vec(2*L, 0, 0), color=color.yellow)
charge = sphere(pos=vec(-L, 0, 0), v=vec(v0, 0, 0), radius=size, color=color.red, m=m, make_trail=True)
# 產生表示電場、磁場的箭頭及標籤
arrow_E = arrow(pos=vec(-L/2, d/2, 0), axis=vec(0, -0.1, 0), shaftwidth=size, color=color.green)
arrow_B = arrow(pos=vec(-L/2, 0, d/2), axis=vec(0, 0, -0.1), shaftwidth=size, color=color.orange)
label_E = label(pos=vec(-L/2, d/2, 0), text="E", xoffset=-25, yoffset=25, color=color.green, font="sans")
label_B = label(pos=vec(-L/2, 0, d/2), text="B", xoffset=-25, yoffset=-25, color=color.orange, font="sans")
# 產生表示速度、加速度的箭頭
arrow_v = arrow(pos=charge.pos, shaftwidth=0.3*size, color=color.cyan)
arrow_a = arrow(pos=charge.pos, shaftwidth=0.3*size, color=color.magenta)

"""
 3. 物體運動部分, 當帶電粒子到達畫面最右側、撞到平行帶電板或撞到擋板時停止
"""
while((charge.pos.x + size + b1.length/2 < L/2 and abs(charge.pos.y) < d/2 - p1.height - size) or \
      (L/2 < charge.pos.x + size + b1.length/2 < L and abs(charge.pos.y) < 0.1*size)):
    rate(500)
# 計算帶電粒子所受合力, 在平行帶電板間才有電場、磁場
    if(-L/2 <= charge.pos.x <= L/2): F = q*(E_field + cross(charge.v, B_field))
    else: F = vector(0, 0, 0)
# 更新帶電粒子加速度、速度、位置
    charge.a = F/charge.m
    charge.v += charge.a*dt
    charge.pos += charge.v*dt
# 更新表示速度、加速度的箭頭, 只畫出方向以避免動畫自動縮小
    arrow_v.pos = charge.pos
    arrow_a.pos = charge.pos
    arrow_v.axis = charge.v.norm()*0.05
    arrow_a.axis = charge.a.norm()*0.05
# 更新時間
    t += dt




程式設計部分


實際上只修改了3處:

    在出口處加上擋板
    b1 = box(pos=vec(L/2, d/4 + size, 0), size=vec(0.01*L, 0.5*d, L), color = color.gray(0.7))
    b2 = box(pos=vec(L/2, -d/4 - size, 0), size=vec(0.01*L, 0.5*d, L), color = color.gray(0.7))
    
  1. while 迴圈運作的條作改為
    (charge.pos.x + size + b1.length/2 < L/2 and abs(charge.pos.y) < d/2 - p1.height - size) or \
    (L/2 < charge.pos.x + size + b1.length/2 < L and abs(charge.pos.y) < 0.1*size)
    
    1. 第1個部分的效果:當粒子在平行帶電板之間,如果還沒有撞到平行帶電板則動畫繼續進行。
    2. 第2個部分的效果:當粒子還未到達畫面邊緣且沒有撞到擋板則動畫繼續進行。




模擬結果


以下是5種不同的數據組合及測試結果:

  1. v0 = 10, V = 1, d = 0.1, B = 1 ⇒ 等速度直線運動
  2. q > 0, v0 = 20 其它條件與組合1相同 ⇒ 向上偏移
  3. q > 0, d = 0.2 其它條件與組合1相同 ⇒ 向上偏移
  4. q > 0, V = 2 其它條件與組合1相同 ⇒ 向下偏移
  5. q > 0, B = 5 其它條件與組合1相同 ⇒ 向上偏移





程式 20-2 數據組合1畫面截圖




程式 20-2 數據組合2畫面截圖




程式 20-2 數據組合3畫面截圖




程式 20-2 數據組合4畫面截圖




程式 20-2 數據組合5畫面截圖



結語


我一開始想要全部採用真實數據製作動畫,例如將 q 和 m 設定電子的電量和質量,但是這樣在帶電粒子合力不為零時粒子的加速度非常大,很難看清楚粒子運動的過程,所以才會將粒子的質量增加很多。這個動畫的目的是為了看出粒子的受力情形與偏轉方向,雖然不是採用真實數據,但至少能清楚地看到粒子的運動過程。




VPython官方說明書


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



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

沒有留言:

張貼留言