phys_state_var_init_mod.F90
快速理解
它做什么: 物理状态数组和基础常数的生命周期编排模块;按固定顺序分配共享模块数组并写入行星常数。
基本过程: 输入 ngrid/nlayer/nq/nslope → 调各共享模块 ini_* 按维度分配 → 写入 prad/pg/pr/pcpp 等行星常数和时间控制。
关键结果: 重新分配所有物理共享模块数组,写入第一批物理常数;由 iniphysiq_mod(3D)和 init_testphys1d_mod(1D)在 inigeomphy 之后调用。
路径
LMDZ.MARS\libf\phymars\phys_state_var_init_mod.F90
所属目录 / 模块
libf/phymars
文件定位
phys_state_var_init_mod.F90 是 phymars 物理状态数组和基础常数的生命周期编排模块。它不计算具体物理 tendency,而是在物理初始化入口里按固定顺序释放旧数组、重新分配共享模块数组,并写入第一批物理常数和时间控制状态。
源码注释说明这些工作过去由 inifis 完成。当前 3D GCM 路径中,iniphysiq_mod.F90 在 inigeomphy 之后进入 OpenMP 并行区,调用 phys_state_var_init,随后才调用 ini_fillgeom 填充几何三角缓存,再调用 conf_phys 读取物理配置。1D init_testphys1d_mod.F90 也复用同一个入口,在它之后执行 ini_fillgeom、conf_phys 和 initracer。
复现时要把本文件看作“分配和初始化顺序契约”:很多下游模块假定自己的数组已经按 ngrid/nlayer/nq/nslope 分配好,但几何值、restart 字段和运行开关仍由后续入口继续填充。
定义的符号
| 符号 | 类型 | 行号 | 作用 |
|---|---|---|---|
phys_state_var_init_mod |
module | 1 | 物理状态变量初始化编排模块 |
phys_state_var_init |
subroutine | 5 | 确定坡面维度,初始化常数和时间状态,并按固定顺序释放/分配多个 phymars 共享模块数组 |
依赖的模块
| use 模块 | only 列表 | 用途 | 待确认 |
|---|---|---|---|
init_print_control_mod |
init_print_control |
初始化输出控制常数和标志 | - |
slope_mod |
ini_slope_mod, end_slope_mod |
分配坡面几何数组 | - |
comsaison_h |
ini_comsaison_h, end_comsaison_h |
分配季节和太阳几何共享数组 | - |
surfdat_h |
ini_surfdat_h, end_surfdat_h |
按 ngrid,nq,nslope 分配地表状态数组 |
- |
comgeomfi_h |
ini_comgeomfi_h, end_comgeomfi_h |
分配几何三角函数缓存 | - |
comsoil_h |
ini_comsoil_h, end_comsoil_h |
按 ngrid,nslope 分配土壤共享状态 |
- |
dimradmars_mod |
ini_dimradmars_mod, end_dimradmars_mod |
按 ngrid,nlayer,nslope 分配辐射维度相关数组 |
- |
yomlw_h |
ini_yomlw_h, end_yomlw_h |
分配长波辐射共享数组 | - |
conc_mod |
ini_conc_mod, end_conc_mod |
分配大气混合物热力学属性缓存 | - |
turb_mod |
ini_turb_mod, end_turb_mod |
分配湍流共享数组 | - |
comcstfi_h |
init_comcstfi_h |
写入半径、比热、重力和气体常数 | - |
tracer_mod |
ini_tracer_mod, end_tracer_mod |
初始化 tracer 定义相关状态 | - |
time_phylmdz_mod |
init_time |
初始化物理时间和日历状态 | - |
compute_dtau_mod |
ini_compute_dtau_mod, end_compute_dtau_mod |
分配尘埃光学厚度时间记忆数组 | - |
rocketduststorm_mod |
ini_rocketduststorm_mod, end_rocketduststorm_mod |
分配火箭式尘暴方案数组 | - |
calchim_mod |
ini_calchim_mod, end_calchim_mod |
分配光化学相关数组 | - |
watercloud_mod |
ini_watercloud_mod, end_watercloud_mod |
分配水云微物理数组 | - |
nonoro_gwd_ran_mod |
ini_nonoro_gwd_ran, end_nonoro_gwd_ran |
分配非地形随机重力波记忆数组 | - |
nonoro_gwd_mix_mod |
ini_nonoro_gwd_mix, end_nonoro_gwd_mix |
分配非地形重力波混合数组 | - |
dust_param_mod |
ini_dust_param_mod, end_dust_param_mod |
分配尘埃参数数组 | - |
dust_rad_adjust_mod |
ini_dust_rad_adjust_mod, end_dust_rad_adjust_mod |
分配尘埃辐射调整状态 | - |
comslope_mod |
nslope, end_comslope_h, ini_comslope_h |
保存并分配坡面维度相关状态 | - |
paleoclimate_mod |
end_paleoclimate, ini_paleoclimate |
分配古气候 lag-layer 状态 | - |
tracer_mass_fixer_dyn_mod |
ini_tracer_mass_fixer_dyn, end_tracer_mass_fixer_dyn |
分配动力 tracer 质量修正缓存 | - |
netcdf |
- | 读取 startfi.nc 的 nslope 维度 |
- |
mod_phys_lmdz_para |
is_master, bcast |
非 MESOSCALE 路径下 master 读取 nslope 并广播 |
- |
调用的关键例程
| 被调用例程 | 所在模块 / 文件 | 调用位置 | 作用 |
|---|---|---|---|
nf90_open / nf90_inq_dimid / nf90_inquire_dimension |
NetCDF | 83-96 | 尝试从 startfi.nc 读取 nslope 维度长度 |
abort_physic |
外部错误处理入口 | 95 | 当 nslope 维度存在但无法读取时中止初始化 |
bcast |
mod_phys_lmdz_para |
103 | 将 master 进程确定的 nslope 广播给其他进程 |
end_tracer_mod / ini_tracer_mod |
tracer_mod |
111-112 | 释放并初始化 tracer 模块状态 |
init_print_control |
init_print_control_mod |
115 | 初始化输出控制 |
init_comcstfi_h |
comcstfi_h |
118 | 写入 rad/cpp/g/r 等基础常数 |
init_time |
time_phylmdz_mod |
121 | 写入初始日、终止日、初始时刻、sol 长度和物理时间步 |
end_* / ini_* 系列 |
多个 phymars 模块 |
124-201 | 逐模块释放并按当前维度重新分配共享数组 |
输入
| 输入 | 来源 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
ngrid |
调用方 | integer scalar | - | 当前物理列数;3D 路径传 klon_omp,1D 路径传 1 |
nlayer |
调用方 | integer scalar | - | 垂直大气层数 |
nq |
调用方 | integer scalar | - | tracer 数量 |
day_ini, day_end |
调用方 / 动力时间模块 | integer scalar | sol | 初始和结束日期 |
hour_ini |
调用方 / 动力时间模块 | real scalar | sol fraction 或小时语义由上游决定 | 初始时刻 |
pdaysec |
调用方 | real scalar | s | sol 长度 |
ptimestep |
调用方 | real scalar | s | 物理时间步 |
prad, pg, pr, pcpp |
调用方 | real scalars | SI 混合 | 行星半径、重力、气体常数和比热 |
startfi.nc |
当前运行目录 | NetCDF file | - | 可选读取 nslope 维度;文件缺失或无该维度时使用 nslope=1 |
输出
| 输出 | 去向 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
nslope |
comslope_mod |
integer scalar | - | 坡面 bin 数;由 startfi.nc 维度或 MESOSCALE/default 路径确定 |
rad, g, r, cpp 等 |
comcstfi_h |
module scalars | SI | 物理常数缓存 |
day_ini/day_end/hour_ini/daysec/dtphys 等 |
time_phylmdz_mod |
module state | 混合 | 物理时间控制状态 |
| 多个共享模块数组 | surfdat_h, comsoil_h, dimradmars_mod, watercloud_mod, nonoro_gwd_* 等 |
allocatable module arrays | 混合 | 按当前运行维度分配后的物理状态缓存 |
共享状态与副作用
- 非
MESOSCALE构建下,只有is_master进程直接打开startfi.nc查询nslope维度;随后bcast(nslope)把结果同步给所有进程。 MESOSCALE构建下不读取startfi.nc的坡面维度,而是打印subgrid slopes temporarily switched off in mesoscale, nslope=1并强制nslope=1。- 例程会连续调用大量
end_*后接ini_*,其副作用是释放旧分配并按新维度重建共享状态。复现初始化顺序时不能跳过这些释放调用,因为下游ini_*入口未必都能安全处理已分配数组。 - 本文件只调用
ini_comgeomfi_h(ngrid)分配sinlat/coslat/sinlon/coslon等缓存;实际几何值由调用方随后调用ini_fillgeom填入。 - 源码直接调用
abort_physic,但本文件未显式use abort_physic所在模块;复现编译行为时应以当前构建系统的外部接口解析为准。
核心逻辑
- 把目标文件名固定为
startfi.nc。 - 非
MESOSCALE下由 master 尝试打开startfi.nc。文件不存在或没有nslope维度时设置nslope=1;若nslope维度存在但无法读取长度,则调用abort_physic中止;读取成功时令nslope=nslope_read。 - 非
MESOSCALE下广播nslope;MESOSCALE下直接强制nslope=1。 - 释放并初始化
tracer_mod,再初始化输出控制。 - 调用
init_comcstfi_h(prad,pcpp,pg,pr)写入基础物理常数。 - 调用
init_time(day_ini,day_end,hour_ini,pdaysec,ptimestep)写入物理日历和时间步状态。 - 按源码顺序释放/分配坡面、季节、地表、几何、土壤、辐射、长波、混合物属性、湍流、尘埃、化学、水云、非地形重力波、坡面分布、古气候和 tracer 质量修正相关模块数组。
伪代码
phys_state_var_init(ngrid,nlayer,nq, day_ini,day_end,hour_ini, pdaysec,ptimestep, prad,pg,pr,pcpp)
filename = "startfi.nc"
if not MESOSCALE:
if is_master:
if startfi.nc cannot be opened:
nslope = 1
else if dimension "nslope" is absent:
nslope = 1
else if dimension length cannot be read:
abort_physic("phys_state_var_init", "nslope present but not readable", 1)
else:
nslope = nslope_read
bcast(nslope)
else:
print mesoscale slope-disabled message
nslope = 1
end_tracer_mod()
ini_tracer_mod()
init_print_control()
init_comcstfi_h(prad, pcpp, pg, pr)
init_time(day_ini, day_end, hour_ini, pdaysec, ptimestep)
for each shared-state module in source order:
call its end_* routine
call its ini_* routine with ngrid, nlayer, nq, and/or nslope
参与的主题流程
| 主题 | 参与方式 |
|---|---|
| 物理初始化 | 在 3D iniphysiq 和 1D init_testphys1d 中分配 phymars 共享状态,是 conf_phys 和 physiq 前的状态准备层 |
| 物理 restart 兼容 | 先从 startfi.nc 的 nslope 维度决定坡面相关数组大小,使后续 phyetat0_mod 读坡面字段时维度匹配 |
| 次网格坡面 | 初始化 slope_mod、surfdat_h、comsoil_h、dimradmars_mod、comslope_mod 和 paleoclimate_mod 的坡面维度相关数组 |
| 水云和 CO2/尘埃相关流程 | 分配 watercloud_mod、dust_param_mod、dust_rad_adjust_mod、compute_dtau_mod 等共享缓存,具体物理值由后续配置、restart 或物理步填充 |
| 非地形重力波 | 分配随机 GW 和 eddy-mix GW 的跨步记忆数组,restart 读取由 phyetat0_mod 负责 |
写法特点
- 本例程是一个长初始化序列,源码顺序就是运行契约。新增模块若有共享数组,一般需要在这里补上对应
end_*/ini_*调用。 nslope在任何坡面相关数组分配前确定,避免surfdat_h、comsoil_h、dimradmars_mod、comslope_mod和paleoclimate_mod维度不一致。- 3D OpenMP 路径中本例程位于
!$OMP PARALLEL COPYIN(day_ini,day_end,hour_ini)内;被初始化模块若含 threadprivate 状态,复现时需要保留调用上下文。
复现要点
- 若
startfi.nc存在且含nslope维度,坡面相关数组会按该长度分配;若文件缺失或无nslope维度,则默认只有一个坡面。 - 若
startfi.nc中存在nslope维度但 NetCDF 无法读取长度,初始化会中止,而不是回退到nslope=1。 - 单独调用
phys_state_var_init只分配comgeomfi_h的几何缓存,不会填入经纬度三角函数;3D 和 1D 调用方都在之后调用ini_fillgeom。 - 1D 无 restart 路径后续可能通过
nslope配置重新释放并分配surfdat_h、comsoil_h、dimradmars_mod和paleoclimate_mod的 slope-var 数组;不要把phys_state_var_init的初始nslope当作 1D 最终坡面维度的唯一来源。 ini_tracer_mod与 1D 后续initracer不是同一层入口:本文件负责 tracer 模块初始化,1D 入口后续还会执行更具体的 tracer 初始场处理。
待确认
abort_physic在本文件中未显式通过use导入;需以当前编译单元和接口声明方式确认是否依赖外部过程解析。