paramfoto_compact.F
路径
LMDZ.MARS\libf\aeronomars\paramfoto_compact.F
所属目录 / 模块
libf/aeronomars
文件定位
paramfoto_compact.F 定义 paramfoto_compact_mod,是热层 C/O/H/O3/N/ion 化学的紧凑积分模块。主例程 paramfoto_compact 由 chemthermos 在 jthermcalc_e107 计算完光吸收率后调用;它逐层读取 rm(nlayer,nesptherm) 数密度,计算光解/电离率、反应速率、寿命和平衡标志,再用隐式格式和光化学平衡近似更新 lswitch:nlayer 的化学物种。
同一模块还暴露 phdisrate,供 photochemistry_mod.F90 在离子光化学路径中直接把 jthermcalc_e107 的 jfotsout 转成 param_v4_h::jion,再映射到 v_phot 的离子反应速率。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
paramfoto_compact_mod |
module |
1-5122 |
热层光化学/离子化学积分模块 |
paramfoto_compact |
subroutine |
9-647 |
对单个水平列的热层化学数密度矩阵执行时间积分,并写回 rm |
implicito |
subroutine |
653-699 |
用 (c+P*dt)/(1+L*dt) 做单物种隐式更新,负值时 stop,低于 1.d-30 时抬底 |
ionsec_nplus / ionsec_n2plus / ionsec_oplus / ionsec_coplus / ionsec_co2plus / ionsec_o2plus |
function |
704-1142 |
按太阳天顶角和高度多项式估算二次电离增强系数 |
phdisrate |
subroutine |
1150-1349 |
由 jfotsout、fluxtop 和 efdis*/efion* 生成 jdistot、jdistot_b、jion |
getch |
subroutine |
1356-1989 |
从 rcoef(61,3) 计算 ch2..ch87 反应速率,含电子温度插值 |
lifetimes |
subroutine |
1996-2686 |
计算各反应寿命 tau*、最短寿命 tmin*,并初设 *_eq 平衡标志 |
timemarching |
subroutine |
2693-2865 |
由外部时间步和最短寿命选择内部 deltat,并撤销不满足平衡条件的 *_eq 标志 |
prodsandlosses |
subroutine |
2872-4074 |
清零并填充 P*/L* 反应矩阵与 *tot 总源汇 |
EF_oscilacion |
subroutine |
4082-5027 |
对处于光化学平衡的物种重算代数平衡值,并做振荡修正 |
avg / dif / cociente |
function |
5030-5120 |
辅助平均、差值和比值保护;cociente 对负输入或不定零比值会报错/停止 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
iono_h |
全模块 |
读写 *_eq 平衡标志和 tau* 寿命数组;主例程、lifetimes、timemarching 直接使用 |
否 |
param_v4_h |
主例程全模块;phdisrate 使用 ninter,nabs,jfotsout,fluxtop,jion,jdistot,jdistot_b,efdis*,efion*;getch 使用 rcoef,ch*;其他例程使用 P*,L*,tmin* 等 |
承载热层光吸收、电离/解离效率、反应速率、源汇矩阵、寿命和总源汇共享状态 |
否 |
调用的关键例程
| 被调用例程 |
所在模块 / 文件 |
调用位置 |
作用 |
phdisrate |
本文件 |
191 |
按当前层 i 计算光解/电离速率 |
getch |
本文件 |
202 |
计算当前层的 ch2..ch87 速率常数 |
lifetimes |
本文件 |
205-212 |
依据光化学项和反应速率计算寿命和平衡标志 |
timemarching |
本文件 |
229-230 |
选内部化学步长并校验平衡近似 |
prodsandlosses |
本文件 |
308-319 |
填充当前层所有物种的源汇矩阵和总源汇 |
implicito |
本文件 |
327-432 |
对非平衡物种执行隐式时间推进 |
EF_oscilacion |
本文件 |
437-469 |
对平衡物种做代数平衡和振荡控制 |
输入
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
ig |
chemthermos 或 photochemistry_mod 当前列 |
integer |
网格索引 |
主要用于错误输出和下游接口 |
nlayer |
调用方 |
integer |
层 |
垂直层数 |
chemthermod |
chemthermos |
integer |
无 |
0: C/O/H;1: 加 O3;2: 加 N;3: 加离子 |
lswitch |
chemthermos |
integer |
层索引 |
主例程只积分 nlayer 到 lswitch |
tx(nlayer) |
chemthermos |
real |
K |
中性温度,转为 tx8 计算反应速率 |
timestep |
chemthermos |
real |
s(按调用链推断) |
外部物理时间步,内部会按寿命细分 |
zenit |
chemthermos / photochemistry_mod |
real |
度(按源码 >140 日夜判断推断) |
控制白天/夜间光化学和二次电离高度多项式 |
zx(nlayer) |
调用方 |
real |
km(按 getch/二次电离函数变量名推断) |
高度,用于电子温度插值和二次电离函数 |
rm(nlayer,nesptherm) |
chemthermos |
real*8 |
数密度 |
输入/输出热层物种数密度矩阵 |
jfotsout、fluxtop、efdis*、efion* |
param_v4_h,由 jthermcalc_e107 和 param_read_e107 填充 |
module arrays |
光化学率相关 |
phdisrate 的光解/电离输入 |
rcoef(61,3) |
param_v4_h,由 chemthermos_readini 填充 |
real*8 |
Arrhenius 参数 |
getch 计算 61 个热层反应速率 |
输出
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
rm(i,*) |
返回 chemthermos 后写回 zycol |
real*8(nlayer,nesptherm) |
数密度 |
lswitch:nlayer 更新后的 C/O/H/O3/N/ion 物种 |
jdistot / jdistot_b / jion |
param_v4_h,本文件和 photochemistry_mod 消费 |
arrays |
s^-1(推断) |
光解、分支光解和电离通道率 |
ch2..ch87 |
param_v4_h |
scalar rates |
依反应阶数 |
化学反应速率常数 |
tau*、tmin*、*_eq |
iono_h / param_v4_h |
arrays |
s / 标志 |
寿命、最短寿命和是否用平衡近似 |
P*,L*,*tot |
param_v4_h |
arrays |
数密度源汇 |
各物种逐反应源汇矩阵与总源汇;chemthermos 后续读取 Pno、Po2 |
共享状态与副作用
- 大量读写
param_v4_h 和 iono_h 的 module 变量;这些变量是热层化学各子例程之间的主要状态传递机制。
phdisrate 在夜间条件 zenit > 140. 下清零当前层 jion/jdistot/jdistot_b 后立即返回。
getch 每层重置 ch*,rcoef(1..33) 用中性温度 tcte,多数离子/电子反应 rcoef(34..61) 用按高度插值的 t_elect;ch74/ch76 仍用 tcte。
implicito、cociente 等辅助例程遇到负浓度、负源汇或未定义比值时直接 write(*,*) 并 stop,不是可恢复错误。
prodsandlosses 声明了 logical,save :: firstcall=.true. 并 THREADPRIVATE,但相关 if(firstcall) 块被注释,实际每次调用都会清零矩阵。
- 离子化学开启时,主例程用离子电荷和重新计算电子数密度,而不是保留
implicito 给出的 electxoutput_timemarching。
核心逻辑
- 主例程把外部
timestep 转为 real*8,从顶层 nlayer 向下循环到 lswitch。
- 按硬编码物种槽位把
rm(i,*) 拆成局部数密度;chemthermod>=1 加 O3,>=2 加 N/N2/NO/N2D/NO2,==3 加 10 个离子和电子。
- 调
phdisrate:从 jfotsout(inter,species,i)、fluxtop(inter) 和分支效率计算 jdistot/jdistot_b/jion,再复制为双精度局部数组。
- 调
getch:用 rcoef 和温度生成 ch2..ch87。
- 调
lifetimes 与 timemarching:计算 tau*、tmin*、最短寿命物种、平衡物种数,并得到内部 deltat。当 H+/(O+H+H2) 过高时,fmargin1 从 5 增大到最高 50,用于稳定 H/O 离子交换。
- 把外部时间步分成
numpasos=int(timefrac_sec/deltat) 个内部步,并用 alfa_laststep 处理最后一个分数步。
- 每个内部步先调
prodsandlosses 填充源汇,再对非平衡物种调用 implicito,对平衡物种调用 EF_oscilacion。
- 离子化学开启时,用正离子总和强制电子数密度满足整体电中性。
- 最后一个内部步把增量乘
alfa_laststep 得到 *xnew,所有负值抬到 1.e-30。
- 把更新后的
*xnew 写回 rm(i,*),供 chemthermos 转回 mole fraction。
伪代码
paramfoto_compact(args):
for i = nlayer down to lswitch:
load rm(i, species slots) into local double variables
call phdisrate(...) to fill jdistot/jdistot_b/jion for layer i
copy photo rates to double local arrays
call getch(...) to fill ch2..ch87
call lifetimes(...) to compute tau/tmin and initial *_eq flags
choose fmargin1, then call timemarching(...) to get deltat
for each internal paso:
carry previous outputs into inputs
call prodsandlosses(...) to build P/L matrices
use implicito for all species not in photochemical equilibrium
call EF_oscilacion for species marked *_eq='Y'
if ion chemistry: replace electron output by positive-ion sum
on last paso, apply alfa_laststep and floor at 1.e-30
write final values back to rm(i, species slots)
参与的主题流程
| 主题 |
参与方式 |
| 热层化学 |
chemthermos 的核心化学积分器,更新热层 C/O/H/O3/N/ion 数密度 |
| 热层光化学 / E107 |
消费 jthermcalc_e107 的光吸收率和 param_read_e107 载入的分支效率 |
| 离子光化学 |
photochemistry_mod.F90 直接调用 phdisrate,把 jion 映射到离子光化学 v_phot |
| 反应速率配置 |
消费 reaction-rates 中的 chemthermos_reactionrates.def 61 个 rcoef |
写法特点
- 固定格式
.F 文件,模块内包含 10 多个内部例程和多段长源汇表。
- 物种槽位
i_co2..i_elec 在本文件内硬编码,源码注释要求与 chemthermos.F90、jthermcalc*、euvheat.F、hrtherm.F 同步。
chemthermod 不是简单开关,而是同时控制输入物种、光化学通道、反应网络、寿命计算和平衡修正。
- 平衡标志用字符
'Y'/'N',在 lifetimes 中初设,在 timemarching 中按寿命条件撤销,在主积分中决定走 implicito 还是 EF_oscilacion。
- 二次电离函数以高度多项式返回百分比式增强,超过 100 或小于 0 时置 0;低于约 80 km 多数函数也置 0。
复现要点
- 复现前必须先初始化
param_v4_h 和 iono_h 数组;当前热层路径由 physiq_mod 的 callthermos 初始化分支分配并调用 param_read_e107。
rm 的列顺序必须严格匹配本文件第 111-138 行和 chemthermos 的 i_co2..i_elec。
jthermcalc_e107 必须先填好 jfotsout,否则 phdisrate 的 jdistot/jion 没有有效来源。
chemthermos_reactionrates.def 必须由 chemthermos_readini 读入到 rcoef;不要用外部库的更新反应常数替换,除非明确要改变历史结果。
- 夜间
zenit > 140. 时光解和电离项会被清零,但热化学反应仍可通过 getch/prodsandlosses 参与。
- 数值复现必须保留
1.d-30/1.e-30 浓度和寿命保护,以及直接 stop 的错误行为。
待确认
phdisrate 第 1260 行把 O2 第二电离通道累加到 jion(2,1,2),同段其他通道都使用当前层 i。这可能是层索引笔误;复现时应按源码字面行为执行,物理意图需开发者确认。
getch 中电子温度使用 Hanson et al. 1977 近似,iono_h::temp_elect 也存在电子温度函数;本文件没有调用后者,两套电子温度路径的设计分工需确认。
prodsandlosses 中 firstcall/THREADPRIVATE 保留但初始化门控被注释,是否为历史优化遗留待确认。
- photochemistry_mod 已核验:
photochemistry 在线离子路径调用 phdisrate(ig,nlayer,2,sza,ilay) 并把 jion 映射为 18 个 photoionization 通道;固定 chemthermod=2 是否覆盖全部所需离子通道仍待开发者确认。
相关页面