日期: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+、12C、16O2-、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,用途已寫在該行的註解當中。為了使動畫較為順暢,刻意將粒子的電量、質量調大很多。
畫面設定
- 產生動畫視窗、金屬板。
- 產生帶電粒子,可以選擇粒子的名稱,程式會從masses、charges、colors讀取粒子的資料。
- 產生表示磁場的箭頭及標籤。
- 產生表示速度、加速度的箭頭。
物體運動
- 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個條件:當粒子沒有偏轉(-0.1*size < x < 0.1*size)而且還沒有到達畫面最上方時(particle.pos.y < L/2),動畫繼續執行。
- 第2個條件:當粒子向左或向右偏轉(abs(particle.pos.x) > 0)而且還沒有撞到金屬板時(particle.pos.y > p1.height/2 + size),動畫繼續執行。
- 計算帶電粒子所受合力,更新帶電粒子加速度、速度、位置。
- 更新表示速度、加速度的箭頭,只畫出方向以避免動畫自動縮小。
- 更新時間。
模擬結果
以下是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 很像,以下只說明修改之處。
- 加上粒子標籤資料 labels,由於 VPython 的標籤支援 html 語法,可以做出上標、下標的效果。 之間的文字為上標, 之間的文字為下標。
- 用 for 迴圈讀取粒子的名稱,並將產生粒子及粒子運動部分的 while 迴圈放到 for 迴圈當中,當 while 迴圈執行完畢時加上粒子的標籤。
模擬結果
以下是程式 23-2 的執行結果,可以看到粒子的迴轉半徑與 m/q 成正比。
程式 23-2 畫面截圖
結語
以前遇到這類的題目時,總是根據計算得到的結果畫示意圖,用 VPython 計算粒子在每個時刻的受力,再將整個運動過程畫出來,感覺上比較真實。也可以試著改變粒子的質量和電量,看看會有什麼變化。
VPython官方說明書
- canvas: http://www.glowscript.org/docs/VPythonDocs/canvas.html
- box: http://www.glowscript.org/docs/VPythonDocs/box.html
- sphere: http://www.glowscript.org/docs/VPythonDocs/sphere.html
- arrow: http://www.glowscript.org/docs/VPythonDocs/arrow.html
- label: http://www.glowscript.org/docs/VPythonDocs/label.html
HackMD 版本連結:https://hackmd.io/@yizhewang/rJZF_t_f7
沒有留言:
張貼留言