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_insok_dyn_ave、编译包含 CPP_IOIPSL、并经过对应 GCM/nogcm 输出门时,COMMON 动力 history/dynav 输出才会初始化和写出。Mars physics 的 diagfi/stats/XIOS 是另一条输出链,不由这些例程写出。

例程定位

inithistinitdynav 定义 IOIPSL history 文件、垂直轴和变量清单;writehistwritedynav 在时间推进中按门控写变量。四个 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_dynbilan_dyn_p,不等同于 dynav 文件。
ok_dyn_ins .FALSE. instant dyn_hist*.nc 初始化和写出门。
ok_dyn_ave .FALSE. averaged dyn_hist*_ave.nc 初始化和写出门。

初始化在 gcmgcm_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.ncstats.nc 或 XIOS 输出。

inithist 字段注册

inithist.F 创建 U/V/scalar 三个 instant 文件。经纬度来自 comgeom.hrlong/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),...)phishistdef 都是注释行。因此当前 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 对应输入 tetatempwritedynav 内由 teta*ppk/cpp 派生。

initdynav 中 tracer 和 phishistdef 同样处于注释状态。当前串行 averaged dynav 不注册 tracer 或 surface geopotential。

写出门控

leapfrog.Fleapfrog_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_dynok_dyn_ave 控制 writedynavok_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

复现和排查顺序

  1. 编译选项先确认 CPP_IOIPSL。没有该宏时,inithist/writehist/initdynav/writedynav 不执行 IOIPSL history API。
  2. run.def 中确认 ok_dyn_insok_dyn_aveok_dynzon。三者分别控制 instant history、averaged dynav 和 bilan_dyn,不要互相替代。
  3. 检查 iecriiperiodperiodavday_step。初始化阶段用这些量换算 t_ops/t_wrt,写出阶段用 MOD(itau,iecri)MOD(itau,iperiod) 进门。
  4. 若 expected 文件是 dyn_hist*.ncdyn_hist*_ave.nc,排查 COMMON 动力 history 链;若 expected 文件是 diagfi.ncstats.nc 或 XIOS physics 输出,转到 Mars physics 输出页。
  5. 若需要 tracer 或 phis 出现在 COMMON 串行 history 文件中,当前源码事实是这些 histdef/histwrite 行被注释,不能只改运行配置解决。

待确认

相关页面