SpectraRust/.claude/skills/fortran-analyzer/references/sp_fortran.md

12 KiB
Raw Blame History


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
  • 拆分编译程序与原始程序输出完全相同,功能验证通过