waterice_tifeedback_mod.F90
快速理解
它做什么: 水冰热惯量反馈模块,被 physiq 调用(physiq_mod.F:2487);根据地表水冰或孔隙冰重算土壤热惯量廓线,供 soil 求解地温时替代默认值。
基本过程: surfaceice_tifeedback(地表块状冰→三层热惯量)或 poreice_tifeedback(孔隙冰→Siegler 公式抬高)→ 输出 newtherm_i → 传给 soil。
关键结果: 更新的热惯量廓线 newtherm_i,供 soil 替代 inertiedat。
路径
LMDZ.MARS\libf\phymars\waterice_tifeedback_mod.F90
所属目录/模块
libf\phymars
文件定位
该文件定义 waterice_tifeedback_mod 模块,含唯一 subroutine waterice_tifeedback。职责是:根据地表水冰覆盖量或土壤孔隙冰填充率,重算一套土壤热惯量廓线 newtherm_i(ngrid,nsoil,nslope),供 soil 例程在求解地温时替代默认热惯量 inertiedat。这是水冰对地表/地下热状态的“热惯量反馈”。
源码头注释说明两种机制(互斥,当前不能同时开启):
surfaceice_tifeedback:地表存在足够厚的块状水冰时,构造三层热惯量(冰层 + 过渡层 + 下伏风化层)。物理依据 Madeleine et al. (2009, Icarus)。poreice_tifeedback:孔隙填充冰,按 Siegler et al. (2012, JGR) 公式sqrt(I_reg² + porosity*pore_filling*I_pureice²)抬高热惯量。
历史:JBM 为纯冰编写(2008-2012),LL 于 2024 移入模块/改 .F90 并加入孔隙冰路径。
定义的符号
| 符号 | 类型 | 行号 | 作用 |
|---|---|---|---|
waterice_tifeedback_mod |
module | 1 | 容器模块 |
waterice_tifeedback |
subroutine | 25 | 按水冰覆盖/孔隙冰重算土壤热惯量廓线 |
依赖的模块
| use 模块 | only 列表 | 用途 | 待确认 |
|---|---|---|---|
tracer_mod |
rho_ice |
水冰密度(kg·m⁻³),把地表冰量 icecover(kg·m⁻²)换算为厚度 icedepth(m) |
否 |
comsoil_h |
layer |
各土壤层深度(m),用于定位冰/风化层边界 | 否 |
comsoil_h |
inertiedat |
默认土壤热惯量廓线 (ngrid,nsoil),无冰层与孔隙冰公式的基底值 |
否 |
comsoil_h |
porosity_reg |
风化层孔隙率(PARAMETER=0.45,comsoil_h.F90:41),孔隙冰公式权重 |
否 |
surfdat_h |
watercaptag |
永久水冰盖标志(logical),为真时整列设为冰热惯量 | 否 |
surfdat_h |
inert_h2o_ice |
地表水冰热惯量(默认 2400 J·m⁻²·K⁻¹·s⁻¹ᐟ²,conf_phys.F:1012) |
否 |
callkeys_mod |
poreice_tifeedback |
孔隙冰反馈开关(默认 .false.,conf_phys.F:1145) |
否 |
callkeys_mod |
surfaceice_tifeedback |
地表冰反馈开关(默认 .false.,conf_phys.F:780) |
否 |
调用的关键例程
| 被调用例程 | 所在模块/文件 | 调用位置 | 作用 |
|---|---|---|---|
| 无 | — | — | 本例程不调用其他例程,仅含算术、sqrt 与循环 |
调用方(核验):
| 调用方 | 位置 | 上下文 |
|---|---|---|
physiq_mod.F |
:737 |
firstcall/初始化土壤前,IF (surfaceice_tifeedback.or.poreice_tifeedback) 内调用,输出 inertiesoil_tifeedback 传给 soil |
physiq_mod.F |
:2487 |
主物理步中再次调用(地温反馈更新) |
调用实参(核验 physiq_mod.F:737-739):icecover = qsurf(:,igcm_h2o_ice,:)、poreice = pore_icefraction,输出 newtherm_i = inertiesoil_tifeedback,随后该热惯量传入 soil(...)(:741)。
输入
| 输入 | 来源 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
ngrid |
调用方 | integer | — | 水平格点数 |
nsoil |
调用方 | integer | — | 土壤层数(传 nsoilmx) |
nslope |
调用方 | integer | — | 次网格坡面数 |
icecover(ngrid,nslope) |
调用方 | real | kg·m⁻² | 地表水冰量(传 qsurf(:,igcm_h2o_ice,:)) |
poreice(ngrid,nsoil,nslope) |
调用方 | real | 1(分数) | 孔隙冰填充率(传 pore_icefraction) |
注意:ngrid/nsoil/nslope 及 icecover/poreice/newtherm_i 在声明区未写 intent(见“写法特点”),但按用途 icecover、poreice 为输入、newtherm_i 为输出。
输出
| 输出 | 去向 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
newtherm_i(ngrid,nsoil,nslope) |
调用方 | real | J·m⁻²·K⁻¹·s⁻¹ᐟ² | 新土壤热惯量廓线,传给 soil 求地温 |
共享状态与副作用
- 无 common block,不写文件,无诊断打印。
- 所有 module 依赖均为只读(
rho_ice、layer、inertiedat、porosity_reg、watercaptag、inert_h2o_ice、两个开关)。 - 无 SAVE 变量、无 firstcall;纯计算,给定输入即给定输出。
- 局部变量
inertie_purewaterice = 2100在声明时初始化(纯水冰热惯量,仅孔隙冰路径用)。注意此值(2100)与地表冰inert_h2o_ice(默认 2400)不同,前者硬编码、后者可配置。
核心逻辑
- 先把
newtherm_i全置 0。 - 若
surfaceice_tifeedback为真(地表块状冰路径),对每个坡面、每个格点:- 冰厚
icedepth = icecover/rho_ice(m)。 - 若
icedepth >= layer(nsoil)或watercaptag(ig)为真(冰极厚或永久冰盖):整列newtherm_i = inert_h2o_ice。 - 否则若
icedepth < layer(1)(冰极薄,忽略):整列newtherm_i = inertiedat。 - 否则(冰介于其间):
- 找冰/风化层边界
iref:第一个满足layer(ik) <= icedepth < layer(ik+1)的ik+1。 - 边界以上各层
ik=1..iref-1设为inert_h2o_ice(纯冰)。 - 边界层
iref用热传导串联公式取过渡值:sqrt( (layer(iref)-layer(iref-1)) / ( (icedepth-layer(iref-1))/inert_h2o_ice² + (layer(iref)-icedepth)/inertiedat(ig,ik)² ) )。 - 边界以下各层
ik=iref+1..nsoil保留inertiedat。
- 找冰/风化层边界
- 冰厚
- 否则若
poreice_tifeedback为真(孔隙冰路径),对每个坡面整层向量化:newtherm_i(:,:,islope) = sqrt(inertiedat(:,:)² + porosity_reg*poreice(:,:,islope)*inertie_purewaterice²)。 - 两个开关都为假时,
newtherm_i保持全 0(调用方此时不会用它,见复现风险)。
伪代码
subroutine waterice_tifeedback(ngrid, nsoil, nslope, icecover, poreice, newtherm_i):
newtherm_i = 0
if surfaceice_tifeedback:
for islope, ig:
icedepth = icecover(ig,islope) / rho_ice
if icedepth >= layer(nsoil) or watercaptag(ig):
newtherm_i(ig,:,islope) = inert_h2o_ice # 整列纯冰
else if icedepth < layer(1):
newtherm_i(ig,:,islope) = inertiedat(ig,:) # 冰太薄,忽略
else:
iref = first ik+1 where layer(ik) <= icedepth < layer(ik+1)
newtherm_i(ig, 1:iref-1, islope) = inert_h2o_ice # 冰层
newtherm_i(ig, iref, islope) = # 过渡层(串联)
sqrt( (layer(iref)-layer(iref-1)) /
( (icedepth-layer(iref-1))/inert_h2o_ice^2
+ (layer(iref)-icedepth)/inertiedat^2 ) )
newtherm_i(ig, iref+1:nsoil, islope) = inertiedat # 下伏风化层
else if poreice_tifeedback:
for islope:
newtherm_i(:,:,islope) =
sqrt(inertiedat^2 + porosity_reg*poreice(:,:,islope)*inertie_purewaterice^2)
参与的主题流程
| 主题 | 参与方式 |
|---|---|
| 水循环 | 地表/地下水冰对土壤热惯量的反馈:改变地温日/季节循环,进而影响地表冰的凝结/升华与 CO2 凝结。是水循环与地表能量收支的耦合点 |
写法特点
- 自由格式 Fortran(
.F90),续行行尾&。 - 形参未声明
intent:ngrid/nsoil/nslope/icecover/poreice/newtherm_i只用维度声明,无intent(in/out)。复现时按用途判定方向。 - 局部
inertie_purewaterice=2100与可配置的inert_h2o_ice(默认 2400)是两个不同的热惯量值,分属孔隙冰路径与地表冰路径,勿混用。 - 过渡层公式是基于热传导的“串联电阻”式平均(按层内冰段/风化段的 1/I² 加权)。
- 两个反馈机制互斥(
IF ... ELSE IF),源码注释明确“can not run with both options”。
复现要点
- 例程只算热惯量,不改任何 tracer/温度/质量;其输出
newtherm_i经soil才影响地温。 - 触发条件:
surfaceice_tifeedback或poreice_tifeedback至少一个为真;二者互斥(同真时只走 surface 分支,因为IF在前)。调用方physiq_mod.F:735用.or.守卫,因此两个都假时不会调用本例程(newtherm_i全 0 不会被使用)。 surfaceice_tifeedback还要求water与callsoil同时为真(核验conf_phys.F:786-797的中止检查)。- 边界层过渡公式中
inertiedat(ig,ik)的ik是紧邻其上的DO ik=1,iref-1循环(:115-117)正常结束后的残留值。按 Fortran 标准,正常结束的 DO 循环索引变量取(iref-1)+1 = iref,因此该处实际等价于inertiedat(ig,iref),即边界层处的风化层热惯量。复现需照源码字面用ik,结果与iref一致。 icedepth用rho_ice(水冰密度)换算;layer是土壤层深度数组。
待确认
- 过渡层公式
newtherm_i(ig,iref,islope)=sqrt(...inertiedat(ig,ik)...)(:119-120)中的ik:此处ik的来源是紧邻其上的DO ik=1,iref-1循环(:115-117),不是边界查找循环。按 Fortran 标准,DO ik=1,iref-1正常结束(未 EXIT)后循环变量取终止值ik=iref。因此inertiedat(ig,ik)实际等于inertiedat(ig,iref),即边界层处的风化层热惯量,物理上合理。这是依赖"DO 循环结束后索引变量值"的隐式写法,可读性差但结果正确。推断:等价于显式写inertiedat(ig,iref);复现时可直接用iref,与源码字面行为一致。 - 形参缺
intent是否在某些编译器下有副作用;当前按惯例理解为 in/in/out。
相关页面
- soil.md:土壤热扩散求解,本例程输出的使用点(
physiq_mod.F:741)。 - physiq 水循环调用点:本例程的调用上下文。
- water-saturation-helpers:水饱和基础公式。
- 水循环父级主题页。
- 待确认页:
comsoil_h(定义layer、inertiedat、porosity_reg)。 - surfdat_h:定义
inert_h2o_ice和watercaptag。