147 lines
5.7 KiB
Markdown
147 lines
5.7 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Fortran stellar atmosphere modeling suite being refactored to Rust. Strategy: **split Fortran into modules first, then incrementally rewrite in Rust**.
|
|
|
|
- **TLUSTY 208**: Non-LTE stellar atmosphere calculator (~50,000 lines → 304 modules)
|
|
- **SYNSPEC 54**: Synthetic spectrum evaluator (~24,000 lines → 168 modules)
|
|
- **Progress**: ~318 Rust modules (290 in `tlusty/math`, 28 in `synspec/math`)
|
|
|
|
## Environment Variables
|
|
|
|
```bash
|
|
export TL208=/home/fmq/program/tlusty
|
|
export TLUSTY=$TL208/tl208-s54
|
|
export LINELIST=$TL208/linelist
|
|
export IRON=$TL208/irondata
|
|
export OPTABLES=$TL208/optables
|
|
```
|
|
|
|
## Build Commands
|
|
|
|
### Rust
|
|
```bash
|
|
cargo build # Debug build
|
|
cargo build --release # Release build
|
|
cargo test # Run all tests (includes Fortran comparison tests)
|
|
cargo test test_expo # Run specific test
|
|
```
|
|
|
|
### Fortran
|
|
```bash
|
|
# Production (single file)
|
|
gfortran -O3 -fno-automatic -mcmodel=large -o tlusty/tlusty.exe tlusty/tlusty208.f
|
|
gfortran -O3 -fno-automatic -mcmodel=large -o synspec/synspec.exe synspec/synspec54.f
|
|
|
|
# Development (modular)
|
|
cd $TLUSTY/rust/tlusty/extracted && make # Output: build/tlusty_extracted
|
|
```
|
|
|
|
**Fortran compile flags:**
|
|
- `-mcmodel=large`: Required for large COMMON blocks (>2GB address space)
|
|
- `-fno-automatic`: Static storage (old Fortran compatibility)
|
|
- **Never use** `-ffixed-line-length-none`: Breaks columns 73-80 handling
|
|
|
|
## Rust Architecture
|
|
|
|
```
|
|
src/
|
|
├── lib.rs # Module exports
|
|
├── tlusty/ # TLUSTY implementation
|
|
│ ├── mod.rs # Module exports + runner
|
|
│ ├── data.rs # Static data arrays (BLOCK DATA)
|
|
│ ├── runner.rs # Main program skeleton (incomplete)
|
|
│ ├── math/ # Pure math functions (290 modules)
|
|
│ │ ├── ali/ # Accelerated Lambda Iteration
|
|
│ │ ├── atomic/ # Atomic physics
|
|
│ │ ├── continuum/ # Continuum opacity
|
|
│ │ ├── eos/ # Equation of state
|
|
│ │ ├── solvers/ # Linear equation solvers
|
|
│ │ ├── special/ # Special functions (expint, voigt, etc.)
|
|
│ │ └── ... # Other physics categories
|
|
│ ├── state/ # COMMON block translations as structs
|
|
│ │ ├── constants.rs # Physical/math constants, array dimensions
|
|
│ │ ├── config.rs # Runtime config
|
|
│ │ ├── atomic.rs # Atomic/ion/level data
|
|
│ │ ├── model.rs # Atmosphere model state (largest struct)
|
|
│ │ ├── arrays.rs # Main linear equation arrays
|
|
│ │ ├── iterat.rs # Iteration control
|
|
│ │ ├── alipar.rs # ALI arrays
|
|
│ │ └── odfpar.rs # ODF data
|
|
│ └── io/ # Fortran-compatible I/O
|
|
│ ├── reader.rs # Free-format input reader
|
|
│ ├── writer.rs # Formatted output
|
|
│ ├── model.rs # fort.7/fort.8 model files
|
|
│ ├── start.rs # Initialization
|
|
│ └── ... # Other I/O routines
|
|
└── synspec/ # SYNSPEC implementation
|
|
└── math/ # Math functions (28 modules)
|
|
```
|
|
|
|
## Running Tests
|
|
|
|
### Rust Tests
|
|
```bash
|
|
cargo test # All unit tests
|
|
cargo test --test fortran_comparison # Fortran comparison tests only
|
|
```
|
|
|
|
### Fortran Integration Tests
|
|
```bash
|
|
# TLUSTY: H-He model test
|
|
cd $TLUSTY/tests/tlusty/hhe
|
|
$TLUSTY/tlusty/tlusty.exe < hhe35lt.5 > hhe35lt.6
|
|
cp fort.7 hhe35lt.7
|
|
diff hhe35lt.7 hhe35lt.7.bak
|
|
|
|
# SYNSPEC: spectrum test
|
|
cd $TLUSTY/tests/synspec/hhe
|
|
ln -sf $TLUSTY/data data
|
|
cp hhe35nl.7 fort.8
|
|
ln -sf fort.55.con fort.55
|
|
$TLUSTY/synspec/synspec.exe < hhe35nl.5
|
|
```
|
|
|
|
## Refactoring Workflow
|
|
|
|
1. **Find pure functions**: Check `$TLUSTY/rust/tlusty/extracted/_PURE_UNITS.txt` for units without COMMON dependencies
|
|
2. **Choose category**: Place in appropriate `src/tlusty/math/<category>/` subdirectory
|
|
3. **Translate**: Create `<name>.rs`, add to category's `mod.rs`
|
|
4. **Verify**: Add test case in `tests/fortran_comparison.rs` with Fortran reference values
|
|
|
|
## Key Architecture
|
|
|
|
**TLUSTY COMMON blocks** (mapped to `src/tlusty/state/` structs):
|
|
- `BASICS.FOR` → `constants.rs`: Array dimensions (`MDEPTH`=100, `MFREQ`=135000, `MLEVEL`=1134)
|
|
- `ATOMIC.FOR` → `atomic.rs`: Atomic masses, abundances, energy levels
|
|
- `MODELQ.FOR` → `model.rs`: Temperature, density, populations
|
|
- `ARRAY1.FOR` → `arrays.rs`: Main linear equation arrays
|
|
|
|
**SYNSPEC** reads model atmosphere from `fort.8`, outputs spectrum to `fort.7`
|
|
|
|
**File unit numbers** (see `src/tlusty/io/mod.rs`):
|
|
- Unit 5: Standard input (fort.5)
|
|
- Unit 7: Model output (fort.7)
|
|
- Unit 8: Model input (fort.8)
|
|
|
|
## Fortran → Rust Translation Notes
|
|
|
|
Critical patterns to avoid mistakes:
|
|
|
|
- **Index conversion**: Fortran 1-indexed → Rust 0-indexed. `arr(i)` → `arr[i-1]`, `DO I=1,N` → `for i in 0..n`
|
|
- **Expression precedence**: `-LOG(X)` is `-(LOG(X))`, not `LOG(-X)`
|
|
- **Decrementing loops**: Use `isize`/`i32` when loop variable may become negative
|
|
- **COMMON dependency**: Check INCLUDE statements before assuming a function is pure
|
|
- **Large structs**: Functions with many COMMON dependencies use lifetime structs:
|
|
```rust
|
|
pub struct Params<'a> {
|
|
pub input: &'a [f64],
|
|
pub output: &'a mut [f64],
|
|
}
|
|
```
|
|
- **Type inference**: `(z1 - z2).powi(2)` may fail; use `(z1 - z2) * (z1 - z2)`
|
|
- **Test tolerance**: Polynomial approximations (Abramowitz-Stegun) need relaxed tolerance (~1e-7)
|