restart 变量读写和控制量重置约定
源码范围:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\dynetat0.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\dynredem.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\sortvarc.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\sortvarc0.F
Mars 运行参与度:必经到条件经过。Mars 3D 从 start.nc 继续运行时经过 dynetat0,动力 restart 写出时经过 dynredem0/1;sortvarc 只在 caldyn/caldyn_p 的守恒诊断门打开时条件经过。
命名澄清
原标题中的 “变量排序” 容易误读。源码里的 sortvarc 注释是 “sortie des variables de controle”,实际作用是输出/重置质量、能量、涡度、角动量等控制量诊断,不是 restart 变量重排算法。真正的 restart 变量匹配发生在:
dynetat0.F90:按固定变量名从start.nc/restart.nc读取controle,vcov,ucov,teta, tracer,masse,ps。dynredem.F90:创建同名变量并追加时间记录;tracer 变量名来自infotrac:tname(iq)。sortvarc.F:在运行中计算控制量,并可用resetvarc/read_start决定是否重设etot0/ptot0/ztot0/stot0/ang0基准。
sortvarc0.F 保留了旧式初始控制量计算实现;当前 当前 COMMON libf 源码搜索只发现它自身定义,未发现活动调用点。
restart 变量名约定
| 变量类别 | 写出端 dynredem.F90 |
读入端 dynetat0.F90 |
风险 |
|---|---|---|---|
| 控制表 | dynredem0 写 controle,当前源码还写 controle_descriptor |
dynetat0 先读 controle |
读入端依赖数组位置,文件若来自旧格式或错误行星布局会造成常量/日期错位。 |
| 时间轴 | Earth-like 文件写 temps;planeto/Mars-like 文件写 Time |
先找 temps,缺失时回退 Time |
文件同时存在或命名不符合行星类型时需要确认实际选择。 |
| 状态场 | ucov, vcov, teta, masse, ps |
固定同名读取 | 缺失会通过 NetCDF 错误 abort。 |
| 地表位势 | dynredem0 写 invariant phisinit |
dynetat0 读取 phisinit |
只在创建骨架时写,不是每个 time record 变量。 |
| tracer | dynredem0 用 tname(iq) 定义变量,dynredem1 用同名写入 |
dynetat0 用 tname(iq) 查询变量 |
traceur.def / infotrac 名称变化会导致旧 restart 中 tracer 缺失;缺失 tracer 默认置零。 |
这意味着 COMMON restart 没有一个独立的“排序表”把文件变量重排到内部数组;它依靠固定动力变量名和当前 infotrac:tname(:) 与 NetCDF 变量名一一匹配。
dynetat0 读入流程
关键源码位置:
| 阶段 | 行号 | 行为 |
|---|---|---|
| 打开文件并读取控制表 | 68-71 | NF90_OPEN(fichnom) 后读取 controle。 |
| 判断布局 | 75-88 | planet_type=="generic" 或 "mars" 使用 planeto-like 布局,idecal=4;Earth/Titan 使用 Earth-like 布局,idecal=5。 |
| 解码控制表 | 92-116 | 解码 im/jm/lllm/day_ini/day_ref/rad/omeg/g/cpp/kappa/daysec/dtvr/etot0/ptot0/ztot0/stot0/ang0 等。 |
| 读取时间轴 | 170-205 | 先查 temps;缺失时查 Time;两者都缺失则 abort。 |
| 选择时间片 | 207-227 | timestart<0 取最后一条;否则按 0.01 容差查匹配时间,找不到则 abort。 |
| Mars 时间重组 | 229-235 | time0=time(indextime)+hour_ini,整数部分加到 day_ini,小数部分写回 hour_ini。 |
| 固定状态场 | 246-295 | 读取 vcov, ucov, teta, tracer, masse, ps。 |
tracer 读取是 Mars 复现中最容易踩到的部分。dynetat0 263-288 行对 iq=1,nqtot 逐个使用当前 tname(iq) 查询 NetCDF 变量;如果缺失,它打印 Tracer <name> is missing 并把该 tracer 初始化为 0。Earth isotope 分支可做理论初始化,但 Mars/generic 不走这个补偿。
dynredem 写出流程
dynredem0 创建 restart 骨架,dynredem1 追加记录:
| 阶段 | 行号 | 行为 |
|---|---|---|
| 写控制表核心项 | 107-129 | 写 im/jm/llm、日期、常量、dtvr 和 etot0/ptot0/ztot0/stot0/ang0。 |
| 定义时间轴 | 303-310 | Earth-like 文件定义 temps,planeto/Mars-like 文件定义 Time。 |
| 定义状态变量 | 312-323 | 定义 ucov, vcov, teta, 每个 tname(iq), masse, ps。 |
| 追加前重写控制表 | 409-420 | 读取 controle,Earth-like 写 tab_cntrl(31/32);非 Earth 把 tab_cntrl(31)=0,再写回。 |
| 写状态场 | 423-427 | 写 ucov/vcov/teta/masse/ps 当前时间记录。 |
| 写 tracer | 429-449 | 若 type_trac=='inca' 且存在 start_trac.nc,可先按 tname(iq) 读取覆盖;随后写到 restart 同名变量。 |
dynredem-restart 中记录了 controle_descriptor 和 tab_cntrl(32)=time 的细节。本页关注变量名和 tracer 对齐风险。
sortvarc 控制量基准
sortvarc 不是 restart 读写器,但它与 restart 控制表有关:dynetat0 会从 controle 恢复 etot0/ptot0/ztot0/stot0/ang0,dynredem0 会把这些基准值写入 controle,而 sortvarc 可以在第一次守恒诊断时重设它们。
| 行号 | 行为 |
|---|---|
| 65 | firstcal=.true. 是 SAVE 状态,只影响首次调用。 |
| 69-75 | 如果第一次调用且 .not.read_start,源码把 resetvarc=.true.,用于理想化初态重设基准。注释文字写 “set to false”,但实际代码赋 .true.。 |
| 141-146 | 计算当前 ptot/etot/ztot/stot/rmsv/ang。 |
| 148-159 | firstcal.and.resetvarc 时把当前值写入 etot0/ptot0/ztot0/stot0/ang0。 |
| 161-172 | 后续输出相对变化;若基准为 0,则置相对值为 1。 |
调用点只有两个:
dyn3d/caldyn.F139-141:conser为真时调用。dyn3dpar/caldyn_p.F207-210:conser为真时调用,注释说明需要 collective communication。
因此 sortvarc 对 restart 文件的影响是间接的:它改变内存中的控制量基准,后续 dynredem0 写 controle 时会把这些基准写出去。若从 start.nc 读入并且 resetvarc 不启用,则基准来自 restart;若不读 start 或显式重置,则基准来自第一次诊断时的当前状态。
Mars tracer 名称对齐风险
Mars restart 是否能无损继续,取决于当前 tracer 表和文件变量名:
infotrac_init先决定nqtot和tname(:)。dynetat0按这些tname(:)读取文件变量。- 缺失 tracer 不 abort,而是置零。
dynredem0按当前tname(:)创建新 restart 变量。dynredem1按当前tname(:)写入。
所以只要 traceur.def、当前 tracer parser 或 MARS physics tracer 名发生变化,旧 restart 仍可读完,但缺失 tracer 可能悄悄变成零场。复现实验时必须检查 dynetat0: Tracer <...> is missing 日志,而不能只看程序是否继续运行。
复现检查表
- 确认
planet_type,决定controle解码偏移和时间轴名。 - 用当前
traceur.def生成的tname(:)对照 restart NetCDF 变量名。 - 检查日志中是否有缺失 tracer;Mars 下缺失就是零初始化。
- 若守恒基准跳变,确认
read_start、resetvarc和第一次sortvarc调用时机。 - 若 restart 时间不对,回到 dynredem-restart 和 leapfrog-output-restart 检查传入
dynredem1的time。
待确认
sortvarc0.F在 当前 COMMONlibf内未找到活动调用点;是否仍被外部或历史构建目标使用,需要构建脚本级证据确认。sortvarc.F注释说无初始化场时resetvarcshould be set to false,但代码实际设为.true.;本页按代码行为记录,设计意图待确认。- MARS 具体实验中哪些 tracer 名变更最常见,需要结合
traceur.def样例和 physics 配置确认。