topmons_mod.F90

路径

LMDZ.MARS\libf\phymars\topmons_mod.F90

所属目录/模块

libf/phymars

文件定位

源码依据(第 8-16 行注释及整体结构):实现"山顶地形尘流"(Mountain Top Dust Flows)参数化方案,模拟火星上亚格点尺度山脉的坡风驱动尘埃抬升机制。

核心物理思想(第 211-214 行注释):

该模块与 rocketduststorm_mod 形成尘埃循环中两种集中垂直输运机制的互补:前者由辐射加热驱动(尘暴),后者由地形坡风驱动(山脉)。

定义的符号

符号 类型 行号 作用
topmons_mod module 1 容器模块
topmons subroutine 18 主例程:辐射加热 → 垂直速度 → PBL 裹挟 + Van Leer 输运 → 脱轨
t_topmons subroutine 705 计算山脉上方和邻近环境的温度廓线
van_leer subroutine 792 lwmax 层开始的 Van Leer 平流(含 PBL 注入边界条件)
topmons_setup subroutine 954 初始化:检测含山格点、计算 alpha_hmonshsummit;内置 19 座火星火山列表

依赖的模块

use 模块 only 列表 用途
tracer_mod igcm_topdust_mass/number, igcm_dust_mass/number, rho_dust topdust/dust 示踪物索引与密度(第 35-37 行)
comcstfi_h r, g, cpp, rcp 比气体常数、重力加速度、定压比热(第 38 行)
dimradmars_mod naerkind 气溶胶种类数(第 39 行)
comsaison_h dist_sol, mu0, fract 太阳距离、天顶角余弦、日照分数(第 40 行)
surfdat_h hmons, summit, alpha_hmons, hsummit, contains_mons, phisfi, base 亚格点地形数据:山高、山顶、面积分数等(第 41-42、960-961 行)
callradite_mod callradite 辐射传输计算(第 43 行)
write_output_mod write_output 诊断输出(第 44 行,当前注释掉)
planetwide_mod planetwide_maxval/minval 全球地形极值(非介观尺度时,第 964 行)
mod_grid_phy_lmdz nvertex 网格顶点数(4=规则,6=二十面体,第 966 行)
geometry_mod longitude_deg, latitude_deg, boundslon, boundslat 格点坐标与边界(第 967-968 行)

调用的关键例程

被调用例程 所在模块/文件 调用位置 作用
callradite callradite_mod 第 291 行 计算含 topdust 的辐射加热率
t_topmons 本模块 第 310 行 计算山脉上方/邻近温度廓线
van_leer 本模块 第 549-552 行 topdust_mass/number 的 Van Leer 平流
planetwide_maxval/minval planetwide_mod 第 1046-1047 行 获取全局地形极值用于计算 alpha_hmons
abort_physic abort_gcm.F 第 1014、1070 行 初始化异常时中止

输入

topmons 主例程

输入 类型/维度 单位 含义
ngrid integer(in) 水平格点数
nlayer integer(in) 垂直层数
nq integer(in) 示踪物数
ptime real(in) s 当前时间
ptimestep real(in) s 物理时间步
pq real(ngrid,nlayer,nq)(in) kg/kg 示踪物混合比
pdq real(ngrid,nlayer,nq)(in) kg/kg/s 上游倾向
pt real(ngrid,nlayer)(in) K 层中点温度
pdt real(ngrid,nlayer)(in) K/s 上游温度倾向
pplev real(ngrid,nlayer+1)(in) Pa 层间界面气压
pplay real(ngrid,nlayer)(in) Pa 层中点气压
pzlev real(ngrid,nlayer+1)(in) m 层间界面高度
pzlay real(ngrid,nlayer)(in) m 层中点高度
pdtsw / pdtlw real(ngrid,nlayer)(in) K/s 短波/长波辐射加热(背景)
totstormfract real(ngrid)(in) 风暴面积分数(辐射用)
clearatm logical(in) 清空标志
clearsky logical(in) 无云标志
totcloudfrac real(ngrid)(in) 总云量
nohmons logical(in) 无亚格点地形标志

topmons_setup

输入 类型/维度 单位 含义
ngrid integer(in) 水平格点数(1D 特殊处理)

输出

topmons 主例程

输出 类型/维度 单位 含义
pdqtop real(ngrid,nlayer,nq)(out) kg/kg/s topdust 方案产生的示踪物倾向
wfin real(ngrid,nlayer+1)(out) m/s 最终垂直速度剖面(含坡风 + 辐射分量)
dsodust / dsords / dsotop real(ngrid,nlayer)(out) 密度标度不透明度
tau_pref_scenario / tau_pref_gcm real(ngrid)(out) 尘埃柱可见光不透明度

topmons_setup

输出 去向 类型/维度 含义
contains_mons surfdat_h logical(ngrid) 含山格点标志
alpha_hmons surfdat_h real(ngrid) 山脉面积分数(0-0.5)
hsummit surfdat_h real(ngrid) 山顶相对 GCM 地表的高度

共享状态与副作用

核心逻辑

按执行顺序(行号为源码行号):

阶段 0:初始化(第 225-276 行)

  1. 全部输出和中间变量清零。
  2. 温度更新(第 265 行):zt = pt + pdt * ptimestep(用上游倾向推进)。
  3. 示踪物更新(第 271 行):zq0 = pq + pdq * ptimestep(含火箭式尘暴后的背景尘埃)。

阶段 1:辐射加热(第 279-369 行)

  1. 辐射传输(第 291 行):调用 callradite 计算含 topdust 的加热率 zdtlw1/zdtsw1
  2. 对每列含山格点mu0 > mu0limcontains_mons(ig) 为真):
    • 山脉温度廓线(第 310 行):调用 t_topmons 计算山脉上方温度 t_top 和环境温度 t_env
    • 加热率插值(第 322-346 行):插值到界面,同 rocketduststorm
    • 辐射垂直速度(第 356-368 行): wrad = -deltahr / (g/cpp + max(zdtvert, -0.99*g/cpp)) 限幅 |wrad| ≤ wmax向下分量强制置零(第 365-367 行:if wrad > 0 → wrad = 0),因为山脉坡风只产生向上输运。

阶段 2:垂直速度合成(第 372-474 行)

对每列含山格点:

  1. 浮力驱动速度(第 382-429 行):

    • dt_top > 0(山脉上方比环境暖):
      • 会聚速度(第 384 行):w0 = -k0 * g * sqrt(dt_top / T_env(lsummit)) 负值表示向上。
      • |w0| > |wrad|:从山顶层逐层向上推进,使用热羽流模型
        wup²(l+1) = (1 - 2*k1*Δz) * wup²(l) + 2*k2*g*Δz * (newzt(l) - t_env(l)) / t_env(l)
        其中 k1 为动量衰减,k2 为浮力加速度。
      • wup² > 0wup = -sqrt(wup2)wfin = wup
      • |wup| < |wrad|wup² ≤ 0:退化到纯辐射方案 wfin = wrad
    • dt_top ≤ 0(山脉上方比环境冷):退化到纯辐射方案。
  2. 最大速度层 lwmax(第 447-450 行):lwmax = minloc(wup) — 最大向上速度所在层,作为 PBL 尘埃注入层。

  3. 子步时间步(第 455-466 行):同 rocketduststormdtmax = min(Δz / (secu * |wfin|))

  4. 空气质量通量(第 468-471 行):w(l) = wfin(l) * pplev(l) / (r * ztlev(l)) * subtimestep

阶段 3:PBL 裹挟 + 垂直输运(第 476-586 行)

  1. 密度与空气质量(第 480-490 行):rho = pplay / (r * pt)masse = (pplev(l) - pplev(l+1)) / g

  2. PBL 总空气质量(第 494-500 行):从地表到 lwmax-1 层的气柱质量。

  3. 裹挟通量(第 516 行):

    entr = alpha_hmons * wup(lwmax) * rhobarz(lwmax) / masse_pbl

    负值表示从 PBL 抽出空气质量。保护:|entr| ≤ 1/ptimestep(第 518-520 行)。

  4. 每个子步(第 525-553 行):

    • PBL 内混合比(第 527-534 行):加权平均 qbar_pbl
    • PBL 尘埃抽出(第 538-544 行):指数衰减模型 dq = (1 - exp(entr*subtimestep)) * q * Δp/g,每层逐层扣除。
    • Van Leer 平流(第 549-552 行):从 lwmaxnlayer,调用本地 van_leer;额外传入 masse_pbldqm_pblalpha_hmonsqbar_pbl 作为 PBL 注入边界条件。
  5. 混合比反解(第 558-572 行):同 rocketduststorm,用 alpha_hmons 做面积分数转换。

  6. 倾向计算(第 576-583 行):dqvl = (zq_after - zq0_before) / ptimestep

阶段 4:脱轨(第 588-624 行)

  1. 脱轨系数(第 599-601 行,白天且含山时):

    coefdetrain = (rhobarz(l+1)*|wfin(l+1)| - rhobarz(l)*|wfin(l)|) / masse(l)

    即质量通量散度除以层质量:散度为正时(质量减少)产生脱轨

  2. 指数脱轨(第 603-612 行): dqdet = -(1 - exp(coefdetrain * ptimestep)) * topdust / ptimestep 保护:不超过可用 topdust 量(第 608-612 行)。

  3. 夜间/非含山格点(第 618-622 行):完全脱轨dqdet = -topdust / ptimestep

阶段 5:最终倾向(第 626-641 行)

pdqtop(topdust) = dqdet_topdust + dqvl_topdust
pdqtop(dust) = -dqdet_topdust + dqvl_dust

t_topmons 子例程(第 705-785 行)

  1. 山顶层定位(第 744-747 行):hsummit ≥ zlay(lsummit) 的最高层。
  2. 山脉上方温度(第 749-753 行):山顶层设为地表温度 zt(1),向上按绝热递减率递减。
  3. 环境温度映射(第 756-774 行):从 lmons(山坡高度对应层)开始,逐层向上映射环境温度。
  4. t_top 下界保护(第 776-781 行):t_top 不低于 t_env
  5. 温差输出(第 783 行):dt_top = t_top(lsummit) - t_env(lsummit)

topmons_setup 子例程(第 954-1100 行)

  1. 19 座火山经纬度(第 984-1001 行):硬编码列表,Olympus Mons 首位(lon=-134, lat=18.4)。
  2. 含山格点检测(第 1020-1042 行):逐格点检查 boundslon/lat 是否包络任一火山坐标。
  3. alpha_hmons 计算(第 1062-1084 行): alpha_hmons = 0.5 * (hmons - hmin) / (hmax - hmin),范围 [0, 0.5]。 alpha_hmons = 0 时禁用(山脉已被格点分辨)。
  4. hsummit 计算(第 1087 行):hsummit = summit - phisfi/g

van_leer 子例程(第 792-951 行)

基于 vlz_fi.F 的本地副本(第 790 行注释明确),关键差异:

伪代码

subroutine topmons(..., pq, pdqtop, wfin, ...):

  #--- 阶段 0: 初始化 ---
  zt = pt + pdt * ptimestep
  zq0 = pq + pdq * ptimestep

  #--- 阶段 1: 辐射加热 ---
  call callradite(..., zq, ..., zdtlw1, zdtsw1, ...)
  for ig where daytime and contains_mons(ig):
    call t_topmons(...) → t_top, dt_top, t_env, lsummit, lmons
    插值加热率到界面
    wrad = -deltahr / (g/cpp + max(zdtvert, -0.99*g/cpp))
    wrad = clamp(wrad, -wmax, wmax)
    if wrad > 0: wrad = 0   # 仅保留向上分量

  #--- 阶段 2: 垂直速度合成 ---
  for ig where daytime and contains_mons(ig):
    if dt_top > 0:
      w0 = -k0 * g * sqrt(dt_top / T_env(lsummit))   # 会聚速度
      if |w0| > |wrad|:
        从山顶向上逐层: wup²(l+1) = (1-2k1Δz)*wup²(l) + 2k2*g*Δz*(newzt-T_env)/T_env
        wup = -sqrt(wup2); wfin = wup
      else:
        wfin = wrad   # 退化为辐射方案
    else:
      wfin = wrad
    lwmax = minloc(wup)   # 最大速度层 = PBL 注入层
    dtmax = min(Δz / (secu*|wfin|)); nsubtimestep = ceil(ptimestep/dtmax)
    w(l) = wfin(l) * pplev(l) / (r*ztlev(l)) * subtimestep

  #--- 阶段 3: PBL 裹挟 + Van Leer 输运 ---
  entr = alpha_hmons * wup(lwmax) * rhobarz(lwmax) / masse_pbl
  for tsub=1..nsubtimestep:
    qbar_pbl = Σ(dust * Δp/g) / masse_pbl    # PBL 平均浓度
    for l=1..lwmax-1:                         # PBL 内逐层扣除
      dqm = (1 - exp(entr*subtimestep)) * dust(l) * Δp/g
      dust(l) = dust(l) - dqm
    call van_leer(topdust_mass, lwmax, ..., dqm_pbl, qbar_pbl)  # lwmax→top
    # van_leer 内: wq(lwmax) = -dqm_pbl / alpha_hmons
  # 反解混合比
  topdust = alpha_hmons * (mr_topdust - mr_dust)
  dqvl = (zq_after - zq0_before) / ptimestep

  #--- 阶段 4: 脱轨 ---
  if daytime and contains_mons and topdust > 0.01*dust:
    coefdetrain = (rho*|w|(l+1) - rho*|w|(l)) / masse(l)  # 质量通量散度
    dqdet = -(1 - exp(coefdetrain*ptimestep)) * topdust / ptimestep
  else:
    dqdet = -topdust / ptimestep   # 完全脱轨

  #--- 阶段 5: 最终倾向 ---
  pdqtop(topdust) = dqdet + dqvl_topdust
  pdqtop(dust) = -dqdet + dqvl_dust

subroutine t_topmons(nlayer, summit, hsummit, hmons, zt, zlay, t_top, dt_top, t_env, lsummit, lmons):
  lsummit = 最高 zlay < hsummit 的层
  t_top(lsummit) = zt(1)   # 山顶温度 = 地表温度
  向上: t_top(l+1) = t_top(l) - (zlay(l+1)-zlay(l)) * g/cpp   # 绝热递减
  lmons = 最高 zlay < hmons 的层
  t_env(lsummit) = zt(lmons)   # 环境温度映射
  dt_top = t_top(lsummit) - t_env(lsummit)

subroutine topmons_setup(ngrid):
  for each of 19 predefined volcanoes:
    检查格点边界是否包络 → contains_mons(ig) = .true.
  alpha_hmons = 0.5 * (hmons - hmin) / (hmax - hmin)
  hsummit = summit - phisfi/g

参与的主题流程

主题 参与方式
尘埃循环 physiq_mod.F:804 调用 topmons_setup(初始化),physiq_mod.F 内通过 topmons 计算 pdqtop 倾向并加到 pdq 上(与 rocketduststorm 同级的集中垂直输运分支)

写法特点

复现要点

待确认

相关页面