前言
在GRAPES、WRF等模式中常見到相似 namelist.input 或 .nml 文件。文件裏放入一些如預報區域範圍、預報時間,技術方案選擇及運行模式所需進程數等控制模式運行的配置變量。實際上 namelist 是 Fortran 中一種特殊的I/O讀寫格式。本文首先介紹 namelist 語法及如何讀寫,而後介紹 GRAPES 模式中是如何應用 namelist 的。app
namelist 語法
namelist 把一組相關變量封裝在一塊兒,輸入/出這一組變量時,只要在 write/read中的nml字段賦值要使用哪個namelist就行。dom
namelist 文件格式
namelist文件格式:ui
1 2 3 4 5 6 7 8 9 10 11 |
&nml_name1 ! &接某一組namelist名字 var1 = value, ! 輸出變量名稱,等號,值及逗號 var2 = value, ... / ! 除號結束這一組namelist ... &nml_nameN ! 第n組namelist ... / |
namelist 聲明
namelist聲明相似common語法,但nml必定要取名字,必須在執行語句前聲明。首先對各個變量進行聲明,而後聲明各組namelist。在輸入/出namelist前,必須先聲明namelist。以下:spa
1 2 3 4 |
integer :: var1 !先對每一個變量如日常同樣聲明 real :: var2 namelist /nml_name1/ var1,var2 !而後聲明那些變量屬於哪一個namelist組 |
namelist 輸出
1
|
write(unit, nml=nml_name) ! nml_name指每組namelist的名字 |
在write的nml字段中指定輸出哪一個namelist,就把nml中變量所有輸出。輸出的namelist不能規定輸出格式。每一個數值內容使用什麼格式來輸出,由編譯器決定。code
namelist 輸入
1
|
read(unit, nml=nml_name) |
若是從鍵盤讀入namelist,必須按照必定的格式輸入,以下所示:進程
1 2 |
&nml_name1 var1=1 var2=2.0 / !以&開始,緊接namelist名字, !而後以var=value輸入每一個變量,以 / 結束 |
讀取namelist時,能夠不填入全部變量的值,只要以 &nml_name 開始輸入,給一個除號就能夠結束輸入。變量能夠不按照順序輸入,程序會自動按照變量名稱來設置數值,變量甚至能夠重複輸入,不過變量會獲得最後一次設置的值。input
namelist一般使用文本文件進行讀寫,nml文件常以 .nml 後綴標示其文件屬性 (這個不必定,Linux系統不之後綴名肯定文件類型,但用 .nml 結尾能夠很方便識別文件屬性)。編譯器
nml 使用read從文件中讀取數據時,會自動從 目前的位置向下尋找存放namelist的地方。it
GRAPES中的namelist
GRAPES中有好幾個namelist : RUN/namelist,input, RUN/rrtmg.nml, RUN/colm.nml(這個是 SRC/physics/CoLM/build.colm.nml 的軟連接) 。io
namelist.input
主要查看namelist.input,其餘兩個相似
該文件保存了模式的一些配置信息(都是標量),配置變量在 shared/module_configure模塊中聲明。
該模塊中子程序 initial_config 用於讀入namelist.input變量。步驟:
-
聲明子程序臨時配置變量,而後把一組組相關變量封裝在各組namelist中。
-
打開namelist.input文件
1 2 3 4 5 |
OPEN ( UNIT = 10 , & FILE = "namelist.input" , & FORM = "FORMATTED" , & STATUS = "OLD" , & IOSTAT = io_status ) |
-
臨時配置變量先賦一個初值,即默認值。以防namelist中沒有這個變量,保證變量都有值。
-
輸入/出namelist,代碼以下
1 2 3 4 5 |
REWIND ( UNIT = nml_unit ) READ ( UNIT = nml_unit , NML = namelist_01 , ERR = 9200 , END = 9200 ) WRITE ( UNIT = * , NML = namelist_01 ) ... 重複以上三句輸入/出下一組namelist |
rewind表示回到文件nml_unit 的開始,在用rewind以前必須保證該文件已打開(即以前有open操做且成功了)。
read語句從文件開頭開始查找nml字段爲namelist_name的相關變量,err字段用來設置當前文件打開錯誤時,程序跳躍到label所指的代碼處繼續執行。end指在讀寫到文件末尾時,轉移到某個行代碼來繼續執行程序。這裏都是到9200處。
write語句向標準輸出寫入namelist,GRAPES中已重定向到 std.out.** 文件。
- 而後向全部進程廣播臨時配置變量
1 2 |
call grapes_bcast( s_we ,1 ) ... |
- 最後將臨時配置變量賦給對應的派生數據類型 config_flags (該派生數據類型是在本模塊中聲明的),關閉文件,結束namelist輸入。
1 2 3 4 |
config_flags % s_we = s_we ... CLOSE ( UNIT = 10 , IOSTAT = io_status ) |
- 另:配置變量經過 shared/module_domain模塊中cpconfig子程序賦給狀態變量 grid 。
總結
由以上分析可得出添加GRAPES配置變量的通常流程:
-
在namelist.input中按照nml格式添加變量,並給出其值
-
在shared/module_configure模塊中grid_config_rec_type聲明中添加相應變量
-
並在子程序 initial_config 聲明臨時配置變量,賦初值,讀入,廣播,賦給配置變量