mod_grid_phy_lmdz.F90

源码基线:LMDZ.COMMON-6.3\LMDZ.COMMON。 Mars 运行参与度:条件经过。Mars 3D 物理初始化经 inigeomphy_mod -> physics_distribution_mod -> init_grid_phy_lmdz 设置本模块;Mars 1D/testphys 也通过 init_physics_distribution(regular_lonlat,4,1,1,1,...) 设置单列网格。后续 diagfi/stats/XIOS/restart/surface 初始化读取 klon_glo/nbp_lon/nbp_lat/grid_type 或调用 Grid1Dto2D_glo

源码范围

LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\mod_grid_phy_lmdz.F90

文件行数:468。

模块职责

mod_grid_phy_lmdz 是物理侧全局网格状态模块。它不分配经纬度、面积或垂直层数组;这些由 regular_lonlat_modgeometry_modvertical_layers_mod 保存。本模块只保存网格类型、顶点数、全局经纬/垂直规模和全局物理列数,并提供两组泛型映射:

泛型 方向 典型用途
Grid1Dto2D_glo klon_glo 物理列 -> (nbp_lon, nbp_lat) lon-lat 场 Mars diagfi/stats/debug 输出前,把 gather 后的全局物理列展开为二维网格。
Grid2Dto1D_glo (nbp_lon, nbp_lat) lon-lat 场 -> klon_glo 物理列 从带极点重复经度的二维场回到物理列表示。

模块状态

符号 行号 类型 含义
unstructured 10 integer parameter = 0 非结构/ICO 类网格枚举。Mars lon-lat GCM 主线通常不走这一类,但 XIOS/diagfi 会检查它。
regular_lonlat 11 integer parameter = 1 regular longitude-latitude 网格枚举;Mars lon-lat 3D 和 1D 初始化都以此传入。
grid_type 13 integer, save 当前物理网格类型,由 init_grid_phy_lmdz 写入。
nvertex 14 integer, save 每个 cell 的顶点数;regular lon-lat 初始化传 4。Mars topmons_mod 读取它。
nbp_lon 15 integer, save 全局 regular 网格经向点数,注释标为 iim
nbp_lat 16 integer, save 全局 regular 网格纬向点数,注释标为 jjmp1;1D 时为 1
nbp_lev 17 integer, save 垂直层数,注释标为 llm
klon_glo 18 integer, save 全局物理列数,去掉两极重复经度后的列数。

这些变量都是模块 SAVE 状态,不是 THREADPRIVATE。它们必须在使用任何物理输出、transfer 或 Mars surface/restart helper 前完成初始化。

初始化入口

init_grid_phy_lmdz(grid_type_, nvertex_, nbp_lon_, nbp_lat_, nbp_lev_) 定义在 39-59 行。它只做赋值和 klon_glo 推导:

grid_type = grid_type_
nvertex   = nvertex_
nbp_lon   = nbp_lon_
nbp_lat   = nbp_lat_
nbp_lev   = nbp_lev_

if nbp_lon * nbp_lat == 1:
    klon_glo = 1
else:
    klon_glo = nbp_lon * nbp_lat - 2 * (nbp_lon - 1)

公式含义:

情况 klon_glo 解释
1D/testphys 1 单列模式不展开极点和经圈。
3D regular lon-lat nbp_lon * nbp_lat - 2*(nbp_lon-1) 二维 lon-lat 场有北极 nbp_lon 个重复经度和南极 nbp_lon 个重复经度;物理列表示每个极点只保留一个点,因此每个极点少 nbp_lon-1 个点。

在 Mars lon-lat 3D 路径中,inigeomphy_modiim*jjm>1 调用:

init_physics_distribution(regular_lonlat, 4, nbp, iim, jjm+1, nlayer, communicator)

随后 physics_distribution_mod 调用 init_grid_phy_lmdz,再初始化物理并行分布和 dimphy

泛型接口库存

Grid1Dto2D_glo 接口从 20 行开始,覆盖 integer/real/logical 三种类型,每种支持 1 到 4 维输入。Grid2Dto1D_glo 接口从 28 行开始,覆盖同样的类型和 rank。

方向 类型族 public wrapper private kernel
1D -> 2D integer grid1dTo2d_glo_i/i1/i2/i3 grid1dTo2d_glo_igen
1D -> 2D real grid1dTo2d_glo_r/r1/r2/r3 grid1dTo2d_glo_rgen
1D -> 2D logical grid1dTo2d_glo_l/l1/l2/l3 grid1dTo2d_glo_lgen
2D -> 1D integer grid2dTo1d_glo_i/i1/i2/i3 grid2dTo1d_glo_igen
2D -> 1D real grid2dTo1d_glo_r/r1/r2/r3 grid2dTo1d_glo_rgen
2D -> 1D logical grid2dTo1d_glo_l/l1/l2/l3 grid2dTo1d_glo_lgen

Wrapper 的职责是按额外维度计算 dimsize。例如 real 3D 物理列输入 VarIn(klon_glo, a, b) 会传入 dimsize = a*b;kernel 把第一维之外的维度作为线性 trailing block 处理。这样同一套两极展开/压缩规则可复用于 2D surface field、3D column field、带 tracer/soil/slope 等额外维度的数组。

Grid1Dto2D_glo 展开规则

三个 private kernel 的逻辑相同,只是数据类型不同。以 296-328 行的 integer 版本为例,输入逻辑尺寸是:

VarIn (klon_glo, dimsize)
VarOut(nbp_lon * nbp_lat, dimsize)
offset = nbp_lon

步骤:

  1. 对每个 trailing index i,把全局物理列 ij=1:klon_glo 写到二维线性场的 ij + nbp_lon - 1
  2. 把二维场第一纬圈 1:nbp_lon 全部填成 VarIn(1,i),即北极单物理点复制到所有经度。
  3. 把二维场最后一纬圈 nbp_lon*(nbp_lat-1)+1 : nbp_lon*nbp_lat 全部填成 VarIn(klon_glo,i),即南极单物理点复制到所有经度。

因此对 3D regular lon-lat,线性对应是:

2D row 1                         <- physical column 1, repeated nbp_lon times
2D rows 2 .. nbp_lat-1            <- physical columns 2 .. klon_glo-1
2D row nbp_lat                    <- physical column klon_glo, repeated nbp_lon times

Mars writediagfi.F 在并行模式中先 Gather(px, dx*_glop)klon_glo 全局物理列,再调用 Grid1Dto2D_glo 得到 dx*_glo(nbp_lon,nbp_lat,...),最后额外复制第一经度到 nbp_lon+1 形成 NetCDF lon wrap。

Grid2Dto1D_glo 压缩规则

2D 到 1D 的 private kernel 定义在 399-466 行,输入逻辑尺寸是:

VarIn (nbp_lon * nbp_lat, dimsize)
VarOut(klon_glo, dimsize)
offset = nbp_lon

步骤:

  1. 对每个 trailing index i,先把二维线性场的 ij + nbp_lon - 1 复制到 VarOut(ij,i)
  2. 然后显式执行 VarOut(1,i)=VarIn(1,i)

第二步会把北极物理列改成二维场第一个格点。南极物理列没有类似显式覆盖,因为第一步已经把 VarOut(klon_glo,i) 对应到最后一纬圈的第一个位置:klon_glo + nbp_lon - 1 = nbp_lon*(nbp_lat-1)+1

复现时要注意:Grid2Dto1D_glo 不对极点重复经度做平均;它取北极/南极纬圈的第一个经度位置。因此输入二维场若在极点经向不一致,压缩会静默丢弃其他经度。

Mars 使用点

使用方 使用符号 作用
COMMON inigeomphy_mod regular_lonlat, klon_glo 初始化 physical distribution 后,用 klon_glo 分配全局物理几何数组。
COMMON physics_distribution_mod init_grid_phy_lmdz 将 grid type、顶点数、lon/lat/lev 写入本模块。
COMMON xios_writefield nbp_lon, nbp_lat, klon_glo, grid_type 按 regular/unstructured 选择 XIOS domain 和 field shape。
COMMON write_field_phy Grid1Dto2D_glo, nbp_lon, nbp_lat, klon_glo 调试写场前把 gather 后的物理列转成 lon-lat。
Mars writediagfi.F, writediagmicrofi.F, writediagsoil.F90, wstats_mod.F90 Grid1Dto2D_glo, klon_glo, nbp_lon, nbp_lat 正式 diagfi/stats 输出从物理列变成 NetCDF lon-lat 场。
Mars xios_output_mod.F90 grid_type, unstructured, nbp_lon, nbp_lat, klon_glo 建立 XIOS domain,unstructured 时走专门 domain helper。
Mars surfini_mod.F90, slope_mod.F90 klon_glo, nbp_lon, nbp_lat surface/ice cap/slope 初始化按全局物理列和 lon-lat 分辨率循环。
Mars iostart.F90, phyredem.F90, phyetat0_mod.F90 klon_glo, nbp_lon, nbp_lat, nbp_lev physics start/restart 读写的维度和控制量。
Mars parse_tracer_file.F90 grid_type, regular_lonlat tracer.def 解析时在 lmdz/dynamico 类型之间分支。

复现要点

待确认

相关页面