mvc_horiz_mod.F
快速理解
它做什么: 最大值复合水平插值模块,取覆盖范围内源格点最大值映射到目标网格。被 datareadnc 调用。
基本过程: 对每个目标格点 → 取覆盖源格点最大值。
关键结果: 目标网格上的最大值化地表数据(如 MOLA 地形/summit/base)。
路径
LMDZ.MARS\libf\dynphy_lonlat\phymars\mvc_horiz_mod.F
所属目录/模块
libf/dynphy_lonlat/phymars
文件定位
最大值复合(Maximum Value Composite)水平插值模块。将高分辨率地表数据(如 MOLA 地形、summit、base 等亚网格地形参数)映射到 GCM 目标网格,对每个目标格点取其覆盖范围内所有源格点的最大值。由 datareadnc 在处理亚网格地形变量时调用。
作者:Chao Wang。
定义的符号
| 符号 | 类型 | 行号 | 作用 |
|---|---|---|---|
mvc_horiz_mod |
module | 1 | 包装 mvc_horiz 子例程 |
mvc_horiz |
subroutine | 7 | 最大值复合水平插值 |
依赖的模块
| use 模块 | only 列表 | 用途 | 待确认 |
|---|---|---|---|
| 无 | — | — | — |
调用的关键例程
| 被调用例程 | 所在模块/文件 | 调用位置 | 作用 |
|---|---|---|---|
| 无 | — | — | — |
输入
| 输入 | 来源 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
imo |
参数 | integer |
— | 源网格经度方向格点数 |
jmo |
参数 | integer |
— | 源网格纬度方向格点数 |
imn |
参数 | integer |
— | 目标网格经度方向格点数 |
jmn |
参数 | integer |
— | 目标网格纬度方向格点数 |
rlonuo |
参数 | real(imo) |
rad | 源网格经度 |
rlatvo |
参数 | real(jmo) |
rad | 源网格纬度 |
rlonv |
参数 | real(imn+1) |
rad | 目标网格经度边界 |
rlatu |
参数 | real(jmn+1) |
rad | 目标网格纬度边界 |
zdata |
参数 | real(imo*jmo) |
任意 | 源数据(一维展开) |
输出
| 输出 | 去向 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
outdata |
OUT | real(imn+1,jmn+1) |
同 zdata | 目标网格上的最大值复合结果 |
共享状态与副作用
无。纯计算例程,不读写任何 module 变量、common block 或文件。
核心逻辑
- 初始化:
iik/jjk清零,outdata初始化为-999999(远低于火星地表最低点 ~8200 m) - 构建目标网格边界:
tmplon(1)=rlonv(1),tmplon(2..imn+1)为相邻经度中点,tmplon(imn+2)=rlonv(imn+1)tmplat(1)=rlatu(1),tmplat(2..jmn+1)为相邻纬度中点,tmplat(jmn+2)=rlatu(jmn+1)
- 源→目标映射:遍历每个源格点
(i,j),在目标网格中找到其落入的单元格(m,n),记录到iik(i,j)=m、jjk(i,j)=n;使用goto 1000找到即跳出内层循环 - 最大值复合:遍历目标网格每个单元格
(m,n),收集所有映射到该单元的源格点,取max(outdata(m,n), zdata(i+imo*(j-1)))
伪代码
Initialize outdata = -999999 (sentinel)
Build template grid boundaries (tmplon, tmplat) at midpoints
FOR each source point (i,j):
FOR each target cell (m,n):
IF rlonuo(i) in [tmplon(m), tmplon(m+1))
AND rlatvo(j) in [tmplat(n+1), tmplat(n)):
Record iik(i,j)=m, jjk(i,j)=n
GOTO next source point
FOR each target cell (m,n):
FOR each source point (i,j):
IF iik(i,j)==m AND jjk(i,j)==n:
outdata(m,n) = max(outdata(m,n), zdata(i+imo*(j-1)))
参与的主题流程
| 主题 | 参与方式 |
|---|---|
| 亚网格地形参数初始化 | 为 hmons/summit/base 取亚网格最大值,传给 GCM 网格 |
写法特点
- 纯 Fortran 90 模块:无 USE/INCLUDE/CALL,完全自包含
goto 1000跳转:找到目标单元格后立即跳出,避免 O(imojmoimn*jmn) 全遍历-999999哨兵值:注释说明 "lowest point on Mars ~8200m",确保任何有效数据都能替换初始值- 一维→二维索引:源数据
zdata(i+imo*(j-1))使用列优先一维展开,与 NetCDF 读取格式对应 - 四重循环复杂度:映射步骤和复合步骤均为 O(N²·M²),适用于本场景(源/目标网格均较小)
复现要点
- 输入经纬度单位为弧度(
pi=2*ASIN(1.)虽声明但未使用) rlonv/rlatu维度为(imn+1)/(jmn+1),即目标网格边界坐标outdata中保持-999999的格点表示无源数据落入(调用方datareadnc后续替换为 0)
待确认
pi变量已声明并赋值但未使用,可能为遗留代码- 纬度方向
rlatvo(j) .lt. tmplat(n) .and. rlatvo(j) .ge. tmplat(n+1)假设纬度递减(北→南),对递增排列不适用 - 对于跨 0° 经度的源格点,周期性处理由调用方负责,本例程不处理
相关页面
- datareadnc — 唯一调用方,在 k=5,6,7(hmons/summit/base)时使用
mvc_horiz - common-dependencies —
interp_horiz的 COMMON 水平插值边界;与本文件最大值复合插值形成对照。 - dynphy_lonlat/index — 所属目录概览