风场转换与质量通量算子组
输入范围
dyn3d_common\covcont.F90
dyn3d_common\covnat.F
dyn3d_common\flumass.F90
dyn3d_common\convmas.F90
dyn3d_common\vitvert.F90
dyn3dpar\covcont_p.F
dyn3dpar\covnat_p.F
dyn3dpar\flumass_p.F
dyn3dpar\convmas_p.F
dyn3dpar\convmas1_p.F
dyn3dpar\convmas2_p.F
dyn3dpar\vitvert_p.F
Mars 运行参与度:必经。covcont、flumass、convmas、vitvert 在 caldyn 初始化段必经;covcont 在 leapfrog 耗散段必经。covnat 不在 caldyn/leapfrog 调用链中。
例程定位
这组算子构成动力 tendency 计算的核心链路:从协变风转到逆变风,再与质量场相乘得到质量通量,进而求散度和垂直积分得到质量散度,最后推导垂直速度。它们被 caldyn/caldyn_p 在初始化阶段顺序调用,covcont 还被 leapfrog 耗散段单独调用用于动能计算。
对照表
| 文件 | 行数 | 角色 | 并行变体 |
|---|---|---|---|
covcont.F90 |
28 | 协变 → 逆变风 | covcont_p.F(60 行) |
covnat.F |
49 | 协变 → 自然风 | covnat_p.F |
flumass.F90 |
76 | 质量通量 + 极点处理 | flumass_p.F |
convmas.F90 |
35 | 质量通量散度 + 垂直积分 | convmas_p.F + convmas1_p.F + convmas2_p.F |
vitvert.F90 |
30 | 垂直速度 | vitvert_p.F(56 行) |
核心流程
covcont:协变 → 逆变
SUBROUTINE covcont( klevel, ucov, vcov, ucont, vcont )
INTEGER, INTENT(IN) :: klevel
REAL, INTENT(IN) :: ucov(ip1jmp1,klevel), vcov(ip1jm,klevel)
REAL, INTENT(OUT) :: ucont(ip1jmp1,klevel), vcont(ip1jm,klevel)公式:ucont(ij,l) = ucov(ij,l) * unscu2(ij),vcont(ij,l) = vcov(ij,l) * unscv2(ij)。unscu2/unscv2 来自 comgeom.h,是网格尺度因子的平方倒数,由 inigeom/iniconst 初始化。
范围限制:ucont 从 iip2 开始计算(极点处 ij=1..iip1 保持为零),vcont 覆盖 1..ip1jm。
Include:dimensions.h、paramet.h、comgeom.h。
并行版 covcont_p 额外 USE parallel_lmdz。子域范围带 halo 扩展(ij_begin-iip1..ij_end+iip1),极点按 pole_nord(u 起点缩进到 ij_begin+iip1)和 pole_sud(u 终点缩减到 ij_end-iip1)条件调整。OMP DO 调度。
covnat:协变 → 自然
SUBROUTINE covnat( klevel, ucov, vcov, unat, vnat )
INTEGER klevel
REAL ucov(ip1jmp1,klevel), vcov(ip1jm,klevel)
REAL unat(ip1jmp1,klevel), vnat(ip1jm,klevel)公式:unat(ij,l) = ucov(ij,l) / cu(ij),vnat(ij,l) = vcov(ij,l) / cv(ij)。cu/cv 来自 comgeom.h,是 C-grid 边长尺度因子。
极点处理:ij=1..iip1(北极)和 ij=ip1jm+1..ip1jmp1(南极)处 unat=0。
调用状态:covnat 和 covnat_p 不在 caldyn/leapfrog 的活跃调用链中。可能在诊断输出或其他非主路径代码中使用。
flumass:质量通量
SUBROUTINE flumass( massebx, masseby, vcont, ucont, pbaru, pbarv )
REAL, INTENT(IN) :: massebx(ip1jmp1,llm), masseby(ip1jm,llm)
REAL, INTENT(IN) :: vcont(ip1jm,llm), ucont(ip1jmp1,llm)
REAL, INTENT(OUT) :: pbaru(ip1jmp1,llm), pbarv(ip1jm,llm)主体:pbaru = massebx * ucont,pbarv = masseby * vcont。质量在 U/V 点的加权平均(来自 massbar)乘以逆变风得到质量通量。
极点处理是此算子的核心复杂性。在南北极点求解一个 2 方程系统:
- 散度方程:极点处各经向线的辐合应等于极点平均的负值。
- 零均值约束:极点环流质量通量的面积加权和为零。
求解过程对北极:先从 pbarv 递推 pbaru(pbaru(i) = pbaru(i-1) + pbarv(i) - ctn*aire(i)),再求面积加权修正 ctn0,最后 pbaru = 2*(pbaru + ctn0)。南极类似但符号不同。
convmas:质量散度
SUBROUTINE convmas( pbaru, pbarv, convm )
REAL, INTENT(IN) :: pbaru(ip1jmp1,llm), pbarv(ip1jm,llm)
REAL, INTENT(OUT) :: convm(ip1jmp1,llm)三步:
- 水平散度:
CALL convflu(pbaru, pbarv, llm, convm)— 计算-(d(pbaru)/dx + d(pbarv)/dy)。 - 滤波:
CALL filtreg(convm, jjp1, llm, 2, 2, .TRUE., 1)— 对散度场施加 2 阶 filtreg 滤波。 - 垂直积分:从顶到底累加
convm(:,l) = convm(:,l) + convm(:,l+1)(l=llmm1..1),得到每层累积质量散度。
并行 split:并行版将 convmas 拆成两个子例程:
convmas1_p:包含convflu_p+filtreg_p步骤(可并行化)。convmas2_p:只包含垂直积分步骤,用c$OMP MASTER单线程执行(垂直积分依赖层级数据,不可简单 OMP 并行化)。convmas_p:完整版本,包含全部三步(convflu_p+filtreg_p+ 垂直积分),在某些调用上下文中使用。
caldyn_p.F 中调用 convmas1_p 后跟 convmas2_p。
vitvert:垂直速度
SUBROUTINE vitvert( convm, w )
USE comvert_mod, ONLY: bp
REAL, INTENT(IN) :: convm(ip1jmp1,llm)
REAL, INTENT(OUT) :: w(ip1jmp1,llm)公式:w(ij,l+1) = convm(ij,l+1) - bp(l+1) * convm(ij,1)。从质量散度和 sigma 坐标系数 bp(来自 comvert_mod)推导 sigma 坐标系下的垂直速度。
边界条件:w(:,1) = 0(地表),w(:,llm+1) = 0(模式顶,不存储)。
Include:dimensions.h、paramet.h。
并行版 vitvert_p 用 ij_begin..ij_end+iip1 子域,pole_sud 缩减。垂直积分用 OMP DO,w(:,1)=0 用 OMP MASTER + BARRIER 确保一致性。
调用链路
caldyn 初始化段(一次性)
caldyn.F 和 caldyn_p.F 中按以下顺序调用:
pression→psextbar→massdair→massbar→massbarxy(压力/质量链,见 common-pressure-mass-operators)covcont/covcont_p(协变 → 逆变)flumass/flumass_p(质量通量)convmas/convmas1_p + convmas2_p(质量散度)vitvert/vitvert_p(垂直速度)
leapfrog 耗散段
leapfrog.F(line 700, 717)和 leapfrog_p.F(line 1353, 1400)在耗散 conservative 修正中调用 covcont/covcont_p 两次:
- 耗散前:
covcont把协变风转逆变用于enercin计算ecin0。 - 耗散后风场更新后:再次
covcont用于重新计算ecin。
这两次调用是为了计算耗散消耗的动能,用于 conservative 热修正。
leapfrog_nogcm
不调用本组任何例程。nogcm 变体替换了完整动力核心为零倾向加 Newtonian 松弛。
数据流
ucov, vcov (协变风, caldyn 输入或 leapfrog 状态)
│
├── covcont ──→ ucont, vcont (逆变风, 乘以 unscu2/unscv2)
│ │
│ ├── flumass(+massebx,masseby) ──→ pbaru, pbarv (质量通量)
│ │ │
│ │ ├── convflu ──→ convm (水平散度)
│ │ ├── filtreg ──→ convm (滤波)
│ │ └── 垂直积分 ──→ convm (累积散度)
│ │ │
│ │ └── vitvert(+bp) ──→ w (垂直速度)
│
└── covnat ──→ unat, vnat (自然风, 除以 cu/cv) [不在活跃调用链中]
串并行差异
| 差异点 | 串行 | 并行 |
|---|---|---|
| 子域 | 全范围 | ij_begin/ij_end 子域 |
| halo 扩展 | 无 | covcont_p 用 ij_begin-iip1..ij_end+iip1 |
| 极点处理 | 无条件全局零化 | pole_nord/pole_sud 条件缩减 |
| OMP | 无 | 全部带 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) |
| convmas | 单一例程 | 拆成 convmas1_p(可并行)+ convmas2_p(MASTER 单线程垂直积分) |
| vitvert w(:,1)=0 | 直接赋值 | OMP MASTER + BARRIER |
| covnat | 不在活跃链中 | 同,但有 _p 变体存在 |
复现要点
covcont依赖unscu2/unscv2(来自comgeom.h),必须在inigeom/iniconst之后调用。flumass的极点处理是数值正确性关键:如果极点质量通量求解出错,后续convmas散度会在极点附近产生非物理辐合/辐散。convmas调用filtreg做滤波,这意味着filtreg的初始化(inifilr/filtreg_mod)必须先完成。- 并行版
convmas2_p的 MASTER 限制说明垂直积分不能 OMP 并行化——如果复现代码想并行化这一步,需要验证数值等价性。 vitvert依赖comvert_mod的bp,与压力/质量链的ap/bp来源相同。covnat虽然有_p变体,但不在 caldyn/leapfrog 活跃调用链中;复现动力核心时不需要它。
待确认
covnat/covnat_p的实际调用方需在源码中追踪(可能是诊断输出或bilan_dyn相关路径)。flumass极点处理的ctn/ctn0修正系数符号差异(北极 vs 南极)需要几何对齐确认。convmas_p(完整版)和convmas1_p + convmas2_p(拆分版)的调用上下文区分需在caldyn_p和leapfrog_p中逐行确认。