thermcell_dqup.F90
路径
LMDZ.MARS\libf\phymars\thermcell_dqup.F90
所属目录 / 模块
libf/phymars
文件定位
thermcell_dqup.F90 定义 Martian thermal plume model 的被动垂直输送算子。它不求解热羽流结构本身,而是在上游已经给定上升质量通量 fm、夹卷 entr 和退卷 detr 后,把任意层中心标量 q_therm 沿热羽流上升输送,最后返回整物理时间步的导数 dq_therm=(q-q_initial)/ptimestep。在 calltherm_interface_mod 中,它用于风、非 CO2 tracer 和可选 TKE;在 thermcell_main_mars 中也用于内部变量输送。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
thermcell_dqup_mod |
module |
1 |
封装热羽流被动变量输送例程。 |
thermcell_dqup |
subroutine |
32 |
用质量通量和夹卷/退卷通量计算标量的热羽流输送 tendency。 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
| 无 |
- |
本文件没有 use 依赖。 |
- |
调用的关键例程
| 被调用例程 |
所在模块 / 文件 |
调用位置 |
作用 |
| 无 |
- |
- |
本例程只使用数组运算和循环。 |
被调用位置
| 调用方 |
文件 |
调用位置 |
作用 |
calltherm_interface |
calltherm_interface_mod.F90 |
行 315、321、331、341 |
分别输送 u、v、非 CO2 tracer 和可选 TKE。 |
thermcell_main_mars |
thermcell_main_mars.F90 |
行 1193 |
在热羽流主求解器内部复用同一输送算子。 |
输入
| 输入 |
来源 |
类型 / 维度 |
单位 |
含义 |
ngrid, nlayer |
调用方 |
integer |
- |
水平列数和垂直层数。 |
ptimestep |
调用方 |
real |
s |
物理时间步。 |
fm(ngrid,nlayer+1) |
热羽流主求解器 |
real array |
mass flux |
界面上升质量通量。 |
entr(ngrid,nlayer) |
热羽流主求解器 |
real array |
mass flux |
每层夹卷质量通量。 |
detr(ngrid,nlayer) |
热羽流主求解器 |
real array |
mass flux |
每层退卷质量通量。 |
masse0(ngrid,nlayer) |
调用方 |
real array |
mass |
层质量,用于把通量收支转为混合比变化。 |
q_therm(ngrid,nlayer) |
调用方 |
real array |
variable-dependent |
待输送的初始标量廓线。 |
ndt |
调用方 |
integer |
- |
内部输送子步数。 |
limz |
调用方 |
integer |
layer index |
计算到的最高有效层。 |
输出
| 输出 |
去向 |
类型 / 维度 |
单位 |
含义 |
dq_therm(ngrid,nlayer) |
调用方 |
real array |
q per second |
热羽流输送导致的标量 tendency。 |
共享状态与副作用
本文件不读写共享模块变量、不做文件 I/O,也不打印诊断。所有状态变化都限制在局部数组 q/qa/invflux0 和输出实参 dq_therm 中。
核心逻辑
- 把环境标量
q 和上升流标量 qa 初始化为 q_therm。
- 用
ztimestep=ptimestep/ndt 和 invflux0=ztimestep/masse0 准备子步长换算因子。
- 每个子步先令底层
qa(:,1)=q(:,1)。
- 从第 2 层到
limz,若 (fm(k+1)+detr(k))*ptimestep 足够大,则用上一层上升流和本层夹卷环境值计算 qa(k);否则令 qa(k)=q(k)。
- 对 1 到
limz 层更新环境 q:退卷加入、夹卷移除、下界面流出、上界面流入。源码第 90-94 行的更新式含 fm(:,k+1)*q(:,k+1),因此 k=limz 时会读取 q(:,limz+1);若调用方传入 limz=nlayer,这里等价读取 q(:,nlayer+1)。
- 子步循环结束后输出整步导数。源码先把
dq_therm=0.,随后第 101-103 行只写 1:limz,所以 limz+1:nlayer 的输出保持为 0,而不是保持某个输入标量的初始化值。
伪代码
q = q_initial
qa = q_initial
for each transport substep:
qa[:,1] = q[:,1]
for k = 2..limz:
if flux is large enough:
qa[:,k] = (fm[:,k]*qa[:,k-1] + entr[:,k]*q[:,k]) /
(fm[:,k+1] + detr[:,k])
else:
qa[:,k] = q[:,k]
for k = 1..limz:
q[:,k] += (detr*qa - entr*q - fm_down*q + fm_up*q[:,k+1]) * dt / mass
dq = 0
for k = 1..limz:
dq[:,k] = (q[:,k] - q_initial[:,k]) / ptimestep
参与的主题流程
| 主题 |
参与方式 |
| 热羽流 / PBL 对流 |
在质量通量已知后输送被动变量,补齐热羽流对风、tracer 和 TKE 的垂直输送。 |
| tracer 输送 |
calltherm_interface 跳过 CO2 tracer 后,对其他 tracer 调用本例程。 |
| 湍流耦合 |
dtke_thermals 为真时,上游把 TKE 作为标量传入本例程输送。 |
写法特点
- 本文件没有模块依赖,便于被接口层和主热羽流求解器共同复用。
limz 限制了计算层范围;源码把 dq_therm 预置为 0 后只写 1:limz,因此 limz+1:nlayer 的输出为 0。
do k=1,limz 的环境标量更新会读取 q(:,k+1)。调用方若允许 limz=nlayer,必须保证实参或调用上下文不会让 q(:,nlayer+1) 访问越界。
- 通量阈值
1.e-5*masse0/ptimestep 用来避免分母太小导致不稳定。
复现要点
ndt 改变会改变内部显式输送的数值扩散和稳定性;接口层当前常用 ndt=10。
masse0 不能为零,否则 invflux0=ztimestep/masse0 会失效。
limz 必须与上游热羽流高度一致,否则会漏输送或越过有效层;特别是 limz=nlayer 时,源码第 90-94 行会访问 q(:,nlayer+1),复现或移植时必须显式检查顶层边界数组是否可读。
待确认
- 已随 thermcell_main_mars 确认第 1193 行调用用于 CO2 tracer 内部输送;
thermcell_dqup 本身不区分变量物理含义,仍需由调用方保证 masse/fm/entr/detrmod/limz 一致。
相关页面