动力控制和逻辑门控链
源码范围:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\conf_gcm.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\gcm.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\gcm.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\leapfrog.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\leapfrog_p.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\control_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\logic_mod.F90
Mars 边界上下文:
LMDZ.MARS\libf\dynphy_lonlat\phymars\nogcm.F90
LMDZ.MARS\libf\dynphy_lonlat\phymars\leapfrog_nogcm.F
Mars 运行参与度:必经到条件经过。COMMON 串行/并行 gcm 主入口经过本页的 conf_gcm -> control_mod/logic_mod -> leapfrog* 链;MARS phymars/nogcm.F90 也使用这些 COMMON 状态模块,但它不是 COMMON 源文件。后续维护不应把 MARS phymars/nogcm.F90 或 leapfrog_nogcm.F 当成 COMMON 当前文件页目标。
这个页面回答什么
common-state-control-contract 已经说明 control_mod、logic_mod、temps_mod、comconst_mod 各自保存什么状态。本页补充调用链问题:一个 run.def/getin 开关如何先被 conf_gcm 写入模块,再由 gcm/gcm_p/nogcm 做入口约束,最后在 leapfrog* 的每个时间步变成 forward/leapf/apphys/apdiss 等逻辑门控。
状态容器
| 模块 | 源码定义 | 本页关注的状态 |
|---|---|---|
control_mod |
dyn3d_common/control_mod.F90 |
nday, day_step, iperiod, iphysiq, ndynstep, less1day, fractday, dissip_period, iconser, iecri, periodav, ok_dyn_ins, ok_dyn_ave, ok_dynzon, ecritstart, planet_type, read_start 相关运行控制。 |
logic_mod |
dyn3d/logic_mod.F90 |
purmats, forward, leapf, apphys, apdiss, conser, statcl, ok_guide, read_start, iflag_phys 等逻辑门。 |
temps_mod |
dyn3d/temps_mod.F90 |
itaufin, itau_dyn, day_ini, day_end, jD_ref, jH_ref, dt 等时间状态。 |
comconst_mod |
dyn3d_common/comconst_mod.F90 |
daysec, dtvr, dtphys, dtdiss 等由入口和初始化链派生的时间常量。 |
control_mod 里大多数变量是 SAVE 全局状态,logic_mod 则没有把 forward/leapf/apphys/apdiss 当成配置默认值保存;这些标志在 leapfrog* 时间循环里反复重置,只代表当前步的阶段。
从配置到入口约束
conf_gcm.F90 的 USE 列表在源码 12-31 行直接写明它会写 control_mod、logic_mod、comconst_mod 和 temps_mod。关键 getin 写入点如下:
| 配置键或状态 | conf_gcm.F90 行 |
写入模块 | 入口约束或后续用途 |
|---|---|---|---|
planet_type |
112-117 | control_mod |
决定 Mars/generic/Earth 日期、restart 和默认分支。 |
nday |
160-166 | control_mod |
默认运行天数;负值在 leapfrog* 中按动力步数解释。 |
ndynstep |
168-171 | control_mod |
若大于 0,覆盖 nday/less1day 推导的 itaufin。 |
starttime, timestart, ecritstart |
180-193 | control_mod |
初始时间和中途 restart 写出门控。 |
less1day, fractday |
195-207 | control_mod |
小于一天运行的替代结束步数。 |
day_step |
209-215 | control_mod |
每日动力步数;入口用它计算 dtvr=daysec/day_step。 |
nsplit_phys, iperiod, iapp_tracvl |
222-236 | control_mod |
physics 子步、Matsuno 周期、tracer advection 累积周期。 |
dissip_period, idissip |
279-281 | control_mod |
耗散调用周期;idissip 是旧 Mars/Generic 兼容键。 |
purmats |
449 | logic_mod |
选择纯 Matsuno 还是 Matsuno + leapfrog。 |
ok_guide |
451-456 | logic_mod |
guide/nudging 条件路径。 |
read_start |
458-464 | logic_mod |
入口选择 dynetat0("start.nc") 或 iniacademic。 |
iflag_phys, iphysiq |
466-479 | logic_mod / control_mod |
physics 是否开启和调用频率。 |
offline |
510-516 | control_mod |
offline flux storage 条件路径。 |
ok_dynzon, ok_dyn_ins, ok_dyn_ave |
538-560 | control_mod |
zonal diagnostic、instant history、dynav/平均输出。 |
入口程序随后做三类硬约束:
- 串行
gcm.F90166-168 行、并行gcm.F180-182 行、MARSnogcm.F90155-157 行都要求iphysiq是iperiod的倍数。 - 串行
gcm.F90292-300 行和并行gcm.F310-318 行要求day_step分别是iperiod和iphysiq的倍数。MARSnogcm.F90保留day_step/iperiod检查,但day_step/iphysiq检查在源码 287-289 行被注释掉。 - 串行
gcm.F90304-309 行、并行gcm.F322-327 行、MARSnogcm.F90293-296 行都用daysec/day_step计算zdtvr,必要时覆盖dtvr。
因此配置层只给出意图,真正进入时间推进前还必须经过入口一致性检查。排查“physics 没调用”或“输出频率不对”时,应先确认这些整除关系是否使配置有效。
入口分流
| 入口 | 配置读取 | 初态分支 | 常量/物理初始化 | 时间推进 |
|---|---|---|---|---|
COMMON 串行 dyn3d/gcm.F90 |
CALL conf_gcm(99,.TRUE.),源码 166 行 |
read_start 时走 dynetat0,否则 iniacademic |
iflag_phys==1 时 iniconst/inigeom/inifilr,iflag_phys==1 or >=100 时 iniphysiq |
CALL leapfrog(...),源码 534 行。 |
COMMON 并行 dyn3dpar/gcm.F |
CALL conf_gcm(99,.TRUE.),源码 180 行 |
同样按 read_start 分流,另有 MPI/OMP、band、halo 初始化 |
iniphysiq 接收本 rank 的物理分布和 dtphys/nsplit_phys |
CALL leapfrog_p(...),源码 567 行。 |
MARS phymars/nogcm.F90 |
CALL conf_gcm(99,.TRUE.),源码 155 行 |
同样使用 read_start,但入口属于 MARS 树 |
调用 COMMON 常量/几何初始化和 MARS physics 初始化 | CALL leapfrog_nogcm(...),源码 518 行。 |
nogcm 行只用于说明 MARS 边界:当前 COMMON 源码已删除 dyn3d/nogcm.F90 和 dyn3d/leapfrog_nogcm.F,当前 COMMON wiki 不为它们创建文件页。
时间循环内的逻辑门
leapfrog.F 和 leapfrog_p.F 使用相同的基础门控,后者再叠加 SetDistrib、halo/swap、gather 输出等并行调度。核心阶段如下:
| 门控 | 串行行号 | 并行行号 | 生成逻辑 | 主要使用位置 |
|---|---|---|---|---|
itaufin |
216-227 | 237-248 | nday*day_step;若 nday<0 用 -nday;less1day 用 fractday*day_step;ndynstep>0 最终覆盖。 |
主循环终止、lafin、最终 restart。 |
forward, leapf 初值 |
344-345 | 405-406 | 每个 Matsuno 周期开头设 forward=.TRUE., leapf=.FALSE.。 |
dt 选择、动力 tendency、输出避开半步状态。 |
apphys |
384-401 | 454-471 | 每步先置 false;purmats 时看 MOD(itau,iphysiq) 且非 forward;非 purmats 时看 MOD(itau+1,iphysiq)。 |
calfis/calfis_p 和 addfi/addfi_p。 |
apdiss |
387-411 | 457-481 | 每步先置 false;按 dissip_period 与阶段设置;offline 或 iflag_phys>=100 时强制 false。 |
dissip/dissip_p,MARS leapfrog_nogcm 不使用。 |
lafin |
520-523 | 851-854 | 末步或末步前的 physics 调用标志,取决于 purmats 和当前阶段。 |
传给 calfis/calfis_p。 |
| 输出/诊断门 | 825-856, 879-887, 993-1042 | 1669-1709, 1762-1784, 1903-2009 | iperiod 控制 dynav/zonal,ok_dyn_ins 控制 instant history,半步状态不写。 |
bilan_dyn*, writehist*, writedynav*。 |
| restart 门 | 900-921, 1055-1074 | 1808-1833, 2033-2056 | 末步必写;ecritstart>0 时中途步可写,Mars 分支使用特殊时间表达式或 JH_cur。 |
dynredem1/dynredem1_p。 |
| 阶段切换 | 932-957, 969-1079 | 1844-1869, 1878-2062 | MOD(itau,iperiod) 或 MOD(itau-1,iperiod) 决定回到 forward、进入 backward 或 leapfrog。 |
下一轮 dt、forward/leapf 和 tendency 解释。 |
MARS leapfrog_nogcm.F 保留 forward/leapf/apphys/lafin 和输出/restart骨架,但源码注释和 USE 列表显示它删除了 apdiss 相关耗散门。它在 403-427 行重置 physics 门,549-571 行调用 calfis/addfi,867-878 和 998-1006 行只在最终步写 restart。
复现顺序
run.def / getin
-> conf_gcm writes control_mod + logic_mod
-> gcm/gcm_p/nogcm checks iphysiq/iperiod/day_step
-> zdtvr = daysec / day_step; dtvr may be overwritten
-> read_start ? dynetat0 : iniacademic
-> iflag_phys gate initializes constants/geometry/physics
-> leapfrog* computes itaufin
-> each step resets forward/leapf/apphys/apdiss
-> caldyn/caladvtrac/integrd, calfis/addfi, dissip, output, restart
最容易混淆的是 iphysiq、iflag_phys 和 apphys:iphysiq 是配置频率,iflag_phys 是物理模式,apphys 是当前步是否真正调用 physics 的临时门。只看 run.def 中 iphysiq 不能判断某一步一定会调用 physics,还必须知道 purmats、forward/leapf、physics=(iflag_phys==1 or iflag_phys>=100) 和当前 itau。
串并行差异
串行 leapfrog.F 和并行 leapfrog_p.F 的时间门控一致,但并行版增加三个约束:
dyn3dpar/gcm.F在进入主循环前初始化 MPI/OMP、读取/写出 band 分布,并在源码 204 行先SetDistrib(jj_Nb_Caldyn)。leapfrog_p.F在动力、物理和耗散之间多次SetDistrib,例如 492、596、1001、1042、1187、1346、1541 行,把当前纬向分布切到对应计算阶段。- 输出和 restart 前需要 gather/root 写出语义;门控仍由
ok_dyn*,iperiod,iecri,ecritstart控制。
所以并行问题要分两层查:先按本页确认时间门是否打开,再按 leapfrog_p、parallel_lmdz、mod_hallo 查 band/halo/gather 是否把数据送到了正确分布。
常见排查入口
| 现象 | 先查 | 再查 |
|---|---|---|
| physics 没有调用 | iflag_phys, iphysiq, MOD(itau,iphysiq), forward/leapf |
leapfrog-physics-coupling、MARS call_physiq。 |
| 耗散没有调用 | dissip_period, apdiss, offline, iflag_phys>=100 |
leapfrog-dissipation-conservation、inidissip。 |
| history 缺步 | ok_dyn_ins, iecri, forward/leapf 半步过滤 |
leapfrog-output-restart、history-output-serial-parallel。 |
| dynav/平均输出频率不对 | iperiod, periodav, ok_dyn_ave, ok_dynzon |
history-xios-getin-boundary。 |
| restart 时间不对 | ecritstart, planet_type, JH_cur, time_0, day_end-day_ini |
dynredem-restart、restart-io。 |
| Mars nogcm 和 COMMON GCM 行为不一致 | 入口是否为 MARS phymars/nogcm.F90 |
本页的 nogcm 边界说明和 dynamics-time-integration。 |
待确认
- MARS 标准生产脚本中完整串行
gcm、并行gcm和 MARSnogcm的使用比例,需要结合具体实验脚本确认;源码只能证明这些入口都使用同一状态层。 - MARS
nogcm.F90注释掉day_step/iphysiq整除检查的运行学原因未在源码附近说明,本页只记录事实。 purmats在当前 Mars 配置中的实际启用场景需要运行配置样例确认。