COMMON tracer advection operator family
源码范围:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\advx.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\advy.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\advz.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\advn.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d_common\adaptdt.F
Mars 运行参与度:条件经过 + 历史兼容。这些例程位于 tracer advection 的旧格式和 moments/slope 支撑层:adaptdt 被串行 advtrac 的 iadv=12/13/30/11/16/17/18 分支调用;advn.F 是 iadv=12/13 的 pseudo-amont 内核;advx/advy/advz 由 pentes_ini.F 的 iadv=20 slope/moments 路径调用。当前 infotrac_init 标准白名单只允许 iadv=0/10/14,因此这些路径通常不是 Mars 标准生产 tracer 输送路径。
命名边界
原标题中写了 “Van Leer 短小平流算子 family”,但源码确认后需要精确区分:
- Mars 标准 Van Leer 路径是
advtrac -> vlsplt或并行advtrac_p -> vlspltgen_p,不直接调用advx/advy/advz。 advx/advy/advz是 first-order moments/slope 方向输送算子,由pentes_ini按 x-y-z-y-x 顺序调用。advn.F是独立 pseudo-amont 文件,内部例程名是advnqx/advnqy/advnqz和advnx/advny/advnz;它不调用外部advx/advy/advz。adaptdt只根据水平 CFL 估计子步数,供advn、Prather 和 PPM 保留分支使用;iadv=10/14的标准 Van Leer 分支不调用它。
因此本页的作用是把这些相邻历史 advection helper 的真实调用边界整理清楚,避免把“源码存在”误读为“当前 Mars 标准可达”。
文件与例程清单
| 文件 | 行数 | 例程 | 活动调用方 |
|---|---|---|---|
advx.F |
497 | advx |
pentes_ini.F 的 x 半步,调用两次。 |
advy.F |
420 | advy |
pentes_ini.F 的 y 半步,调用两次。 |
advz.F |
320 | advz |
pentes_ini.F 的 z 整步,调用一次。 |
advn.F |
977 | advn, advnqx, advnqy, advnqz, advnx, advny, advnz |
串行 advtrac.F90 在 iadv=12/13 分支调用;标准 白名单通常阻断。 |
adaptdt.F |
54 | adaptdt |
串行 advtrac.F90 的 iadv=12/13/30/11/16/17/18 分支;并行文件中同名文本在 GOTO 1234 后不可达。 |
调用图
当前源码中的直接调用关系:
advtrac.F90
iadv=12 -> adaptdt -> repeat advn(...,mode=1)
iadv=13 -> adaptdt -> repeat advn(...,mode=2)
iadv=20 -> pentes_ini
-> limx -> advx(0.5*dtvr)
-> limy -> advy(0.5*dtvr)
-> limz -> advz(dtvr)
-> limy -> advy(0.5*dtvr)
-> limx -> advx(0.5*dtvr)
iadv=30 -> adaptdt -> prather
iadv=11/16/17/18 -> adaptdt -> interpre -> ppm3d -> interpost
并行 advtrac_p.F90 源码中也保留 adaptdt/advn/prather/ppm3d 文本,但当前控制流先调用 vlspltgen_p,随后 GOTO 1234 跳过这些旧分支。
advx/advy/advz moments 算子
这三个文件处理的是 pentes_ini 构造出的 moments 表示:
| 参数组 | 含义 |
|---|---|
SM |
每个网格盒空气质量。 |
S0 |
tracer 质量,而非 mixing ratio。 |
sx/sy/sz |
三个方向的一阶矩。 |
limit |
是否将对应方向的一阶矩限制到 [-S0,S0]。 |
dtx/dty/dtz |
本方向输送时间;pentes_ini 传 x/y 半步和 z 整步。 |
advx
advx(limit,dtx,pbaru,sm,s0,sx,sy,sz,lati,latf) 只处理纬度范围 lati:latf。它把 pbaru 复制到 UGRI,然后逐层逐纬圈更新:
- 若
limit为真,限制TX的绝对值不超过S0的非负部分。 - 以
UGRI的符号决定从左格或右格抽取部分质量FM。 - 用
ALF=FM/TM(upwind)和ALF^2更新被抽出部分的一阶矩。 - 把临时 moments
F0/FX/FY/FZ加到下游格点。 - 若
NUMK>1,先把 extended polar zone 合并为T*,更新后再拆回;当前源码中NUM(j)=1,因此该分支通常不激活。 - 对
iip1经向周期边界复制SM/S0/sx/sy/sz。
源码中 advx 会无条件打印 DIAG DANS ADVX 的入口/出口 tracer 总量;这对批量 Mars 运行是一个历史诊断副作用。
advy
advy(limit,dty,pbarv,sm,s0,sx,sy,sz) 先构造 VGRI=-pbarv,并把 VGRI(:,0,:) 与 VGRI(:,jjp1,:) 设为 0。它的核心分三段:
- 北极通量特殊处理:用
SM0/S00汇总穿过极冠边界的质量和 tracer 质量。 - 中间纬圈
K=1..LAT-1按VGRI正负从上游格抽取FM/F0/FY/FX/FZ,再加入下游格。 - 南极通量特殊处理:逻辑与北极对称,但符号条件相反。
advy 不做经向周期复制;南北极行由极点 special block 维护。
advz
advz(limit,dtz,w,sm,s0,sx,sy,sz) 把垂直通量复制到 WGRI(i,j,llm+1-l)=w(i,j,l),并设置 WGRI(:,:,0)=0。主循环按纬圈 K=1..LAT、层界 L=1..NIV-1 处理:
- 若
limit为真,限制sz的绝对值。 - 用
WGRI正负决定上下游层,抽取临时质量和 moments。 - 把
F0/FX/FY/FZ加入下游层。 - 垂直边界由
WGRI(:,:,0)=0和只循环到NIV-1共同形成无通量边界。
与 advx 一样,advz 也无条件打印入口/出口 tracer 总量诊断。
pentes_ini 中的 split 约定
pentes_ini.F 调用这三个外部方向算子时,每个方向前都先调 limiter:
limx -> advx(limit, 0.5*dtvr, pbaru, ...)
limy -> advy(limit, 0.5*dtvr, pbarv, ...)
limz -> advz(limit, dtvr, w, ...)
limy -> advy(limit, 0.5*dtvr, pbarv, ...)
limx -> advx(limit, 0.5*dtvr, pbaru, ...)
这是一条对称的 x-y-z-y-x 顺序。虽然形式上类似其他 split transport,但它属于 iadv=20 slope/moments 保留路径,不是当前 Mars 标准 iadv=10 Van Leer。
advn pseudo-amont 内核
advn.F 的详细文件页见 dyn3d_common/advn。本页只强调它与 advx/advy/advz 的边界:
advn内部自己完成界面重构和通量更新。advnqx/advnqy/advnqz负责 4 阶界面值、单调约束和边界退化。advnx/advny/advnz负责方向通量和质量/tracer 更新。- 主例程
mode只被advnx使用,影响 E-W 通量公式;N-S 和垂直方向没有 mode 分支。 advn的 split 顺序同样是 x-y-z-y-x,但数据结构是q/masse工作副本,不是SM/S0/sx/sy/szmoments 表。
adaptdt 子步长
adaptdt(nadv,dtbon,n,pbaru,masse) 的逻辑很短:
CFLmax = 0
for l = 1..llm:
for j = 2..jjm:
for i = 1..iim:
CFLmax = max(CFLmax, pbaru(i,j,l) * dtvr / masse(i,j,l))
CFLmax = max(CFLmax, -pbaru(i,j,l) * dtvr / masse(i+1,j,l))
n = int(CFLmax) + 1
dtbon = dtvr / n
要点:
- 只看水平
pbaru,不看pbarv或w。 nadv当前不改变结果;源码里有nadv==30的 Prather 特例注释掉。n至少为 1;若CFLmax恰好是整数,n=int(CFLmax)+1会留出一个额外子步。- 调用方再循环
indice=1..n执行advn或 PPM 子步。
Mars 可达性
| 路径 | 当前源码 | Mars 标准状态 |
|---|---|---|
iadv=10 Van Leer |
advtrac -> vlsplt |
标准可达;不经过本页的 advx/advy/advz/adaptdt。 |
iadv=14 饱和路径 |
advtrac -> vlspltqs |
第 1 tracer 可达;不经过 adaptdt。 |
iadv=12/13 pseudo-amont |
adaptdt -> advn |
源码保留;infotrac_init 标准白名单阻断。 |
iadv=20 slope/moments |
pentes_ini -> advx/advy/advz |
源码保留;标准白名单阻断。 |
iadv=30 Prather |
adaptdt -> prather |
源码保留;标准白名单阻断。 |
iadv=11/16/17/18 PPM |
adaptdt -> interpre -> ppm3d -> interpost |
源码保留;标准白名单阻断。 |
复现检查点
- 先从
infotrac_init判断iadv是否能通过;当前标准 Mars 不应自然到达12/13/20/30/11/16/17/18。 - 复现
pentes_ini路径时必须使用SM/S0/sx/sy/szmoments 表,不能直接把q传给advx/advy/advz。 advx/advy/advz的ntra固定为 1,循环结构不是多 tracer 泛型。advx和advz有无条件PRINT*总量诊断,可能影响日志和性能。adaptdt只用pbaru估计水平 CFL;若要约束南北或垂直 CFL,需要调用方另行检查。advn内部advnx/advny/advnz与外部advx/advy/advz是两组不同例程,不要混用公式或工作数组。
相关页面
- dyn3d/advtrac
- caladvtrac 到 tracer advection 循环
- Transport And Advection
- dyn3d_common/advn
- pentes_ini
- ppm3d 入口约定
- vlsplt
待确认
advx/advy/advz中无条件总量诊断是否仍应保留在生产构建,源码未说明。adaptdt只考虑pbaru的设计意图,以及是否曾依赖调用方另行检查pbarv/wCFL。advx的NUM(j)当前全部设为 1,extended polar zone 分支是否仍有运行配置会启用,源码未提供外部入口。