Mars utility 常量和垂直坐标使用链路
源码范围:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\comconst_mod.F90LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\comvert_mod.F90LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\vertical_layers_mod.F90- Mars 使用边界:
LMDZ.MARS\libf\dynphy_lonlat\phymars\newstart.F、start2archive.F、lect_start_archive.F、ini_archive.F、readhead_NC.F、datareadnc.F,以及LMDZ.MARS\libf\phymars\dyn1d\testphys1d.F90、init_testphys1d_mod.F90。
本文只解释 Mars utility 如何读取、重建、写回 COMMON 常量和垂直坐标状态;更宽的 start/restart/archive 文件职责见 Mars start/restart/archive 边界,垂直离散公式见 Mars 垂直坐标约定。
NetCDF 读写和 helper 边界见 Mars utility NetCDF 和 COMMON helper 边界:Mars archive utilities 主要直接使用 netcdf.inc/NF_*,COMMON netcdf95/handle_err 只适用于实际 nf95_* 调用链。
结论
Mars newstart/start2archive/archive 工具不是只搬 NetCDF 变量。它们会把 archive 或 start/startfi 中的控制量重新灌回 COMMON 状态模块,再调用 COMMON 初始化链重建当前编译网格下的常量、垂直坐标和物理侧垂直层副本。
核心链路是:
archive/start header or Mars defaults
-> comconst_mod: rad/omeg/g/cpp/kappa/r/daysec/dtvr/dtphys
-> comvert_mod: ap/bp/aps/bps/pa/preff/presnivs/pseudoalt
-> iniconst/inigeom/iniphysiq
-> inigeomphy -> init_vertical_layers
-> vertical_layers_mod physical-side copy
-> archive write, vertical interpolation, physics restart/writeout
这条链的关键边界是:comvert_mod 是动力侧固定维度数组,vertical_layers_mod 是物理侧 ALLOCATABLE, SAVE, THREADPRIVATE 副本。两者不会自动同步,必须由 inigeomphy -> init_vertical_layers 或 1D 初始化显式复制。
状态提供者
| 模块 | 状态 | 维度和含义 | Mars utility 使用方式 |
|---|---|---|---|
comconst_mod |
im,jm,lllm, dtvr, daysec, dtphys, rad, omeg, g, r, cpp, kappa, pi |
动力维度、时间步和行星常量 | newstart/readhead_NC/ini_archive/start2archive 读写 controle,lect_start_archive 用 kappa/g/pi 重构热力和守恒量,datareadnc 用 g/pi 做地形和角度换算。 |
comvert_mod |
ap,bp,aps,bps,presnivs,pseudoalt,pa,preff,scaleheight |
动力侧 hybrid/sigma 垂直层状态 | ini_archive 写入 archive;lect_start_archive 用新旧 ap/bp/aps/bps/preff 做垂直重映射;newstart/start2archive 在压力、Exner 和写出前使用。 |
vertical_layers_mod |
ap,bp,aps,bps,presnivs,pseudoalt,preff,scaleheight |
物理侧 allocatable/threadprivate 副本 | inigeomphy 或 1D init_testphys1d 调 init_vertical_layers 后供 Mars physics/XIOS/diagfi 使用。 |
vertical_layers_mod.F90 的 init_vertical_layers(nlayer,...) 只分配并复制输入数组,不重新计算垂直坐标。因此上游必须先保证 comvert_mod 中的 ap/bp/aps/bps/presnivs/pseudoalt 已经由 restart/header 或 disvert_noterre 等初始化路径生成。
newstart.F 的重建顺序
newstart.F 读取 start_archive.nc 或 start.nc/startfi.nc 后,会同时恢复 Mars 物理控制量和 COMMON 动力状态:
- 入口
USE comvert_mod, ONLY: ap,bp,pa,preff,并从comconst_mod取lllm/daysec/dtphys/dtvr/cpp/kappa/rad/omeg/g/r/pi。 - 初始 Mars 常量先给默认值:
cpp=744.499,preff=610.。这不是最终唯一来源,后续会结合controle和tabfi重写。 - 从 archive 或 start/startfi 读取
controle,把kappa和守恒基准量写回 COMMON 动力状态。 - 调
tabfi读 Mars physics 控制量,再写回rad/omeg/g/daysec;随后根据day_step计算dtvr=daysec/day_step,并派生dtphys=dtvr*iphysiq。 - 调
iniconst和inigeom后再调 Marsiniphysiq。iniphysiq内会进入 COMMONinigeomphy,把动力侧垂直层复制到vertical_layers_mod。 - 从 archive 分支进入
lect_start_archive;从 start/startfi 分支进入dynetat0/phyetat0。二者之后再写新的restart.nc/restartfi.nc。
复现要点:newstart 的 preff=610. 是 Mars utility 保护性默认值,但 archive/start 分支仍会把大量控制量从文件读回。不要把这一行理解为所有垂直坐标都绕过 controle 或 disvert_noterre。
start2archive.F 的合并顺序
start2archive.F 从 start.nc/startfi.nc 合成 start_archive.nc:
USE comvert_mod, ONLY: ap,bp,并从comconst_mod取daysec/dtphys/rad/g/r/cpp。- 先
defrun_new和infotrac_init,再调用dynetat0从start.nc恢复动力状态。 - 调
iniconst/inigeom/inifilr/iniphysiq之后,COMMON 常量、几何和物理侧垂直层状态才对后续 archive 写出可用。 - 物理网格字段通过
gr_fi_dyn回到动力 scalar 网格。 - 若 archive 不存在,调用
ini_archive写头、controle和垂直坐标;随后写当前Time=day_ini+hour_ini以及 2D/3D 变量。
复现要点:start2archive 依赖 dynetat0 和 phyetat0/tabfi 分别恢复动力与物理状态,但 archive 头中的常量和垂直坐标来自当前 COMMON 全局状态。因此如果先前的 iniconst/inigeom/iniphysiq 顺序被跳过,ini_archive 写出的 header 会不完整或不一致。
archive header 的写回和读取
ini_archive.F 是写出方向。它从 comconst_mod 和 comvert_mod 读取状态,填入长度 100 的 tab_cntrl:
tab_cntrl(1:3)=iim,jjm,llmtab_cntrl(4)=idayreftab_cntrl(5:11)=rad,omeg,g,molar-mass/kappa/daysec/dtvrtab_cntrl(12:16)=etot0,ptot0,ztot0,stot0,ang0tab_cntrl(17:18)=pa,preff
同一例程还定义并写出 ap,bp,aps,bps,presnivs,pseudoalt。这些变量让后续 archive 可同时支持动力侧 pressure 计算、物理侧 vertical axis 和旧网格到新网格的垂直插值。
readhead_NC.F 是读取方向。它把 controle 写回 im/jm/lllm/day_ini/rad/omeg/g/cpp/kappa/daysec/dtvr 和能量基准量,再设置 r=kappa*cpp。源码中 preff=610. 覆盖了注释里的 tab_cntrl(18) 读取路径,并带有“diagfi 不一定适用”的注释。这是 Mars utility 的特殊边界:readhead_NC 并不等价于完整反序列化 ini_archive 的每一个字段。
lect_start_archive.F 的垂直插值使用
lect_start_archive.F 是 newstart 从 archive 重建 start 的核心读入器。它直接 USE comvert_mod, ONLY: ap,bp,aps,bps,preff,并从 comconst_mod 取 kappa,g,pi。
关键使用点:
- 读取旧 archive 的垂直坐标,与当前
comvert_mod中的新坐标对照。 aps/bps参与 mid-layer 变量垂直插值;ap/bp参与 interface 变量和 pressure 层构造。preff和kappa用于热力变量重构,例如h = t*((ps/preff)**kappa)。g用于 surface pressure、CO2 ice 和大气质量的守恒缩放。
复现要点:lect_start_archive 是兼容旧 archive 的地方。它可以处理某些旧变量名或缺失分支,但这种 fallback 不应推广到 readhead_NC、ini_archive 或其他读取器。
datareadnc.F 的常量使用
datareadnc.F 不使用垂直坐标,但使用 COMMON 常量接口。它从 comconst_mod 取 g,pi,读取 surface.nc 并把地形、反照率、热惯量等插值到当前动力网格:
pi用于角度和弧度转换。g用于地形/位势高度相关换算。getin("datadir",datadir)决定 surface 数据路径。
这说明 Mars utility 的常量使用不只在 archive header 内,也贯穿 surface 初始化和网格插值输入准备。
1D/testphys1d 边界
Mars 1D 路径通过 phymars/dyn1d 转发文件暴露 COMMON 模块名,但初始化顺序不同于 3D GCM:
init_testphys1d_mod.F90手写 Mars 常量:rad=3397200.,daysec=88775.,g=3.72,mugaz=43.49,并派生r/cpp/rcp。- 默认
psurf=610.、pa=50.、preff=610.,也可以从start1D.txt或testphys1d.def覆盖。 - 调
disvert_noterre写入comvert_mod。 - 立即调用
init_vertical_layers(nlayer,preff,scaleheight,ap,bp,aps,bps,presnivs,pseudoalt)。 - 用
plev=ap+psurf*bp、play=aps+psurf*bps供physiq调用;主循环中 surface pressure 变化后再重算plev/play。
复现要点:1D 是接口兼容路径,不走 3D newstart/start2archive 的 archive header 链,也不应把 1D 的手写常量顺序误写成 3D GCM 的正常初始化顺序。
检查清单
复现或排查 Mars utility 常量/垂直状态时,按以下顺序检查:
- 文件来源:当前路径是 archive、start/startfi、还是 1D 文本 restart。
- 常量来源:
rad/omeg/g/daysec/kappa/cpp/r/dtvr/dtphys是从controle/tabfi恢复,还是由 1D/Mars 默认值重建。 - 垂直坐标来源:
ap/bp/aps/bps/presnivs/pseudoalt是从当前disvert_noterre生成,还是由 archive 变量参与插值。 - 物理侧副本:是否已经调用
iniphysiq -> inigeomphy -> init_vertical_layers,或 1D 直接调用init_vertical_layers。 preff边界:newstart/readhead_NC/init_testphys1d存在 Mars610 Pa默认或覆盖,不能简单假设tab_cntrl(18)在所有工具中原样生效。- 旧 archive 兼容:
lect_start_archive的 fallback 只属于 archive 读入插值路径,不能替代 header 读取器的要求。
风险和待确认
readhead_NC.F中preff=610.与ini_archive.F写tab_cntrl(18)=preff存在非对称行为;源码注释说明这和diagfi/start适用范围有关,但未做运行样例验证。- 本页根据源码静态确认,不验证具体
start_archive.nc是否包含完整ap/bp/aps/bps/presnivs/pseudoalt。 - 1D 路径的
init_vertical_layers调用已确认;但不同testphys1d.def/start1D.txt组合下的输入覆盖优先级需要结合运行文件进一步检查。