physiq_mod.F
路径
LMDZ.MARS\libf\phymars\physiq_mod.F
所属目录/模块
libf/phymars
MODULE physiq_mod
文件定位
physiq_mod.F 是 Mars physics package 的主时间步调度文件。它定义 physiq_mod 模块和唯一入口 physiq,由动力-物理接口 call_physiq 以及 1D 测试程序直接调用,接收动力核给出的压力、温度、风、tracer 和垂直质量通量,返回物理过程对风、温度、tracer 与表压的 tendency。源码注释在 physiq_mod.F:163-170 明确说明本文件组织 LMD Mars GCM 的物理参数化。
本文件不是某个单一物理方案,而是把 firstcall 初始化、restart 读取/写出、太阳几何、辐射、尘埃输运、垂直扩散、热羽流、对流、重力波、水循环、CO2 云/凝结、化学、热层、地表/土壤更新和诊断输出串成一个物理时间步。下游单个过程的内部算法见相关文件页;本页重点记录 physiq 如何按源码顺序连接这些过程、累加 tendency、更新共享状态并产生副作用。
定义的符号
| 符号 | 类型 | 行号 | 作用 |
|---|---|---|---|
physiq_mod |
module | 1-4162 | 包装 Mars physics 主入口。 |
physiq |
subroutine | 7-4160 | 主物理时间步;输入动力状态,输出物理 tendency,并更新大量 phymars 共享物理状态。 |
day_ini |
INTEGER,SAVE local state |
295, 299 | run 初始 sol;从 startfi.nc 或 MESOSCALE/academic 初始化路径设置,firstcall 后保持。 |
icount |
INTEGER,SAVE local state |
296, 299, 4158 | physiq 调用计数器;控制辐射步、NLTE 每 sol 更新、restart 时间和诊断时序。 |
time_phys |
REAL,SAVE local state |
297, 299 | restart 中的物理起始时间记忆;写 restart 时间时使用。 |
check_physics_inputs |
logical,save local switch |
560-563, 604, 828-830 | 可选步首输入场检查开关;由 getin_p("check_physics_inputs",...) 读取。 |
check_physics_outputs |
logical,save local switch |
560-563, 605, 4153-4155 | 可选步尾输出场检查开关;由 getin_p("check_physics_outputs",...) 读取。 |
day_ini/icount/time_phys 与两个检查开关都声明为 OpenMP THREADPRIVATE,说明每个 OpenMP 线程保存自己的局部记忆状态。
依赖的模块
physiq 的 use 列表非常长,源码位于 physiq_mod.F:16-158。为了复现调度逻辑,按用途分组如下;每一组都在调用链或共享状态更新中被直接使用。
直接调用方
| 调用方 | 文件 | 调用位置 | 作用 |
|---|---|---|---|
call_physiq |
libf/dynphy_lonlat/phymars/callphysiq_mod.F90 | 22, 69-89 | 3D lon-lat 动力-物理接口;检查 planet_type=="mars" 后把动力核数组映射到 physiq 参数。 |
testphys1d 主循环 |
libf/phymars/dyn1d/testphys1d.F90 | 194 | 1D 测试程序复用 3D 物理入口;调用后再施加 1D 特有风场/水汽强迫。 |
调用的关键例程
下表按源码执行顺序列出主路径调用点。write_output 和 wstats 字段很多,本页只记录分段入口,具体字段见“诊断与输出”。
| 行号 | 条件/阶段 | 被调用例程 | 作用 |
|---|---|---|---|
| 604-605 | firstcall | getin_p |
读取步首/步尾场检查开关。 |
| 620, 823, 839, 4140-4149 | CPP_XIOS |
wxios_context_init, initialize_xios_output, update_xios_timestep, send_xios_field, xios_context_finalize |
XIOS 上下文、时间步和固定字段输出。 |
| 628 | firstcall, 非 MESOSCALE | phyetat0 |
读取 startfi.nc 的物理状态、地表/土壤/tracer/restart 记忆。 |
| 725, 729 | firstcall | initracer, surfini |
初始化 tracer 索引/属性和水冰帽/地表相关状态。 |
| 737, 741, 745 | firstcall + callsoil |
waterice_tifeedback, soil |
初始化带或不带水冰热惯量反馈的土壤状态。 |
| 772-775 | firstcall | init_r_cp_mu, nlte_setup, NIR_leedat |
初始化平均热力属性、NLTE 表和 NIR 修正表。 |
| 789/795, 2754 | 非 MESOSCALE | physdem0, physdem1 |
写 restartfi.nc 初始控制/网格信息与运行中/末尾物理 restart。 |
| 804, 808, 815 | firstcall | topmons_setup, dust_coagulation_init, atke_ini |
山顶尘流、尘埃凝并和 ATKE 湍流初始化。 |
| 857, 1617, 2567 | 每步 | compute_meshgridavg |
坡面/子网格变量聚合到网格平均。 |
| 879/881, 1010, 1017/1021 | 每步/辐射 | solarlong, orbite, solang/mucorr |
太阳经度、日火距离、赤纬、太阳角和日照比例。 |
| 897 | call_mass_fixer_dyn |
tracer_mass_fixer_dyn |
对动力输运后的 tracer 质量非守恒作修正 tendency。 |
| 910 | photochem.or.callthermos |
update_r_cp_mu_ak |
用当前 tracer 组成更新 rnew/cpnew/mmean。 |
| 1030/1045/1065 | callnlte |
nltecool 或 nlte_tcool, nlthermeq |
NLTE 冷却和 LTE/NLTE 分界层选择。 |
| 1097, 1121 | callrad, 可选 CLFvarying |
callradite |
主辐射计算;CLFvarying 时再算 clear-sky 并按云分数混合。 |
| 1229/1270, 1289, 1307 | 辐射分支 | param_slope, nirco2abs, blendrad |
坡面通量、NIR CO2 加热、LTE/NLTE/NIR 倾向合成。 |
| 1379, 1445, 1481, 1526 | 尘埃分支 | rocketduststorm, topmons, dust_coagulation_main, compute_dtau |
风暴尘埃、山顶尘流、凝并和表面尘埃注入调度。 |
| 1538 | calllott |
calldrag_noro |
地形/次网格重力波拖曳 tendency。 |
| 1601 | calldifv |
vdifc |
垂直扩散、边界层混合、地表通量与部分地表 tracer tendency。 |
| 1692 | calltherm 且非 turb_resolved |
calltherm_interface |
热羽流 tendency 和 wstar/hfmax 反馈。 |
| 1744 | calladj |
convadj |
干对流调整 tendency。 |
| 1776, 1785 | calllott_nonoro |
nonoro_gwd_ran, nonoro_gwd_mix |
非地形重力波动量拖曳与可选 GW-induced mixing。 |
| 1831 | water |
watercloud |
水云微物理,返回水/CCN/尘埃与温度 tendency。 |
| 1934 | co2clouds |
co2cloud |
CO2 云微物理,返回 CO2 云/CCN/尘埃 tendency、CO2 冰沉降通量。 |
| 2110, 2143 | callddevil, sedimentation |
dustdevil, callsedim |
尘卷风起尘和尘埃/水冰沉降。 |
| 2214, 2223 | photochem |
surfacearea, calchim |
为化学计算气溶胶表面积并调用化学模块。 |
| 2281 | callthermos |
thermosphere |
热层/高层大气倾向。 |
| 2301, 2315 | tituscap, callcond |
geticecover, co2condens |
CO2 极冠观测掩膜和 CO2 凝结/升华;后者是最后一个大气物理过程。 |
| 2487, 2491/2494 | 每步 callsoil |
waterice_tifeedback, soil |
地表温度更新后推进土壤温度和地热通量。 |
| 2593, 2665, 2894, 2973, 3248, 3324+ | 诊断 | compute_tracer_mass_global, pbl_parameters, watersat, wstats, mkstats, write_output |
质量、近地层、水饱和、统计和 diagfi/XIOS 诊断。 |
| 4155 | check_physics_outputs |
check_physics_fields |
步尾输出场检查。 |
输入
physiq 的参数方向在 physiq_mod.F:265-291 声明。
| 输入 | 来源 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
ngrid |
caller | integer scalar | - | 物理水平列数。 |
nlayer |
caller | integer scalar | - | 大气垂直层数。 |
nq |
caller | integer scalar | - | tracer 数量。 |
firstcall |
caller | logical scalar | - | 是否为物理包第一次调用;触发 restart/表/土壤/输出初始化。 |
lastcall |
caller | logical scalar | - | 是否为最后一次调用;触发末次 restart、mkstats、XIOS finalize。 |
pday, ptime |
caller | real scalar | sol / sol fraction | 从参考 Ls=0 起的 sol 和日内时刻。 |
ptimestep |
caller | real scalar | s | 物理时间步。 |
pplev(ngrid,nlayer+1) |
caller | real array | Pa | 层界面压力。 |
pplay(ngrid,nlayer) |
caller | real array | Pa | 层中心压力。 |
pphi(ngrid,nlayer) |
caller | real array | m2 s-2 | 层中心位势。 |
pu, pv |
caller | real arrays | m s-1 | 纬向/经向风。 |
pt |
caller | real array | K | 温度。 |
pq(ngrid,nlayer,nq) |
caller | real array | kg kg_air-1 或对应 tracer 单位 | tracer 混合比。 |
flxw(ngrid,nlayer) |
caller | real array | kg s-1 | 每层下界垂直质量通量;在 physiq 中转为诊断垂直速度 pw。 |
pplev 和 pplay 是动力输入,源码在 physiq_mod.F:445-447 明确要求 physics 不得修改它们,因此 physiq 复制到工作数组 zplev/zplay,CO2 凝结后的压力坐标更新只改工作副本。
输出
| 输出 | 去向 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
pdu(ngrid,nlayer) |
caller | real array | m s-2 | 物理过程给纬向风的 tendency。 |
pdv(ngrid,nlayer) |
caller | real array | m s-2 | 物理过程给经向风的 tendency。 |
pdt(ngrid,nlayer) |
caller | real array | K s-1 | 物理过程给温度的 tendency。 |
pdq(ngrid,nlayer,nq) |
caller | real array | tracer unit s-1 | 物理过程给 tracer 的 tendency。 |
pdpsrf(ngrid) |
caller | real array | Pa s-1 | 表面压力 tendency,主要由 CO2 凝结/升华产生。 |
这些输出在每步开始统一清零(physiq_mod.F:844-848),随后各物理过程按源码顺序做加法累积。地表 tracer、地表温度、土壤、XIOS/diagfi/stats/restart 等副作用不通过这五个输出返回,而是直接写共享模块或文件。
共享状态与副作用
| 类别 | 读写对象 | 源码证据 | 副作用 |
|---|---|---|---|
| 时间/太阳几何 | comsaison_h::zls, dist_sol, declin, mu0, fract, local_time |
870-882, 1010-1021 | 每步写入季节、太阳角和本地时;辐射、NIR、坡面、尘埃注入等下游读取。 |
| 地表/土壤 | surfdat_h::tsurf, emis, capcal, fluxgrd, qsurf, watercap, perennial_co2ice, comsoil_h::tsoil, inertiesoil, qsoil |
628-634, 729, 2411-2497, 2540-2562 | 从 restart 初始化,随后每步更新地表储量、地表温度、土壤温度和地热通量。 |
| 辐射共享数组 | dimradmars_mod::aerosol, dtrad, fluxrad_sky, fluxrad, albedo, totcloudfrac |
609-614, 1097, 1327-1349 | 初始化/更新辐射加热率、通量、气溶胶和云分数。 |
| 湍流状态 | turb_mod::q2, wstar, ustar, sensibFlux, zmax_th, hfmax_th |
632, 1601, 1692, 3260-3305 | 垂直扩散和热羽流更新边界层/TKE 相关状态,并用于诊断。 |
| tracer 质量记忆 | tracer_mass_fixer_dyn_mod::mass_predyn |
893-899, 2593 | 可选地修正动力 tracer 质量误差并输出质量诊断。 |
| restart | startfi.nc, restartfi.nc |
628, 789/795, 2710-2758 | firstcall 读物理初始状态;运行中/末尾按 ecritstart 或 lastcall 写 restart。 |
| 诊断文件 | write_output, wstats/mkstats, comm_wrf, XIOS |
2973-3248, 3260-3297, 3324-4088, 4140-4149 | 写 stats、diagfi/diagsoil/XIOS 字段;MESOSCALE 分支写 comm_* 缓存。 |
| 运行日志/中止 | write(*,*), abort_physic |
713-718, 1202, 1682 | 输出初始化/警告信息;日期不同步、turbulence-resolved 未支持等路径会中止。 |
初始化、restart 与诊断行为
firstcall 初始化
IF (firstcall) 从 physiq_mod.F:602 开始。非 MESOSCALE 路径调用 phyetat0("startfi.nc",...) 读取物理初始状态;MESOSCALE 路径假定模块变量已由外部设置,只打印检查信息、设置 day_ini=pday 并填充一些默认值。若非 MESOSCALE 且 startphy_file 为假,源码走 academic 初始化:给土壤层深度、tsurf/tsoil 和热惯量设置默认值,并把 day_ini=pday。
firstcall 之后会检查 pday 与 day_ini 是否同步(713-718),初始化 tracer 和地表(725, 729),按 callsoil 初始化土壤(733-746),初始化热层/电离层、平均热力属性、NLTE/NIR 表(763-775),写 restart 初始控制信息(789/795),准备 topmons、尘埃凝并、ATKE 和 XIOS 输出(804-823)。
每步初始化
每个物理步都会更新 XIOS 时间(837-839),清零所有输出 tendency、地表 tendency、通量和若干诊断数组(842-856),计算坡面到网格平均状态(857-858),设置 IRtoVIScoef=2.6 初值(860-862),计算 zday、local_time 和 zls(870-882),并把动力压力输入复制到 zplev/zplay(884-888)。
restart 写出
非 MESOSCALE 路径在诊断前计算 write_restart:ecritstart>0 且 MODULO(icount*iphysiq,ecritstart)==0 时写多时间 restart,lastcall 时一定写(2710-2721)。写出时间 ztime_fin 对 DYNAMICO/unstructured 与 LMDZ 规则不同(2723-2749),最后调用 physdem1("restartfi.nc",...) 写 tsurf/tsoil/inertiesoil/albedo/emis/q2/qsurf/qsoil/tauscaling/totcloudfrac/wstar/watercap/perennial_co2ice 等状态(2754-2758)。
诊断与输出
诊断先构造更新后工作态 zt/zu/zv/zq(2565 之后;水/CO2 调用点页也记录了 zq=pq+pdq*ptimestep 的诊断用法),再计算密度、位温、辐射通量和各主题柱积分。wstats 在非 MESOSCALE 路径累计 ps/tsurf/radiation/temp/u/v/w/rho/pressure/q2/water/co2/dust/chemistry 等字段,并在 lastcall.and.callstats 时调用 mkstats(2973-3248)。MESOSCALE 路径只填 comm_wrf 缓存(3260-3297)。常规 diagfi/XIOS 输出通过大量 write_output 调用完成(3324-4088),末尾还输出 CO2 总量守恒诊断 co2conservation(4110-4134)并发送 XIOS 固定字段(4140-4145)。
核心流程
- 步首清零与时间/网格准备:输出 tendency 和地表增量全部清零,写
local_time/zls,复制动力压力为zplev/zplay,可选修正动力 tracer 质量非守恒,并计算zzlay/zzlev/zh/pw等工作变量。 - 辐射准备与辐射倾向:
callrad分支计算轨道几何与太阳角,按callnlte/nltemodel/callnirco2/callslope/CLFvarying调用 NLTE、LTE 辐射、坡面通量和近红外 CO2 加热,最终把dtrad累加到pdt。 - 尘埃与地形相关过程:按
rdstorm -> topflows -> dust_coagulation -> dustinjection的顺序更新尘埃/风暴尘埃/topdust tendency 或dustliftday;然后地形重力波calldrag_noro把zdugw/zdvgw/zdtgw累加到风温 tendency。 - 边界层、热羽流、对流与非地形 GW:
vdifc用辐射+地热通量、当前累计温度 tendency 和地表状态计算垂直扩散 tendency;热羽流、干对流和非地形 GW 随后继续往pdu/pdv/pdt/pdq累加。 - tracer 物理:水、CO2 云、尘卷风、沉降、化学、热层:水云和 CO2 云分别在第 9a/9a bis 段处理,
callsedim处理尘埃和水冰沉降,calchim可读取云过程输出,thermosphere在高层分支追加 tendency。 - CO2 凝结与坐标更新:
co2condens被源码标注为最后一个大气物理过程(2296-2298),输出pdpsrf、风温/tracer/地表 tendency。非 MESOSCALE 路径随后用pdpsrf更新ps/zplay/zplev/zzlay/zzlev(2357-2403)。 - 地表/土壤和非负保护:累加
qsurf += ptimestep*dqsurf,tsurf += ptimestep*zdtsurf,按水冰/CO2 霜条件调整反照率/发射率,再调用soil;随后对风暴尘埃/背景尘埃做非负保护并更新watercap。 - 输出、restart、场检查和计数:计算诊断工作态,按 stats/MESOSCALE/diagfi/XIOS 写出,末尾可检查输出场并
icount=icount+1。
伪代码
physiq(args):
pdq = 0
if firstcall:
read check_physics_inputs/outputs
initialize radiation arrays and optional XIOS
if not MESOSCALE:
phyetat0(startfi.nc) -> tsurf/tsoil/albedo/emis/qsurf/q2/...
if no startphy_file: build academic defaults
else:
check externally prepared state and set MESOSCALE defaults
require pday == day_ini
initracer; surfini
if callsoil: optionally waterice_tifeedback, then soil(firstcall)
initialize thermosphere/NLTE/NIR/mean gas properties/topmons/coagulation/ATKE/output
if check_physics_inputs: check pt/pu/pv/pplev/pq
zero pdu/pdv/pdt/pdq/pdpsrf, zdtsurf, dqsurf, diagnostic fluxes
compute mesh averages, zday, local_time, zls
copy pplev/pplay into zplev/zplay; ps = zplev(:,1)
if call_mass_fixer_dyn: pdq += tracer_mass_fixer_dyn(...)
if photochem or callthermos: update_r_cp_mu_ak(...)
compute zzlay/zzlev, potential temperature, vertical velocity
compute initial CO2 total for conservation diagnostic
if callrad:
orbite -> dist_sol/declin
solang or mucorr -> mu0/fract
optional NLTE cooling and daily nlthermeq
callradite -> radiative tendencies and fluxes
optional clear-sky callradite for CLFvarying
optional slope radiation and NIR CO2 absorption
dtrad = blendrad(...) or sum SW/LW/NIR/NLTE
pdt += dtrad
if rdstorm: rocketduststorm; add pdqrds to dust/stormdust pdq
if topflows: topmons; add pdqtop to topdust and dust pdq
if dust_coagulation: dust_coagulation_main; add pdqcoag
if dustinjection > 0: compute_dtau -> dustliftday
if calllott: calldrag_noro; add wind/temp tendencies
if calldifv: vdifc; add vertical diffusion tendencies and surface fluxes
if calltherm: calltherm_interface; add thermals tendencies
if calladj: convadj; add dry-convection tendencies
if calllott_nonoro: nonoro_gwd_ran; optional nonoro_gwd_mix
if water: watercloud; inject water/HDO/CCN/dust tendencies with guards
if co2clouds: co2cloud; inject CO2-cloud tendencies with guards
if callddevil: dustdevil; add dustdevil tendencies
if sedimentation: callsedim; add atmospheric and surface sedimentation tendencies
if photochem: surfacearea; calchim; add chemical tendencies
if callthermos: thermosphere; add high-atmosphere tendencies
if tituscap: geticecover -> qsurf_tmp(co2)
if callcond:
co2condens -> zdtc/zdtsurfc/zduc/zdvc/zdqc/zdqsc/pdpsrf
if ngrid == 1: scale selected outputs by CO2cond_ps
add CO2 condensation tendencies
if not MESOSCALE: update ps, zplay, zplev, zzlay, zzlev
qsurf += ptimestep*dqsurf
tsurf += ptimestep*zdtsurf
if water: update frost albedo/emissivity, watercap/refill_watercap
if callsoil: waterice_tifeedback if enabled, then soil
protect dust/stormdust from negative updated values
build updated diagnostic state zt/zu/zv/zq
write optional restartfi, stats, MESOSCALE comm_wrf, diagfi/XIOS fields
compute and write CO2 conservation diagnostic
if check_physics_outputs: check zt/zu/zv/zplev/zq
icount += 1
参与的主题流程
| 主题 | 参与方式 |
|---|---|
| radiation | 计算太阳几何、调用 callradite、处理 CLFvarying clear-sky、NIR CO2、NLTE/LTE 合成和坡面辐射。 |
| dust-cycle | 串联尘暴、山顶尘流、凝并、compute_dtau 注入、dustdevil、callsedim 和 dust diagnostics。 |
| water-cycle | 在 water 分支调用 watercloud,之后沉降、化学、地表水冰、热惯量反馈、watercap 和诊断都在本文件衔接。 |
| co2-cycle | 控制 co2cloud -> co2condens -> 表压/坐标更新 -> 地表 CO2/诊断 的顺序;CO2 凝结是最后大气物理过程。 |
| dynamics coupling | callphysiq_mod.F90 把动力核数组传给 physiq,并把 pdu/pdv/pdt/pdq/pdpsrf tendency 传回动力侧。 |
| 1D physics | testphys1d.F90 直接调用 physiq,并在 CO2 凝结后通过 CO2cond_ps 缩放 1D 表压相关输出。 |
写法特点
- 固定格式 Fortran + 大型调度例程:文件主体是一个 4000 行级别的固定格式 Fortran 子程序,局部数组承担跨物理段的工作态。
- 加法式 tendency 总线:每个物理过程返回局部 tendency,随后显式
pdt += ...、pdq += ...、pdu/pdv += ...。复现时要保留源码顺序。 - 动力输入不原地修改:
pplev/pplay被复制为zplev/zplay,CO2 凝结后的压力坐标只更新工作副本。 - firstcall 与每步初始化严格分离:表文件、restart、土壤/NLTE/NIR/ATKE/XIOS 初始化只在 firstcall;tendency、时间、太阳几何和工作压力每步重置。
- 大量 compile-time 分支:
MESOSCALE、CPP_XIOS、DUSTSTORM、MESOINI会改变 restart、输出、共享缓存和某些初始化行为。 - 成对非负保护:水云、CO2 云和尘埃相关质量/数浓度 tracer 多处使用
where把 mass/number 成对钳到-pq/ptimestep + 1.e-30。 - 诊断基于更新后工作态:水、CO2、尘埃、化学等柱积分和输出使用
zq = pq + pdq*ptimestep这类更新后副本,而不是裸pq。
复现要点
- 按源码顺序累加
pdu/pdv/pdt/pdq/pdpsrf/dqsurf/zdtsurf;不要把辐射、水云、沉降、CO2 凝结或土壤更新重排。 co2condens必须位于最后一个大气物理过程位置;它之后的ps/zplay/zplev/zzlay/zzlev更新依赖pdpsrf。callradite -> watercloud -> callsedim的顺序决定水冰半径rice和沉降输入;相关细节见 physiq-water-cycle-callpoints。co2cloud -> co2condens之间通过zdqssed_co2与zcondicea_co2microp传递 CO2 云沉降/凝结信息;相关细节见 physiq-co2-cycle-callpoints。- 对
pplev/pplay的任何后处理都应写到zplev/zplay;源码注释明确禁止 physics 修改动力输入。 - 在非 MESOSCALE 与 MESOSCALE 分支中 restart 和输出路径不同;普通 GCM 写
restartfi.nc/stats/diagfi/XIOS,MESOSCALE 写comm_wrf缓存。 - 若开启
check_physics_inputs或check_physics_outputs,失败会经check_fields_mod打印诊断并中止;默认值在本文件为.false.。
待确认
physiq_mod.F:2957的icetotco2(ig) = icetot(ig) + ...疑似把水冰柱积分icetot用作 CO2 冰累加基值;已有 physiq-co2-cycle-callpoints 和 co2-cycle 标注为疑似 bug,仍需上游版本或开发者确认。callradite_mod.F已有 callradite_mod 文件页,lwmain_mod.F已有 lwmain_mod 文件页,swmain_mod.F已有 swmain_mod 文件页,vdifc_mod.F已有 vdifc_mod 文件页。本页只记录它们在physiq的调用位置,不展开其完整内部算法。calchim对zdqcloud/zdqscloud的具体非均相化学使用需要在 aeronomars 化学文件页中继续确认。- MESOSCALE 编译路径跳过部分普通 GCM restart/坐标更新逻辑;本页按源码分支记录,未复现外部 WRF/mesoscale 驱动如何消费所有
comm_*字段。