GRAPES源碼分析之namelist

前言

在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 聲明臨時配置變量,賦初值,讀入,廣播,賦給配置變量

相關文章
相關標籤/搜索