comgeomfi_h.F90
路径
LMDZ.MARS\libf\phymars\comgeomfi_h.F90
所属目录/模块
libf\phymars
文件定位
comgeomfi_h.F90 定义 comgeomfi_h,是 phymars 中保存物理网格经纬度三角函数的共享几何缓存模块。它不保存原始 longitude、latitude 或 cell_area,而是在初始化后由调用方传入物理网格经纬度数组,并把每个格点的 sin(lat)、cos(lat)、sin(lon)、cos(lon) 缓存在 sinlat/coslat/sinlon/coslon 中。
这个模块的复现意义在于:太阳天顶角、近红外 CO2 吸收、尘埃顶高经验式和 1D Coriolis 参数都读取这些缓存值。若只重建了 geometry_mod 的经纬度而没有执行 ini_fillgeom,下游物理仍会读到未填充的 comgeomfi_h 数组。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
comgeomfi_h |
module |
2 |
保存物理网格经纬度三角函数缓存 |
sinlon |
real allocatable save module variable |
6 |
每个物理格点经度的正弦 |
coslon |
real allocatable save module variable |
7 |
每个物理格点经度的余弦 |
sinlat |
real allocatable save module variable |
8 |
每个物理格点纬度的正弦 |
coslat |
real allocatable save module variable |
9 |
每个物理格点纬度的余弦 |
ini_comgeomfi_h |
subroutine |
15 |
按 ngrid 分配四个几何缓存数组 |
end_comgeomfi_h |
subroutine |
28 |
若数组已分配则逐个释放 |
ini_fillgeom |
subroutine |
39 |
用传入的纬度、经度数组填充四个三角函数缓存 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
| 无 |
- |
本模块没有 use 依赖 |
- |
调用的关键例程
| 被调用例程 |
所在模块/文件 |
调用位置 |
作用 |
sin |
Fortran intrinsic |
comgeomfi_h.F90 行 47、49 |
计算纬度和经度正弦 |
cos |
Fortran intrinsic |
comgeomfi_h.F90 行 48、50 |
计算纬度和经度余弦 |
输入
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
ngrid |
phys_state_var_init、ini_fillgeom 调用方 |
integer scalar |
- |
物理网格列数,也是四个缓存数组长度 |
plat(ngrid) |
GCM: geometry_mod::latitude;1D: init_testphys1d_mod 本地 latitude |
real array |
rad |
每个物理格点纬度 |
plon(ngrid) |
GCM: geometry_mod::longitude;1D: init_testphys1d_mod 本地 longitude |
real array |
rad |
每个物理格点经度 |
parea(ngrid) |
GCM: geometry_mod::cell_area;1D: (/1.0/) |
real array |
m2,1D 为占位值 |
传入接口保留的网格面积;本文件源码没有读取该参数 |
输出
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
sinlat(ngrid) |
physiq_mod.F、nirco2abs.F、aeropacity_mod.F、1D 初始化 |
real allocatable save array |
- |
sin(latitude) 缓存 |
coslat(ngrid) |
physiq_mod.F、nirco2abs.F |
real allocatable save array |
- |
cos(latitude) 缓存 |
sinlon(ngrid) |
physiq_mod.F、nirco2abs.F |
real allocatable save array |
- |
sin(longitude) 缓存 |
coslon(ngrid) |
physiq_mod.F、nirco2abs.F |
real allocatable save array |
- |
cos(longitude) 缓存 |
共享状态与副作用
sinlon、coslon、sinlat、coslat 都是 ALLOCATABLE,SAVE 模块数组。
- 源码行 11 用 OpenMP
THREADPRIVATE(sinlon,coslon,sinlat,coslat) 声明四个数组为线程私有状态。
ini_comgeomfi_h(ngrid) 只分配数组,不写入有效几何值。
ini_fillgeom(ngrid,plat,plon,parea) 写入四个数组;parea 在源码中未被读取。
end_comgeomfi_h 释放已分配数组;被 phys_state_var_init 在重新分配前调用。
- 本模块没有文件 I/O、日志输出或错误中止。
核心逻辑
phys_state_var_init_mod.F90 行 40 导入 ini_comgeomfi_h,end_comgeomfi_h,行 135-137 先调用 end_comgeomfi_h,再以当前 ngrid 调用 ini_comgeomfi_h(ngrid) 分配缓存。
- GCM lon-lat 初始化路径
dynphy_lonlat/phymars/iniphysiq_mod.F90 行 20 导入 ini_fillgeom,行 21-23 从 geometry_mod 读取 cell_area、longitude、latitude,行 75 在 phys_state_var_init(...) 后调用 ini_fillgeom(klon_omp,latitude,longitude,cell_area)。
- 1D 路径
dyn1d/init_testphys1d_mod.F90 行 415、417 先把纬度和经度从度转换为弧度,行 430 调用 phys_state_var_init(...) 分配状态,行 431 调用 ini_fillgeom(1,latitude,longitude,(/1.0/)) 填充单列缓存。
ini_fillgeom 对 ig=1..ngrid 循环,依次写入 sinlat(ig)=sin(plat(ig))、coslat(ig)=cos(plat(ig))、sinlon(ig)=sin(plon(ig))、coslon(ig)=cos(plon(ig))。
- 下游
physiq_mod.F 行 1017、nirco2abs.F 行 216 把这四个数组传给 solang;solang.F 行 101-104 用 psilat/pcolat/pcolon/psilon 组合太阳几何并输出 pmu0。
aeropacity_mod.F 行 353 单独读取 sinlat,用 60. -22.*sinlat(ig)**2 设置 topdust0 的纬向依赖。
- 1D 初始化行 607 读取
sinlat(1),计算 ptif = 2.*omeg*sinlat(1)。
伪代码
module comgeomfi_h:
keep threadprivate arrays:
sinlon, coslon, sinlat, coslat
ini_comgeomfi_h(ngrid):
allocate sinlat(ngrid)
allocate coslat(ngrid)
allocate sinlon(ngrid)
allocate coslon(ngrid)
end_comgeomfi_h:
if each array is allocated:
deallocate it
ini_fillgeom(ngrid, plat, plon, parea):
for ig from 1 to ngrid:
sinlat(ig) = sin(plat(ig))
coslat(ig) = cos(plat(ig))
sinlon(ig) = sin(plon(ig))
coslon(ig) = cos(plon(ig))
参与的主题流程
| 主题 |
参与方式 |
| 物理状态初始化 |
phys_state_var_init 分配/重分配四个几何缓存数组 |
| 动力-物理初始化 |
iniphysiq_mod 从 geometry_mod 取得物理网格经纬度并调用 ini_fillgeom |
| 1D testphys |
1D 初始化把用户纬度/经度转弧度后填充单列缓存,并用 sinlat(1) 计算 Coriolis 参数 |
| 太阳几何 / 辐射 |
physiq_mod 和 nirco2abs 将四个缓存数组传入 solang 计算太阳天顶角余弦和日照比例 |
| 尘埃光学厚度 |
aeropacity_mod 用 sinlat 的纬向依赖设置 topdust0 |
写法特点
- 这是很小的自由格式
.F90 状态模块,使用 ALLOCATABLE,SAVE 数组加 OpenMP THREADPRIVATE。
ini_comgeomfi_h 与 ini_fillgeom 分离:分配成功不代表数组已有有效经纬度三角函数。
ini_fillgeom 的经纬度单位由调用方保证;源码直接调用 sin/cos,因此要求输入为弧度。GCM geometry_mod 导入注释标明 longitude、latitude 为 rad,1D 路径也显式把度转换为弧度。
parea 是接口参数但在本文件未使用;可能是历史接口或与 geometry_mod 合并计划相关。iniphysiq_mod.F90 行 76 注释提到需要把 comgeomfi_h 的内容放入 geometry_mod。
复现要点
- 复现任意读取
sinlat/coslat/sinlon/coslon 的物理过程前,必须确认已先执行 ini_comgeomfi_h 分配,并执行 ini_fillgeom 写入当前网格经纬度。
ini_fillgeom 的 plat/plon 必须为弧度;若误传度数,太阳几何、近红外 CO2 加热率、尘埃顶高纬向项和 1D Coriolis 参数都会偏离。
THREADPRIVATE 表示每个 OpenMP 线程有自己的数组副本;并行复现时需要确认初始化区域覆盖实际参与物理计算的线程。
parea 传入但未用;不要据此推断本模块保存或使用格点面积。
- 若网格尺寸变化,
phys_state_var_init 的 end_comgeomfi_h + ini_comgeomfi_h 只处理释放/重分配,仍需要随后用新网格调用 ini_fillgeom。
待确认
parea 参数是否只是历史兼容接口,或是否曾计划用于面积相关几何缓存;本文件没有使用证据。
- OpenMP 运行时如何保证所有线程私有数组都已分配并填充,需要结合当前并行初始化约定进一步确认。
相关页面