history/dynav 字段注册和写出门控
输入范围
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\com_io_dyn_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\inithist.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\writehist.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\initdynav.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\writedynav.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\gcm.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\leapfrog.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\gcm.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\leapfrog_p.F
LMDZ.MARS\libf\dynphy_lonlat\phymars\nogcm.F90
LMDZ.MARS\libf\dynphy_lonlat\phymars\leapfrog_nogcm.F
Mars 运行参与度:条件经过。只有同时满足运行配置 ok_dyn_ins 或 ok_dyn_ave、编译包含 CPP_IOIPSL、并经过对应 GCM/nogcm 输出门时,COMMON 动力 history/dynav 输出才会初始化和写出。Mars physics 的 diagfi/stats/XIOS 是另一条输出链,不由这些例程写出。
例程定位
inithist 和 initdynav 定义 IOIPSL history 文件、垂直轴和变量清单;writehist 和 writedynav 在时间推进中按门控写变量。四个 COMMON 串行例程都被 #ifdef CPP_IOIPSL 包住;未定义该宏时只向 lunout 打 warning,不会创建或写 NetCDF history 文件。
当前 COMMON 串行入口 dyn3d/gcm.F90 直接调用 inithist/initdynav。并行入口 dyn3dpar/gcm.F 在 root 分支也调用这两个串行初始化例程,当前源码中的 inithist_p/initdynav_p 调用处是注释保留路径。因此本页以当前可达的 COMMON 串行 history id 和 root 写出链为准;*_p 支撑实现见串并行对照页。
文件名和 id 持有者
com_io_dyn_mod.F90 保存文件名常量和 IOIPSL file id。初始化例程写入这些 id,写出例程随后复用;这些 id 与 temps_mod:itau_dyn 的生命周期见 动力输出状态持有者。
| 输出族 | 文件名常量 | 默认文件 | id | 初始化者 | 写出者 |
|---|---|---|---|---|---|
| instant scalar | dynhist_file |
dyn_hist.nc |
histid |
inithist |
writehist |
| instant V grid | dynhistv_file |
dyn_histv.nc |
histvid |
inithist |
writehist |
| instant U grid | dynhistu_file |
dyn_histu.nc |
histuid |
inithist |
writehist |
| averaged scalar | dynhistave_file |
dyn_hist_ave.nc |
histaveid |
initdynav |
writedynav |
| averaged V grid | dynhistvave_file |
dyn_histv_ave.nc |
histvaveid |
initdynav |
writedynav |
| averaged U grid | dynhistuave_file |
dyn_histu_ave.nc |
histuaveid |
initdynav |
writedynav |
配置读取和初始化门控
串行 conf_gcm.F90 和并行 conf_gcm.F90 都读取同一组输出控制键:
| 配置键 | 默认值 | 作用 |
|---|---|---|
iecri |
1 |
instant history 写出步长门,leapfrog* 用 MOD(itau,iecri)==0 判断是否进入 instant 输出段。 |
periodav |
1. |
averaged dynav 文件写出周期,初始化时进入 t_wrt=periodav*daysec。 |
ok_dynzon |
.FALSE. |
动力纬向/守恒诊断门,调用 bilan_dyn 或 bilan_dyn_p,不等同于 dynav 文件。 |
ok_dyn_ins |
.FALSE. |
instant dyn_hist*.nc 初始化和写出门。 |
ok_dyn_ave |
.FALSE. |
averaged dyn_hist*_ave.nc 初始化和写出门。 |
初始化在 gcm 或 gcm_p 完成动力、物理和 I/O 基础状态后执行:
if ok_dyn_ins:
t_ops = (iecri / day_step) * daysec
t_wrt = daysec
inithist(day_ref, annee_ref, time_step, t_ops, t_wrt)
if ok_dyn_ave:
t_ops = iperiod * time_step
t_wrt = periodav * daysec
initdynav(day_ref, annee_ref, time_step, t_ops, t_wrt)
dtav = iperiod * dtvr / daysec
MARS phymars/nogcm.F90 也在 ok_dyn_ins/ok_dyn_ave 下初始化同一组 COMMON history/dynav 例程,然后进入 phymars/leapfrog_nogcm.F。这说明 Mars nogcm 路径可以使用 COMMON 动力 history 机制;它仍然不同于 Mars physics 自己的 diagfi.nc、stats.nc 或 XIOS 输出。
inithist 字段注册
inithist.F 创建 U/V/scalar 三个 instant 文件。经纬度来自 comgeom.h 的 rlong/rlat,垂直轴使用 comvert_mod:presnivs/100.,单位标注为 mb。
| 文件 id | 网格尺寸 | histbeg 输入 |
注册字段 | 单位 | 说明 |
|---|---|---|---|---|---|
histuid |
iip1 * jjp1 |
dyn_histu.nc,U grid |
u |
m/s |
vcov/ucov 后续经 covnat 转自然风后写入。 |
histvid |
iip1 * jjm |
dyn_histv.nc,V grid |
v |
m/s |
V 纬向维度用 jjm。 |
histid |
iip1 * jjp1 |
dyn_hist.nc,scalar grid |
teta, phi, masse, ps |
-, -, kg, Pa |
scalar 文件承载位温、位势、层质量和地表压。 |
源码中 tracer 循环 histdef(histid,ttext(iq),...) 和 phis 的 histdef 都是注释行。因此当前 COMMON 串行 inithist 不注册 tracer 或 phis 字段;若后续看到并行 _p 页列出更多变量,应按调用链确认 _p 是否在当前入口活跃。
initdynav 字段注册
initdynav.F90 创建 averaged dynav 三个文件,垂直轴同样使用 presnivs/100. 和 mb。字段清单与 instant history 接近,但 scalar 文件多出由写出阶段派生的 temp。
| 文件 id | 默认文件 | 注册字段 | 单位 | 说明 |
|---|---|---|---|---|
histuaveid |
dyn_histu_ave.nc |
u |
m/s |
平均 U 风。 |
histvaveid |
dyn_histv_ave.nc |
v |
m/s |
平均 V 风。 |
histaveid |
dyn_hist_ave.nc |
temp, theta, phi, masse, ps |
K, K, -, kg, Pa |
theta 对应输入 teta;temp 在 writedynav 内由 teta*ppk/cpp 派生。 |
initdynav 中 tracer 和 phis 的 histdef 同样处于注释状态。当前串行 averaged dynav 不注册 tracer 或 surface geopotential。
写出门控
leapfrog.F 与 leapfrog_p.F 都有两处输出段,分别覆盖正常 leapfrog 段和接近结束/重启段。核心条件相同:
if MOD(itau, iperiod) == 0 or itau == itaufin:
if ok_dynzon:
bilan_dyn* (...)
if ok_dyn_ave:
writedynav(itau, vcov, ucov, teta, ppk, phi, q, masse, ps, phis)
if MOD(itau, iecri) == 0:
if ok_dyn_ins:
writehist(itau, vcov, ucov, teta, phi, q, masse, ps, phis)
MARS phymars/leapfrog_nogcm.F 保留同类门控:ok_dynzon 控制 bilan_dyn,ok_dyn_ave 控制 writedynav,ok_dyn_ins 控制 writehist。因此排查 Mars 动力 history 是否生成时,要同时检查 nogcm/gcm 初始化门和 leapfrog* 时间步门,不能只看 ok_dyn_* 是否为 true。
writehist 写出字段
writehist.F 先计算 itau_w = itau_dyn + time,再调用 covnat(llm,ucov,vcov,unat,vnat) 把协变风转为自然风。随后按 inithist 已注册字段写出,并在末尾同步三个文件 id。
| 字段 | file id | 数据来源 | 写出尺寸/索引 | 说明 |
|---|---|---|---|---|
u |
histuid |
unat |
iip1*jjp1*llm, ndexu |
U grid instant 风。 |
v |
histvid |
vnat |
iip1*jjm*llm, ndexv |
V grid instant 风。 |
teta |
histid |
teta |
iip1*jjp1*llm, ndexu |
位温。 |
phi |
histid |
phi |
iip1*jjp1*llm, ndexu |
位势。 |
masse |
histid |
masse |
iip1*jjp1*llm, ndexu |
层质量。 |
ps |
histid |
ps |
iip1*jjp1, ndex2d |
地表压。 |
tracer 循环和 phis 写出在当前串行源码中仍为注释行,与注册清单一致。写出末尾依次 histsync(histid), histsync(histvid), histsync(histuid)。
writedynav 写出字段
writedynav.F90 也先计算 itau_w = itau_dyn + time 并调用 covnat。它还分配局部数组 tm,按 tm = teta * ppk / cpp 计算温度,再写 averaged 字段。
| 字段 | file id | 数据来源 | 写出尺寸/索引 | 说明 |
|---|---|---|---|---|
u |
histuaveid |
unat |
iip1*jjp1*llm, ndexu |
averaged U 风。 |
v |
histvaveid |
vnat |
iip1*jjm*llm, ndexv |
averaged V 风。 |
theta |
histaveid |
teta |
iip1*jjp1*llm, ndexu |
位温。 |
temp |
histaveid |
teta*ppk/cpp |
iip1*jjp1*llm, ndexu |
温度派生量;依赖 comconst_mod:cpp。 |
phi |
histaveid |
phi |
iip1*jjp1*llm, ndexu |
位势。 |
masse |
histaveid |
masse |
iip1*jjp1*llm, ndexu |
层质量。 |
ps |
histaveid |
ps |
iip1*jjp1, ndex2d |
地表压。 |
tracer 和 phis 写出同样被注释。写出末尾同步 histaveid/histvaveid/histuaveid。
复现和排查顺序
- 编译选项先确认
CPP_IOIPSL。没有该宏时,inithist/writehist/initdynav/writedynav不执行 IOIPSL history API。 - 在
run.def中确认ok_dyn_ins、ok_dyn_ave和ok_dynzon。三者分别控制 instant history、averaged dynav 和bilan_dyn,不要互相替代。 - 检查
iecri、iperiod、periodav和day_step。初始化阶段用这些量换算t_ops/t_wrt,写出阶段用MOD(itau,iecri)和MOD(itau,iperiod)进门。 - 若 expected 文件是
dyn_hist*.nc或dyn_hist*_ave.nc,排查 COMMON 动力 history 链;若 expected 文件是diagfi.nc、stats.nc或 XIOS physics 输出,转到 Mars physics 输出页。 - 若需要 tracer 或
phis出现在 COMMON 串行 history 文件中,当前源码事实是这些histdef/histwrite行被注释,不能只改运行配置解决。
待确认
- 串行
inithist/writehist/initdynav/writedynav中 tracer 和phis被注释,而部分_p支撑实现保留更多字段;这是否是历史选择、当前 root 写出路径的有意裁剪,还是待清理差异,需要维护者确认。 histdef的t_ops/t_wrt时间单位由 IOIPSL API 解释;本页按调用方换算公式记录,未做运行文件 header 实测。