compute_dtau_mod.F90
路径
LMDZ.MARS\libf\phymars\compute_dtau_mod.F90
所属目录/模块
libf\phymars
文件定位
该文件定义尘埃地表注入(dust injection)调度模块 compute_dtau_mod(136 行),导出例程 compute_dtau,由 physiq(行 1526,dustinjection>0 时)每物理步调用。它的职责是把 GCM 当前尘埃柱光学厚度 tau_pref_gcm 与尘埃场景目标值 tau_pref_target 的差额(dtau,在 610 Pa 处的可见光不透明度差)转换为地表尘埃注入速率 dustliftday,使模式尘埃量逐日向观测场景收敛。
模块还保存注入时窗 ti_injection_sol/tf_injection_sol(供 vdifc 在地表交换段决定何时实际注入)和按格点的 dtau 数组(restart 经 phyetat0/phyredem 读写),并提供 ini/end_compute_dtau_mod 管理 dtau 分配。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
compute_dtau_mod |
module |
1 |
尘埃地表注入调度模块 |
ti_injection_sol |
real SAVE |
5 |
注入开始时刻(sol 分数),由 ti_injection/24 得 |
tf_injection_sol |
real SAVE |
6 |
注入结束时刻(sol 分数),由 tf_injection/24 得 |
dtau |
real SAVE ALLOCATABLE(:) |
8 |
GCM 与场景在 610 Pa 处的尘埃不透明度差,按格点 |
compute_dtau |
subroutine |
15 |
计算 dtau 与注入速率 dustliftday |
ini_compute_dtau_mod |
subroutine |
118 |
分配 dtau(ngrid) |
end_compute_dtau_mod |
subroutine |
128 |
释放 dtau |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
geometry_mod |
longitude_deg |
firstcall 计算每格点初始 local_time_prev(经度→本地时偏移) |
否 |
time_phylmdz_mod |
dtphys, daysec |
物理步长与一个 sol 秒数,算每日步数与注入速率分母 |
否 |
comcstfi_h |
g |
重力加速度(声明引入;本例程注入速率公式用 pplev/odpref) |
待确认其直接使用点 |
tracer_mod |
alpha_lift, igcm_dust_mass, igcm_dust_number |
尘埃升华系数与尘埃 tracer 索引(声明引入) |
待确认其直接使用点 |
dimradmars_mod |
tauvis |
iaervar=1 时目标厚度取常数 tauvis |
否 |
dust_param_mod |
odpref, t_scenario_sol |
参考气压 610 Pa;场景厚度精确时刻(触发 dtau 更新) |
否 |
read_dust_scenario_mod |
read_dust_scenario |
读取次日(zday+1)场景目标厚度 tau_pref_target |
否 |
write_output_mod |
write_output |
输出 tau_pref_target/dtau/dustliftday 诊断 |
否 |
callkeys_mod |
iaervar, coeff_injection, ti_injection, tf_injection |
场景选择开关、注入系数、注入时窗(局地时 h) |
否 |
调用的关键例程
| 被调用例程 |
所在模块/文件 |
调用位置 |
作用 |
read_dust_scenario |
read_dust_scenario_mod |
行 78 |
读次日场景目标尘埃柱厚度 |
write_output |
write_output_mod |
行 83、105、107 |
写 tau_pref_target/dtau/dustliftday 诊断 |
输入
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
ngrid, nlayer |
physiq |
integer scalar |
- |
水平格点数、垂直层数 |
zday |
physiq |
real scalar |
sol |
lon=0 处日期(sol 分数) |
pplev(ngrid,nlayer+1) |
physiq |
real |
Pa |
层界面气压(取 pplev(:,1) 表压缩放) |
tau_pref_gcm(ngrid) |
physiq(来自 aeropacity) |
real |
- |
GCM 在 610 Pa 的可见光尘埃柱厚度 |
ptimestep |
physiq |
real scalar |
s |
物理时间步 |
local_time(ngrid) |
physiq |
real |
sol 分数 |
各格点本地时 |
IRtoVIScoef(ngrid) |
physiq(来自 aeropacity) |
real |
- |
场景 IR→VIS 换算系数,传给 read_dust_scenario |
输出
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
dustliftday(ngrid) |
physiq→vdifc(地表交换注入段) |
real (OUT) |
s⁻¹ |
尘埃地表注入速率 |
dtau(ngrid) |
module SAVE;restart phyetat0/phyredem |
real |
- |
GCM 与场景在 610 Pa 的不透明度差(注入时刻更新) |
ti_injection_sol/tf_injection_sol |
module SAVE;vdifc 读 |
real |
sol 分数 |
注入时窗 |
共享状态与副作用
- module 级
SAVE+THREADPRIVATE:ti_injection_sol、tf_injection_sol、dtau(行 11);例程内 SAVE+THREADPRIVATE:nb_daystep、local_time_prev、firstcall(行 55)。
- firstcall:分配
local_time_prev 并按 zday-ptimestep/daysec 与经度初始化;算 nb_daystep=daysec/dtphys;把 ti_injection/tf_injection(h)转 sol 分数。
dtau 只在“本地时跨过 t_scenario_sol(约 14:00)那一步”更新(行 89-92),其余步沿用上次值。
local_time_prev 每步末更新为当前 local_time(行 111)。
- 标准诊断输出:
tau_pref_target、dtau、dustliftday(write_output)。
ini/end_compute_dtau_mod 由 phys_state_var_init 管理 dtau 生命周期。
- 不修改源码、不写文件(除诊断后端)。
核心逻辑
- firstcall(行 58-70):分配并初始化
local_time_prev(用上一步时刻+经度偏移);nb_daystep=daysec/dtphys;ti_injection_sol=ti_injection/24、tf_injection_sol=tf_injection/24。
- 取目标厚度(行 72-85):
iaervar=1 时 tau_pref_target=tauvis;否则取当日整数 sol +1(次日,场景在 14:00 测)调 read_dust_scenario 得 tau_pref_target;写诊断。
- 算 dtau 与注入速率(行 87-102):逐格点,若本地时本步跨过
t_scenario_sol(local_time>=t_scenario_sol 且 local_time_prev<t_scenario_sol)则更新 dtau=tau_pref_target-tau_pref_gcm;若 dtau<0 则 dustliftday=0,否则 dustliftday=coeff_injection*(dtau*pplev(:,1)/odpref)/(daysec*(tf_injection_sol-ti_injection_sol))。
- 写诊断、保存本地时(行 104-111):输出
dtau/dustliftday;local_time_prev=local_time。
伪代码
if firstcall:
allocate local_time_prev; 初始化为 上一步时刻+经度偏移
nb_daystep = daysec/dtphys
ti_injection_sol = ti_injection/24 ; tf_injection_sol = tf_injection/24
# 1. 目标厚度
if iaervar==1: tau_pref_target = tauvis
else:
zday_scenario = floor(zday) + 1 # 次日, 场景测于 14:00
tau_pref_target = read_dust_scenario(zday_scenario, ...)
write_output(tau_pref_target)
# 2. dtau 与注入速率
for ig:
if local_time crosses t_scenario_sol this step:
dtau(ig) = tau_pref_target(ig) - tau_pref_gcm(ig)
if dtau(ig) < 0: dustliftday(ig) = 0
else: dustliftday(ig) = coeff_injection*(dtau*pplev(:,1)/odpref)
/ (daysec*(tf_injection_sol-ti_injection_sol))
write_output(dtau, dustliftday)
local_time_prev = local_time
参与的主题流程
| 主题 |
参与方式 |
| 尘埃循环 |
把 GCM 与场景的尘埃柱厚度差转为地表注入速率 dustliftday,驱动模式尘埃逐日向观测场景收敛;vdifc 在注入时窗内据此注入 |
写法特点
- 自由格式 Fortran 90(
.F90)。
- module 级与例程内均大量使用
SAVE+THREADPRIVATE。
dtau 只在每日某一固定本地时刻(跨 t_scenario_sol)更新一次,是“每日校准”设计。
- 场景目标读取次日值(
zday+1),对应场景 DOD 在 14:00 测量的约定。
end_compute_dtau_mod 用 if(allocated) 幂等释放保护。
- 注入速率分母
daysec*(tf-ti) 把当日注入量摊到注入时窗。
复现要点
- 仅
physiq 中 dustinjection>0 时调用;注入实际发生在 vdifc 地表段且限于 [ti_injection_sol, tf_injection_sol] 时窗(vdifc 行 840-856)。
dtau 每 sol 仅在本地时跨过 t_scenario_sol(dust_param_mod 中 =14/24)的那一步更新。
- 目标厚度来自次日场景(
floor(zday)+1);iaervar=1 退化为常数 tauvis。
- 注入速率公式:
coeff_injection*(dtau*pplev(:,1)/odpref)/(daysec*(tf_injection_sol-ti_injection_sol)),dtau<0 时置 0。
dtau 按 ngrid 分配(phys_state_var_init 管理),restart 经 phyetat0/phyredem 读写,复现需保留其跨步状态。
- 注入时窗
ti_injection/tf_injection(局地时小时)与 coeff_injection 来自 callphys.def(callkeys_mod)。
待确认
use comcstfi_h, only: g 与 use tracer_mod, only: alpha_lift, igcm_dust_mass, igcm_dust_number 被引入,但在本例程可见逻辑(行 58-111)中未见直接使用 g/alpha_lift/igcm_dust_*;推断为历史遗留或预留 import。复现时可忽略,但标注以免误以为参与注入速率公式(公式实际只用 pplev/odpref)。
相关页面