filtreg_mod.F90 滤波初始化模块

源码范围:

LMDZ.COMMON-6.3\LMDZ.COMMON\libf\filtrez\filtreg_mod.F90

源码行数:559。

Mars 运行参与度:条件经过。Mars 3D GCM 和 Mars nogcm 在动力初始化后调用 inifilrnewstartstart2archive 等 Mars 工具链在构造或转换 start/archive 文件前也调用它,以便后续压力、几何或动力变量处理拥有同一套纬向滤波状态。

文件职责

filtreg_modfiltrez 目录的滤波状态初始化模块。它不直接滤波字段,而是在 inifilr 中:

实际施加滤波的是 filtreg.Fdyn3dpar/filtreg_p.F;它们使用本模块保存的矩阵数组和 coefils.h 中的滤波边界状态。

符号清单

符号 类型 定义位置 作用
filtreg_mod module 行 4 保存纬向滤波矩阵和初始化入口。
matriceun(iim,iim,jfiltnu) allocatable module state 行 6, 235 scalar/U 网格北半球普通滤波矩阵;j=2..jfiltnu 使用,极点行避开。
matriceus(iim,iim,jjm-jfiltsu+1) allocatable module state 行 6, 236 scalar/U 网格南半球普通滤波矩阵;索引用 j-jfiltsu+1
matricevn(iim,iim,jfiltnv) allocatable module state 行 6, 237 V/Z 网格北半球普通滤波矩阵。
matricevs(iim,iim,jjm-jfiltsv+1) allocatable module state 行 7, 238 V/Z 网格南半球普通滤波矩阵。
matrinvn(iim,iim,jfiltnu) allocatable module state 行 7, 239 scalar/U 网格北半球 inverse filter 矩阵。
matrinvs(iim,iim,jjm-jfiltsu+1) allocatable module state 行 7, 240 scalar/U 网格南半球 inverse filter 矩阵。
inifilr subroutine 行 11-557 构造滤波纬带、系数、矩阵和可选 FFT 状态。
first_call_inifilr SAVE local logical 行 41 只在第一次调用 inifilr 时分配矩阵数组。

本文件没有 THREADPRIVATE 声明;并行路径通过模块全局数组和 coefils.h 状态共享初始化结果。

依赖和状态

USE 依赖

依赖 条件 使用内容 作用
logic_mod always fxyhypb, ysinus 判断 sinusoidal/非 hyperbolic zoom 情况,必要时覆盖 colat0alphax
serre_mod always alphax stretch 系数,进入 lamdamax 公式;alphax==1 直接停止。
mod_filtre_fft CPP_PARA use_filtre_fft, Init_filtre_fft 并行构建中初始化全局 FFT 滤波系数。
mod_filtre_fft_loc CPP_PARA Init_filtre_fft_loc 并行构建中初始化本地 FFT 滤波系数。

include 状态

include 提供内容 本页相关使用
dimensions.h iim, jjm, llm 等编译维度 决定矩阵和纬向循环尺寸。
paramet.h jjp1, ip1jmp1 等派生维度 参与南北半球索引。
comgeom.h rlatu, rlatv, xprimu, eignfnu, eignfnv 等几何/特征函数数组 计算纬向尺度、特征函数矩阵和滤波系数。
coefils.h coefilu, coefilv, coefilu2, coefilv2, modfrstu, modfrstv, jfiltn*, jfilts* 等滤波状态 inifilr 写入,filtreg/filtreg_p 使用。

调用关系

主要调用方

调用方 源码位置 参与度 说明
dyn3d/gcm.F90 CALL inifilr 约行 415 Mars 3D 串行条件经过 inigeom 之后、动力主循环之前初始化滤波状态。
dyn3dpar/gcm.F CALL inifilr 约行 433 Mars 3D 并行条件经过 并行动力入口同样在主循环前初始化滤波状态。
MARS dynphy_lonlat/phymars/nogcm.F90 CALL inifilr 约行 408 Mars nogcm 条件经过 Mars 侧保留的 no-GCM/utility 式入口复用 COMMON 滤波初始化。
MARS phymars/newstart.F use filtreg_mod, only: inifilr; CALL inifilr 约行 1943 工具链条件经过 在计算压力 pression 前初始化几何相关滤波状态。
MARS phymars/start2archive.F use filtreg_mod, only: inifilr; call inifilr 工具链条件经过 inigeom 后、iniphysiq 前初始化滤波状态。
dyn3d_common/iniacademic.F90 CALL inifilr idealized/academic 条件经过 理想化初始化路径在 inigeom 后调用。

被调例程和后续使用位置

inifilr 调用 inifgn(eignvl),由 filter-helpers 覆盖。矩阵路径后续由 filtreg-system 中的串行 filtreg.F 和并行 dyn3dpar/filtreg_p.F 使用。

初始化流程

1. 读取网格尺度并计算特征值

inifilr 首先设置 pi = 2*asin(1.),把 xprimu(i) 拷贝到 dlonu(i),调用 inifgn(eignvl) 计算离散 Laplacian 特征值。随后从 rlatu(j)-rlatu(j+1) 得到 dlatu(j)

普通构建分支用显式循环求:

CRAY 分支则用 ISMIN 找最小值位置。

2. 计算 colat0lamdamax

默认:

colat0 = min(0.5, dymin / dxmin)

这表示规则网格从约 60 度纬度附近开始滤波;zoom 网格则在纬向长度和经向长度相近时开始向极区滤波。

特殊分支:

if (.not. fxyhypb .and. ysinus) then
  colat0 = 0.6
  alphax = 0.
endif

alphax == 1.,例程打印错误并 STOP。否则:

lamdamax = iim / (pi * colat0 * (1 - alphax))
rlamda(i) = lamdamax / sqrt(abs(eignvl(i)))   for i=2..iim

rlamda(1) 没有在源码中赋值,因为后续模态循环从 k=2 开始,零波数不进入滤波系数构造。

3. 初始化系数和纬带边界

coefilu/coefilv/coefilu2/coefilv2 先在全部 i=1..iim, j=1..jjm 上清零。

默认滤波纬带为:

jfiltnu = 2
jfiltsu = jjm
jfiltnv = 1
jfiltsv = jjm

随后例程在北半球和南半球分别扫描 scalar/U 纬度 rlatu 与 V/Z 纬度 rlatv。当同时满足:

cos(latitude) / colat0 < 1
rlamda(imx) * cos(latitude) < 1

对应 jfiltn*jfilts* 被更新。源码明确不在 U/scalar 极点滤波;V 网格没有极点行,因此 jfiltnv 从 1 开始。

边界检查包括:

任一越界都会打印错误并 STOP

jfiltnv >= jjm/2jfiltnu >= jjm/2 时,源码有一个 limit-case 修正:若南北滤波带在赤道附近相遇,则把 jfiltsvjfiltsu 推到南侧下一行,避免同一纬带被两侧重复覆盖。源码注释本身也提示这里是边界情形处理。

4. 分配矩阵

只在 first_call_inifilr 为真时分配:

matriceun(iim,iim,jfiltnu)
matriceus(iim,iim,jjm-jfiltsu+1)
matricevn(iim,iim,jfiltnv)
matricevs(iim,iim,jjm-jfiltsv+1)
matrinvn(iim,iim,jfiltnu)
matrinvs(iim,iim,jjm-jfiltsu+1)

随后 first_call_inifilr 置为 .FALSE.。源码没有 DEALLOCATE 或尺寸变化后的重新分配逻辑;同一进程内若第二次调用时网格或滤波纬带尺寸不同,会复用第一次分配的数组形状。这在标准 GCM 启动的一次性初始化中不是问题,但在工具链或测试中重复初始化不同网格时需要特别注意。

5. 构造滤波系数

modfrstu(j)modfrstv(j) 默认置为 iim,表示所有模态保留。然后对北/南 scalar/U 纬带和北/南 V/Z 纬带分别寻找第一个满足:

rlamda(k) * cos(latitude) < 1

的模态 k,将其记录为 modfrstu(j)modfrstv(j)。从该模态到 modemax=iim,写入:

coefilu(k,j)  = cof - 1
coefilu2(k,j) = cof*cof - 1
coefilv(k,j)  = cof - 1
coefilv2(k,j) = cof*cof - 1

其中 cof = rlamda(k) * cos(latitude)。因此低模态不滤波,高模态从 modfrst* 起按纬度和特征值衰减。

6. 构造普通滤波矩阵

scalar/U 网格使用 eignfnv 参与矩阵构造:

eignft(i,k) = eignfnv(k,i) * coff
matriceu    = eignfnv * eignft

其中若 i < modfrstu(j)coff 强制为 0。北半球写入 matriceun(:,:,j),南半球写入 matriceus(:,:,j-jfiltsu+1)

V/Z 网格使用 eignfnu

eignft(i,k) = eignfnu(k,i) * coff
matricev    = eignfnu * eignft

北半球写入 matricevn(:,:,j),南半球写入 matricevs(:,:,j-jfiltsv+1)

乘法实现按编译条件选择:

7. 构造 inverse filter 矩阵

inverse filter 只为 scalar/U 网格构造:

coff = coefilu(i,j) / (1 + coefilu(i,j))

同样使用 eignfnv * eignft 得到:

源码没有为 V/Z 网格构造 matrinv 对应矩阵;串行和并行滤波例程也只在 iaire == 3 的 inverse 分支使用 matrinvn/matrinvs

8. 可选 FFT 初始化

CPP_PARA 构建中,如果 use_filtre_fft 为真,inifilr 调用:

Init_filtre_fft(coefilu, modfrstu, jfiltnu, jfiltsu,
                coefilv, modfrstv, jfiltnv, jfiltsv)
Init_filtre_fft_loc(coefilu, modfrstu, jfiltnu, jfiltsu,
                    coefilv, modfrstv, jfiltnv, jfiltsv)

这说明 FFT backend 不取代本例程的系数和纬带判定,而是复用同一套 coefil*modfrst*jfiltn*/jfilts* 状态。

复现顺序

最小复现上下文必须先完成:

  1. 编译维度和水平网格常量可用:dimensions.h, paramet.h
  2. 几何初始化已写入 comgeom.h 数组:rlatu, rlatv, xprimu, eignfnu, eignfnv 等。
  3. logic_modserre_mod 已给出 fxyhypb, ysinus, alphax
  4. coefils.h 中的滤波状态数组已按编译维度存在。
  5. 调用 inifilr
  6. 后续调用 filtregfiltreg_p 时,按 iaireifiltre 选择普通矩阵、inverse 矩阵或 FFT 路径。

在 Mars 3D GCM 中,调用顺序是 conf_gcm/iniconst/inigeom 等初始化之后进入 inifilr,再进入动力主循环;Mars newstart/start2archive 工具链也在 inigeom 后调用。

风险和待确认

相关页面