# 冰與水蒸氣混合達熱平衡時溫度與質量比值關係圖 >作者:王一哲     日期:2018/11/18 <br></br> ## 題目 假設 0°C 的冰塊質量為 _M_~1~,100°C 的水蒸氣質量為 _M_~2~,將兩者放入絕熱容器內達到熱平衡時的溫度為 _T_,請畫出 _T_ 與質量比值 $\frac{M_1}{M_2}$ 的關係圖。(水的熔化熱為 80 cal/g,水的汽化熱為 540 cal/g) <br></br> ## 解答 假設平衡時的溫度為 _T_,由於系統與外界沒有熱交換,冰塊吸收的熱等於水蒸氣釋放的熱,因此 \\[ M_1 \times 80 + M_1 \times 1 \times (T-0) = M_2 \times 540 + M_2 \times 1 \times (100 - T) \\] \\[ \frac{M_1}{M_2} \times 80 + \frac{M_1}{M_2} \times T = 640 - T \\] 若$\frac{M_1}{M_2} \equiv x$,則上式可改為 \\[ 80x + xT = 640 - T \\] \\[ T = \frac{640 - 80x}{x+1} \\] 若 $x < 3$ 代入上式則 $T > 100$,代表水蒸氣沒有用完,此時水與水蒸氣共存 $T = 100$;若 $x > 8$ 代入上式則 $T < 0$,代表冰塊沒有用完,此時水與冰塊共存 $T = 0$。因此 \\[ T(x) = \begin{cases} 100 & \text{ if } x < 3 \\ 0 & \text{ if } x > 8 \\ \frac{640 - 80x}{x + 1} & \text{ if } 3 \leq x \leq 8 \end{cases} \\] 很明顯地,這個函數圖形並不好畫,我們需要使用一些輔助工具會比較方便。 <br></br> ## 作圖(使用 Matplotlib) 以下是使用 Python 搭配 Matplotlib 以及 numpy 的作法,程式碼的功能請參考註解,大致上的步驟如下: 1. 用 np.linspace 產生要繪圖的 x 軸數據。 2. 將 x 軸數據代入算式求出對應的 y 軸數據,也就是溫度 T 的數值。 3. 用 np.where 找出 T > 100 的元素對應的索引值,再將這些位置的值都改成 100;再用同樣的方式將 T < 0 的元素都換成 0。 4. 設定圖片格式、繪圖、存檔。 ```python= import numpy as np # 引入科學計算函式庫 import matplotlib.pyplot as plt # 引入繪圖函式庫 xmin, xmax, num = 1, 10, 100 # 設定繪圖範圍、取點數 x = np.linspace(xmin, xmax, num) # 產生x # T = (640 - 80 * x) / (x + 1), 當 x < 3 時 T = 100, 當 x > 8 時 T = 0 T = (640 - 80 * x) / (x + 1) T[np.where(T > 100)] = 100 T[np.where(T < 0)] = 0 plt.figure(figsize = (6, 4.5), dpi = 100) # 設定圖片尺寸 plt.xlabel(r'$ M_1 / M_2 $', fontsize = 14) # 設定坐標軸標籤 plt.ylabel(r'$ T ({}^{\circ} \mathrm{C}) $', fontsize = 14) plt.xticks(fontsize = 12) # 設定坐標軸數字格式 plt.yticks(fontsize = 12) plt.grid(color = 'red', linestyle = '--', linewidth = 1) # 設定格線顏色、種類、寬度 plt.ylim(-10, 110) # 設定y軸繪圖範圍 # 繪圖並設定線條顏色、寬度 plt.plot(x, T, color = 'blue', linewidth = 3) plt.savefig('M_T_plot.svg') # 儲存圖片 plt.savefig('M_T_plot.png') plt.show() # 顯示圖片 ``` --- 2018/11/27 補充 ```python T = (640 - 80 * x) / (x + 1) T[np.where(T > 100)] = 100 T[np.where(T < 0)] = 0 ``` 以上的程式碼可以用 **numpy.clip** 簡化為 ```python T = ((640 - 80 * x) / (x + 1)).clip(0, 100) ``` numpy.clip 的語法為 ```python numpy.clip(最小值, 最大值) ``` 將陣列中小於最小值的元素都改為最小值,將陣列中大於最大值的元素都改為最大值。 <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/Lk91WaZ.png"> <center>使用 Matplotlib 繪製的 T - M<sub>1</sub> / M<sub>2</sub> 關係圖</center> <br></br> ## 作圖(使用 GeoGebra) 如果不想看到程式碼的同學可以使用 GeoGebra 繪圖。開啟 GeoGebra 之後在最下方的方框中輸入以下指令 ```cpp T(x) = If(x < 3, 100, If(x > 8, 0, (640 - 80x) / (x + 1))) ``` 因為這個函數分為 3 個區域,若 $x < 3$ 則 $T = 100$,若 $x > 8$ 則 $T = 0$,若 $3 \leq x \leq 8$ 則 $T = \frac{640 - 80x}{x+1}$,所以我們需要用到兩層的 If 來輸入這個函數。GeoGebra 的 If 指令格式為 ```cpp If[條件, 條件成立時執行的指令, 條件不成立時執行的指令] ``` 最後再調整一下座標軸的比例、線條的樣式,加上座標軸標籤,就可以得到以下的圖形。 <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/nNvqxVc.png"> <center>使用 GeoGebra 繪製的 T - M<sub>1</sub> / M<sub>2</sub> 關係圖</center> <br></br> ## 結語 在這篇文章中我們使用兩種不同的方法繪製函數圖形,如果各位同學想要繪製其它的函數圖形,可以參考這篇文章的作法再修改一下即可。 <br></br> --- ###### tags:`Physics`、`Python`、`GeoGebra`