tracer_mass_fixer_dyn_mod.F90
路径
LMDZ.MARS\libf\phymars\tracer_mass_fixer_dyn_mod.F90
所属目录/模块
libf/phymars
文件定位
tracer_mass_fixer_dyn_mod.F90 修正动力学过程中对大气成分占比显著的 tracer(CO、O₂、H₂、HO₂、H₂O₂、N₂、Ar、He)的质量非守恒问题。它在每个物理时步开始时,比较当前 tracer 全球总质量与上一时步结束时的值,按比例缩放所有层的混合比,确保动力传输不产生虚假的质量源/汇。
作者:Y. Luo(2026 年 3 月)。通过 callphys.def 中 call_mass_fixer_dyn 开关控制。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
tracer_mass_fixer_dyn_mod |
module |
1 |
包裹所有子程序和共享状态的模块 |
call_mass_fixer_dyn |
logical, save |
5 |
配置开关,由 conf_phys 从 callphys.def 读取 |
found_startfi_co/o2/h2/ho2/h2o2/n2/ar/he |
logical, save |
6–13 |
标记 startfi.nc 中是否找到对应 mass_predyn_<tracer> 字段 |
mass_predyn(nq) |
real, allocatable, save |
14 |
上一时步结束时各 tracer 全球总质量(数组) |
mass_predyn_co/o2/h2/ho2/h2o2/n2/ar/he |
real, save |
16–17 |
上一时步结束时各 tracer 全球总质量(标量,用于 startfi I/O) |
tracer_mass_fixer_dyn |
subroutine |
28 |
主修正例程:计算修正因子并返回 tendency |
compute_tracer_mass_global |
subroutine |
102 |
计算单个 tracer 的全球总质量 |
set_mass_predyn_from_startfi |
subroutine |
154 |
从 startfi 标量赋值到 mass_predyn 数组 |
ini_tracer_mass_fixer_dyn |
subroutine |
195 |
分配 mass_predyn 数组 |
end_tracer_mass_fixer_dyn |
subroutine |
209 |
释放 mass_predyn 数组 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
tracer_mod |
noms, igcm_co, igcm_o2, igcm_h2, igcm_ho2, igcm_h2o2, igcm_n2, igcm_ar, igcm_he, mmol |
tracer 名称、索引和分子量 |
|
comcstfi_h |
g |
重力加速度 |
|
geometry_mod |
cell_area |
网格面积(全球质量积分) |
|
planetwide_mod |
planetwide_sumval |
全球求和(MPI 归约) |
|
调用的关键例程
| 被调用例程 |
所在模块/文件 |
调用位置 |
作用 |
compute_tracer_mass_global |
本模块 |
行 54 |
计算各 tracer 的全球总质量 |
planetwide_sumval |
planetwide_mod |
行 145–147 |
全球求和(MPI 归约) |
set_mass_predyn_from_startfi |
本模块 |
由 physiq_mod 在 firstcall 时调用 |
从 startfi 标量赋值到 mass_predyn 数组 |
ini_tracer_mass_fixer_dyn |
本模块 |
由 phys_state_var_init_mod 调用 |
分配 mass_predyn 数组 |
end_tracer_mass_fixer_dyn |
本模块 |
由 phys_state_var_init_mod 调用 |
释放 mass_predyn 数组 |
输入
tracer_mass_fixer_dyn
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
ngrid |
physiq |
integer |
— |
水平网格点数 |
nlayer |
physiq |
integer |
— |
垂直层数 |
nq |
physiq |
integer |
— |
tracer 数量 |
ptimestep |
physiq |
real |
s |
物理时步 |
pq(ngrid,nlayer,nq) |
physiq |
real |
kg/kg |
tracer 质量混合比 |
zplev(ngrid,nlayer+1) |
physiq |
real |
Pa |
层界面气压 |
firstcall |
physiq |
logical |
— |
首次调用标志 |
compute_tracer_mass_global
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
pq(ngrid,nlayer,nq) |
同上 |
real |
kg/kg |
tracer 质量混合比 |
zplev(ngrid,nlayer+1) |
同上 |
real |
Pa |
层界面气压 |
输出
tracer_mass_fixer_dyn
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
pdq_corrdyn(ngrid,nlayer,nq) |
physiq(加到 pdq) |
real |
kg/kg/s |
tracer 质量修正 tendency |
compute_tracer_mass_global
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
mass(nq) |
调用方 |
real |
kg |
各 tracer 的全球总质量 |
共享状态与副作用
call_mass_fixer_dyn:!$omp threadprivate,由 conf_phys 从 callphys.def 读取。
found_startfi_*:!$omp threadprivate,在 phyetat0_mod 读取 startfi.nc 时设置。
mass_predyn(nq):!$omp threadprivate,allocatable SAVE 数组,跨时步保存上一时步的全球总质量。
mass_predyn_*(标量):!$omp threadprivate,用于 startfi.nc 的 I/O(phyetat0_mod 读、phyredem.F90 写)。
pdq 修改:修正 tendency 加入 physiq 的 pdq 数组(行 899)。
核心逻辑
主修正流程(tracer_mass_fixer_dyn,行 28–100)
- 计算当前全球质量(行 54):调用
compute_tracer_mass_global 得到 mass_postdyn。
- 逐 tracer 修正(行 58–96):对 8 个指定 tracer(CO、O₂、H₂、HO₂、H₂O₂、N₂、Ar、He):
- 条件:tracer 存在(
igcm_xx ≠ 0)且有有效参考质量(firstcall 时需 found_startfi_xx,后续时步直接用 mass_predyn)
- 修正因子:
masscorrfac = mass_predyn / mass_postdyn
- 修正混合比:
pq_corrdyn = pq * masscorrfac
- 计算 tendency(行 98):
pdq_corrdyn = (pq_corrdyn - pq) / ptimestep
全球质量计算(compute_tracer_mass_global,行 102–152)
- 仅对 8 个指定 tracer 计算(按名称匹配
noms(iq))
- 柱密度:
colden(ig,iq) = Σ_l pq(ig,l,iq) * Δp(ig,l) * 6.022e22 / (mmol(iq) * g)
- 全球质量:
mass(iq) = planetwide_sumval(colden / 6.022e23 * mmol(iq) * 1e4 * cell_area)
初始化(ini_tracer_mass_fixer_dyn,行 195–207)
- 分配
mass_predyn(nq),初始化为 -999.
-999. 确保从 newstart 输出启动时,found_startfi_* 保持 .false.,第一步不执行修正
startfi 读写
- 读取:
phyetat0_mod.F90 读取 mass_predyn_co 等标量,若存在且 > 0 则设 found_startfi_xx = .true.
- 写入:
phyredem.F90 在重启文件中写入 mass_predyn(igcm_co) 等标量
- 设置:
set_mass_predyn_from_startfi 在 physiq 的 firstcall 时将标量值复制到 mass_predyn 数组
伪代码
! tracer_mass_fixer_dyn
mass_postdyn = compute_tracer_mass_global(pq, zplev)
for each tracer in {co, o2, h2, ho2, h2o2, n2, ar, he}:
if tracer exists and (not firstcall or found_startfi):
masscorrfac = mass_predyn / mass_postdyn
pq_corrdyn = pq * masscorrfac
pdq_corrdyn = (pq_corrdyn - pq) / dt
! compute_tracer_mass_global
for each target tracer:
for each column:
colden = Σ_layers pq * Δp * 6.022e22 / (mmol * g)
mass = planetwide_sumval(colden / 6.022e23 * mmol * 1e4 * cell_area)
参与的主题流程
| 主题 |
参与方式 |
| 动力学-物理耦合 |
修正动力学传输产生的 tracer 质量非守恒 |
| 大气成分 |
保护 CO、O₂、N₂ 等主要大气成分的质量守恒 |
写法特点
!$omp threadprivate:所有共享变量都标注线程私有(行 19–24)。
- 8 个 tracer 硬编码:修正逻辑对 8 个 tracer 各写一个
if 块,而非循环——代码冗长但每个 tracer 有独立的 found_startfi_* 标志。
- startfi 标量 I/O:
mass_predyn_* 以标量形式写入/读取 startfi.nc(非数组),每个 tracer 一个独立变量。
-999. 初始化:mass_predyn 初始化为 -999.,确保从 newstart 启动时第一步不修正(found_startfi_* 保持 .false.)。
- 均匀缩放:修正方法是简单的全球质量比例缩放(
pq * masscorrfac),不区分高度或区域。
compute_tracer_mass_global 选择性计算:只对 8 个指定 tracer 计算质量,其他 tracer 跳过。
复现要点
call_mass_fixer_dyn = .true.(callphys.def)时才启用。
- 修正依赖
startfi.nc 中的 mass_predyn_co 等标量字段;若不存在或 ≤ 0,该 tracer 在第一步不修正。
phyredem.F90 在重启时写入 mass_predyn(igcm_co) 等,确保跨重启连续性。
- 修正因子是全局均匀缩放,不考虑空间分布差异。
待确认
- 行 141
6.022e22 和行 146 6.022e23 的来源(待确认:推断为阿伏伽德罗常数相关的单位换算因子,6.022e23 是 NA/mol,6.022e22 可能是 NA/10*mol 或 cm² 相关换算)。
- 修正因子
mass_predyn / mass_postdyn 若 mass_postdyn 接近 0 可能产生极大值(待确认:是否有除零保护)。
compute_tracer_mass_global 中只对 8 个 tracer 计算,但 mass(nq) 返回完整数组——未计算的 tracer 值未初始化(待确认:调用方是否只使用已计算的 tracer)。
相关页面