• GRAPES源码分析之namelist


    前言

    在GRAPES、WRF等模式中常见到类似 namelist.input 或 .nml 文件。文件里放入一些如预报区域范围、预报时间,技术方案选择及运行模式所需进程数等控制模式运行的配置变量。实际上 namelist 是 Fortran 中一种特殊的I/O读写格式。本文首先介绍 namelist 语法及如何读写,然后介绍 GRAPES 模式中是如何应用 namelist 的。

    namelist 语法

    namelist 把一组相关变量封装在一起,输入/出这一组变量时,只要在 write/read中的nml字段赋值要使用哪一个namelist就行。

    namelist 文件格式

    namelist文件格式:

    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。如下:

    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不能规定输出格式。每个数值内容使用什么格式来输出,由编译器决定。

    namelist 输入

    1
    
    read(unit, nml=nml_name)

    如果从键盘读入namelist,必须按照一定的格式输入,如下所示:

    1
    2
    
    &nml_name1 var1=1 var2=2.0 /    !以&开始,紧接namelist名字,
                                  	!然后以var=value输入每个变量,以 / 结束

    读取namelist时,可以不填入所有变量的值,只要以 &nml_name 开始输入,给一个除号就可以结束输入。变量可以不按照顺序输入,程序会自动按照变量名称来设置数值,变量甚至可以重复输入,不过变量会得到最后一次设置的值。

    namelist通常使用文本文件进行读写,nml文件常以 .nml 后缀标示其文件属性 (这个不一定,Linux系统不以后缀名确定文件类型,但用 .nml 结尾可以很方便识别文件属性)。

    nml 使用read从文件中读取数据时,会自动从 目前的位置向下寻找存放namelist的地方。

    GRAPES中的namelist

    GRAPES中有好几个namelist : RUN/namelist,input, RUN/rrtmg.nml, RUN/colm.nml(这个是 SRC/physics/CoLM/build.colm.nml 的软链接) 。

    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 声明临时配置变量,赋初值,读入,广播,赋给配置变量

  • 相关阅读:
    TextBox 只有下划线
    can't find web control library(web控件库)
    DropDownListSalesAC”有一个无效 SelectedValue,因为它不在项目列表中。
    IDE、SATA、SCSI、SAS、FC、SSD 硬盘类型
    如何打印1px表格
    CSS控制打印 分页
    Virtual Server could not open its emulated Ethernet switch driver. To fix this problem, reenable the Virtual Server Emulated Et
    Xml中SelectSingleNode方法中的xpath用法
    热带水果莫入冰箱?水果存放冰箱大法
    探索Asp.net的Postback机制
  • 原文地址:https://www.cnblogs.com/Parallel-Life/p/3231842.html
Copyright © 2020-2023  润新知