Phase 1 翻译 (完成): - TLUSTY 350 函数 100% 翻译 - SYNSPEC 168 函数 100% 翻译 - ~495 Rust 模块 Phase 2 集成 (完成): - TLUSTY RESOLV 7 个 TODO 全部清除 - TLUSTY Runner IJALI 频率选择实现 - OPFRAC ioniz.dat 解析完整实现 - SYNSPEC Runner 编排流程连接完成 - SYNSPEC RESOLV OPAC→RTE→OUTPRI 调用链完整 Phase 3 验证 (完成, 修复 8 处 bug): - INITIA: compute_hydrogen_level_bounds 索引混合修复 - INILIN: GAMR0/GS0/GW0 展宽公式修复, 经典 VdW 公式修复 - INIBL0: CNM 常数 2.997925e18→e17 修复 - OPAC: Lyman IJ=2 修正缺失修复 - RTE: minv3 矩阵求逆符号错误修复 自动化脚本改进: - specf2r.sh: 添加 429 限流退避、完成检测、同步等待 - SKILL.md: 三阶段工作流 + 状态文件系统 - references/: Phase 1/2/3 独立参考文档 新增: - src/bin/synspec.rs: SYNSPEC 可执行文件入口 - .f2r_phase/.f2r_tasks/.f2r_complete: 状态管理文件 编译: 0 错误 | Clippy: 0 错误 | 测试: voigt 28 + eldens 5 通过 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.9 KiB
6.9 KiB
Phase 3: 验证工作流参考
状态:待启动(Phase 2 集成完成后进入) 模式:参照
tlusty-iterationskill 的逐模块严格验证流程
文件路径
| 内容 | 路径 |
|---|---|
| Fortran 源码 | tlusty/extracted/*.f、synspec/extracted/*.f |
| Rust 源码 | src/tlusty/、src/synspec/ |
| 验证进度 | .claude/skills/codegraph-guide/references/verify-progress.md |
| TLUSTY Fortran 测试 | $TLUSTY/tests/tlusty/hhe/ |
| SYNSPEC Fortran 测试 | $TLUSTY/tests/synspec/hhe/ |
| TLUSTY Rust 测试 | tests/tlusty/hhe_rust/ |
| SYNSPEC Rust 测试 | tests/synspec/hhe/ |
测试方式
TLUSTY 端到端
# Fortran 参考
cd $TLUSTY/tests/tlusty/hhe
$TLUSTY/tlusty/tlusty.exe < hhe35lt.5 > hhe35lt.6
cp fort.7 hhe35lt.7.ref
# Rust
cargo build --bin tlusty
cd tests/tlusty/hhe_rust
rm -f fort.7
../../../target/debug/tlusty < hhe35lt.5 > rust.6 2>stderr.txt
# 对比
diff hhe35lt.7.ref fort.7
SYNSPEC 端到端
# 准备(测试目录 tests/synspec/hhe/ 已有 fort.8、fort.55.con 等文件)
cd tests/synspec/hhe
cp hhe35nl.7 fort.8
ln -sf fort.55.con fort.55
# Fortran 参考(生成 results_original/ 中的 .spec/.cont/.iden)
# 需要先编译:gfortran -O3 -fno-automatic -mcmodel=large -o synspec.exe synspec54.f
./synspec.exe < hhe35nl.5
# Rust
cargo build --bin synspec
cd tests/synspec/hhe
rm -f fort.7
../../../target/debug/synspec < hhe35nl.5 > rust.6 2>stderr.txt
# 对比(与 Fortran 参考结果比对)
diff results_original/hhe35nl.spec fort.7
验证工作流(严格遵守)
每次会话:
1. 读取 verify-progress.md → 恢复验证进度
2. 运行 Rust → 与 Fortran 参考输出对比
3. 输出完全一致 → 更新 verify-progress.md → 结束
4. 输出不一致 → 从断点继续逐模块验证:
a. 读取 verify-progress.md 中 "下一个待验证模块"
b. ★ 必须先读取对应的 Fortran 文件,逐行理解原始逻辑
c. 然后读取对应的 Rust 文件
d. 逐行对比: 调用顺序、变量映射、索引转换、逻辑分支
e. 发现差异 → 立即修复 → cargo build 验证
f. 更新 verify-progress.md → 继续下一个模块
5. 全部通过 → 运行测试套件 → 更新 verify-progress.md
★ 核心原则:必须参考 Fortran 代码
严禁凭猜测修改代码!每次修改前必须:
1. 先读取对应的 Fortran 源码文件
2. 理解 Fortran 的确切逻辑流程
3. 找到 Fortran 中的对应行
4. 然后对照修改 Rust 代码
违反此原则是产生 bug 的最主要原因。
验证顺序
TLUSTY 调用链
TLUSTY (tlusty.f)
→ START (start.f)
→ INITIA (initia.f) ★ 最大模块
→ HEDIF (hedif.f) [可选]
→ COMSET (comset.f)
→ PRDINI (prdini.f)
→ RESOLV (resolv.f)
→ INILAM, LINSEL, OPAINI ...
→ OPACF0, OPACF1, RTEFR1 ...
→ LUCY (lucy.f)
→ OUTPUT
→ ACCEL2 (accel2.f)
→ SOLVE / SOLVES / RYBSOL
→ MATGEN → BRTE, BHE, BRE
→ MATINV
SYNSPEC 调用链
SYNSPEC (synspec54.f)
→ START
→ INITIA → STATE0, RDATA
→ INPMOD / INKUR
→ TINT, INIMOD
→ INILIN → read_line_list
→ INIBL0 / INIBL1
→ RESOLV
→ INILAM, HYLSET, HE2SET
→ INIBLA, INIBLM
→ OPAC → HYDLIN, LINOP, ...
→ RTE / RTECD
→ OUTPRI
模块文件映射
TLUSTY
| Fortran 模块 | Fortran 文件 | Rust 文件 | 子目录 |
|---|---|---|---|
| TLUSTY | tlusty.f | src/tlusty/main.rs |
(主程序) |
| START | start.f | src/tlusty/io/start.rs |
io/ |
| INITIA | initia.f | src/tlusty/io/initia.rs |
io/ |
| RESOLV | resolv.f | src/tlusty/io/resolv.rs |
io/ |
| ACCEL2 | accel2.f | src/tlusty/math/ali/accel2.rs |
math/ali/ |
| SOLVE | solve.f | src/tlusty/math/solvers/solve.rs |
math/solvers/ |
特殊映射(多合一 Rust 文件):
bhe.rs← BHE, BHED, BHEZgfree.rs← GFREE0, GFREED, GFREE1interpolate.rs← YINT, LAGRANsgmer.rs← SGMER0, SGMER1, SGMERDctdata.rs← HCTION, HCTRECOMcross.rs← CROSS, CROSSDexpint.rs← EINT, EXPINXerfcx.rs← ERFCX, ERFCIN
math 子目录: ali, atomic, continuum, convection, eos, hydrogen, interpolation, odf, opacity, partition, population, radiative, rates, solvers, special, temperature, utils
SYNSPEC
| Fortran 模块 | Fortran 文件 | Rust 文件 | 子目录 |
|---|---|---|---|
| SYNSPEC | synspec54.f | src/bin/synspec.rs → src/synspec/runner.rs |
bin/ |
| INITIA | initia.f | src/synspec/math/initia_synspec.rs |
math/ |
| INILIN | inilin.f | src/synspec/math/inilin.rs |
math/ |
| RESOLV | resolv.f | src/synspec/math/resolv.rs |
math/ |
| OPAC | opac.f | src/synspec/math/opac.rs |
math/ |
| RTE | rte.f | src/synspec/math/rte.rs |
math/ |
| OUTPRI | outpri.f | src/synspec/math/outpri.rs |
math/ |
检查清单(每个模块必须逐项验证)
[ ] 调用顺序: Fortran CALL 顺序 == Rust 函数顺序
[ ] 变量映射: Fortran COMMON 变量 → 正确的 Rust struct 字段
[ ] 数组下标: 1-based→0-based, Fortran 列主序→Rust 行主序
[ ] 循环边界: DO I=1,N → 0..n, DO I=N,1,-1 → (0..n).rev()
[ ] IF 条件: .AND.→&&, .OR.→||, .EQ.→==, .NE.→!=, 全覆盖
[ ] 赋值完整性: 每个 Fortran 赋值都有对应 Rust 赋值(无遗漏)
[ ] I/O 语句: WRITE/READ/PRINT 对应 Rust 的文件 I/O
[ ] 函数调用: 每个子程序调用参数正确传递
[ ] 回调模式: 回调/closure 必须调用实际函数(不能是空壳 NoOp)
[ ] 数学公式: 常数和计算公式与特殊函数完全一致
[ ] 编译验证: cargo build 无错误
[ ] DATA 语句: 已预提取到 src/data.rs
判断标准
模块检查结果只有三种状态:
通过 — 逐行对比一致,调用完整,无空壳,逻辑相同。通过时立即检查下一个模块
未通过 — 发现具体差异,修复后 cargo build 通过,但输出仍不一致
跳过 — 不需要检查(如纯工具函数,已有充分单元测试覆盖)
修复原则
1. 严格对照 Fortran: 按 Fortran 代码行号逐行对比 Rust 实现
2. 保持调用顺序: Fortran 中的 CALL 顺序必须严格保持
3. 正确映射 COMMON: 使用 Fortran INCLUDE 文件确认变量含义
4. 控制流程等价: IF/DO/SELECT CASE 逻辑必须一致
5. 数组下标转换: Fortran 列主序 1-based → Rust 行主序 0-based
6. 不能用 NoOp 回调: 如果 Fortran 有 CALL,Rust 必须调用实际函数
7. 复杂模块分解: 分步骤修复,每步验证编译
完成标准
- TLUSTY 端到端:
fort.7与 Fortran 参考二进制一致 - SYNSPEC 端到端:
fort.7与 Fortran 参考二进制一致 cargo clippy零错误- 相关模块的单元测试通过(禁止全量测试,内存会被占满)
- 全部通过后创建
.f2r_complete文件