SpectraRust/.learnings/LEARNINGS.md
2026-03-22 00:30:20 +08:00

447 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Learnings
Corrections, insights, and knowledge gaps captured during development.
**Categories**: correction | insight | knowledge_gap | best_practice
**Areas**: frontend | backend | infra | tests | docs | config
**Statuses**: pending | in_progress | resolved | wont_fix | promoted | promoted_to_skill
## Status Definitions
| Status | Meaning |
|--------|---------|
| `pending` | Not yet addressed |
| `in_progress` | Actively being worked on |
| `resolved` | Issue fixed or knowledge integrated |
| `wont_fix` | Decided not to address (reason in Resolution) |
| `promoted` | Elevated to CLAUDE.md, AGENTS.md, or copilot-instructions.md |
| `promoted_to_skill` | Extracted as a reusable skill |
---
## [LRN-20260321-F01] correction
**Logged**: 2026-03-21T19:55:00Z
**Priority**: high
**Status**: resolved
**Area**: backend
### Summary
Fortran 1-indexed 转 Rust 0-indexed 的关键规则
### Details
- 数组访问: `arr(i)``arr[i-1]`
- 循环范围: `DO I=1,N``for i in 0..n`
- 边界条件: Fortran jl=0 表示"在第一个有效索引之前"Rust jl=0 就是第一个有效索引
### Suggested Action
重构时删除类似 `IF (J.EQ.0) J = J+1` 的调整逻辑
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: ylintp.f, locate.f
- Tags: indexing, fortran, rust
---
## [LRN-20260321-F02] correction
**Logged**: 2026-03-21T19:55:00Z
**Priority**: high
**Status**: resolved
**Area**: backend
### Summary
Fortran 表达式 `-LOG(X)``-(LOG(X))`,不是 `LOG(-X)`
### Details
`XL=-LOG(X)` 应翻译为 `let xl = -x.ln()`,不是 `let xl = (-x).ln()`
后者对 x>0 会返回 NaN
### Suggested Action
翻译数学表达式时注意运算符优先级
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: erfcin.f
- Tags: expression, fortran, rust
---
## [LRN-20260321-F03] insight
**Logged**: 2026-03-21T19:55:00Z
**Priority**: medium
**Status**: resolved
**Area**: backend
### Summary
`(z1 - z2).powi(2)` 编译错误 - 类型推断失败
### Details
编译器无法推断中间表达式的类型,使用显式乘法 `(z1 - z2) * (z1 - z2)` 代替
### Metadata
- Source: fortran-to-rust refactoring
- Tags: rust, type_inference, powi
---
## [LRN-20260321-F04] best_practice
**Logged**: 2026-03-21T19:55:00Z
**Priority**: medium
**Status**: resolved
**Area**: tests
### Summary
多项式近似精度容差:简单函数 1e-10多项式 1e-7
### Details
Abramowitz-Stegun 多项式近似本身精度有限
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: eint.f
- Tags: precision, polynomial, testing
---
## [LRN-20260321-F05] correction
**Logged**: 2026-03-21T19:55:00Z
**Priority**: high
**Status**: resolved
**Area**: backend
### Summary
递减循环变量用 isize 不用 usize避免溢出
### Details
当循环变量递减到负数时,无符号整数会溢出
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: collhe.f
- Tags: overflow, rust, loop
---
## [LRN-20260321-F06] best_practice
**Logged**: 2026-03-21T19:55:00Z
**Priority**: high
**Status**: resolved
**Area**: backend
### Summary
重构前必须检查所有 INCLUDE 语句,不仅是 IMPLIC.FOR
### Details
已确认有 COMMON 依赖的"纯函数"文件:
gamsp.f, sgmer1.f, sgmerd.f, cross.f, gfree0.f, gfreed.f, gfree1.f, wn.f, crossd.f, dopgam.f, verner.f, sbfhe1.f
### Suggested Action
添加新结构体前先 grep 检查是否已存在
### Metadata
- Source: fortran-to-rust refactoring
- Tags: common, fortran, dependency
---
## [LRN-20260321-F07] correction
**Logged**: 2026-03-21T19:55:00Z
**Priority**: high
**Status**: resolved
**Area**: tests
### Summary
测试数组值不能全部相同,会导致除零
### Details
```rust
// 错误:全部相同 → ddm = 0 → dtm = 1/0 = inf
let dm = vec![0.01; MDEPTH];
// 正确:递增模拟物理分布
let dm: Vec<f64> = (0..MDEPTH).map(|i| 0.01 + i as f64 * 0.01).collect();
```
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: rybmat.rs
- Tags: testing, data_design
---
## [LRN-20260321-F08] insight
**Logged**: 2026-03-21T19:55:00Z
**Priority**: medium
**Status**: resolved
**Area**: backend
### Summary
Fortran 修改 COMMON 块数组 → Rust 需要 &mut 引用
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: tabint.f
- Tags: rust, mutability, reference
---
## [LRN-20260321-F09] correction
**Logged**: 2026-03-21T19:55:00Z
**Priority**: high
**Status**: resolved
**Area**: config
### Summary
analyze_fortran.py 只匹配 CALL 语句,漏掉 FUNCTION 调用
### Details
需要两遍扫描1) 收集所有已定义函数名 2) 只匹配已知函数名
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: scripts/analyze_fortran.py
- Tags: dependency, analysis, python
---
## [LRN-20260321-F10] correction
**Logged**: 2026-03-21T19:55:00Z
**Priority**: high
**Status**: resolved
**Area**: tests
### Summary
测试参数设置时避免矩阵列重叠
### Details
主循环更新列和温度/密度列可能重叠,设置 inre=0, inpc=0 避免重叠
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: bpopf.rs
- Tags: testing, matrix, indexing
---
## [LRN-20260321-F11] correction
**Logged**: 2026-03-21T19:55:00Z
**Priority**: high
**Status**: resolved
**Area**: backend
### Summary
公式中 `1/x``x` 的顺序要仔细核对
### Details
`5.484e-14 / x2 * (...)` 其中 x2=1/x²等于乘以 x²不是除以
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: rayleig.f
- Tags: formula, rust, physics
---
## [LRN-20260321-F12] best_practice
**Logged**: 2026-03-21T19:55:00Z
**Priority**: medium
**Status**: resolved
**Area**: backend
### Summary
大型 COMMON 块函数使用生命周期结构体
### Details
```rust
pub struct Alifr3ModelState<'a> {
pub elec: &'a [f64], // 输入
pub heit: &'a mut [f64], // 输出
}
```
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: alifr3.rs, alifr6.rs
- Tags: rust, struct, lifetime
---
## [LRN-20260321-F13] insight
**Logged**: 2026-03-21T19:55:00Z
**Priority**: medium
**Status**: resolved
**Area**: backend
### Summary
Fortran GOTO 分支 → Rust if-else + early return
### Details
每个 GOTO 标签对应一个 if 块
### Metadata
- Source: fortran-to-rust refactoring
- Tags: fortran, goto, control_flow
---
## [LRN-20260321-F14] correction
**Logged**: 2026-03-21T19:55:00Z
**Priority**: medium
**Status**: resolved
**Area**: backend
### Summary
循环中重新赋值的变量必须声明为 mut
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: alifr6.rs
- Tags: rust, mutability
---
## [LRN-20260321-F15] correction
**Logged**: 2026-03-21T12:00:00Z
**Priority**: high
**Status**: resolved
**Area**: backend
### Summary
Fortran 3D 数组转 Rust 扁平数组时,必须知道所有维度才能正确计算索引
### Details
Fortran `absopac(jt,jr,jf)` 是 3D 数组 (numtemp × numrh × nfreq),转 Rust 扁平数组时:
- **错误**: 用 `jt_idx * numtemp * nfreq` (用了 numtemp 作为第二维度)
- **正确**: 用 `jt_idx * max_numrh * nfreq` (必须用实际维度 max_numrh)
类似地2D 数组 `rhomat(jt,jr)` 转扁平时:
- **错误**: `rhomat[jt_idx * numtemp]`
- **正确**: `rhomat[jt_idx * max_numrh]`
### Suggested Action
重构多维数组时,结构体必须包含所有维度信息,特别是可能变化的维度(如每个温度有不同的密度数)
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: opctab.rs, opctab.f
- Tags: array, indexing, fortran, rust, multi-dimensional
---
## [LRN-20260321-F16] correction
**Logged**: 2026-03-21T12:00:00Z
**Priority**: high
**Status**: resolved
**Area**: backend
### Summary
Fortran 条件 `if(a.eq.b)` 转 Rust 时不要误用其他变量
### Details
Fortran `if(numtemp.eq.nd)` 检查表温度数是否等于总深度数:
- **错误**: `if table.numtemp == params.id` (用了当前深度索引)
- **正确**: `if table.numtemp == table.nd` (用总深度数)
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: opctab.rs, opctab.f
- Tags: condition, variable, fortran, rust
---
## [LRN-20260321-F17] correction
**Logged**: 2026-03-21T12:00:00Z
**Priority**: high
**Status**: resolved
**Area**: backend
### Summary
分支条件相同代码是 bug必须对照 Fortran 完整实现
### Details
`if params.ibc == 0 { ... } else { ... }` 两个分支代码完全相同时是错误的。
Fortran 原代码 ELSE 分支有额外项:
```fortran
REIT(ID)=REIT(ID)+WW*(D0*(DSFT1-DBDT)+E0*DABT1(ID)+
* RAD1(ID)*DABT1(ID)-DEMT1(ID)+
* ALI1(ID)/ABST*DBDT)
```
变量 `DBDT``E0` 在边界条件块中计算,需要在更大作用域中声明才能在积分方程块中使用。
### Suggested Action
重构时如果看到 if-else 分支代码相同,立即检查 Fortran 原代码
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: alifr1.rs, alifr1.f
- Tags: branch, bug, fortran, rust
---
## [LRN-20260321-F18] best_practice
**Logged**: 2026-03-21T12:00:00Z
**Priority**: medium
**Status**: resolved
**Area**: docs
### Summary
模块文档应完整描述所有功能,不仅是主要功能
### Details
opctab.rs 原文档只提到"插值计算",漏掉了:
- Rayleigh 散射计算(简单公式或调用 rayleigh 函数)
- 电子散射计算
### Suggested Action
重构完成后对照 Fortran 原代码检查文档是否完整
### Metadata
- Source: fortran-to-rust refactoring
- Related Files: opctab.rs, opctab.f
- Tags: documentation, completeness
---
## Quick Reference - Refactoring Checklist
重构新函数前检查:
- [ ] 是否有 INCLUDE 语句 (除 IMPLIC.FOR 外)
- [ ] 是否使用 COMMON 块
- [ ] COMMON 块结构体是否已存在于其他模块
- [ ] 是否有文件 I/O (OPEN, READ, WRITE)
- [ ] 数组索引是否需要 -1 调整
- [ ] 循环变量是否可能变负 (用 isize/i32)
- [ ] 多项式近似精度是否需要放宽
- [ ] 是否有嵌套 IF 分支遗漏
- [ ] 矩阵列索引是否可能与温度/密度列重叠
- [ ] 公式中 `1/x``x` 的顺序是否正确
- [ ] 大型 COMMON 块函数是否需要创建综合输入结构体
- [ ] 多分支 GOTO 是否正确转换为 if-else
- [ ] 循环中重新赋值的变量是否声明为 mut
- [ ] 多维数组扁平化时是否使用了正确的维度(不是第一个维度)
- [ ] 条件语句中的变量是否与 Fortran 原代码一致
- [ ] 模块文档是否描述了所有功能(包括次要功能)
- [ ] if-else 分支代码是否完全相同(相同则是 bug
- [ ] 边界条件块中计算的变量是否在积分方程块中可用(作用域问题)