跳到主要內容區

計算物理習題演練 - 醫學系四年級 蔡崇德

課程名稱計算物理習題演練      授課教師太空與電漿科學研究所 西村泰太郎老師
心得分享者醫學系四年級 蔡崇德
修課動機
  我從高中到大學都學過一些程式語言設計,但是練習都以較沒有實用價值的題目為主,故在程式學習的目的上容易失焦,也難有進一步的延伸,例如在實驗室研究等用途發揮功效。
  今年,我在校內的合成生物研究社負責水凝膠藥物擴散的數值模擬,過程中發現自己程設能力(MATLAB)和模擬相關的數理知識(物理化學的菲克擴散定律)都十分有限,需要耗費大量的時間學習程設的語法,以及前往圖書館查閱許多相關書籍,才能稍稍理解並完成手中工作。因此我決定選修這門「計算物理習題演練」課彌補自己的不足。
  此外,我在醫學系內亦加入周邊神經電刺激治療研究的實驗室,模擬電刺激對神經的電性影響。這正呼應近年來,生醫領域因動物權爭議,以及多數實驗費財、費工、費時的缺點,逐漸強調電腦模擬 (in silico simulation)取代部分動物或細胞實驗的重要性。這項模擬需運用有限元素(finite element)的方法,將神經模型切成有限數量的節點,再對各點套用物理公式和微分方程,計算所求量值。恰巧本課程大綱提到這門課會介紹微分方程和分子動力學等領域,基本原理和有限元素法十分相似,可預想上完課對實驗室研究會很有幫助。前述的諸多能力不足、生醫研究領域趨勢的變化,再加上上課內容和實驗室工作的關聯性,都強化了我參與此門課程的動機。
授課老師風格
  計算物理習題演練由來自電漿所的西村泰太郎教授上課,西村老師上課非常用心,其巧思在這門學生只有六人的課程中嶄露無遺。
  由於上課採取英語授課,學生們吸收和理解上都相對困難一些,但是老師一直非常注意個別學生的學習狀況,所以整體課程下來大家都還算跟得上。在理論推導較為艱澀的地方,如克卜勒行星運動定律的非特殊解等,都很樂意在我們卡關時耐心地反覆講解,甚至在我們下課後不厭其煩的回答我們問題。當進入實際程式語言操作時,老師也十分關心我們是否有跟上進度,尤其在一開始熟悉Linux系統、C語言語法和終端機指令時,給予了我們很多引導和協助。
  當進入較為進階的程式模擬問題時,老師都會事先提供範本程式碼以供我們參考,但仍然非常鼓勵我們 “get our hands dirty”,跳脫標準答案,嘗試修改參數和語法邏輯,看看是否會產生自己預期的結果,從錯誤中慢慢學習。老師設計的回家程式作業也大多是基於範本程式碼延伸的進階題,寫起來都不會太難,但往往仍需要一些思考和反覆除錯才能夠順利完成,讓我們可以從實作裡挖掘自己邏輯思考上的漏洞,並提供了我們一次次腦力激盪的機會。
  成績評量方面分別有小考、程式碼作業以及報告三項,不論是哪一項,老師都會親手批改和檢閱,還會很細心的把學生寫得不夠完善的地方標示出來,予以建議和指正。
課程介紹
  課程主要可以分成三大部分:程式語言面、理論面和硬體面。課程規劃讓這幾個面向相互搭配呼應,以便學生掌握狀況。
  程式語言方面,本課程使用的程式語言以C為主,並大都在Linux的環境中進行設計與執行。老師會提供Linux作業系統的電腦,但也鼓勵學生自行下載並設定Ubuntu的Linux環境。
  由於大部分的人對於Linux以及終端機較為不熟悉,因此老師在第一節課會帶著大家慢慢熟悉作業系統操作與終端機指令。例如如何呼叫、編輯和編譯程式碼、如何轉換檔案目錄,以及如何利用程式輸出的數值結果作圖。尤其是作圖的部分對電腦模擬尤為重要,老師上課花許多時間特別著墨,教導設立標題、坐標軸、以及數據點符號等種格式設定的方式。
  C語言撰寫的部分,老師預設大家沒有任何程式基礎,從最基本的輸出(Hello world!) 開始教起,進而導向簡單的for/while/if迴圈設計,以及輸出數值格式指令設定,例如整數或是浮點數等。後續的程式設計題有了這些語法基礎,搭配上課學到理論知識之後大多都不難,課程還附有pseudocode和範例題的程式碼,讓我們在實際操作前先有一點想法。課程最後面進階的部分包含設計出產生亂數的程式碼,以及mpicc語法,藉由程式操控電腦的硬體面,讓電腦的每一個CPU都參與程式運作,將計算模擬速度提升至最高。
  理論方面,老師在第一天先簡單進行引言,介紹計算物理在科學和工程學廣泛的利用,例如氣候模擬、賽車流體力學設計等。接下來的課程當中,老師也是以循序漸進的方式,從高中物理和數學的基礎知識,慢慢銜接引導我們進入愈來愈難的理論中。
  老師先介紹電腦計算時的微積分方法(梯形黎曼和與泰勒展開式推導出來的微分式),在這之後便進入整個課程的核心:微分方程的模擬運算。老師依序介紹了三個計算微分方程的演算法:Euler method、improved Euler method和leapfrog method。三者計算的結果誤差依序愈來愈小,尤其是leapfrog method,邏輯相對簡單,並藉由交叉計算下一個時間點的位置(位能項)和速度(動能項),將整個物體系統的哈密爾頓量值(能量總和)維持在穩定的範圍內,大幅降低誤差。
  其後,老師介紹並深入推導克卜勒行星運動定律,讓我們了解不同初始參數設定下對星體軌跡形狀的影響。老師再以前述的三個演算法設計程式,進行星體軌跡模擬和比較,以實際模擬出的結果,搭配手寫推導的理論模擬誤差進行比較,讓我們確實看見三者誤差的差異,更加理解三個演算法的不同。在這個模擬作業中,老師也引導我們注意此類運算出現的龐大數字不利於人工判讀以及電腦運作,進而介紹normalization method,告訴我們如何以幾個常數為基準,等比例調整各項變數的大小,讓計算模擬較為順暢。
  課程最後教導的理論為Monte-Carlo method,這是利用模擬眾多粒子在多次亂數決定距離的移動後,分析位置分布等的演算法。由於牽涉到亂數產生,老師除了教導我們如何呼叫C語言內建的亂數函數,也有先告訴我們亂數產生演算法的背後理論。而Monte-Carlo method牽涉到的運算步驟非常多,為了提升運算速率,老師在硬體面的教學提供解決方法。
  硬體方面,老師著重於偏計算機科學方面的知識,教導二進位法、不同數字類型在電腦的儲存方式以及每種儲存方式的數值上限。這會影響到牽涉超大數字運算的程式,老師也藉由修改範本程式碼產生的錯誤數值展現這個問題,讓我們注意數值上限的重要性。課程的最後,老師經由Monte-Carlo method的程式模擬凸顯善用電腦硬體資源,提高運算速度的需求,因此帶到message passing interface (MPI)的理論,可以藉由把一項計算任務分攤給電腦全部的CPU進行平行運算,對於極度複雜的模擬系統,可以大幅降低電腦計算的時間。
心得
  我覺得這門課在學識上面的難度和挑戰性並不算很高,畢竟一週的時間著實有限,傳授大量艱澀知識並不實際。或許「計算物理」這個名稱乍看之下很像是門五天都在用紙筆推導物理題目和公式的課程,但所謂「計算」其實是英文computational的直翻,主要目標在於刺激我們以程式為輔具,練習解題與思考的能力。因此舉凡對電腦數值模擬有興趣的學生,就算只有最基本的高中數理背景,應該都能在五天的反覆腦力激盪中累積一些經驗值和手感,未來面對較為複雜的模擬題目也能相對輕鬆以對。這門課程唯一可惜之處是受限於授課時間,習題的領域較多著墨在古典力學的部分,範圍相對單一。不過我認為,經過扎實的基礎知識和解題訓練,修課後的學生定能夠舉一反三,拓展所學,應用於其他多元的領域。
  修完這門課的我,對這五天程式設計和理論邏輯思考的訓練深感著迷,進而對程式設計的實際應用有了更明瞭的認識,提升了相關領域學習的熱忱。身為醫學系學生,我也有幸於修讀這門課後,在本科系實驗室以更有效率的方式應用所學,執行模擬神經傳導專題。最後,我希望能夠把課堂上所學進行延伸,結合自己的domain knowledge在相關醫學研究中有所貢獻
 關鍵字  #成大模組化 #數值模擬 #微分方程模型 #平行運算 #跨領域整合
瀏覽數: