soil_settings.F
快速理解
它做什么: 从 startfi.nc 读取土壤层深度/热惯量/温度/地热通量,层数不匹配时做垂直插值。被 phyetat0 调用。
基本过程: 经 iostart 读字段 → 必要时用 interp_line 做垂直插值 → 填充 comsoil_h。
关键结果: layer/mlayer/inertiedat/inertiesoil/tsoil/qsoil/flux_geo,为土壤热传导提供初值。
路径
LMDZ.MARS\libf\phymars\soil_settings.F
所属目录/模块
libf/phymars
文件定位
soil_settings.F 是土壤初始化设置例程。它从 startfi.nc 重启文件中读取土壤层深度几何、热惯量、土壤温度和地热通量等字段,并在层数不匹配时执行垂直插值。由 phyetat0_mod 在 GCM 初始化阶段调用一次。
定义的符号
| 符号 | 类型 | 行号 | 作用 |
|---|---|---|---|
soil_settings_mod |
module | 1 | 包裹 soil_settings 子程序的模块 |
soil_settings |
subroutine | 7 | 从重启文件读取并初始化土壤属性 |
依赖的模块
| use 模块 | only 列表 | 用途 | 待确认 |
|---|---|---|---|
comsoil_h |
layer, mlayer, inertiedat, inertiesoil, volcapa, flux_geo, adsorption_soil, igcm_h2o_vap_soil, igcm_h2o_ice_soil, igcm_h2o_vap_ads |
土壤共享状态:层几何、热惯量、体积热容量、地热通量、吸附开关和 tracer 索引 | |
iostart |
inquire_field_ndims, get_var, get_field, inquire_field, inquire_dimension_length |
NetCDF 重启文件 I/O 接口 | |
comslope_mod |
nslope |
坡面 bin 数量 | |
interp_line_mod |
interp_line |
一维线性插值 |
调用的关键例程
| 被调用例程 | 所在模块/文件 | 调用位置 | 作用 |
|---|---|---|---|
inquire_dimension_length |
iostart |
行 106 | 查询 subsurface_layers 维度长度 |
inquire_field_ndims |
iostart |
行 128 | 查询 inertiedat 字段的维度数 |
get_var |
iostart |
行 143, 148 | 读取 soildepth 坐标变量 |
get_field |
iostart |
行 203, 229, 236, 279, 286, 335, 342, 440, 457, 472, 488 | 读取 inertiedat/inertiesoil/tsoil/flux_geo/h2o_vap_soil/h2o_ice_soil/h2o_vap_ads 字段 |
inquire_field |
iostart |
行 247, 301 | 检查 inertiesoil/tsoil 字段是否存在 |
interp_line |
interp_line_mod |
行 370, 395, 403, 419 | 一维线性插值(层数不匹配时) |
abort_physic |
物理基础设施 | 行 119, 206, 224, 232, 240, 274, 282, 290, 331, 339, 345 | 关键字段缺失或分配失败时终止 |
输入
| 输入 | 来源 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
nid |
phyetat0_mod |
integer | — | 已打开的 startfi.nc NetCDF 文件 ID |
ngrid |
phyetat0_mod |
integer | — | 水平网格点数 |
nsoil |
phyetat0_mod(nsoilmx) |
integer | — | 目标土壤层数(=57) |
nqsoil |
phyetat0_mod |
integer | — | 土壤 tracer 数量 |
tsurf(ngrid,nslope) |
phyetat0_mod |
real | K | 地表温度 |
indextime |
phyetat0_mod |
integer | — | 时间轴索引 |
输出
| 输出 | 去向 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
tsoil(ngrid,nsoil,nslope) |
phyetat0_mod → comsoil_h |
real | K | 土壤各层温度 |
qsoil(ngrid,nsoil,nqsoil,nslope) |
phyetat0_mod → comsoil_h |
real | kg/kg | 土壤 tracer(h2o_vap_soil, h2o_ice_soil, h2o_vap_ads) |
同时写入 comsoil_h 中的:layer/mlayer(层深度)、inertiedat/inertiesoil(热惯量)、volcapa(体积热容量)、flux_geo(地热通量)。
共享状态与副作用
- 写入
comsoil_hmodule 变量:layer/mlayer(层深度几何)、inertiedat/inertiesoil(热惯量)、volcapa(体积热容量)、flux_geo(地热通量) - 写入
qsoil:土壤 tracer 数组(h2o_vap_soil, h2o_ice_soil, h2o_vap_ads) - 日志输出:大量
write(*,*)打印读取状态和字段范围
核心逻辑
1. 深度坐标(行 100–168)
- 查询层数(行 106):从
startfi.nc读取subsurface_layers维度长度dimlen。 - 层数不匹配(行 108–123):
dimlen ≠ nsoil时设interpol=.true.,分配oldmlayer。 - 旧格式检测(行 128–153):查询
inertiedat维度数ndims:ndims=1:旧格式(热惯量仅地表),设olddepthdef=.true.,用公式oldmlayer(k) = sqrt(887.75/π) * (2^(k-0.5) - 1)构建旧深度。ndims≠1:新格式,读取soildepth坐标到mlayer或oldmlayer。
- 构建新深度(行 156–162):
interpol=.true.时用公式mlayer(k) = lay1*(1+k^2.9*(1-exp(-k/20))),lay1=2e-4。 - 构建层界面(行 165–168):
layer(k) = (mlayer(k)+mlayer(k-1))/2,最后一层外推。
2. 体积热容量(行 170–183)
volcapa由tabfi.F在读取controle表时设置。- 若
volcapa ≤ 0,设为默认值1e6J/m³/K。
3. 热惯量(行 185–294)
3.1 当日气候热惯量 inertiedat(行 190–243):
ndims=1(旧格式):读取地表值surfinertia,复制到所有层。ndims≠1(新格式):直接读取 3D 字段,或存入oldinertiedat待插值。
3.2 PEM 热惯量 inertiesoil(行 245–294):
- 字段不存在时:从
inertiedat复制。 - 字段存在时:直接读取,或存入
oldinertiesoil待插值。
4. 土壤温度(行 298–349)
- 字段不存在时:从
tsurf复制到所有层。 - 字段存在时:直接读取,或存入
oldtsoil待插值。
5. 垂直插值(行 352–432)
olddepthdef路径(行 355–380):旧格式深度用inertiesoil/volcapa缩放,插值 tsoil。interpol路径(行 381–432):新格式层数不匹配时,用interp_line对inertiedat/inertiesoil/tsoil分别插值到新网格。
6. 地热通量(行 436–445)
- 读取
flux_geo;不存在时设为 0。
7. 吸附 tracer(行 448–501)
adsorption_soil=.true.时读取h2o_vap_soil、h2o_ice_soil、h2o_vap_ads;不存在时设为 0。
8. 报告(行 505–523)
- 打印
volcapa、inertiedat/inertiesoil/tsoil的最小最大值。
伪代码
dimlen = inquire("subsurface_layers")
if dimlen ≠ nsoil: interpol = true
ndims = inquire_field_ndims("inertiedat")
if ndims == 1: ! 旧格式
olddepthdef = true
oldmlayer = sqrt(887.75/π)*(2^(k-0.5)-1)
else:
read "soildepth" → mlayer or oldmlayer
if interpol: mlayer = lay1*(1+k^2.9*(1-exp(-k/20)))
layer(k) = (mlayer(k)+mlayer(k-1))/2
if volcapa ≤ 0: volcapa = 1e6
read inertiedat → inertiedat or oldinertiedat
if inertiesoil exists: read → inertiesoil or oldinertiesoil
else: inertiesoil = inertiedat
if tsoil exists: read → tsoil or oldtsoil
else: tsoil = tsurf (all layers)
if olddepthdef or interpol:
interp_line(oldgrid, oldval, mlayer, newval) ! 对每个字段
read flux_geo (default 0)
if adsorption_soil: read h2o_vap_soil, h2o_ice_soil, h2o_vap_ads (default 0)
report min/max of volcapa, inertiedat, inertiesoil, tsoil
参与的主题流程
| 主题 | 参与方式 |
|---|---|
| 土壤初始化 | 从 startfi.nc 读取土壤层几何、热惯量、温度和 tracer,是 GCM 启动的关键步骤 |
| 水循环 | adsorption_soil 控制是否读取地下 h2o_vap/ice/ads tracer |
写法特点
- 固定格式 Fortran:使用
c列注释、DO/ENDDO大写。 - 旧格式兼容:
ndims=1检测旧格式(热惯量仅地表),用公式重建深度坐标。 - 垂直插值:层数不匹配时用
interp_line线性插值,支持olddepthdef(旧格式深度缩放)和interpol(新格式直接插值)两种路径。 - 大量日志:每个字段读取都打印状态和范围。
phyetat0_mod唯一调用方:仅在 GCM 初始化时调用一次。
复现要点
startfi.nc必须包含subsurface_layers维度、soildepth坐标、inertiedat字段。inertiesoil和tsoil可选;不存在时分别从inertiedat和tsurf初始化。flux_geo可选;不存在时设为 0。volcapa由tabfi.F读取controle表设置;若为 0 则用默认值1e6。adsorption_soil开关控制是否读取地下 h2o tracer。
待确认
- 行 138
oldmlayer(k) = sqrt(887.75/π) * (2^(k-0.5)-1)中 887.75 的来源(待确认:推断为火星热扩散特征参数,但无文献引用)。 - 行 368
oldgrid(2:) = oldmlayer * (inertiesoil/volcapa)中深度用inertie/volcapa缩放的物理含义(待确认:推断为扩散长度尺度sqrt(κ*t)的简化)。 - 日志中
phyetat0:前缀(行 455 等)来自调用方名称,推断为复制粘贴遗留。
相关页面
- comsoil_h — 土壤共享参数文件,本文件写入层几何、热惯量等
- soil — 土壤热扩散求解器,使用本文件设置的
layer/mlayer/volcapa - waterice_tifeedback_mod — 水冰热惯量反馈,修改
inertiesoil - iniwritesoil — 土壤诊断 NetCDF 初始化
- soil_settings.md:本页面。
- water-cycle-config —
adsorption_soil开关说明 - water-cycle — 水循环主题页