iniwrite.F
路径
LMDZ.MARS\libf\phymars\iniwrite.F
所属目录 / 模块
libf\phymars
文件定位
iniwrite.F 定义外部子程序 iniwrite,用于初始化传统物理诊断 NetCDF 文件的固定结构。源码注释说明其目标是初始化 diagfi.nc:写入维度,以及随时间不变的字段,例如地表位势和网格面积。实际调用点还包括 writediagmicrofi.F,因此同一初始化例程也服务微物理诊断文件。
它不负责逐时间步追加诊断变量;后续变量由 writediagfi.F 或 writediagmicrofi.F 使用 def_var 等路径定义并写入。iniwrite 的职责是先建立坐标轴、垂直层坐标、控制参数、土壤深度、网格面积和地表位势,使后续诊断变量可以复用这些维度。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
iniwrite |
subroutine |
1 |
初始化已打开 NetCDF 诊断文件的维度、坐标变量和固定二维/一维字段 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
comsoil_h |
mlayer, nsoilmx |
定义 subsurface_layers 维度,并写入土壤层中点深度 soildepth |
- |
comcstfi_h |
g, mugaz, omeg, rad, rcp, pi |
把行星常数用于诊断打印;pi 用于经纬度弧度转角度 |
- |
vertical_layers_mod |
ap, bp, aps, bps, pseudoalt |
写入垂直坐标:伪高度、hybrid pressure/sigma midlayer 与 interlayer 系数 |
- |
time_phylmdz_mod |
hour_ini, daysec, dtphys |
诊断打印中输出时间常数;hour_ini 在当前可执行语句中未使用 |
- |
regular_lonlat_mod |
lon_reg, lat_reg |
写入规则经纬度坐标;3D 情况下扩展一个冗余经度点 |
- |
mod_grid_phy_lmdz |
nbp_lon, nbp_lat, nbp_lev |
定义经度、纬度、垂直层维度,并判断 1D/3D 网格 |
- |
phyetat0_mod |
tab_cntrl_mod |
写入 controle 控制参数数组,并用其长度定义 index 维度 |
- |
netcdf.inc |
include file |
提供传统 NetCDF Fortran NF_* 常量和接口 |
- |
调用的关键例程
| 被调用例程 |
所在模块 / 文件 |
调用位置 |
作用 |
NF_REDEF / NF_ENDDEF |
NetCDF Fortran 接口 |
多处 |
在定义维度或变量前后切换 NetCDF define mode |
NF_DEF_DIM |
NetCDF Fortran 接口 |
113-124 |
定义 index、latitude、longitude、interlayer、altitude、subsurface_layers |
NF_DEF_VAR |
NetCDF Fortran 接口 |
131-366 |
定义 controle、经纬度、altitude、soildepth、aire、phisinit 等变量 |
NF_PUT_ATT_TEXT |
NetCDF Fortran 接口 |
多处 |
写入 title、long_name、units、positive 等文本属性 |
NF_PUT_VAR_REAL / NF_PUT_VAR_DOUBLE |
NetCDF Fortran 接口 |
多处 |
按 NC_DOUBLE 编译开关写入单精度或双精度变量值 |
def_var |
def_var.F90 |
244, 252, 260, 268 |
定义 aps、bps、ap、bp 垂直 hybrid 坐标变量 |
上游调用点
| 调用方 |
调用位置 |
传入形态 |
作用 |
writediagfi.F |
251 |
iniwrite(nid,day_ini,phis,area,nbp_lon+1,nbp_lat) |
3D lon-lat 传统 diagfi 输出初始化 |
writediagfi.F |
253 |
iniwrite(nid,day_ini,phisfi_glo(1),areafi_glo(1),1,1) |
1D 情况下用单点面积和位势初始化 |
writediagmicrofi.F |
257 |
iniwrite(nid,day_ini,phis,area,nbp_lon+1,nbp_lat) |
3D 微物理诊断输出初始化 |
writediagmicrofi.F |
259 |
iniwrite(nid,day_ini,phisfi_glo(1),areafi_glo(1),1,1) |
1D 微物理诊断输出初始化 |
输入
| 输入 |
来源 |
类型 / 维度 |
单位 |
含义 |
nid |
调用方已创建或打开的 NetCDF 文件 |
integer |
- |
NetCDF file ID;本例程在这个文件内定义维度和变量 |
idayref |
调用方传入,通常为 day_ini |
INTEGER*4 |
sol / model day |
初始日期;当前源码只在末尾诊断打印中使用 |
phis |
调用方传入 |
real(nbplon,nbp_lat) |
geopotential |
地表位势,写入 phisinit |
area |
调用方传入 |
real(nbplon,nbp_lat) |
m2 |
网格面积,写入 aire |
nbplon |
调用方传入 |
integer |
grid points |
phis 和 area 第一维长度;3D 通常为 nbp_lon+1,1D 为 1 |
nbplat |
调用方传入 |
integer |
grid points |
接口参数;当前源码声明后未直接使用,纬度维度使用模块变量 nbp_lat |
tab_cntrl_mod |
phyetat0_mod |
real array |
mixed |
控制参数数组,长度定义 index 维度并写入 controle |
lon_reg, lat_reg |
regular_lonlat_mod |
real arrays |
radians |
规则经纬度坐标,写出前乘 180/pi |
ap, bp, aps, bps, pseudoalt |
vertical_layers_mod |
real arrays |
Pa / sigma / km |
垂直 hybrid 坐标和伪高度 |
mlayer, nsoilmx |
comsoil_h |
real array / integer |
m / layers |
土壤层中点深度和土壤层数 |
输出
| 输出 |
去向 |
类型 / 维度 |
单位 |
含义 |
index |
NetCDF dimension |
SIZE(tab_cntrl_mod) |
- |
controle 控制参数轴 |
latitude |
NetCDF dimension + variable |
nbp_lat |
degrees_north |
纬度坐标 |
longitude |
NetCDF dimension + variable |
1 或 nbp_lon+1 |
degrees_east |
经度坐标;3D 写入冗余闭合经度点 |
interlayer |
NetCDF dimension |
nbp_lev+1 |
- |
层间界面维度 |
altitude |
NetCDF dimension + variable |
nbp_lev |
km |
伪高度坐标,属性 positive="up" |
subsurface_layers |
NetCDF dimension |
nsoilmx |
- |
土壤层维度 |
controle |
NetCDF variable |
index |
mixed |
物理控制参数数组 |
aps, bps, ap, bp |
NetCDF variables |
altitude 或 interlayer |
Pa / sigma |
hybrid 垂直坐标系数 |
soildepth |
NetCDF variable |
subsurface_layers |
m |
土壤中层深度,属性 positive="down" |
aire |
NetCDF variable |
(longitude, latitude) |
source value |
网格面积 |
phisinit |
NetCDF variable |
(longitude, latitude) |
source value |
地表位势 |
共享状态与副作用
- 本例程没有 module 变量、
SAVE 局部状态或 COMMON block;主要副作用是修改 nid 指向的 NetCDF 文件结构和内容。
- 会分配局部 allocatable 数组
lon_reg_ext,1D 时长度为 1,3D 时长度为 nbp_lon+1。源码末尾没有显式 DEALLOCATE;作为局部 allocatable,离开子程序时通常由 Fortran 运行时自动释放。
- 会向标准输出打印
nbp_lon/nbp_lat/nbp_lev/idayref、rad/omeg/g/mugaz/rcp、daysec/dtphys 三组诊断信息。
- 大多数 NetCDF 调用把返回码覆盖到
ierr,但没有立即检查或中止;这不同于 def_var.F90 内部对若干错误调用 abort_physic 的风格。
核心逻辑
- 根据
nbp_lon*nbp_lat==1 判断是否为 1D 模式;1D 分配单点 lon_reg_ext(1),3D 分配 lon_reg_ext(nbp_lon+1)。
- 进入 NetCDF define mode,定义
index、latitude、longitude、interlayer、altitude 和 subsurface_layers 维度;经度维度在 1D 时为 1,在 3D 时为 nbp_lon+1。
- 定义并写入
controle,数据来源是 tab_cntrl_mod,变量类型由 NC_DOUBLE 条件编译决定。
- 定义并写入
latitude,把 lat_reg 从弧度转换为角度,属性包含 units="degrees_north" 和 long_name="North latitude"。
- 填充
lon_reg_ext:先复制 lon_reg(1:nbp_lon),3D 时把最后一点设为 -lon_reg_ext(1),源码注释说明这是因为 lon_reg 从 -180 开始,所以补上 180 的冗余点。
- 定义并写入
longitude,把 lon_reg_ext 从弧度转换为角度,属性包含 units="degrees_east"。
- 定义并写入
altitude,数据来源是 pseudoalt,单位 km,正方向向上。
- 通过
def_var 定义 aps、bps、ap、bp,随后分别写入 vertical_layers_mod 中的同名数组。
- 定义并写入
soildepth,数据来源是 mlayer,维度是 subsurface_layers。
- 用
(longitude, latitude) 维度定义并写入 aire 和 phisinit。
- 打印初始化摘要并返回。
伪代码
subroutine iniwrite(nid, idayref, phis, area, nbplon, nbplat)
if nbp_lon * nbp_lat == 1:
allocate lon_reg_ext(1)
else:
allocate lon_reg_ext(nbp_lon + 1)
define dimensions:
index = size(tab_cntrl_mod)
latitude = nbp_lat
longitude = 1 or nbp_lon + 1
interlayer = nbp_lev + 1
altitude = nbp_lev
subsurface_layers = nsoilmx
define and write controle(tab_cntrl_mod)
define and write latitude(lat_reg * 180/pi)
lon_reg_ext(1:nbp_lon) = lon_reg(1:nbp_lon)
if 3D:
lon_reg_ext(nbp_lon+1) = -lon_reg_ext(1)
define and write longitude(lon_reg_ext * 180/pi)
define and write altitude(pseudoalt)
def_var/write aps, bps on altitude
def_var/write ap, bp on interlayer
define and write soildepth(mlayer)
define and write aire(area)
define and write phisinit(phis)
print grid and constant summary
end
参与的主题流程
| 主题 |
参与方式 |
| 传统物理诊断输出 |
为 writediagfi.F 的 diagfi.nc 首次写入建立坐标轴、固定字段和控制参数 |
| 微物理诊断输出 |
被 writediagmicrofi.F 复用,用同一 NetCDF 初始化结构服务微物理诊断文件 |
| 垂直坐标 / z2sig |
把 vertical_layers_mod 的 ap/bp/aps/bps/pseudoalt 写入诊断文件,供输出解释和后处理使用 |
| 土壤诊断上下文 |
虽然不写 diagsoil.nc,但会在常规诊断文件中写入 soildepth,与 comsoil_h 的土壤层定义保持一致 |
写法特点
- 固定格式
.F 文件,使用传统 include "netcdf.inc" 和 NF_* NetCDF F77 接口。
- 多处通过
#ifdef NC_DOUBLE 在 NF_DOUBLE 与 NF_FLOAT 写出之间切换;垂直坐标变量定义本身由 def_var 完成,需注意 def_var.F90 页面记录其变量定义固定为 NF_FLOAT。
nbplat 是接口参数但当前源码没有直接引用;纬度维度来自模块变量 nbp_lat。
- 3D 输出使用
nbp_lon+1 经度维度并写入冗余闭合点;调用方也以 nbp_lon+1 形状传入 phis 和 area。
- 已注释掉的旧
tab_cntrl 填充逻辑仍保留在文件中;当前实际写入的控制参数来自 phyetat0_mod:tab_cntrl_mod。
复现要点
- 调用
iniwrite 前,nid 必须已经指向一个可写的 NetCDF 文件;本例程会反复切换 define/data mode。
tab_cntrl_mod 必须先由物理初始化路径填好,否则 controle 会写入未期望的控制参数。
lon_reg、lat_reg、ap/bp/aps/bps/pseudoalt、mlayer 和 nsoilmx 必须在调用前初始化;这些数组直接写入文件,没有本地合法性检查。
- 3D 情况下
phis 和 area 的第一维必须与 nbp_lon+1 一致;1D 情况下调用方传入单点数组。
- NetCDF 错误返回码大多未检查;复现实验若诊断文件缺字段或维度异常,不能仅依赖模型是否中止判断初始化是否完整。
待确认
hour_ini 被 use 引入但当前可执行路径未读写;是否为历史遗留依赖需要结合旧版本或编译告警确认。
nbplat 接口参数未直接使用;当前是否仅为旧接口兼容保留,需要结合调用方和历史接口确认。
lon_reg_ext 未显式释放;现代 Fortran 对局部 allocatable 的自动释放通常成立,但具体老编译器行为需结合构建环境确认。
相关页面