convadj.F
路径
LMDZ.MARS\libf\phymars\convadj.F
所属目录 / 模块
libf\phymars
文件定位
convadj.F 定义 convadj_mod,只提供一个入口 convadj,用于在 physiq 主物理时间步中执行干对流调整。调用方在 calladj 为真时把当前已累积的风、焓和 tracer tendency 传入;本例程先构造时间步末的工作副本,再查找对流不稳定柱,把不稳定层段混合到常值焓、平均水平风和平均 tracer 剖面,最后把调整量转换成 pduadj/pdvadj/pdhadj/pdqadj tendency 返回给 physiq。
该实现还包含 CO2 大气成分修正:首次调用时扫描 tracer_mod:noms 查找名为 "co2" 的 tracer。如果存在 CO2 tracer,稳定度判断不直接用焓 zh,而用 zhc = zh*(A*qco2+B),其中 A=1/m_co2-1/m_noco2、B=1/m_noco2,从而把 CO2 凝结导致的平均分子量变化纳入对流触发条件。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
convadj_mod |
module |
1 |
干对流调整模块 |
convadj |
subroutine |
7 |
检测并混合对流不稳定层段,输出风、焓和 tracer 的调整 tendency |
ico2 |
saved local integer |
75 |
首次调用后缓存 "co2" tracer 索引;0 表示未找到 |
A, B |
saved local real |
79 |
CO2 平均分子量修正中 1/Mair=A*qco2+B 的系数 |
firstcall |
saved local logical |
82 |
控制 CO2 tracer 扫描只在每个 OpenMP 线程首次调用时执行 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
tracer_mod |
noms, igcm_h2o_vap |
用 noms 查找 "co2" tracer;在水汽守恒检查中定位 h2o_vap tracer |
- |
comcstfi_h |
g |
水汽守恒检查中把压力层厚转成单位面积质量 masse=(pplev(l)-pplev(l+1))/g |
- |
callkeys_mod |
water |
只在水循环开启时执行水汽守恒崩溃检查 |
- |
调用的关键例程
| 被调用例程 |
所在模块 / 文件 |
调用位置 |
作用 |
abort_physic |
外部错误处理例程 |
371 |
当 water 路径的水汽调整净损失低于阈值时中止运行 |
上游调用点
| 调用方 |
源码位置 |
调用条件 |
传入 / 接收关系 |
physiq_mod.F::physiq |
physiq_mod.F:22, 1733-1768 |
calladj 为真 |
传入 pdu/pdv/pdh/pdq 以及已累积的 pdufi/pdvfi/pdhfi/pdqfi;接收 pduadj/pdvadj/pdhadj/pdqadj |
输入
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
ngrid, nlay, nq |
physiq |
integer scalar |
- |
水平格点数、垂直层数、tracer 数 |
ptimestep |
physiq |
real scalar |
s |
物理时间步,用于把 tendency 转成步末状态 |
pplay, pplev, ppopsk |
physiq |
real arrays |
Pa / Exner-like |
层中压力、层界压力、p/p0 相关权重;pplay 仅在崩溃诊断打印中使用 |
lmax_th(ngrid) |
physiq |
integer array |
- |
热羽流或边界层相关的最低可调整层界;l <= lmax_th 不触发本干调整 |
pu, pv, ph |
physiq |
real (ngrid,nlay) |
m/s, m/s, model enthalpy/potential variable |
时间步开始的水平风和焓/位温型热力变量 |
pq |
physiq |
real (ngrid,nlay,nq) |
kg/kg |
时间步开始的 tracer 质量混合比 |
pdufi, pdvfi, pdhfi, pdqfi |
physiq |
real arrays |
per second |
调用前已累积的风、焓和 tracer tendency |
noms(:) |
tracer_mod |
character array |
- |
tracer 名称表,用于首次调用时查找 "co2" |
water, igcm_h2o_vap, g |
callkeys_mod / tracer_mod / comcstfi_h |
logical / integer / real |
- / - / m s-2 |
控制并执行水汽守恒检查 |
输出
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
pduadj, pdvadj |
physiq |
real (ngrid,nlay) |
m/s/s |
对流调整产生的水平风 tendency |
pdhadj |
physiq |
real (ngrid,nlay) |
source variable per second |
对流调整产生的焓/热力变量 tendency |
pdqadj |
physiq |
real (ngrid,nlay,nq) |
kg/kg/s |
对流混合产生的 tracer tendency |
共享状态与副作用
ico2/A/B/firstcall 是 SAVE 局部变量,并由 !$OMP THREADPRIVATE 声明为每线程私有缓存。
- 例程不写 module 变量、common block 或文件;正常路径没有诊断输出。
- 如果
water 为真且水汽守恒检查得到 cadjncons < -1.e-6,例程会打印列号、层段、压力、焓和水汽剖面等调试信息,然后调用 abort_physic("convadj","crashed",1) 中止。
pplay 在计算调整时不参与物理公式,只用于上述崩溃诊断打印。
核心逻辑
- 首次调用时,扫描
noms(1:nq)。若某个 tracer 名称等于 "co2",缓存其索引到 ico2,并用 m_co2=44.01e-3 kg/mol、m_noco2=33.37e-3 kg/mol 计算 A 和 B。
- 构造时间步末工作场:
zh = ph + pdhfi*ptimestep、zu = pu + pdufi*ptimestep、zv = pv + pdvfi*ptimestep、zq = pq + pdqfi*ptimestep,然后复制到可调整工作副本 zh2/zu2/zv2/zq2。
- 如果存在 CO2 tracer,按
zhc = zh2*(A*zq2(:,:,ico2)+B) 构造稳定度检测变量;否则 zhc=zh2。
- 从第 2 层到顶层寻找
zhc(l) < zhc(l-1) 且 l > lmax_th(ig) 的格点,把这些格点加入 jadrs 调整列表。
- 对每个不稳定格点,从触发层向下和向上扩展不稳定层段
[l1,l2]。扩展时用 sdsig=ppopsk*dsig 权重更新层段平均焓 zhm,如果有 CO2 tracer,还用 dsig 权重更新层段平均 CO2 混合比 zqco2m 并重算 zhmc=zhm*(A*zqco2m+B)。
- 对最终层段,设置
zh2(i,l)=zhm;用 dsig 权重计算水平风平均 zum/zvm 和每个 tracer 平均 zqm(iq)。
- 计算调整强度
zalpha。源码先累积层段中 zhc 与平均焓的偏差,再除以 zhm*(sig(l1)-sig(l2+1));zalpha 被限制在 1.e-4 到 1。
- 对风场使用松弛更新:
zu2 += zalpha*(zum-zu2),zv2 += zalpha*(zvm-zv2)。对 tracer,当前源码直接设置 zq2(i,l,iq)=zqm(iq),注释掉了按 zalpha 松弛的写法。
- 如果有 CO2 tracer,更新层段内
zhc,然后继续向上寻找下一个不稳定层段。
- 对
water 路径,积分 zq2(h2o_vap)-zq(h2o_vap) 的柱质量变化;若净损失低于阈值,打印调试信息并中止。
- 例程结束前把工作副本与调用前工作场的差除以
ptimestep,得到 pdhadj/pduadj/pdvadj/pdqadj。
伪代码
convadj:
if firstcall:
ico2 = index where noms(iq) == "co2", or 0
if ico2 != 0:
A = 1/m_co2 - 1/m_noco2
B = 1/m_noco2
firstcall = false
zh, zu, zv = input state + incoming tendencies * ptimestep
zq = pq + pdqfi * ptimestep
zh2, zu2, zv2, zq2 = working copies
if ico2 != 0:
zhc = zh2 * (A*zq2(:,:,ico2) + B)
else:
zhc = zh2
mark columns where any layer has zhc(l) < zhc(l-1)
and l > lmax_th(ig)
for each marked column:
scan upward
when an unstable adjacent pair is found:
expand the mixed layer downward/upward while surrounding
layers remain unstable relative to the mixed mean
compute mean enthalpy, wind, and tracer mixing ratios
set zh2 to mean enthalpy in the mixed layer
relax wind toward its layer mean by zalpha
set all tracers in the mixed layer to zqm
if ico2 exists:
recompute zhc for the adjusted layer
if water:
integrate h2o_vap column change
abort if the column loses more than the threshold
output tendencies = (adjusted_working_state - pre_adjustment_working_state)
/ ptimestep
参与的主题流程
| 主题 |
参与方式 |
| 主物理时间步 |
physiq 在第 7 段干对流调整中根据 calladj 调用本例程 |
| 对流 |
对不稳定层段做干对流混合,返回风、热力变量和 tracer tendency |
| CO2 循环 / 大气组成 |
如果 tracer 表含 "co2",对流触发变量包含平均分子量变化 |
| 水循环 |
当 water 为真时,对 h2o_vap 调整结果做柱质量守恒检查 |
写法特点
- 固定格式 Fortran
.F,但文件内部定义的是 convadj_mod 模块。
ico2/A/B/firstcall 使用 SAVE + THREADPRIVATE,每个 OpenMP 线程都会独立执行一次 CO2 tracer 扫描。
lmax_th 是对流触发的硬门槛之一,低于或等于该层号的层间不稳定不会触发本例程调整。
- 风场按
zalpha 部分松弛到层段均值;tracer 场则直接替换为层段平均值。源码注释说明旧的部分松弛写法已被改成直接守恒混合,以避免相邻层段连续触发时破坏 tracer 守恒。
zalpha 的 CO2 分支表达式为 ABS(zhc(i,l)/(A+B*zqco2m) - zhm)。待确认:这与前面 zhc=zh*(A*q+B) 的形式不完全对称;本页按源码字面记录,不推断其物理意图。
复现要点
- 输入状态应先加上调用前已累积的 tendency;本例程不是从
pu/pv/ph/pq 原值直接判断稳定度。
- 若存在 CO2 tracer,必须按 tracer 名称
"co2" 定位,不是按固定 tracer 序号。
lmax_th 会抑制较低层的干调整;复现实验中同一热力剖面在不同 lmax_th 下可能有不同结果。
- tracer 混合使用
dsig 权重,焓平均使用 sdsig=ppopsk*dsig 权重;不要把二者混成同一种权重。
- 水汽守恒检查只在
water=true 时执行,且检查对象是 igcm_h2o_vap。
待确认
zalpha 的 CO2 分支中 zhc/(A+B*zqco2m) 是否为有意写法;源码没有解释,本页按字面记录。
water 路径只在 cadjncons < -1.e-6 时中止;正的净变化或较小负值是否可接受,需要由物理方案容差确认。
firstcall 缓存意味着运行中若动态改变 tracer 名称或顺序,本例程不会重新扫描;常规流程通常在初始化后固定 tracer 表。
相关页面