advn 界面重构:advnqx/advnqy/advnqz 的模板和边界处理

输入范围

dyn3d_common\advn.F: L141-257(advnqx)
dyn3d_common\advn.F: L258-352(advnqy)
dyn3d_common\advn.F: L354-468(advnqz)

Mars 运行参与度:条件经过。本页聚焦 advn 的三个界面重构子例程的模板结构、边界处理和极值检测机制。这些子例程为 advnx/advny/advnz 提供界面重构值。主例程调用关系和通量计算详见 advn-dispatcher-order

例程定位

advnqx/advnqy/advnqz 共享相同的重构模板:4 阶中心差分 → 单调约束 → 极值检测 → 界面赋值。差异在于各方向的边界条件和周期包裹方式。三个子例程都有一个局部的 save mode 固定为 1,不受主例程传入的 mode 参数影响。这意味着重构总是使用 4 阶模板,mode 只影响后续通量计算。

advnqx:E-W 界面重构

SUBROUTINE advnqx(q,qg,qd)
参数 说明
q(ip1jmp1,llm) 格点混合比(IN)
qg(ip1jmp1,llm) 左界面重构值(OUT,gauche)
qd(ip1jmp1,llm) 右界面重构值(OUT,droite)

重构模板

mode=0(1 阶)qg(ij)=qd(ij)=q(ij,l),平坦重构。

mode=1(默认,4 阶)

  1. 斜率dxqu(ij) = q(ij+1,l) - q(ij,l)ij = iip2..ip1jm-1
  2. 界面值zqu(ij) = 0.5*(q(ij+1,l)+q(ij,l))
  3. 4 阶修正(两步):
    • zqu(ij) -= dxqu(ij+1)/12ij = iip2..ip1jm-1
    • zqu(ij) += dxqu(ij-1)/12ij = iip2+1..ip1jm
  4. 单调约束zqu(ij) = min(max(zqmin(ij), zqu(ij)), zqmax(ij)),其中 zqmax/min = max/min(q(ij), q(ij+1))
  5. 极值检测extremum(ij) = dxqu(ij)*dxqu(ij-1) <= 0(相邻斜率异号 → 局部极值)
  6. 界面赋值
    • 极值处:qg(ij)=qd(ij)=q(ij,l)(退化为 1 阶)
    • 非极值处:qd(ij)=zqu(ij), qg(ij)=zqu(ij-1)

E-W 周期包裹

经向周期通过三步 mod 循环实现:对 ij = iip1+iip1, ip1jm, iip1(每行的最后一个格点),复制 ij-iim 处的值。这确保经向首尾格点的界面值一致。

GOTO 8888 跳过段

L235 goto 8888 跳过了 L237-252 的代码段。被跳过的代码是备选的极值处理逻辑:在极值点相邻的非极值格点处用极值点的值覆盖界面值。当前版本不使用这段代码,改为在极值点直接退化为 1 阶。

advnqy:N-S 界面重构

SUBROUTINE advnqy(q,qs,qn)
参数 说明
q(ip1jmp1,llm) 格点混合比(IN)
qs(ip1jmp1,llm) 南界面重构值(OUT,south)
qn(ip1jmp1,llm) 北界面重构值(OUT,north)

重构模板

mode=0qs=qn=q

mode=1

  1. 斜率dyqv(ij) = q(ij,l) - q(ij+iip1,l)(注意符号:N-S 方向递减)
  2. 界面值zqv(ij,l) = 0.5*(q(ij+iip1,l)+q(ij,l))
  3. 4 阶修正zqv += (dyqv(ij+iip1)-dyqv(ij-iip1))/12
  4. 极值检测extremum(ij) = dyqv(ij)*dyqv(ij-iip1) <= 0
  5. 单调约束:同 advnqx
  6. 界面赋值
    • 极值处:qs=qn=q
    • 非极值处:qs=zqv(ij,l), qn=zqv(ij-iip1,l)

N-S 边界处理

极点无斜率j=1j=jjp1(极点行)不做 4 阶重构,直接设 zqv=qextremum=.true.。这是因为极点只有单行格点,无法构造有意义的 4 阶模板。

极点行的界面值被强制设为格点值:

qs(ij,l) = q(ij,l)     ! ij = 1..iip1 和 ip1jm+1..ip1jmp1
qn(ij,l) = q(ij,l)

注释掉的代码(L334-335)显示备选的极值传播逻辑,当前未使用。

advnqz:垂直界面重构

SUBROUTINE advnqz(q,qh,qb)
参数 说明
q(ip1jmp1,llm) 格点混合比(IN)
qh(ip1jmp1,llm) 上界面重构值(OUT,haut=top)
qb(ip1jmp1,llm) 下界面重构值(OUT,bas=bottom)

重构模板

mode=0qh=qb=q

mode=1

  1. 斜率dzqw(ij,l) = q(ij,l-1) - q(ij,l)l = 2..llm
  2. 界面值zqw(ij,l) = 0.5*(q(ij,l-1)+q(ij,l))l = 2..llm
  3. 4 阶修正zqw += (dzqw(ij,l+1)-dzqw(ij,l-1))/12l = 2..llm
  4. 极值检测extremum(ij,l) = dzqw(ij,l)*dzqw(ij,l+1) <= 0l = 2..llm-1
  5. 单调约束:同 advnqx
  6. 界面赋值
    • 极值处:qh=qb=q
    • 非极值处:qh=zqw(ij,l+1), qb=zqw(ij,l)

垂直边界处理

顶底无斜率

最终界面值:

qb(ij,1) = q(ij,1),    qh(ij,1) = q(ij,1)       ! 顶部
qb(ij,llm) = q(ij,llm), qh(ij,llm) = q(ij,llm)  ! 底部

注释掉的代码(L449-456)显示备选的极值传播逻辑,当前未使用。

三方向重构对比

特征 advnqx (E-W) advnqy (N-S) advnqz (垂直)
界面命名 gauche/droite south/north haut/bas
4 阶修正 ±dxqu/12 ±dyqv/12 ±dzqw/12
极值检测 dxqu(ij)*dxqu(ij-1)≤0 dyqv(ij)*dyqv(ij-iip1)≤0 dzqw(ij,l)*dzqw(ij,l+1)≤0
周期包裹 经向 mod 循环 无(极点特殊处理)
边界退化为 1 阶 极点(j=1, j=jjp1) 顶底(l=1, l=llm)
内部范围 iip2..ip1jm iip2..ip1jm-iip1 l=2..llm
极值传播代码 GOTO 8888 跳过 注释掉 注释掉

4 阶修正的数值意义

三个子例程使用的 4 阶修正公式为:

z_interface = 0.5*(q_L + q_R) ± (slope_far - slope_near) / 12

这是标准的 4 阶中心差分插值。对均匀网格,1/12 修正项将插值精度从 2 阶提升到 4 阶。加上单调约束后,格式在有极值区域退化为 1 阶,在平滑区域保持 4 阶精度。

复现要点

  1. 三个子例程的局部 save mode 固定为 1,不受 advn 主例程传入的 mode 影响。这意味着即使 mode=0(主例程传入),重构子例程仍使用 4 阶模板。mode=0 的一阶行为只能在 advnx 的通量计算中体现(通过 zsigd=zsigg=0.5 退化)。
  2. advnqx 的 GOTO 8888 和 advnqy/advnqz 注释掉的极值传播代码代表同一套备选逻辑的不同处理方式。当前版本统一使用"极值处退化为 1 阶"的策略。
  3. advnqy 的 N-S 斜率符号 dyqv = q(ij) - q(ij+iip1) 是"北减南"(因为 iip1 是向北一步),与 advnqx 的"东减西"符号约定不同。这影响后续 advny 中上游方向的选择。
  4. advnqz 的 zqw(ij,2)=q(ij,1)zqw(ij,llm)=q(ij,llm) 是硬编码的 1 阶边界,不使用 4 阶修正。这是因为大气顶和地面缺少足够的邻层构造 4 阶模板。

相关页面

待确认