首先簡單說明一下,CHEMKIN由美國Sandia國家實驗室開發,CHEMKIN II即以下版本爲開源版本,CHEMKIN III開始科研使用需要購買版權,或使用舊版本實現相同功能。CHEMKIN III之後的版本開始帶有簡單的圖形界面。這個軟件包是一個比較經典的數值燃燒的代碼包,主要提供和化學反應相關的翻譯器,利用Arrhenius公式計算反應速率的計算器,以及一些經典的算例。
此處說幾句題外話,CHEMKIN III的完成時間大概是九十年代,當時的編程語言和編程模式發展還非常不成熟,程序本身並不具備面向對象的特性,函數名和變量名也由於時代的限制沒有完整的體現功能和存儲內容,程序包中的各個fortran文件都是極其冗長的工具箱。這導致CHEMKIN III的代碼本身其實結構並不方便閱讀和維護。如果對燃燒的基本知識並不熟悉,建議首先學習李新亮openCFD-comb模塊的使用手冊,模塊本身其實是對這個代碼庫的簡單實現,更加方便閱讀和使用。
CHEMKIN III是有使用手冊的,使用手冊中主要介紹的是CKLIB1,2兩個代碼庫,最後介紹了CONP.f函數,函數調用前面的代碼庫中的一系列函數,完成了一個0維燃燒的算例。另外一個實現的功能是Premix.f中的一維預混燃燒,這裏計算的是一個定常火焰燃燒模型,但是這個代碼的計算過程使用的是牛頓迭代求解非線性系統,計算過程並非現在常見的時間推進過程。
CHEMKIN的基本結構
代碼的基本結構如下:
其中chem.inp
爲化學反應機理的輸入文件,therm.dat
爲一個熱學參數的數據庫。將他們分別用翻譯器ckinterp.f
進行讀取,生成輸出文件chem.out
和linking file
文件名chem.bin
。linking file
可以在Gas-Phase Library
即文件cklib.f
中使用。具體使用方法如下:
這裏的unit 5
是指fortran代碼中read(5,*)
中的文件編號。另外需要注意的是,sample.f
中如果想要調用cklib.f
中的子函數,必須首先調用subroutine ckinit
創建化學反應所使用的數組,並讀入linking file
中的數據。首先我們給出chem.inp
的一個例子並進行說明:
ELEMENTS
H O AR
END
SPECIES
H2 O2 H O OH HO2 H2O2 H2O AR
END
REACTIONS
H2+O2=2OH 1.7E13 0.0 47780.
OH+H2=H2O+H 1.17E9 1.3 3626. !D-L$W
H+O2=OH+O 5.13E16 -0.816 16507. !JAM,JCP 1981
O+H2=OH+H 1.8E10 1.0 8826.
H+O2+M=HO2+M 2.1E18 -1.0 0. !SLACK
H2O/21./ H2/3.3/ O2/0.0/
H+O2+O2=HO2+O2 6.7E19 -1.42 0. !SLACK,JAN
OH+HO2=H2O+O2 5.0E13 0.0 1000.
H+HO2=2OH 2.5E14 0.0 1900.
O+HO2=O2+OH 4.8E13 0.0 1000.
2OH=O+H2O 6.0E+8 1.3 0. !COHEN-WEST.
H2+M=H+H+M 2.23E12 0.5 92600.
H2O/6/ H/2/ H2/3/
O2+M=O+O+M 1.85E11 0.5 95560.
H+OH+M=H2O+M 7.5E23 -2.6 0.
H2O/20/
H+HO2=H2+O2 2.5E13 0.0 700.
HO2+HO2=H2O2+O2 2.0E12 0.0 0.
H2O2+M=OH+OH+M 1.3E17 0.0 45500.
H2O2+H=HO2+H2 1.6E12 0.0 3800.
H2O2+OH=H2O+HO2 1.0E13 0.0 1800.
END
基本結構是首先聲明元素ELEMENTS
,然後聲明組分SPECIES
,最後聲明化學反應REACTIONS
。三個部分的聲明都必須以這三個關鍵字開頭,然後以END
結尾。對於聲明的詳細聲明在說明文件裏有特別詳細的解釋,這裏不做進一步說明。除去化學反應相關的信息外,還需要熱學參數的數據,即文件therm.dat
,這部分非常長,只羅列出其中一部分:
THERMO
300.000 1000.000 5000.000
! GRI-Mech Version 3.0 Thermodynamics released 7/30/99
! NASA Polynomial format for CHEMKIN-II
! see README file for disclaimer
O L 1/90O 1 G 200.000 3500.000 1000.000 1
2.56942078E+00-8.59741137E-05 4.19484589E-08-1.00177799E-11 1.22833691E-15 2
2.92175791E+04 4.78433864E+00 3.16826710E+00-3.27931884E-03 6.64306396E-06 3
-6.12806624E-09 2.11265971E-12 2.91222592E+04 2.05193346E+00 4
O2 TPIS89O 2 G 200.000 3500.000 1000.000 1
3.28253784E+00 1.48308754E-03-7.57966669E-07 2.09470555E-10-2.16717794E-14 2
-1.08845772E+03 5.45323129E+00 3.78245636E+00-2.99673416E-03 9.84730201E-06 3
-9.68129509E-09 3.24372837E-12-1.06394356E+03 3.65767573E+00 4
END
熱學參數是以THERMO
開頭,以END
結尾的,另外可以通過THERMO ALL
關鍵字控制是否調用LTHRM
中內置的熱學參數。同樣說明文件中有非常詳細的說明,而主要的熱學參數來源可以參考這個文章
Kee, R. J., Rupley, F. M. and Miller, J. A.: “The CHEMKIN Thermodynamic Data Base,” Sandia
National Laboratories Report SAND87-8215B (1990).
將。經過翻譯器翻譯過後的輸出文件chem.out
如下:
**************************************************************
* CHEMKIN Collection Release 3.7 *
* CHEM Application *
* GAS-PHASE MECHANISM INTERPRETER *
* Copyright 1997-2002 Reaction Design. All Rights Reserved. *
**************************************************************
--------------------
ELEMENTS ATOMIC
CONSIDERED WEIGHT
--------------------
1. H 1.00797
2. O 15.9994
3. AR 39.9480
--------------------
-------------------------------------------------------------------------------
C
P H
H A
A R
SPECIES S G MOLECULAR TEMPERATURE ELEMENT COUNT
CONSIDERED E E WEIGHT LOW HIGH H O AR
-------------------------------------------------------------------------------
1. H2 G 0 2.01594 200 3500 2 0 0
2. O2 G 0 31.99880 200 3500 0 2 0
3. H G 0 1.00797 200 3500 1 0 0
4. O G 0 15.99940 200 3500 0 1 0
5. OH G 0 17.00737 200 3500 1 1 0
6. HO2 G 0 33.00677 200 3500 1 2 0
7. H2O2 G 0 34.01474 200 3500 2 2 0
8. H2O G 0 18.01534 200 3500 2 1 0
9. AR G 0 39.94800 300 5000 0 0 1
-------------------------------------------------------------------------------
(k = A T**b exp(-E/RT))
REACTIONS CONSIDERED A b E
1. H2+O2=2OH 1.70E+13 0.0 47780.0
2. OH+H2=H2O+H 1.17E+09 1.3 3626.0
3. H+O2=OH+O 5.13E+16 -0.8 16507.0
4. O+H2=OH+H 1.80E+10 1.0 8826.0
5. H+O2+M=HO2+M 2.10E+18 -1.0 0.0
H2O Enhanced by 2.100E+01
H2 Enhanced by 3.300E+00
O2 Enhanced by 0.000E+00
6. H+O2+O2=HO2+O2 6.70E+19 -1.4 0.0
7. OH+HO2=H2O+O2 5.00E+13 0.0 1000.0
8. H+HO2=2OH 2.50E+14 0.0 1900.0
9. O+HO2=O2+OH 4.80E+13 0.0 1000.0
10. 2OH=O+H2O 6.00E+08 1.3 0.0
11. H2+M=H+H+M 2.23E+12 0.5 92600.0
H2O Enhanced by 6.000E+00
H Enhanced by 2.000E+00
H2 Enhanced by 3.000E+00
12. O2+M=O+O+M 1.85E+11 0.5 95560.0
13. H+OH+M=H2O+M 7.50E+23 -2.6 0.0
H2O Enhanced by 2.000E+01
14. H+HO2=H2+O2 2.50E+13 0.0 700.0
15. HO2+HO2=H2O2+O2 2.00E+12 0.0 0.0
16. H2O2+M=OH+OH+M 1.30E+17 0.0 45500.0
17. H2O2+H=HO2+H2 1.60E+12 0.0 3800.0
18. H2O2+OH=H2O+HO2 1.00E+13 0.0 1800.0
NO ERRORS FOUND ON INPUT:
ASCII Vers. 1.2 CHEMKIN linkfile chem.asc written.
WORKING SPACE REQUIREMENTS ARE
INTEGER: 593
REAL: 441
CHARACTER: 12
CKLIB的主要功能
CKLIB.f
中實現了和化學反應相關的幾乎所有功能,庫本身的函數變量此處進行簡單的說明。首先是所有的相關函數均以CK開頭避免和用戶的子函數混淆,例如suboutine ckinit
。
變量也分別給出了相應的命名,比如說壓力P
溫度T
質量分數Y
摩爾分數X
摩爾濃度C
定壓比熱CP
定容比熱CV
焓H
熵S
內能U
等等。
子函數中均以CK
開頭,但是緊跟字母W
的代表是計算反應速率相關的,CK,CD
分別代表產生和消耗的速率的關鍵字,Q
代表和反應平衡常數相關的子函數。
手冊中詳細的羅列了CKLIB
中所有的子函數極其功能,此處不全部例舉,但是要羅列出該模塊能夠實現的功能:
- 初始化:讀取文件,輸出數組長度,輸出反應機理,查看是否爲等離子體反應
- 元素相關:輸出原子質量,輸出元素對應的字符串數組,輸出元素名的字符
- 組分相關:返回組分的電荷、字符串、元素種類數、組分標籤、分子質量
- 反應機理相關:返回Arrhenius公式係數、摩爾反應熱、組分和對應的係數、描述反應的字符串、某個反應的反應係數。輸出是否爲某個特殊反應。
- 氣態常數和單位:返回通用氣態常數和標準大氣壓
- 濃度和摩爾質量相關:計算平均分子質量、壓力、密度、摩爾分數、質量分數、摩爾濃度或者摩爾分數。
- 無量綱熱學性質相關:返回比熱的擬合參數、定壓比熱、無量綱焓、可以計算的最高溫。
- 帶量綱熱學性質相關:計算Cp,Cv,焓、熵、內能
- 摩爾單位下的熱學性質:同上
- 質量單位下的熱學性質:同上
- 摩爾單位下的平均熱學性質:同上
- 化學反應速率相關:計算反應速率、組分的摩爾變化、生成速率、正逆反應速率、組分生成速率
- 平衡常數相關:計算平衡常數
算例conp.f
這是一個constant presssure的0維燃燒算例。依賴的是ode方程,形式如下:
給初始時刻各個組分的濃度,利用CKLIB
計算反應速率,然後更新組分的質量分數,並利用反應放熱和比熱計算溫度變化。這是一個具有一定剛性的ode問題,對於ode的求解,CHEMKIN中也提供了相應的計算模塊vode.f
。而這個ode方程的描述,寫在subroutine fun
中。這部分直接打印手冊中的代碼閱讀即可,可讀性較強。需要注意的是程序本身存在文件名大小寫讀取的bug,在運行之前需要進行調試。運行程序後,在控制檯依次輸入所需的參數
1 1000
H2 1
O2 3
N2 .1
END
3.0e-4 3.0e-5
相當於給定p爲一個標準大氣壓,溫度爲1000K,組分和摩爾濃度初始值和步長和終止時間。之後輸出的計算結果爲:
T(SEC) TMP(K) H2 H O2 O OH
HO2 H2O2 H2O N N2
NO
0.000E+00 0.100E+04 0.244E+00 0.000E+00 0.732E+00 0.000E+00 0.000E+00
0.000E+00 0.000E+00 0.000E+00 0.000E+00 0.244E-01
0.000E+00
0.300E-04 0.100E+04 0.244E+00 0.817E-05 0.732E+00 0.425E-05 0.144E-05
0.129E-04 0.103E-07 0.259E-04 0.181E-20 0.244E-01
0.375E-19
0.600E-04 0.196E+04 0.890E-02 0.169E-01 0.625E+00 0.570E-01 0.411E-01
0.174E-03 0.355E-04 0.224E+00 0.229E-09 0.262E-01
0.167E-07
0.900E-04 0.235E+04 0.367E-02 0.331E-02 0.658E+00 0.235E-01 0.392E-01
0.845E-04 0.445E-05 0.246E+00 0.193E-08 0.271E-01
0.163E-05
0.120E-03 0.243E+04 0.258E-02 0.185E-02 0.665E+00 0.165E-01 0.352E-01
0.693E-04 0.254E-05 0.251E+00 0.229E-08 0.272E-01
0.438E-05
0.150E-03 0.246E+04 0.216E-02 0.139E-02 0.669E+00 0.138E-01 0.330E-01
0.641E-04 0.197E-05 0.254E+00 0.236E-08 0.273E-01
0.730E-05
0.180E-03 0.248E+04 0.197E-02 0.120E-02 0.670E+00 0.125E-01 0.319E-01
0.619E-04 0.173E-05 0.255E+00 0.237E-08 0.273E-01
0.102E-04
0.210E-03 0.248E+04 0.188E-02 0.111E-02 0.671E+00 0.119E-01 0.313E-01
0.609E-04 0.162E-05 0.255E+00 0.238E-08 0.273E-01
0.131E-04
0.240E-03 0.249E+04 0.183E-02 0.106E-02 0.671E+00 0.116E-01 0.310E-01
0.604E-04 0.157E-05 0.256E+00 0.239E-08 0.273E-01
對應各個組分在隨時間推進時的摩爾濃度變化。其中使用手冊也對ode求解器進行了說明,subroutine vode
中使用了計算剛性問題的算法,有需求可以進一步瞭解。
算例Premix.f
這是一個比較特別的算例,計算的是一個一維的定常燃燒問題,建議查看一下《層流預混燃燒的數值研究》秦鳳華,東北大學。使用的就是這個代碼模塊裏面的算法,並進行了更多的數值試驗。算法計算的並非NS方程,而是針對當前定解,且一維的情形進行簡化的火焰模型:
計算過程中假設工況如圖:
預混氣體從左側以恆定的流量導入,經過預熱區的加熱後,在反應區燃燒。燃燒產物再從右側排出。燃燒消耗的反應物速度和氣體流入的速度一致,所以變成一個定常問題。這類定常問題在現在求解時,常常使用隨時間推進的迭代算法。而當前程序爲了滿足計算結果定常,採用的方法是給定計算區域某點的溫度爲定值。而計算方法也並非隨時間迭代,而是直接牛頓法迭代求解離散的代數方程組。求解的結果大體圖像如下:
下面介紹Premix.f
代碼中的基本結構。參考另外一篇文獻《PREMIX: a fortran program for modeling steady laminar one-dimensional premixed flames》Printed April 1998。程序需要依賴cklib
,具體的程序依賴關係如圖:
首先我們看到和conp.f
一樣,使用到了CHEMKIN INTERPRETER
和CHEMKIN subroutine library
,而另外引入的模塊TRANSPORT PROPERTY FITTING
和TRANSPORT subroutine library
在這個文獻中可以找到詳細說明:
R. J. Kee, G. Dixon-Lewis, J. Warnatz, M. E. Coltrin, and J. A. Miller, “A Fortran Computer Code Package for the Evaluation of Gas-Phase Multicomponent Transport Properties,” Sandia National Laboratories Report SAND86-8246 (1986).
在組分的守恆方程中,存在組分之間的擴散係數。這一系數的計算需要藉助圖中右端的庫函數。此處給出各個模塊和CHEMKIN各個模塊之間的對應關係:
Gas-phase Species and Kinetics Description ----> chem.inp
Thermodynamics Data Base ----> therm.dat
Transport Data Base ----> tran.data
CHEMKIN Interpreter ----> ckinterp.f
Transport Property Fitting ----> tranfit.f
ASCII CHEMKIN Output File ----> chem.out
CHEMKIN Linking file ----> chem.asc 注意此處是.asc不是.bin
Transport Linking file ----> tran.bin
ASCII Transport Output file ----> tran.out
CHEMKIN subroutine library ----> cklib1.f cklib2.f
Transport subroutine library ----> tranlib.f
Restart File ----> rest.bin 讀取文件繼續算之前沒算完的部分
Save File ----> save.bin
Recover File ----> recov.bin 沒算完的話存在這裏
函數的調用過程比較簡單:
PROGRAM PRDRIV
C*****precision > double
IMPLICIT DOUBLE PRECISION (A-H,O-Z), INTEGER (I-N)
C*****END precision > double
C*****precision > single
C IMPLICIT REAL (A-H,O-Z), INTEGER (I-N)
C*****END precision > single
PARAMETER (LENLWK=100, LENIWK=5000, LENRWK=200000, LENCWK=100,
1 LENSYM=16, LIN=5, LOUT=6, LRIN=14, LROUT=15,
2 LRCVR=16, LINCK=25, LINMC=35, NMAX=65, ZERO=0.0)
C LENLWK allocates the logical working space
C LENIWK allocates the integer working space
C LENRWK allocates the real working space
C LENCWK allocates the character working space
C LENSYM is the length of a character string
C LIN is the unit from which user input is read
C LOUT is the unit to which printed output is written
C LRIN is the unit from which the restart file is read
C LROUT is the unit to which the save file is written
C LRCVR is the unit to which the scratch save file is written
C LINCK is unit from which the Chemkin binary file is read
C LINTP is unit from which the Transport binary file is read
C NMAX is the total number of grid points allowed
DIMENSION IWORK(LENIWK), RWORK(LENRWK)
CHARACTER CWORK(LENCWK)*(LENSYM)
LOGICAL LWORK(LENLWK)
EXTERNAL CKTIME
TSTART = CKTIME(ZERO)
C
OPEN(LRIN,FORM='UNFORMATTED',STATUS='UNKNOWN',FILE='./rest.bin')
OPEN(LROUT,FORM='UNFORMATTED',STATUS='UNKNOWN',FILE='./save.bin')
OPEN(LRCVR,FORM='UNFORMATTED',STATUS='UNKNOWN',FILE='./recov.bin')
OPEN(LINCK,STATUS='UNKNOWN',FORM='FORMATTED',FILE='./chem.asc')
OPEN(LINMC,STATUS='UNKNOWN',FORM='FORMATTED', FILE='./tran.asc')
C
CALL PREMIX (NMAX, LIN, LOUT, LINCK, LINMC, LRIN, LROUT, LRCVR,
1 LENLWK, LWORK, LENIWK, IWORK, LENRWK, RWORK, LENCWK,
2 CWORK)
TEND = CKTIME (TSTART)
IF (TEND .GT. 60.) THEN
WRITE (LOUT, '(A,1PE15.2)') ' Total CPUtime (min): ',TEND/60.
ELSE
WRITE (LOUT, '(A,1PE15.2)') ' Total CPUtime (sec): ',TEND
ENDIF
CLOSE(LRIN)
CLOSE(LROUT)
CLOSE(LRCVR)
CLOSE(LINCK)
CLOSE(LINMC)
STOP
END
就是說另外寫函數然後,之間在函數中調用這個子函數即可這個代碼段對應文件Premxdem.f
。計算過程中的求解器是一個Newton-Raphson方法,對應着文件Twopoints.f
。變量說明在文獻中有詳細說明,這裏不展開。文章介紹了兩個算例,分別爲氫氧燃燒和甲烷燃燒。對應的輸入輸出文件數據都很長,這裏均不給出。對於當前算例,首先需要根據問題給定合適的輸入文件chem.inp
和therm.dat
,以及tran.dat
。通過兩個翻譯器分別生成兩個linking file
名爲chem.asc
和tarn.bin
之外。還需要在運行後手動輸入如下的代碼段,作爲控制關鍵字:
/ flame configuration, burner stabilized with specified temperature
BURN
TGIV
/ in the event of a Newton failure, take 100 timesteps of 1.E-6
TIME 100 1.00E-6
/ begin on a uniform mesh of 6 points
NPTS 6
/ definition of the computational interval
XEND 10.0
XCEN 5.0
WMIX 10.0
/ pressure and inlet mass flow rate
PRES 0.0329 (atmospheres)
FLRT 4.63E-3 (g/cm**2-sec)
/ adaptive mesh criteria
GRAD 0.2
CURV 0.5
/ unreacted mole fractions
MOLE
REAC O2 0.09
REAC AR .63
REAC H2 0.28
/ estimated products
PROD AR 0.68
PROD H2O 0.12
PROD H2 0.15
PROD OH 0.02
PROD O 0.02
PROD H 0.01
/ estimated intermediate mole fractions
INTM H2O2 .00001
INTM HO2 .001
INTM H2 .01
/ tolerances for the Newton iteration
ATOL 1.E-10
RTOL 1.E-4
/ tolerances for the time step Newton iteration
ATIM 1.E-5
RTIM 1.E-5
/ print control
PRNT 1
/ given temperature profile
TEMP 0. 373.7
TEMP .1250 484.5
TEMP .250 583.7
TEMP .375 672.2
TEMP .5 753.5
TEMP .75 901.4
TEMP 1.0 1027.
TEMP 1.25 1120.
TEMP 1.5 1184.
TEMP 2.0 1260.
TEMP 3.0 1348.
TEMP 6.0 1475.
TEMP 10.0 1524.
END
注意/
中的說明文字也必須敲進去程序才能識別,空格多少個並不影響。當前調試好的Premix文件夾中,在控制檯分別敲入如下命令:
make interp
make tranfit
make premix
./chem.exe
./tranfit.exe
./premix.exe
然後按順序鍵入前面提到的控制命令,就可以輸出結果,爲文獻中Page56的計算結果,如圖:
MAKEFILE文件
CHEMKIN III中自帶了一個MAKEFILE
文件,內容如下:
# Make file for compile and link CHEMKIN Demo
# Compatible to Mircosoft Fortran Powerstation 4.0 or Digital Fortran 5.0
# Note: PCMACH.F is used
FC = DF
# Mircosoft Fortran Powerstation 4.0
FFLAGS = -4R8 -W0 -G5
# Compaq fortran 6.0
# FFLAGS = /align:rec8byte /integer_size:32 /real_size:64 /architecture:p5
LD = fl32
.F.o :
$(FC) $(FFLAGS) $<
INTPOBJ=CKINTERP.obj CKLIB1.OBJ CKLIB2.OBJ
EQUIOBJ=equi.obj eqlib.obj cklib1.obj cklib2.obj stanlib.obj
CONPOBJ=conp.obj cklib1.obj CKLIB2.OBJ vode.obj math.obj pcmach.obj
PREMIXOBJ=premix.obj premxdem.obj cklib1.obj cklib2.obj tranlib.obj twopnt.obj cputim.obj math.obj pcmach.obj
FITOBJ=fitdat.obj lsei.obj math.obj pcmach.obj
SENKINOBJ=senkin.obj senkdem.obj cklib1.obj cklib2.obj dasac.obj
PSROBJ=psr.obj psrdem.obj eqlib.obj stanlib.obj cklib1.obj cklib2.obj twopnt.obj cputim.obj math.obj pcmach.obj
TRANFITOBJ=tranfit.obj cklib1.obj cklib2.obj math.obj pcmach.obj
SHOCKOBJ=shock.obj cklib1.obj cklib2.obj vode.obj math.obj pcmach.obj
all: ckinterp EQUI CONP PREMIX FIT SENKIN PSR TRANFIT SHOCK
ckinterp: $(INTPOBJ)
$(LD) $(INTPOBJ)
EQUI: $(EQUIOBJ)
$(LD) $(EQUIOBJ)
CONP: $(CONPOBJ)
$(LD) $(CONPOBJ)
PSR: $(PSROBJ)
$(LD) $(PSROBJ)
PREMIX: $(PREMIXOBJ)
$(LD) $(PREMIXOBJ)
FIT: $(FITOBJ)
$(LD) $(FITOBJ)
SENKIN: $(SENKINOBJ)
$(LD) $(SENKINOBJ)
TRANFIT: $(TRANFITOBJ)
$(LD) $(TRANFITOBJ)
SHOCK: $(SHOCKOBJ)
$(LD) $(SHOCKOBJ)
說明我們當前的算例只是CHEMKIN中的其中兩個模塊。另外經過測試,當前這個Makefile文件並不能直接使用。文件中不同.f文件的依賴關係存在缺失,並且當前的編譯器對輸入輸出文件以及.f文件的大小寫是區分的,導致程序中有很多bug,而且代碼段中部分format定義也存在bug,需要經過調試才能使用。