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 阶):
- 斜率:
dxqu(ij) = q(ij+1,l) - q(ij,l),ij = iip2..ip1jm-1 - 界面值:
zqu(ij) = 0.5*(q(ij+1,l)+q(ij,l)) - 4 阶修正(两步):
zqu(ij) -= dxqu(ij+1)/12,ij = iip2..ip1jm-1zqu(ij) += dxqu(ij-1)/12,ij = iip2+1..ip1jm
- 单调约束:
zqu(ij) = min(max(zqmin(ij), zqu(ij)), zqmax(ij)),其中zqmax/min = max/min(q(ij), q(ij+1)) - 极值检测:
extremum(ij) = dxqu(ij)*dxqu(ij-1) <= 0(相邻斜率异号 → 局部极值) - 界面赋值:
- 极值处:
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=0:qs=qn=q。
mode=1:
- 斜率:
dyqv(ij) = q(ij,l) - q(ij+iip1,l)(注意符号:N-S 方向递减) - 界面值:
zqv(ij,l) = 0.5*(q(ij+iip1,l)+q(ij,l)) - 4 阶修正:
zqv += (dyqv(ij+iip1)-dyqv(ij-iip1))/12 - 极值检测:
extremum(ij) = dyqv(ij)*dyqv(ij-iip1) <= 0 - 单调约束:同 advnqx
- 界面赋值:
- 极值处:
qs=qn=q - 非极值处:
qs=zqv(ij,l), qn=zqv(ij-iip1,l)
- 极值处:
N-S 边界处理
极点无斜率:j=1 和 j=jjp1(极点行)不做 4 阶重构,直接设 zqv=q,extremum=.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=0:qh=qb=q。
mode=1:
- 斜率:
dzqw(ij,l) = q(ij,l-1) - q(ij,l),l = 2..llm - 界面值:
zqw(ij,l) = 0.5*(q(ij,l-1)+q(ij,l)),l = 2..llm - 4 阶修正:
zqw += (dzqw(ij,l+1)-dzqw(ij,l-1))/12,l = 2..llm - 极值检测:
extremum(ij,l) = dzqw(ij,l)*dzqw(ij,l+1) <= 0,l = 2..llm-1 - 单调约束:同 advnqx
- 界面赋值:
- 极值处:
qh=qb=q - 非极值处:
qh=zqw(ij,l+1), qb=zqw(ij,l)
- 极值处:
垂直边界处理
顶底无斜率:
dzqw(ij,1) = 0,dzqw(ij,llm+1) = 0(大气顶和地面无差分)zqw(ij,2) = q(ij,1)(顶部界面退化为 1 阶)zqw(ij,llm) = q(ij,llm)(底部界面退化为 1 阶)extremum(ij,1) = .true.,extremum(ij,llm) = .true.
最终界面值:
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 阶精度。
复现要点
- 三个子例程的局部
save mode固定为 1,不受 advn 主例程传入的mode影响。这意味着即使mode=0(主例程传入),重构子例程仍使用 4 阶模板。mode=0 的一阶行为只能在 advnx 的通量计算中体现(通过zsigd=zsigg=0.5退化)。 - advnqx 的 GOTO 8888 和 advnqy/advnqz 注释掉的极值传播代码代表同一套备选逻辑的不同处理方式。当前版本统一使用"极值处退化为 1 阶"的策略。
- advnqy 的 N-S 斜率符号
dyqv = q(ij) - q(ij+iip1)是"北减南"(因为 iip1 是向北一步),与 advnqx 的"东减西"符号约定不同。这影响后续 advny 中上游方向的选择。 - advnqz 的
zqw(ij,2)=q(ij,1)和zqw(ij,llm)=q(ij,llm)是硬编码的 1 阶边界,不使用 4 阶修正。这是因为大气顶和地面缺少足够的邻层构造 4 阶模板。
相关页面
待确认
- 局部
save mode = 1是否为有意设计(始终使用 4 阶重构)还是遗留 bug。 - 被跳过的极值传播代码(GOTO 8888 和注释段)在历史版本中是否被使用过。