12 KiB
12 KiB
TLUSTY208.F 拆分工作 (2026-03-18)
任务:将单文件拆分为多个独立模块
执行流程:
cd /home/fmq/program/tlusty/tl208-s54/rust
python3 extract_fortran.py tlusty/tlusty208.f tlusty/extracted/
cp tlusty/*.FOR tlusty/extracted/
提取结果
| 项目 | 数量 |
|---|---|
| 程序单元 | 304 |
| 子程序 (SUBROUTINE) | 269 |
| 函数 (FUNCTION) | 32 |
| 主程序 (PROGRAM) | 1 |
| BLOCK DATA | 2 (含1个无名) |
| 无 COMMON 依赖的纯函数 | 195 |
注意: 2026-03-19 修复了无名 BLOCK DATA 提取问题,单元数从 303 增加到 304
Include 文件
tlusty/extracted/*.FOR
├── IMPLIC.FOR # 隐式类型声明
├── BASICS.FOR # 基本参数和物理常数
├── ITERAT.FOR # 迭代控制参数
├── ALIPAR.FOR # ALI 参数
├── ATOMIC.FOR # 原子数据
├── MODELQ.FOR # 模型物理量
├── ODFPAR.FOR # ODF 参数
└── ARRAY1.FOR # 主工作数组
编译配置
关键编译选项:
FFLAGS = -O3 -fno-automatic -mcmodel=large
-mcmodel=large: 支持 >2GB 地址空间-fno-automatic: 所有变量默认为静态存储(兼容旧Fortran代码)- 不要使用
-ffixed-line-length-none: 会将第73-80列的注释区当作代码解析
编译验证
cd tlusty/extracted && make clean && make
# 生成: tlusty_extracted (1,940,488 bytes)
# 直接编译
gfortran -fno-automatic -mcmodel=large -O3 -o tlusty.exe tlusty208.f
# 生成: tlusty.exe (1,997,416 bytes)
结论: 功能等价,拆分编译文件更小 (-2.9%)
拆分编译 vs 直接编译对比
| 方面 | 直接编译 | 拆分编译 |
|---|---|---|
| 文件大小 | 1,997,416 B | 1,940,488 B |
| 功能 | 相同 | 相同 |
| 增量编译 | ❌ | ✅ |
| 代码定位 | 困难 | 简单 |
无 COMMON 依赖的纯函数 (198个)
可独立测试和重构的单元:
ACCEL2, ALIFR1, ALIFR3, ALIFR6, ALIFRK, ALISK1, ALISK2, ALIST1, ALIST2,
ANGSET, BETAH, BHE, BKHSGO, BPOP, BPOPE, BPOPF, BPOPT, BRE, BREZ,
BRTE, BRTEZ, BUTLER, CARBON, CEH12, CHANGE, CHCKSE, CHEAV, CHEAVJ,
CIA_H2H, CIA_H2H2, CIA_H2HE, CIA_HHE, CION, CKOEST, COLH, COLHE,
COLLHE, CONCOR, CORRWM, CROSS, CROSSD, CSPEC, DIELRC, DIETOT, DIVSTR,
DMEVAL, DOPGAM, DWNFR, DWNFR0, DWNFR1, EINT, EMAT, ENTENE, ERFCIN,
ERFCX, EXPINT, EXPINX, EXPO, FFCROS, GAMI, GAMSP, GAULEG, GAUNT,
GETWRD, GFREE0, GFREE1, GFREED, GNTK, GRCOR, GREYD, GRIDP, H2MINUS,
HEPHOT, HIDALG, IJALI2, IJALIS, INCLDY, INDEXX, INIFRS, INILAM, INTERP,
INTHYD, INTLEM, INTXEN, IRC, LAGRAN, LAGUER, LEMINI, LEVGRP, LEVSET,
LEVSOL, LINEQS, LINSEL, LINSET, LINSPL, LOCATE, LTEGR, LUCY, LYMLIN,
MATGEN, MATINV, MEANOP, MEANOPT, MINV3, NEWPOP, NSTOUT, ODF1, ODFFR,
ODFHST, ODFHYD, ODFHYS, ODFMER, OPACFL, OPADD0, OPAHST, OPAINI, OPCTAB,
OSCCOR, OUTPUT, PFCNO, PFFE, PFHEAV, PFNI, PFSPEC, PRCHAN, PRD, PRDINI,
PRINC, PRNT, PROFSP, PSOLVE, PZERT, QUARTC, QUIT, RADPRE, RAPH, RATES1,
RATMAL, RATMAT, RATSP1, RAYINI, RAYSET, RDATAX, READBF, RECHCK, REFLEV,
REIMAN, RHOEOS, RHONEN, ROSSOP, ROSSTD, RTEDF2, RTEFE2, RTESOL, RTE_SC,
SABOLF, SBFCH, SBFHE1, SBFHMI, SBFHMI_OLD, SBFOH, SFFHMI, SFFHMI_ADD,
SGHE12, SGMER0, SGMER1, SGMERD, SIGAVE, SIGK, SIGMAR, SPSIGK, SRTFRQ,
STARK0, STARKA, SWITCH, SZIRC, TDPINI, TIMING, TIOPF, TLUSTY, TRAINI,
TRIDAG, UBETA, VERN16, VERN18, VERN20, VERN26, VERNER, VISINI, VOIGT,
VOIGTE, WN, WNSTOR, XENINI, XK2DOP, YINT, YLINTP, ZMRHO
SYNSPEC54.F 拆分工作 (2026-03-18)
任务:将单文件拆分为多个独立模块
执行流程:
1. 创建提取脚本 extract_fortran.py
# 核心功能:
# - 正则匹配 SUBROUTINE/FUNCTION/PROGRAM/BLOCK DATA
# - 查找对应的 END 语句确定边界
# - 提取到独立 .f 文件
# - 分析 COMMON 块依赖
# - 生成 Makefile
2. 运行提取
cd /home/fmq/program/tlusty/tl208-s54/rust
python3 extract_fortran.py synspec/synspec54.f synspec/extracted/
cp synspec/*.FOR synspec/extracted/
3. 提取结果
| 项目 | 数量 |
|---|---|
| 程序单元 | 168 |
| 子程序 (SUBROUTINE) | 134 |
| 函数 (FUNCTION) | 33 |
| 主程序 (PROGRAM) | 1 |
| 总代码行数 | 23,050 |
| 无 COMMON 依赖的纯函数 | 93 |
4. 编译配置
关键编译选项 (解决大型 COMMON 数组链接问题):
FFLAGS = -O3 -fno-automatic -mcmodel=large
-mcmodel=large: 支持 >2GB 地址空间-fno-automatic: 所有变量默认为静态存储(兼容旧Fortran代码)- 不要使用
-ffixed-line-length-none: 会将第73-80列的注释区当作代码解析
5. 编译验证
cd synspec/extracted && make clean && make
# 生成: synspec_extracted (1,000,408 bytes)
对比原始编译:
gfortran -O3 -fno-automatic -mcmodel=large -o synspec_direct.exe synspec54.f
# 生成: synspec_direct.exe (1,044,928 bytes)
结论: 功能完全等价,拆分编译更小 (-4.3%)
生成的文件结构
synspec/extracted/
├── synspec.f # 主程序 (174行)
├── start.f # 子程序 (107行)
├── sbfhmi.f # H⁻ 光电离截面函数 (42行)
├── expint.f # 指数积分函数 (18行)
├── ... # 共168个 .f 文件
├── PARAMS.FOR # 参数定义 (include)
├── MODELP.FOR # 模型参数 (include)
├── LINDAT.FOR # 谱线数据 (include)
├── SYNTHP.FOR # 合成谱参数 (include)
├── WINCOM.FOR # 窗口通信 (include)
├── Makefile # 自动构建
├── _SUMMARY.txt # 提取摘要
├── _COMMON_ANALYSIS.txt # COMMON 依赖分析
└── _PURE_UNITS.txt # 纯函数列表
COMMON 块分析结果
有 COMMON 依赖的单元: 75 个 唯一 COMMON 块: 68 个
主要 COMMON 块:
BLAPAR,LIMPAR- 谱线参数EMFLUX- 辐射流RTEOPA- 辐射转移不透明度NLTPOP- 非LTE布居数lasers- 激光数据处理
拆分编译 vs 直接编译对比
| 方面 | 直接编译 | 拆分编译 |
|---|---|---|
| 文件大小 | 1,044,928 B | 1,000,408 B |
| 功能 | 相同 | 相同 |
| 增量编译 | ❌ | ✅ |
| 代码定位 | 困难 | 简单 |
| 模块化重构 | 困难 | 容易 |
提取脚本位置
extract_fortran.py
推荐用法
# 开发/调试/重构
cd synspec/extracted && make
# 生产环境/快速编译
cd synspec && gfortran -O3 -fno-automatic -mcmodel=large -o synspec.exe synspec54.f
无 COMMON 依赖的纯函数 (93个)
可独立测试和重构的函数:
CARBON, CHANGE, CHCKAB, CIA_H2H, CIA_H2H2, CIA_H2HE, CIA_HHE,
COUNT_WORDS, DENSIT, DIVHE2, DIVSTR, DWNFR0, DWNFR1, EPS,
EXOPF, EXPINT, EXTPRF, FEAUTR, GAMHE, GAUNT, GETWRD, GFREE,
GNTK, GRIEM, H2MINUS, H2OPF, HE2SET, HE2SEW, HEPHOT, HESET,
HIDALG, HYDINI, HYDTAB, HYLSET, HYLSEW, INIBLM, INKUR, INPBF,
INTERP, INTHYD, INTRP, INTXEN, IRWPF, ISPEC, LEVSOL, LINEQS,
LOCATE, LYMLIN, MATINV, MOLOP, MPARTF, OPADD, PARTDV, PARTF,
PFFE, PFHEAV, PFNI, PFSPEC, PHTX, QUIT, RATMAT, READBF,
REIMAN, SABOLF, SBFCH, SBFHE1, SBFHMI, SBFHMI_OLD, SBFOH,
SETRAY, SFFHMI, SFFHMI_OLD, SGHE12, SGMERG, SPSIGK, STARK0,
STARKA, STARKIR, STATE0, SYNSPEC, TINT, TRIDAG, VELSET,
VOIGTE, VOPF, WGTJH1, WN, WNSTOR, WTOT, XENINI, XK2DOP, YINT, YLINTP
功能验证测试 (2026-03-19)
测试环境变量
export TL208=/home/fmq/program/tlusty
export TLUSTY=$TL208/tl208-s54
export LINELIST=$TL208/linelist
export IRON=$TL208/irondata
export OPTABLES=$TL208/optables
测试目录
tests/tlusty/hhe/ # H-He 模型测试用例
├── hhe35lt.5 # LTE 模型输入
├── hhe35nc.5 # NLTE continua 模型输入
├── hhe35nl.5 # NLTE with lines 模型输入
└── hhe35*.7,9,14 # 预期输出文件
测试流程
cd /home/fmq/program/tlusty/tl208-s54/rust/tests/tlusty
# 创建测试目录
mkdir -p test_extracted
cd test_extracted
cp ../hhe/*.5 .
ln -sf $TLUSTY/data data
# 设置环境变量
export TL208=/home/fmq/program/tlusty
export TLUSTY=$TL208/tl208-s54
export LINELIST=$TL208/linelist
export IRON=$TL208/irondata
export OPTABLES=$TL208/optables
# 可执行文件路径
EXE=../../tlusty/extracted/build/tlusty_extracted
# 测试1: LTE 模型 (从零开始)
$EXE < hhe35lt.5 > hhe35lt.6
cp fort.7 hhe35lt.7; cp fort.9 hhe35lt.9; cp fort.14 hhe35lt.14
# 测试2: NLTE continua (使用 LTE 作为初始模型)
cp hhe35lt.7 fort.8
$EXE < hhe35nc.5 > hhe35nc.6
cp fort.7 hhe35nc.7; cp fort.9 hhe35nc.9; cp fort.14 hhe35nc.14
# 测试3: NLTE with lines (使用 NC 作为初始模型)
cp hhe35nc.7 fort.8
$EXE < hhe35nl.5 > hhe35nl.6
cp fort.7 hhe35nl.7; cp fort.9 hhe35nl.9; cp fort.14 hhe35nl.14
# 验证: 与原始结果比较
diff hhe35lt.7 ../hhe/hhe35lt.7
diff hhe35nc.7 ../hhe/hhe35nc.7
diff hhe35nl.7 ../hhe/hhe35nl.7
测试结果
| 测试用例 | 拆分编译 | 直接编译 | 原始结果 |
|---|---|---|---|
| hhe35lt (LTE) | ✓ 通过 | ✓ 通过 | ✓ 相同 |
| hhe35nc (NLTE continua) | ✓ 通过 | ✓ 通过 | ✓ 相同 |
| hhe35nl (NLTE lines) | ✓ 通过 | ✓ 通过 | ✓ 相同 |
MD5 校验和 (hhe35nl.7):
01f3169947ca24bf1c989619b83ae8f2
结论: 拆分编译与直接编译输出完全相同,功能验证通过
SYNSPEC54 功能验证测试 (2026-03-19)
测试目录
tests/synspec/hhe/
├── hhe35nl.5 # 输入文件
├── hhe35nl.7 # 模型大气 (来自 TLUSTY 测试)
├── fort.55.con # 附加输入文件
├── data # 数据目录路径文件 (内容: $TLUSTY/data)
└── results/ # 预期输出
├── hhe35nl.spec # 合成光谱
├── hhe35nl.cont # 连续谱
└── hhe35nl.iden # 谱线标识
测试流程
cd /home/fmq/program/tlusty/tl208-s54/rust/tests/synspec/hhe
# 设置环境变量
export TL208=/home/fmq/program/tlusty
export TLUSTY=$TL208/tl208-s54
export LINELIST=$TL208/linelist
export IRON=$TL208/irondata
export OPTABLES=$TL208/optables
# 准备输入文件
cp hhe35nl.7 fort.8
ln -sf fort.55.con fort.55
ln -sf $TLUSTY/data/gfATO.dat fort.19
# 关键: data 必须是符号链接指向数据目录
rm -f data
ln -sf $TLUSTY/data data
# 可执行文件路径
EXE_ORIG=$TLUSTY/synspec/synspec.exe
EXE_DIRECT=../../synspec/synspec_direct.exe
EXE_EXTRACTED=../../synspec/extracted/build/synspec_extracted
# 测试原始版本
$EXE_ORIG < hhe35nl.5 > hhe35nl_orig.log
cp fort.7 hhe35nl_orig.spec; cp fort.17 hhe35nl_orig.cont
# 测试直接编译版本
rm -f fort.7 fort.17 fort.12
$EXE_DIRECT < hhe35nl.5 > hhe35nl_direct.log
cp fort.7 hhe35nl_direct.spec; cp fort.17 hhe35nl_direct.cont
# 测试拆分编译版本
rm -f fort.7 fort.17 fort.12
$EXE_EXTRACTED < hhe35nl.5 > hhe35nl_extracted.log
cp fort.7 hhe35nl_extracted.spec; cp fort.17 hhe35nl_extracted.cont
# 验证
diff hhe35nl_orig.spec hhe35nl_direct.spec
diff hhe35nl_orig.spec hhe35nl_extracted.spec
# 恢复 data 文件
rm -f data
echo "/home/fmq/program/tlusty/tl208-s54/data" > data
测试结果
| 测试用例 | 原始程序 | 直接编译 | 拆分编译 |
|---|---|---|---|
| hhe35nl (NLTE lines) | ✓ 通过 | ✓ 通过 | ✓ 相同 |
MD5 校验和 (hhe35nl.spec):
7925533b21b16d6bcdfff40e626cab83
注意事项:
data文件/符号链接必须正确设置,否则报错Cannot open file './data/h1.dat': Not a directory- 拆分编译程序与原始程序输出完全相同,功能验证通过