熱門文章

2018年5月13日 星期日

質譜儀

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




有5種粒子以相同之速度垂直進入均勻磁場B,其軌跡如下圖所示。設此5種粒子為:碳原子(12C)、氧離子(16O2-)、鈉離子(23Na+)、鎂離子(24Mg2+)及氯離子(35Cl-)。若不考慮重力因素,則圖中1、2、3、4及5之示意軌跡分別代表何者?


粒子在質譜儀中運動軌跡示意圖



這是84年日大聯招的題目,雖然年代已經很久遠,但在坊間各家的參考書中仍然可以找到這個題目。當粒子向上進入磁場時,帶正電粒子所受的磁力向左,帶負電粒子所受的磁力向右,電中性的粒子沒有受到磁力。若以磁力當作向心力,在磁場中做等速率圓周運動,則

$$ qvB = m \cdot \frac{v^2}{R} ~\Rightarrow~ R = \frac{mv}{qB} \propto \frac{m}{q} $$

因此本題的答案為23Na+24Mg2+、12C16O2-35Cl-。這次我們要試著用 VPython 將粒子在質譜儀中的運動過程畫出來。





程式 23-1.質譜儀


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

"""
 VPython教學: 23-1.質譜儀
 Ver. 1: 2018/4/8
 Ver. 2: 2019/9/19
 作者: 王一哲
"""
from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
size, m, q = 0.01, 1E-10, 2E-8  # 粒子半徑, 質量, 電量
v0 = vec(0, 10, 0)              # 粒子初速度
# 用 dictionary 儲存的粒子資料, 用 list 儲存的粒子名稱
masses = {"C": 12*m, "O": 16*m, "Na": 23*m, "Mg": 24*m, "Cl": 35*m}
charges = {"C": 0, "O": -2*q, "Na": q, "Mg": 2*q, "Cl": -q}
colors = {"C": color.red, "O": color.yellow, "Na": color.orange, "Mg": color.white, "Cl": color.green}
particles = ["C", "O", "Na", "Mg", "Cl"]
L = 0.4                         # 金屬板長度
B_field = vec(0, 0, -10)        # 磁場
t, dt = 0, 1E-5                 # 時間, 時間間隔

"""
 2. 畫面設定
"""
# 產生動畫視窗、金屬板
scene = canvas(title="Mass Spectrometer", width=800, height=600, x=0, y=0,
               center=vec(0, 0, 0), background=color.black)
p1 = box(pos=vec(-0.55*L, 0, 0), size=vec(L, 0.01*L, 0.1*L), color=color.blue)
p2 = box(pos=vec(0.55*L, 0, 0), size=vec(L, 0.01*L, 0.1*L), color=color.blue)
# 產生帶電粒子
name = particles[0]
particle = sphere(pos=vec(0, -L/3, 0), v=v0, radius=size, m=masses[name],
                  q=charges[name], color=colors[name], make_trail=True)
# 產生表示磁場的箭頭及標籤
arrow_B = arrow(pos=vec(-0.5*L, 0.5*L, 0), axis=vec(0, 0, -0.1), shaftwidth=size, color=color.green)
label_B = label(pos=vec(-0.5*L, 0.5*L, 0), text="B", xoffset=25, yoffset=25, color=color.green, font="sans")
# 產生表示速度、加速度的箭頭
arrow_v = arrow(pos=particle.pos, shaftwidth=0.5*size, color=color.cyan)
arrow_a = arrow(pos=particle.pos, shaftwidth=0.5*size, color=color.magenta)

"""
 3. 物體運動部分
"""
while((abs(particle.pos.x) < 0.1*size and particle.pos.y < L/2) or \
      (abs(particle.pos.x) > 0 and particle.pos.y > p1.height/2 + size)):
    rate(1000)
# 計算帶電粒子所受合力, 更新帶電粒子加速度、速度、位置
    if(particle.pos.y > p1.height/2 + size): F = particle.q*cross(particle.v, B_field)
    else: F = vec(0, 0, 0)
    particle.a = F/particle.m
    particle.v += particle.a*dt
    particle.pos += particle.v*dt
# 更新表示速度、加速度的箭頭, 只畫出方向以避免動畫自動縮小
    arrow_v.pos = particle.pos
    arrow_a.pos = particle.pos
    arrow_v.axis = particle.v.norm()*0.1
    arrow_a.axis = particle.a.norm()*0.1
# 更新時間
    t += dt




參數設定


在此設定變數為size、m、q、masses、charges、colors、particles、v0、L、B_field、t、dt,用途已寫在該行的註解當中。為了使動畫較為順暢,刻意將粒子的電量、質量調大很多。




畫面設定


  1. 產生動畫視窗、金屬板。
  2. 產生帶電粒子,可以選擇粒子的名稱,程式會從masses、charges、colors讀取粒子的資料。
  3. 產生表示磁場的箭頭及標籤。
  4. 產生表示速度、加速度的箭頭。




物體運動


  1. while 迴圈當中的條件設定為 (abs(particle.pos.x) < 0.1*size and particle.pos.y < L/2) or (abs(particle.pos.x) > 0 and particle.pos.y > p1.height/2 + size)
    1. 第1個條件:當粒子沒有偏轉(-0.1*size < x < 0.1*size)而且還沒有到達畫面最上方時(particle.pos.y < L/2),動畫繼續執行。

    2. 第2個條件:當粒子向左或向右偏轉(abs(particle.pos.x) > 0)而且還沒有撞到金屬板時(particle.pos.y > p1.height/2 + size),動畫繼續執行。

  2. 計算帶電粒子所受合力,更新帶電粒子加速度、速度、位置。
  3. 更新表示速度、加速度的箭頭,只畫出方向以避免動畫自動縮小。
  4. 更新時間。




模擬結果


以下是3種不同粒子的執行結果。程式 23-1 是測試用的,一次輸入一個粒子的資料並觀察執行的結果,接下來要用 for 迴圈一口氣將 5 個粒子的軌跡畫出來。




程式 23-1:12C 畫面截圖




程式 23-1:16O2- 畫面截圖




程式 23-1:23Na+ 畫面截圖



程式 23-2.質譜儀, 用 for 迴圈自動跑完 5 種粒子


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

"""
 VPython教學: 23-2.質譜儀, 用 for 迴圈自動跑完 5 種粒子
 Ver. 1: 2018/4/8
 Ver. 2: 2019/9/19
 作者: 王一哲
"""
from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
size, m, q = 0.01, 1E-10, 2E-8  # 粒子半徑, 質量, 電量
v0 = vec(0, 10, 0)              # 粒子初速度
# 用 dictionary 儲存的粒子資料, 用 list 儲存的粒子名稱
masses = {"C": 12*m, "O": 16*m, "Na": 23*m, "Mg": 24*m, "Cl": 35*m}
charges = {"C": 0, "O": -2*q, "Na": q, "Mg": 2*q, "Cl": -q}
colors = {"C": color.red, "O": color.yellow, "Na": color.orange, "Mg": color.white, "Cl": color.green}
labels = {"C": "C", "O": "<sup>16</sup>O<sup>2-</sup>", "Na": "<sup>23</sup>Na<sup>+</sup>", 
          "Mg": "<sup>24</sup>Mg<sup>2+</sup>", "Cl": "<sup>35</sup>Cl<sup>-</sup>"}
particles = ["C", "O", "Na", "Mg", "Cl"]
L = 0.4                         # 金屬板長度
B_field = vec(0, 0, -10)        # 磁場
t, dt = 0, 1E-5                 # 時間, 時間間隔


"""
 2. 畫面設定
"""
# 產生動畫視窗、金屬板
scene = canvas(title="Mass Spectrometer", width=800, height=600, x=0, y=0,
               center=vec(0, 0, 0), background=color.black)
p1 = box(pos=vec(-0.55*L, 0, 0), size=vec(L, 0.01*L, 0.1*L), color=color.blue)
p2 = box(pos=vec(0.55*L, 0, 0), size=vec(L, 0.01*L, 0.1*L), color=color.blue)
# 產生表示磁場的箭頭及標籤
arrow_B = arrow(pos=vec(-0.5*L, 0.5*L, 0), axis=vec(0, 0, -0.1), shaftwidth=size, color=color.green)
label_B = label(pos=vec(-0.5*L, 0.5*L, 0), text="B", xoffset=25, yoffset=25, color=color.green, font="sans")

"""
 3. 用 for 迴圈自動跑完 5 種粒子
"""
for name in particles:
# 產生帶電粒子
    particle = sphere(pos=vec(0, -L/3, 0), v=v0, radius=size, m=masses[name], q=charges[name], 
                      color=colors[name], make_trail=True, retain=1000)
# 物體運動部分
    while((abs(particle.pos.x) < 0.1*size and particle.pos.y < L/2) or \
          (abs(particle.pos.x) > 0 and particle.pos.y > p1.height/2 + size)):
        rate(1000)
# 計算帶電粒子所受合力, 更新帶電粒子加速度、速度、位置
        if(particle.pos.y > p1.height/2 + size): F = particle.q*cross(particle.v, B_field)
        else: F = vec(0, 0, 0)
        particle.a = F/particle.m
        particle.v += particle.a*dt
        particle.pos += particle.v*dt
# 更新時間
        t += dt
# 粒子標籤
    particle_label = label(pos=particle.pos, text=labels[name], xoffset=25, yoffset=25,
                           color=colors[name], font = "sans")




程式設計部分


程式 23-2 和 23-1 很像,以下只說明修改之處。

  1. 加上粒子標籤資料 labels,由於 VPython 的標籤支援 html 語法,可以做出上標、下標的效果。 之間的文字為上標, 之間的文字為下標。
  2. 用 for 迴圈讀取粒子的名稱,並將產生粒子及粒子運動部分的 while 迴圈放到 for 迴圈當中,當 while 迴圈執行完畢時加上粒子的標籤。




模擬結果


以下是程式 23-2 的執行結果,可以看到粒子的迴轉半徑與 m/q 成正比。





程式 23-2 畫面截圖



結語


以前遇到這類的題目時,總是根據計算得到的結果畫示意圖,用 VPython 計算粒子在每個時刻的受力,再將整個運動過程畫出來,感覺上比較真實。也可以試著改變粒子的質量和電量,看看會有什麼變化。




VPython官方說明書


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



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

沒有留言:

張貼留言