水平微分/耗散 stencil family 深度

输入范围

dyn3d_common: grad.F, gradiv.F, gradiv2.F,
              diverg.F, divergf.F, divergst.F, diverg_gam.F,
              rotat.F, rotatf.F, rotatst.F, rotat_nfil.F,
              laplacien.F, laplacien_gam.F, laplacien_rot.F, laplacien_rotgam.F,
              nxgrad.F, nxgradst.F, nxgrad_gam.F,
              nxgraro2.F, nxgrarot.F
dyn3dpar:     对应 17 个 _p 变体

Mars 运行参与度:条件经过。所有复合算子由 dissip/dissip_pinidissip 调用,仅在 apdiss 为真时执行。叶子算子由复合算子内部调用,不直接从外部入口调用。

页面定位

本页提供 dyn3d_common 中水平微分/耗散 stencil 算子族的深度签名、公式、变体关系和串并行对照。它承接 差分算子总览 的分类框架,补充每个算子的精确签名、网格位置、Include 依赖和内部调用链。耗散链路的端到端数据流由 Mars 水平耗散链路 覆盖;inidissip 的配置和特征值估算由 inidissip 文件页 覆盖。gradsdef.h(GrADS I/O header)不属于差分算子,本页不覆盖。

文件总览

叶子算子(基础微分)

算子 串行文件 并行文件 行数 (串/并) 输入格点 输出格点 Include
grad grad.F grad_p.F 45/54 P U, V dimensions.h, paramet.h
diverg diverg.F diverg_p.F 86/107 U, V P + comgeom.h
divergf divergf.F divergf_p.F 86/116 U, V P + comgeom.h
diverg_gam diverg_gam.F diverg_gam_p.F 81/98 U, V P + comgeom.h
rotat rotat.F rotat_p.F 59/64 U, V Z + comgeom.h
rotatf rotatf.F rotatf_p.F 59/68 U, V Z + comgeom.h
rotat_nfil rotat_nfil.F rotat_nfil_p.F 50/53 U, V Z + comgeom.h
nxgrad nxgrad.F nxgrad_p.F 49/68 Z U, V + comgeom.h
nxgrad_gam nxgrad_gam.F nxgrad_gam_p.F 48/68 Z U, V + comgeom.h

Laplacian 复合算子

算子 串行文件 并行文件 行数 (串/并) 内部调用 Include
laplacien laplacien.F laplacien_p.F 41/57 filtreggraddivergf + comgeom.h
laplacien_gam laplacien_gam.F laplacien_gam_p.F 54/66 graddiverg_gam + comgeom.h
laplacien_rot laplacien_rot.F laplacien_rot_p.F 40/46 filtregnxgradrotatf + comgeom.h
laplacien_rotgam laplacien_rotgam.F laplacien_rotgam_p.F 45/49 nxgrad_gamrotat_nfil× unsairz_gam + comgeom.h

耗散复合算子

算子 串行文件 并行文件 行数 (串/并) 内部调用链 Include
gradiv gradiv.F gradiv_p.F 57/109 迭代 ld 次:divergfiltreggrad × -cdivu + comdissipn.h
gradiv2 gradiv2.F gradiv2_p.F 80/148 divergflaplacien → (ld-2)× laplacien_gamfiltreggrad × cdivu + comgeom.h, comdissipn.h
nxgrarot nxgrarot.F nxgrarot_p.F 55/101 迭代 lr 次:rotatfiltregnxgrad × -crot + comdissipn.h
nxgraro2 nxgraro2.F nxgraro2_p.F 69/142 rotatflaplacien_rot → (lr-2)× laplacien_rotgamfiltregnxgrad × crot + comdissipn.h

死代码

divergst.F(63 行)、rotatst.F(44 行)和 nxgradst.F(48 行)在整个代码库中无任何调用方,也不存在对应的 _p 并行变体。它们是 staggered-grid 简化版本,可能用于早期开发或已废弃的诊断路径。

grad — 标量梯度

SUBROUTINE grad(klevel, pg, pgx, pgy)
  INTEGER klevel
  REAL pg(ip1jmp1, klevel)    ! 输入:P 点标量场
  REAL pgx(ip1jmp1, klevel)   ! 输出:U 点 x-梯度
  REAL pgy(ip1jm, klevel)     ! 输出:V 点 y-梯度

有限差分:pgx(ij) = pg(ij+1) - pg(ij)(前向差),pgy(ij) = pg(ij) - pg(ij+iip1)(南向北差)。周期性修正 pgx(ij+iim) = pgx(ij)。无滤波、无度量权重。

散度族

diverg — 协变向量散度(无滤波)

SUBROUTINE diverg(klevel, x, y, div)
  REAL x(ip1jmp1, klevel), y(ip1jm, klevel)  ! 输入:U/V 点协变分量
  REAL div(ip1jmp1, klevel)                   ! 输出:P 点散度

公式:div(ij) = (x(ij)*cvusurcv(ij) - x(ij-1)*cvusurcv(ij-1)) + (y(ij)*cuvscu(ij) - y(ij-iip1)*cuvscu(ij-iip1)),再乘以 unaire(ij)(逆格点面积)。极点用面积加权求和除以 apoln/apols

divergf — 滤波散度

diverg 相同公式,但在面积乘法前调用 filtreg(div, jjp1, klevel, 2, 1, .TRUE., 1) 施加正则滤波。用于 gradiv2laplacien 内部。

diverg_gam — gamma 权重散度

SUBROUTINE diverg_gam(klevel, cuvscvgam, cvuscugam, unsairegam,
                       unsapolnga, unsapolsga, x, y, div)

使用 gamma-耗散度量比(cvuscugam/cuvscvgam)和 gamma 逆面积(unsairegam)替代标准度量。由 comdissipn.hinidissip 初始化的 gamma 权重数组驱动。用于 laplacien_gam 内部。

旋度族

rotat — 协变向量旋度(无滤波)

SUBROUTINE rotat(klevel, x, y, rot)
  REAL x(ip1jmp1, klevel), y(ip1jm, klevel)  ! 输入:U/V 点协变分量
  REAL rot(ip1jm, klevel)                     ! 输出:Z 点旋度

公式:rot(ij) = y(ij+1) - y(ij) + x(ij) - x(ij+iip1)(离散旋度),再乘以 unairez(ij)(Z 点逆面积)。

rotatf — 滤波旋度

rotat 相同公式,在面积乘法前调用 filtreg。用于 nxgraro2laplacien_rot 内部。

rotat_nfil — 无滤波无面积归一化旋度

rotat 相同差分公式,但调用 filtreg乘以 unairez。返回原始环量。用于 laplacien_rotgam 内部,gamma 面积归一化在外部完成。

nxgrad — 旋转梯度族

nxgrad — π/2 旋转梯度

SUBROUTINE nxgrad(klevel, rot, x, y)
  REAL rot(ip1jm, klevel)       ! 输入:Z 点旋度场
  REAL x(ip1jmp1, klevel)       ! 输出:U 点旋转梯度 x
  REAL y(ip1jm, klevel)         ! 输出:V 点旋转梯度 y

公式:y(ij) = (rot(ij) - rot(ij-1)) * cvsurcuv(ij)x(ij) = (rot(ij) - rot(ij-iip1)) * cusurcvu(ij)。极点置零,周期性修正。

nxgrad_gam — gamma 权重旋转梯度

使用 gamma 度量比 cvscuvgam/cuscvugam 替代标准 cvsurcuv/cusurcvu。用于 laplacien_rotgam 内部。

Laplacian 复合算子

laplacien — 标准标量 Laplacian

SUBROUTINE laplacien(klevel, teta, divgra)

内部链:teta → divgra(复制)→ filtreggraddivergf。即 div_f(grad(teta)):先滤波再取梯度的滤波散度。

laplacien_gam — gamma 权重 Laplacian

SUBROUTINE laplacien_gam(klevel, cuvsga, cvusga, unsaigam,
                          unsapolnga, unsapolsga, teta, divgra)

内部链:teta → divgra(复制)→ graddiverg_gam。无滤波。gamma 度量数组由 comdissipn.h 提供。

laplacien_rot — 旋转 Laplacian

SUBROUTINE laplacien_rot(klevel, rotin, rotout, ghx, ghy)

内部链:rotinfiltregnxgradrotatf。即 rot_f(nxgrad(rotin)):先滤波再取旋转梯度的滤波旋度。

laplacien_rotgam — gamma 旋转 Laplacian

SUBROUTINE laplacien_rotgam(klevel, rotin, rotout)

内部链:rotinnxgrad_gamrotat_nfil× unsairz_gam。无滤波。gamma 面积归一化在最后一步完成。

耗散复合算子

gradiv — 迭代 grad(div)(标准版)

SUBROUTINE gradiv(klevel, xcov, ycov, ld, gdx, gdy)
  REAL xcov(ip1jmp1, klevel), ycov(ip1jm, klevel)  ! 输入:协变风场
  INTEGER ld                                        ! 迭代次数
  REAL gdx(ip1jmp1, klevel), gdy(ip1jm, klevel)     ! 输出:耗散增量

迭代 ld 次,每次:diverg(gdx,gdy) → filtreg(div) → grad(div) → × -cdivucdivu 来自 comdissipn.h,由 inidissip 初始化。当 lstardis=.false. 时使用。

gradiv2 — gamma 高阶 grad(div)(star 版)

SUBROUTINE gradiv2(klevel, xcov, ycov, ld, gdx, gdy)

单次 divergflaplacien → (ld-2) 次 laplacien_gamfiltreggrad× cdivu(符号由 ld 决定)。gamma 度量数组 cuvscvgam1/cvuscugam1/unsair_gam1 来自 comdissipn.h。当 lstardis=.true. 时使用。

nxgrarot — 迭代 n×grad(rot)(标准版)

SUBROUTINE nxgrarot(klevel, xcov, ycov, lr, grx, gry)

迭代 lr 次,每次:rotat(grx,gry) → filtreg(rot) → nxgrad(rot) → × -crotcrot 来自 comdissipn.h。当 lstardis=.false. 时使用。

nxgraro2 — gamma 高阶 n×grad(rot)(star 版)

SUBROUTINE nxgraro2(klevel, xcov, ycov, lr, grx, gry)

单次 rotatflaplacien_rot → (lr-2) 次 laplacien_rotgamfiltregnxgrad× crot。当 lstardis=.true. 时使用。

内部调用图

gradiv (ld 迭代)                   gradiv2 (gamma star)
  ├─ diverg                          ├─ divergf
  ├─ filtreg                         ├─ laplacien (filtreg→grad→divergf)
  └─ grad                            ├─ (ld-2)× laplacien_gam (grad→diverg_gam)
                                     ├─ filtreg
                                     └─ grad

nxgrarot (lr 迭代)                 nxgraro2 (gamma star)
  ├─ rotat                            ├─ rotatf
  ├─ filtreg                          ├─ laplacien_rot (filtreg→nxgrad→rotatf)
  └─ nxgrad                           ├─ (lr-2)× laplacien_rotgam (nxgrad_gam→rotat_nfil→×unsairz_gam)
                                     ├─ filtreg
                                     └─ nxgrad

外部调用方:
  dissip/dissip_p: gradiv2/gradiv (lstardis 分支)
                   nxgraro2/nxgrarot (lstardis 分支)
                   divgrad2/divgrad (第三路)
  inidissip:       同上 (特征值估算, klevel=1)

串并行差异

叶子算子并行模式

所有 9 个叶子算子的并行化模式一致:USE parallel_lmdzc$OMP DO SCHEDULE(STATIC,OMP_CHUNK)klevel 外层循环,子域范围 ijb=ij_begin, ije=ij_end 加极点条件调整(pole_nord 跳过北极行,pole_sud 跳过南极行),filtregfiltreg_pjjb/jje 子域。无 halo 交换——叶子算子依赖调用者保证 halo 已同步。

复合算子并行模式

四个 Laplacian 复合算子内部调用 _p 叶子算子,自身不增加额外 halo 交换(halo 由上层保证)。

四个耗散复合算子有两种并行 halo 策略:

算子 halo 策略 额外模块
gradiv_p 阻塞 exchange_Hallo (MASTER/BARRIER) parallel_lmdz, times
gradiv2_p 异步 Register_Hallo/SendRequest/WaitRequest parallel_lmdz, times, mod_hallo
nxgrarot_p 阻塞 exchange_Hallo (MASTER/BARRIER) parallel_lmdz, times
nxgraro2_p 异步 Register_Hallo/SendRequest/WaitRequest parallel_lmdz, times, mod_hallo

标准版(gradiv_p/nxgrarot_p)用阻塞 halo 交换,每次迭代在 OMP MASTER 块中同步。Star 版(gradiv2_p/nxgraro2_p)用异步非阻塞 halo,在 OMP BARRIER 之间注册和等待,允许计算/通信重叠。

输出数组分离

串行耗散复合算子直接在 gdx/gdygrx/gry 中就地迭代。并行版使用 SAVE 内部数组做迭代,最终用 OMP DO 把子域结果复制到独立的 gdx_out/gdy_out(或 grx_out/gry_out)输出数组。

已知异常

gradiv2_p.F L104 调用串行 laplacien_gam(不是 laplacien_gam_p)。对比 divgrad2_p.F L88 正确调用 laplacien_gam_p。这可能是一个遗留 bug 或有意为之(laplacien_gam 内部只调叶子算子,可能不需要额外 halo),但需确认。

调用方总览

所有 20 个活跃算子的外部调用方仅限于 dissip.F/dissip_p.F(耗散施加)和 inidissip.F90(特征值估算)。叶子算子和 Laplacian 复合算子没有外部直接调用方——它们只被其他 stencil 算子内部调用。

外部调用方 调用的算子 说明
dissip.F L81-108 gradiv2/gradiv, nxgraro2/nxgrarot lstardis 分支选择
dissip_p.F L104-147 gradiv2_p/gradiv_p, nxgraro2_p/nxgrarot_p 同上
dissip.F L137-139 divgrad2/divgrad 第三路温度耗散
dissip_p.F L195-197 divgrad2_p/divgrad_p 同上
inidissip.F90 L129-177 全部 6 个复合算子 特征值估算 (klevel=1)

caldyn.F/caldyn_p.F、COMMON leapfrog.F/leapfrog_p.F 和 MARS phymars/leapfrog_nogcm.F 不直接调用任何 stencil 算子。

复现要点

待确认

相关页面