swmain_mod.F
路径
LMDZ.MARS\libf\phymars\swmain_mod.F
所属目录 / 模块
libf/phymars
MODULE swmain_mod
文件定位
swmain_mod.F 是短波太阳辐射主程序模块。它由 callradite_mod 在每个辐射子域内调用,接收已经准备好的气溶胶可见光光学厚度、两太阳谱段的 QVISsQREF3d/omegaVIS3d/gVIS3d、地表反照率、太阳天顶角和日照分数;对两个太阳谱段分别调用 Fouquart 或 Toon solver,得到归一化上下行短波通量,再乘入当前日火距离下的太阳常数和日照几何因子,最后由谱段合计净通量差计算短波加热率。
本文件只负责 1:nlaylte 的 LTE 短波层。nlaylte 由 nlthermeq 写入 yomlw_h,上游 callradite 会把 nlaylte+1:nlayer 的短波倾向置零。
定义的符号
| 符号 | 类型 | 行号 | 作用 |
|---|---|---|---|
swmain_mod |
module | 1 | 短波辐射主程序模块 |
SWMAIN |
subroutine | 7-196 | 调度两个太阳谱段的短波 solver,输出谱段上下行 flux 和合计短波加热率 |
本文件没有 SAVE、THREADPRIVATE 或 common block。
依赖的模块
| use 模块 | only 列表 | 用途 | 待确认 |
|---|---|---|---|
dimradmars_mod |
ndlo2, ndlon, nflev, nsun, naerkind |
工作数组维度、太阳谱段数和气溶胶种类数 | |
yomlw_h |
nlaylte, gcp |
LTE 有效层数;gcp=g/cpp 用于 flux divergence 转 K/s |
|
callkeys_mod |
swrtype |
选择短波 solver:1 为 Fouquart,2 为 Toon | |
swr_fouquart_mod |
swr_fouquart |
swrtype=1 的短波连续散射方案 |
|
swr_toon_mod |
swr_toon |
swrtype=2 的 Toon two-stream 方案 |
调用的关键例程
| 被调用例程 | 所在模块 / 文件 | 调用位置 | 作用 |
|---|---|---|---|
SWR_FOUQUART |
swr_fouquart.F |
151-154 | 给定太阳谱段的 Fouquart 短波散射通量求解 |
SWR_TOON |
swr_toon.F |
157-160 | 给定太阳谱段的 Toon two-stream 通量求解 |
abort_physic |
公共错误处理 | 162-163 | swrtype 不是 1 或 2 时终止 |
直接调用方
| 调用方 | 位置 | 调用目的 |
|---|---|---|
callradite_mod.F::callradite |
547-551 | 在每个 ndomainsz 子域内计算短波加热率和上下行短波通量 |
输入
| 输入 | 来源 | 类型 / 维度 | 单位 | 含义 |
|---|---|---|---|---|
KDLON, KFLEV |
callradite 子域 |
integer | - | 当前子域列数和辐射垂直层维度 |
PCST |
callradite |
real | W/m2 | 当前日火距离下的太阳常数,flux_1AU/dist_sol^2 |
albedo(NDLO2,2) |
callradite |
real | - | 两个太阳谱段地表半球反照率 |
PRMU0(NDLO2) |
callradite |
real | - | 原始太阳天顶角余弦 |
PDP(NDLO2,KFLEV) |
callradite |
real | Pa | 每层压力厚度 |
PPLEV(NDLO2,KFLEV+1) |
callradite |
real | Pa | 层界面压力;本文件用来算 sigma 厚度 |
aerosol(NDLO2,KFLEV,naerkind) |
aeropacity -> callradite |
real | optical depth | 各类气溶胶逐层参考波长光学厚度 |
PFRACT(NDLO2) |
physiq/callradite |
real | - | 当前时间步白昼分数 |
QVISsQREF3d, omegaVIS3d, gVIS3d |
aeroptproperties -> callradite |
real | - | 两太阳谱段的气溶胶消光比、单次散射反照率和不对称因子 |
输出
| 输出 | 去向 | 类型 / 维度 | 单位 | 含义 |
|---|---|---|---|---|
PHEAT(NDLO2,KFLEV) |
callradite -> dtsw |
real | K/s | 合计两个太阳谱段后的短波加热率 |
PFLUXD(NDLON,NFLEV+1,2) |
callradite |
real | W/m2 | 每个界面、每个太阳谱段的向下短波通量 |
PFLUXU(NDLON,NFLEV+1,2) |
callradite |
real | W/m2 | 每个界面、每个太阳谱段的向上短波通量 |
共享状态与副作用
- 读取
callkeys_mod::swrtype选择 solver。 - 读取
yomlw_h::nlaylte限制循环层数;读取yomlw_h::gcp计算加热率。 - 不写 module 状态,不做文件 I/O,不写诊断。
- 当
swrtype非 1/2 时打印错误并调用abort_physic。
核心流程
1. 太阳入射通量和修正太阳角
行 111-122 对每列计算:
ZFACT = PRMU0 * PCST * PFRACT
ZRMU = sqrt(1224*PRMU0^2 + 1) / 35 if PRMU0 > 0
= 1/35 otherwise
ZSEC = 1/ZRMU
ZFACT 是把 solver 返回的归一化 flux 转成物理 W/m2 的列因子,含太阳天顶角、当前太阳常数和日照分数。ZRMU 是大太阳天顶角修正后的有效余弦,传给短波 solver。
2. Sigma 层厚
行 126-138 用界面压力构造 ZDSIG。从地表 ZSIGO=1 开始,对 JK=1:nlaylte:
ZSIGN = PPLEV(JK+1) / PPLEV(1)
ZDSIG(JK) = ZSIGO - ZSIGN
ZSIGO = ZSIGN
这把压力层厚转换成相对地表压力的 sigma 厚度,供 Fouquart/Toon solver 分配层光学量。
3. 两个太阳谱段 solver
行 147-173 对 INU=1,2 循环。源码注释说明两个太阳谱段分别是 long1vis-long2vis 和 long2vis-long3vis,具体边界在 dimradmars_mod 中定义。
swrtype=1调SWR_FOUQUART。swrtype=2调SWR_TOON。- 其他值 abort。
两个 solver 都返回归一化 ZFD/ZFU。SWMAIN 随后把每个界面的归一化 flux 乘 ZFACT,写入 PFLUXD/PFLUXU(:,:,INU)。
4. 谱段合计和短波加热率
行 179-185 先把两个谱段相加:
ZFUP = PFLUXU(:,:,1) + PFLUXU(:,:,2)
ZFDOWN = PFLUXD(:,:,1) + PFLUXD(:,:,2)
行 187-193 计算每层净通量散度:
ZDFNET = ZFUP(JK) - ZFDOWN(JK) - ZFUP(JK+1) + ZFDOWN(JK+1)
PHEAT = gcp * ZDFNET / PDP(JK)
这把 W/m2 的界面净通量差转为 K/s。符号按源码:层顶/层底上下行组合决定正加热或冷却。
伪代码
SWMAIN:
for each column:
ZFACT = mu0 * solar_constant * daylight_fraction
ZRMU = high-zenith corrected solar angle cosine
ZSEC = 1 / ZRMU
build sigma layer thickness ZDSIG from pressure interfaces for 1:nlaylte
for INU in [1, 2]:
if swrtype == 1:
call SWR_FOUQUART(..., INU, aerosol, VIS optical properties, albedo, ZDSIG, ZRMU, ZSEC, ZFD, ZFU)
else if swrtype == 2:
call SWR_TOON(... same role ...)
else:
abort
PFLUXD(:,:,INU) = ZFD * ZFACT
PFLUXU(:,:,INU) = ZFU * ZFACT
for each interface:
ZFDOWN = sum downward flux over two bands
ZFUP = sum upward flux over two bands
for each LTE layer:
PHEAT = (g/cpp) * net_flux_divergence / layer_pressure_thickness
参与的主题流程
| 主题 | 参与方式 |
|---|---|
| 短波辐射 | 两太阳谱段主调度,输出短波加热率和上下行通量 |
| 气溶胶辐射 | 消费 aerosol、QVISsQREF3d、omegaVIS3d、gVIS3d,由下游 solver 合成层散射参数 |
| Rayleigh 散射 | 本文件不直接读 rayleigh,但 SWR_FOUQUART/SWR_TOON 会在各自内部按开关调用 swrayleigh |
| LTE/NLTE 边界 | 仅循环 nlaylte 层;高层短波倾向由 callradite 置零,后续由其他 NIR/NLTE 路径处理 |
| 地表能量收支 | 输出地表界面的上下行短波通量,供 physiq 的地表能量路径使用 |
写法特点
- 固定格式 Fortran,例程名大写;
INTENT大小写不一致但语义明确。 KFLEV是接口层维度,但主要物理循环受nlaylte控制。- solver 输出是归一化通量;本文件统一乘
ZFACT后才成为物理通量。 ZRMU对夜侧也给出1/35,但夜侧ZFACT=0,所以实际 flux 为零。
复现要点
PCST必须已经由callradite按日火距离缩放;SWMAIN不再处理dist_sol。PFLUXD/PFLUXU第三维固定为两个太阳谱段,计算加热率时必须先对两个谱段求和。swrtype必须与尘埃场景处理保持一致;例如read_dust_scenario_mod中对旧 Fouquart 路径有swrtype==1修正。ZDSIG从压力界面按地表压力归一化,不是直接用PDP;PDP只在最终加热率分母出现。- 比较 Fouquart 和 Toon 结果时,应同时固定
rayleigh、albedo、aerosol光学表和mu0/fract。
待确认
ZDSIG循环中JKL=nlaylte+1-JK被赋值但未使用,可能是历史层序翻转遗留变量。KFLEV传入两个 solver,但本文件内部通量和加热率循环使用nlaylte;KFLEV/nflev/nlaylte的越界安全依赖上游维度配置。SWR_FOUQUART和SWR_TOON细节分别在已有页面说明;细节见对应页面其内部多层递推或 two-stream 线性系统。
相关页面
- callradite_mod - 唯一直接调用方。
- swr_fouquart -
swrtype=1短波 solver。 - swr_toon -
swrtype=2短波 solver。 - swrayleigh - Rayleigh 光学厚度辅助。
- dimradmars_mod - 太阳谱段、维度和气溶胶数量。
- yomlw_h -
gcp和nlaylte。 - callkeys_mod -
swrtype、rayleigh等辐射开关。 - radiation