comsaison_h.F90
路径
LMDZ.MARS\libf\phymars\comsaison_h.F90
所属目录/模块
libf\phymars
文件定位
comsaison_h.F90 定义 comsaison_h,是 phymars 中保存当前季节、太阳-火星距离、太阳赤纬、太阳天顶角余弦、日照时段比例和本地太阳时的共享状态模块。它本身不计算轨道或太阳几何,只声明 SAVE 变量、分配三个逐格点数组,并在结束时释放这些数组。
复现上,这个模块是 physiq 中辐射、近红外 CO2 吸收、坡面辐射、山顶尘流、火箭尘暴、尘暴注入和边界层尘埃释放时间窗的共同状态入口。若只分配 mu0/fract/local_time 而没有由 physiq_mod.F 在当前物理步写入,后续过程会读取未定义或过期的太阳几何状态。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
comsaison_h |
module |
1 |
保存季节和太阳几何共享状态 |
dist_sol |
real save module variable |
5 |
Sun-Mars distance,单位 AU |
declin |
real save module variable |
6 |
太阳赤纬,单位 rad |
zls |
real save module variable |
7 |
太阳经度 Ls,单位 rad |
mu0 |
real allocatable save module variable |
8 |
每个物理格点的太阳天顶角余弦 |
fract |
real allocatable save module variable |
9 |
当前时间间隔内日照比例,0 为夜间,1 为整段白天 |
local_time |
real allocatable save module variable |
10 |
每个格点的本地太阳时,单位为 sol/day fraction,范围 (0,1) |
ini_comsaison_h |
subroutine |
16 |
按 ngrid 分配 mu0/fract/local_time |
end_comsaison_h |
subroutine |
28 |
若数组已分配则释放 mu0/fract/local_time |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
| 无 |
- |
本模块不 use 其他模块 |
- |
调用的关键例程
| 被调用例程 |
所在模块/文件 |
调用位置 |
作用 |
| 无外部例程 |
- |
- |
本模块只使用 Fortran allocate/deallocate/allocated 机制 |
输入
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
ngrid |
phys_state_var_init_mod.F90 行 129 调用 ini_comsaison_h(ngrid) |
integer scalar |
- |
物理列数,也是 mu0/fract/local_time 的数组长度 |
zday |
physiq_mod.F 行 870 |
real scalar |
sol |
当前物理步的日期,含小数日 |
longitude_deg(ngrid) |
geometry_mod 经 physiq_mod.F 使用 |
real array |
degree |
计算 local_time 时的经度输入 |
season / day_ini |
physiq_mod.F 季节分支 |
logical / integer |
- / sol |
控制 zls 用当前 zday 还是初始日计算 |
diurnal |
physiq_mod.F 太阳几何分支 |
logical |
- |
控制 mu0/fract 用瞬时昼夜变化还是日平均修正 |
输出
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
zls |
physiq_mod.F 下游辐射、CO2 凝结、冰盖反照率、诊断 |
real scalar |
rad |
当前太阳经度 |
dist_sol |
callradite、nirco2abs、坡面辐射、thermosphere、topmons、rocketduststorm |
real scalar |
AU |
用于把 1 AU 太阳常数缩放为火星当前太阳常数 |
declin |
solang / mucorr 输入、坡面辐射、nirco2abs |
real scalar |
rad |
太阳赤纬 |
mu0(ngrid) |
callradite、topmons、rocketduststorm、坡面辐射、nirco2abs、thermosphere、诊断 |
real array |
- |
太阳天顶角余弦 |
fract(ngrid) |
callradite、topmons、rocketduststorm、nirco2abs |
real array |
- |
当前辐射时间间隔中白天所占比例 |
local_time(ngrid) |
compute_dtau、vdifc、write_output("local_time") |
real array |
sol fraction |
本地太阳时,驱动尘埃注入和诊断输出 |
共享状态与副作用
dist_sol、declin、zls、mu0、fract、local_time 都是 SAVE 模块状态。
- 源码行 12 使用 OpenMP
THREADPRIVATE(dist_sol,declin,zls,mu0,fract,local_time),表示每个线程拥有独立副本。
ini_comsaison_h(ngrid) 只分配三个数组,不初始化数值;标量也没有在本模块中给默认值。
end_comsaison_h 对三个数组逐个 allocated(...) 检查后释放。
- 本模块不写文件、不输出日志、不调用中止例程。
核心逻辑
phys_state_var_init_mod.F90 行 38 导入 ini_comsaison_h,end_comsaison_h。
phys_state_var_init_mod.F90 行 127-129 在物理状态初始化时先调用 end_comsaison_h,再调用 ini_comsaison_h(ngrid),确保三个逐格点数组按当前物理列数分配。
physiq_mod.F 行 63-64 导入 dist_sol, declin, zls, mu0, fract, local_time。
physiq_mod.F 行 870-875 计算 zday=pday+ptime,然后对每个格点用 zday 的小数部分和 longitude_deg/15/24 写入 local_time(ig)。
physiq_mod.F 行 878-882 按 season 分支调用 solarlong(zday,zls) 或 solarlong(float(day_ini),zls)。
- 当
callrad 为真时,physiq_mod.F 行 1010 调用 orbite(zls,dist_sol,declin),用当前 Ls 写入太阳-火星距离和赤纬。
- 若
diurnal 为真,physiq_mod.F 行 1012-1018 用 declin 和 zday 构造太阳方向,并调用 solang(...,mu0,fract);否则行 1021 调用 mucorr(ngrid,declin,latitude,mu0,fract,10000.,rad) 计算日平均辐射几何。
- 之后
physiq 把 mu0/fract/dist_sol/zls/declin/local_time 传给辐射、近红外吸收、坡面、尘暴、边界层和诊断路径。
伪代码
module comsaison_h:
keep scalar SAVE state:
dist_sol, declin, zls
keep allocatable SAVE arrays:
mu0(ngrid), fract(ngrid), local_time(ngrid)
mark all state THREADPRIVATE
ini_comsaison_h(ngrid):
allocate mu0(ngrid)
allocate fract(ngrid)
allocate local_time(ngrid)
end_comsaison_h:
if mu0 is allocated:
deallocate mu0
if fract is allocated:
deallocate fract
if local_time is allocated:
deallocate local_time
physiq step:
zday = pday + ptime
for each grid point:
local_time = modulo(1 + fractional_sol + longitude_deg / 360, 1)
compute zls from current day or initial day
if radiation is active:
compute dist_sol and declin from zls
if diurnal cycle is active:
compute mu0 and fract with solang
else:
compute mu0 and fract with mucorr
参与的主题流程
| 主题 |
参与方式 |
| 物理状态初始化 |
phys_state_var_init 负责释放并重新分配 mu0/fract/local_time |
| 太阳几何 / 辐射 |
physiq 计算 zls/dist_sol/declin/mu0/fract,callradite 用 dist_sol 缩放太阳常数并把 mu0/fract 传入短波辐射 |
| 尘暴与山顶尘流 |
rocketduststorm_mod 和 topmons_mod 读取 dist_sol/mu0/fract 做第二次辐射调用,topmons 还用 mu0 > mu0lim 判定白天 |
| 坡面辐射 |
physiq 坡面分支用 mu0、declin 和 dist_sol 计算直接辐射并调用 param_slope |
| 尘埃注入 |
compute_dtau 用 local_time 穿越 t_scenario_sol 的时刻计算 dtau,vdifc 用 local_time 判断注入时间窗 |
| 诊断输出 |
physiq 行 3423-3424 输出 local_time 字段 |
写法特点
- 这是一个很小的自由格式
.F90 共享状态模块,采用 LMD 常见的 SAVE + ALLOCATABLE + THREADPRIVATE 写法。
ini_comsaison_h 没有 .not.allocated(...) 保护;调用方通过先执行 end_comsaison_h 避免重复分配。
- 数组分配和数值填充分离;本模块只分配,实际填充集中在
physiq_mod.F 的每个物理步。
local_time 注释标明是 (0,1) 的日/sol fraction,不是小时;physiq 使用经度换算 (longitude_deg/15)/24 也等价于经度除以 360。
复现要点
- 复现任何读取
mu0/fract/local_time 的路径前,必须先执行 phys_state_var_init 的分配步骤,并在物理步中让 physiq 写入当前时刻的太阳几何。
dist_sol/declin/zls 在本模块内没有初始值;若绕过 physiq 直接调用 topmons、rocketduststorm 或 callradite,需要显式设置这些标量。
mu0/fract 只在 callrad 分支内由 orbite 后续的 solang 或 mucorr 更新;关闭辐射时仍读取这些数组的自定义流程需要单独确认其值来源。
local_time 是 sol fraction。把它当作小时会使 compute_dtau 和 vdifc 的尘埃注入时间窗错位。
THREADPRIVATE 表示并行运行中每个线程持有自己的状态副本;复现 OpenMP 运行时要确认分配和填充发生在实际执行物理过程的线程上下文中。
- 如果网格大小变化,必须先释放再按新
ngrid 分配;直接重复调用 ini_comsaison_h 可能触发已分配数组再次分配错误。
待确认
mu0/fract 在 callrad=.false. 的运行配置下是否仍有其他路径需要有效值;本页只确认源码中字面更新发生在 callrad 分支。
- OpenMP 多线程运行时各线程何时获得并填充
THREADPRIVATE 副本,需要结合外层并行初始化约定进一步确认。
相关页面