regular_lonlat_mod.F90 与 vertical_layers_mod.F90
源码路径:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\regular_lonlat_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\vertical_layers_mod.F90
Mars 运行参与度:条件经过。Mars 3D 初始化通过 inigeomphy_mod 写入这两组状态;Mars 1D/testphys1d 也会初始化;Mars 输出、XIOS 输出和若干 physics 参数化读取 regular grid 或垂直层状态。
文件职责
这两个模块保存的是物理侧“坐标状态”,但粒度不同:
regular_lonlat_mod保存全局 regular longitude-latitude 网格中心和边界,不声明THREADPRIVATE,注释明确为所有线程共享。vertical_layers_mod保存当前 OpenMP 线程的物理侧垂直坐标副本,所有变量在同一个THREADPRIVATE指令中声明。
它们都只分配和复制输入,不计算动力网格、物理列切分或插值。全局物理列一维/二维映射由 mod_grid_phy_lmdz 管;局部物理列经纬度、cell area 和 cell index 由 geometry_mod 管。
模块状态
regular_lonlat_mod
| 符号 | 维度 | 单位/含义 | 并行语义 |
|---|---|---|---|
north_east, north_west, south_west, south_east |
scalar parameters | unstructured/四角边界枚举值 1..4 | 常量 |
east, west, north, south |
scalar parameters | regular lon/lat 二边界枚举值 | 常量 |
lon_reg(:) |
nbp_lon |
longitude center, rad | 全局共享 |
lat_reg(:) |
nbp_lat |
latitude center, rad | 全局共享 |
boundslon_reg(:,:) |
nbp_lon,2 |
longitude boundaries,1 east、2 west,rad | 全局共享 |
boundslat_reg(:,:) |
nbp_lat,2 |
latitude boundaries,1 north、2 south,rad | 全局共享 |
源码注释写着 Do not set threadprivate directives,因此不要把这些数组当作每线程局部切片。它们代表完整 regular lon-lat 坐标轴。
vertical_layers_mod
| 符号 | 维度 | 单位/含义 | 并行语义 |
|---|---|---|---|
preff |
scalar | reference surface pressure, Pa | THREADPRIVATE |
scaleheight |
scalar | atmospheric reference scale height, km | THREADPRIVATE |
ap(:) |
nlayer+1 |
hybrid pressure coordinate at layer interfaces, Pa | THREADPRIVATE |
bp(:) |
nlayer+1 |
hybrid sigma coordinate at layer interfaces | THREADPRIVATE |
aps(:) |
nlayer |
hybrid pressure coordinate at mid-layer, Pa | THREADPRIVATE |
bps(:) |
nlayer |
hybrid sigma coordinate at mid-layer | THREADPRIVATE |
presnivs(:) |
nlayer |
reference pressure at mid-layer, Pa | THREADPRIVATE |
pseudoalt(:) |
nlayer |
pseudo-altitude, km | THREADPRIVATE |
vertical_layers_mod 是 comvert_mod 动力垂直坐标状态的物理侧副本。初始化后 Mars physics 可以在物理侧直接读取这些数组,而不需要依赖动力模块。
例程
| 例程 | 输入 | 行为 |
|---|---|---|
init_regular_lonlat(nbp_lon, nbp_lat, lon_reg_, lat_reg_, boundslon_reg_, boundslat_reg_) |
全局 longitude/latitude 坐标轴和边界 | 分配 lon_reg/lat_reg/boundslon_reg/boundslat_reg 并复制输入。 |
init_vertical_layers(nlayer, preff_, scaleheight_, ap_, bp_, aps_, bps_, presnivs_, pseudoalt_) |
垂直坐标和参考压力/高度数组 | 分配 ap/bp/aps/bps/presnivs/pseudoalt,复制 scalar 与数组。 |
两个例程都没有 deallocate 或重复初始化保护。正常运行应保证同一线程/进程上下文只初始化一次。
初始化链
Mars 3D
iniphysiq_mod
-> inigeomphy_mod
-> 构造 boundslon_reg(iim,2), boundslat_reg(jjm+1,2)
-> init_regular_lonlat(iim, jjm+1, rlonv(1:iim), rlatu,
boundslon_reg, boundslat_reg)
-> ... 初始化局部 geometry_mod ...
-> init_vertical_layers(nlayer, preff, scaleheight,
ap, bp, aps, bps, presnivs, pseudoalt)
inigeomphy_mod 对 longitude 第一列边界做特殊处理:boundslon_reg(1,west)=rlonu(iim)-2*PI,使从 -180 附近开始的 regular grid 具有正确 west boundary。latitude 两端则用 PI/2 和 -PI/2 作为极点边界。
垂直层初始化发生在 OpenMP parallel 区内,复制的是 comvert_mod 中已经由 disvert 或 disvert_noterre 建好的 preff/ap/bp/aps/bps/presnivs/scaleheight/pseudoalt。
Mars 1D/testphys1d
init_testphys1d_mod
-> disvert_noterre
-> init_vertical_layers(nlayer, preff, scaleheight, ap, bp, aps, bps, presnivs, pseudoalt)
-> init_regular_lonlat(1, 1, longitude, latitude, (/0.,0./), (/0.,0./))
1D 路径先在 disvert_noterre 后初始化垂直层,再为单列网格初始化 regular_lonlat_mod。
Mars 使用关系
| 使用方 | 读取符号 | 用途 |
|---|---|---|
Mars iniwrite.F |
lon_reg, lat_reg, ap/bp/aps/bps/pseudoalt |
写 diagfi/physics 输出文件的 longitude、latitude 和 altitude 轴。3D 时给 longitude 追加冗余端点。 |
Mars iniwritesoil.F90 |
lon_reg, lat_reg |
写 soil 输出的 longitude/latitude 轴,3D 时同样追加冗余 longitude 端点。 |
Mars physiq_mod.F |
ap/bp/aps/bps/presnivs/pseudoalt |
CPP_XIOS 下把 presnivs/pseudoalt/mlayer 传给 initialize_xios_output。 |
Mars co2cloud_mod.F90, co2condens_mod.F |
ap, bp |
CO2 cloud/condensation vertical coordinate calculations。 |
Mars nonoro_gwd_* |
presnivs |
构造重力波 drag 的 reference pressure mid-layer heights。 |
Mars aeronomars/inichim_newstart.F90 |
aps, bps |
chemistry/newstart vertical interpolation or matching。 |
复现要点
regular_lonlat_mod使用 rad;Mars 输出通常写前乘180/pi。- 3D longitude 输出会在 Mars
iniwrite/iniwritesoil中追加一个冗余端点,源码用lon_reg_ext(nbp_lon+1)=-lon_reg_ext(1)。 vertical_layers_mod中pseudoalt单位是 km,presnivs/ap/aps/preff是 Pa;输出文件的 axis 名可能叫altitude,但值来自pseudoalt。- OpenMP 下垂直层状态是 threadprivate;若某线程未执行
init_vertical_layers,它读到的 allocatable 数组不会自动来自 master 线程。 - 本页只保存坐标状态,不定义垂直坐标生成算法;
disvert/disvert_noterre和comvert_mod见 vertical-coordinate-mars-contract。
待确认
regular_lonlat_mod中lat_reg与boundslat_reg的源码注释有 “longitude cell” 文案,按形参与调用点判断应为 latitude;本页按变量名和inigeomphy_mod调用解释。north_east/north_west/south_west/south_east在本模块中定义但 regular 初始化只使用east/west/north/south;四角枚举的活跃使用位置需要在 unstructured/subslope 页面继续确认。