Transport And Advection

源码范围:LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\advtrac.F90libf\dyn3dpar\advtrac_p.F90libf\dyn3d_common\infotrac.F90 和 tracer transport 内核组。

Mars 运行参与度:必经 + 条件经过。Mars 3D 运行必经 infotrac_init 建立 tracer 元数据,并在动力时间步中通过 advtracadvtrac_p 进入输送调度;具体数值格式由 traceur.def 读出的 iadv(:) 和当前白名单共同决定。

阅读顺序

这条主题页面向排查 tracer 输送路径、复现单个 tracer 结果和判断旧格式是否可达的读者。推荐顺序:

  1. 先读 infotrac,确认 traceur.defnqtrue/nqtotiadv(:)、父子 tracer 和 isotope 状态。
  2. 再读 dyn3d/advtraccaladvtrac 到 tracer advection 循环advtrac 串并行对照,理解串行文件局部状态、iapp_tracvl 累计门控、nqperes/iadv 循环、串行 caladvtrac wrapper 和并行 advtrac_p 直调差异。
  3. 标准 Mars tracer 优先读 vlspltvlsplt_pvlspltgen_p
  4. 饱和水汽路径读 vlspltqsvlspltqs_p
  5. 历史或本地补丁格式先读 COMMON tracer advection schemes,再深入 ppm3dadvnpratherpentes_ini
  6. 若需要区分 advx/advy/advzadvn.F 内部 advnx/advny/advnzadaptdt,读 COMMON tracer advection operator family

总入口

traceur.def
  -> infotrac_init
      -> nqtot, tname, ttext, iadv, niadv, family/isotope state
  -> gcm/gcm_p allocate q(...,nqtot)
  -> leapfrog/leapfrog_p
      -> caladvtrac -> advtrac   (串行)
      -> advtrac_p               (并行)
          -> transport scheme

advtrac 不是数值格式本身。它是把当前质量、水平质量通量、垂直通量和 tracer 表送入具体格式的调度层。排查结果差异时,不能只看 advtrac,必须同时确认:

iadv 到格式

infotrac.F90 源码注释保留了完整历史编号,但 当前可运行边界更窄:

iadv 格式 主要页面 当前 Mars 标准可达性
0 跳过 advection infotrac advection scheme 可通过,表示不输送。
10 Van Leer split vlsplt, vlsplt_p 标准可达;普通 tracer 主路径。
14 Van Leer + specific humidity / saturated path vlspltqs, vlspltqs_p 仅允许第 1 个 tracer;通常用于水汽或饱和路径。
11, 16, 17, 18 PPM / Lin-Rood transport ppm3d 串行代码保留,但当前 infotrac_init 白名单通常阻断。
12, 13 Hourdin pseudo amont advn advn 串行代码保留,但当前 infotrac_init 白名单通常阻断。
20 Slopes / moments 扩展 pentes_ini 扩展逻辑保留,当前白名单阻断。
30 Prather moments prather 扩展逻辑保留,当前白名单阻断。

当前 infotrac_init 在写入 iadv(:) 后逐 tracer 检查:只允许 1014014 还要求 iq==1。父子 tracer 额外要求子 tracer 使用 10,父 tracer只能使用 1014

标准 Van Leer 路径

Van Leer 是当前 Mars tracer 输送最应优先理解的路径。

串行:

advtrac.F90
  -> if iadv(iq)==10: vlsplt(q,2.,massem,wg,pbarug,pbarvg,dtvr,iq)
  -> if iadv(iq)==14: vlspltqs(q,2.,massem,wg,pbarug,pbarvg,dtvr,p,pk,teta,iq)

并行:

advtrac_p.F90
  -> vlspltgen_p(q,iadv,2.,massem,wg,pbarug,pbarvg,dtvr,p,pk,teta)
  -> GOTO 1234

串行 vlsplt 和并行 vlsplt_p 都采用 x-y-z-y-x split,水平通量半步、垂直通量整步。关键差异是并行版要处理 ij_begin/ij_end band、halo 注册、OpenMP 同步和父子 tracer 垂直通量修正。

主题 串行 并行
调度入口 advtrac 对每个 iq 分支 advtrac_p 先调用 vlspltgen_p
普通 Van Leer vlsplt vlspltgen_p 调用 vlx_p/vly_p/vlz_p
饱和路径 vlspltqs vlspltgen_p/vlspltqs_p
父子 tracer nqdesc/nqfils/iqfils 递归比例输送 同一概念,外加 band/halo/OMP 同步
极点 串行全域处理 仅持有 pole_nord/pole_sud 的 rank 处理

深入页:

PPM 路径

PPM 相关代码主要保留为历史兼容和本地补丁风险面。串行 advtrac.F90iadv=11/16/17/18 时有完整 adaptdt -> interpre -> ppm3d -> interpost 调用链:

iadv IORD/JORD/KORD 含义
11 2/2/2 水平 Van Leer + 垂直 PPM 兼容映射。
16 3/3/3 Monotonic PPM。
17 4/4/4 Semi-monotonic PPM。
18 5/5/5 Positive-definite PPM。

但在当前:

PPM 复现必须同时复现 interpre 的垂直翻转、经向风取反、地面气压换算和 interpost 的周期闭合。只直接调用 ppm3d 不等价于 LMDZ 串行分支。

advn 和 Prather 路径

advn 是 Hourdin pseudo amont 内核,串行 advtraciadv=12/13 时调用;它和 Van Leer 一样使用 x-y-z-y-x split,但在 advnqx/advnqy/advnqz 中先做 4 阶界面重构,再由 advnx/advny/advnz 做通量更新。mode=1/2 只直接影响 E-W advnx

prather 使用 q(...,0:9) 的 moments 表示,并调用 advxp/advyp/advzp 做方向输送。iadv=30 会让 nqtot 对每个真实 tracer 扩展 9 个 moments 条目;iadv=20 的 slopes 路径会扩展 3 个条目。

这两类路径当前同样受 infotrac_init 白名单阻断。读这些页面时应把它们视为:

串并行边界

并行 advtrac_p 的当前控制流是本主题最容易误读的点。源码中虽然保留 vlsplt_pvlspltqs_padvnpentes_inipratherppm3d 等分支文本,但实际在 vlspltgen_p 之后跳到标签 1234

因此并行生产路径应按以下规则读:

  1. 先读 vlspltgen_p,它是并行 tracer split 调度入口。
  2. 再读 vlsplt_p_p 内核和 halo/band 机制。
  3. 不要从 advtrac_pGOTO 1234 之后的旧分支推断当前可达性。
  4. 若本地补丁删除或移动 GOTO 1234,需要重新审计 PPM/advn/Prather 的并行化状态。

复现检查点

  1. 保存并确认 traceur.defiadvtname、父子关系和 nqtot 都从它推导,不应只记录 tracer 数。
  2. 先用 infotrac_init 的白名单判断格式能否启动,再看 advtrac 中是否有下游分支。
  3. nqtruenqtotniadv 不可混用;moments 扩展会让动力数组维度大于真实 tracer 数。
  4. Van Leer 水平 split 使用半步通量,垂直使用整步通量;PPM 和 advn 也有自己的子步或通量缩放约定。
  5. 父子 tracer 复现必须带上 nqdesc/nqfils/iqfils/qperemin/masseqmin
  6. 并行结果排查必须同时看 halo 宽度、band 范围、极点 rank 和 OpenMP barrier。
  7. PPM、advn、Prather 的源码存在不等于当前 Mars 标准配置可达。

相关页面

待确认