Files
pinn/CLAUDE.md
T
2026-05-13 21:24:26 +02:00

93 lines
3.7 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.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
**Heat Equation PINN** — A Physics-Informed Neural Network that solves the 1D time-varying heat equation with physical boundary conditions:
```
∂T/∂t = α ∂²T/∂x² x ∈ [0, L], t ∈ [0, T_END]
```
- **IC:** `T(x, 0) = T0` (uniform)
- **BC x=0:** Neumann — heat flux step: `k ∂T/∂x = Q(t)` where `Q = Q_VAL` if `t ≥ T_STEP` else `0`
- **BC x=L:** Robin — convection: `k ∂T/∂x = h (T T_AMB)`
No experimental data is needed. A `fdm/` module provides a reference numerical solution (FTCS explicit scheme) used for evaluation and visualization comparison.
All physical and numerical parameters live in `config.py`.
## Running
Always activate the virtual environment first:
```bash
source .venv/bin/activate
```
**PINN:**
```bash
python app.py # Train / Evaluate (L2 vs FDM) / Visualize
```
**FDM reference solver:**
```bash
python fdm/app.py # Solve / Heatmap / Animation / Time-series
```
Saved artifacts (git-ignored): `models/best_heat_pinn_model.pth`, HTML plots in `animations/` and `animations/fdm/`.
To retrain from scratch: `rm models/best_heat_pinn_model.pth` before running option 1.
## Dependencies
`requirements.txt` exists. Key packages: `torch`, `numpy`, `plotly`. No `pandas` or `scikit-learn` needed.
GPU is auto-detected (`cuda``mps``cpu`) in `engine.py:_get_device()`.
## Architecture
```
config.py ← all physical + numerical parameters (edit here to change the problem)
app.py ← PINN CLI menu
model.py ← HeatPINN + heat_pinn_loss()
engine.py ← data sampling, Adam+L-BFGS training, evaluation vs FDM, visualization call
visualizer.py ← PINN vs FDM: heatmap, animated T(x), time-series at fixed points
fdm/
solver.py ← FTCS explicit scheme, ghost-cell Neumann, explicit Robin
visualizer.py ← same 3 plot types for FDM-only output
app.py ← FDM CLI menu
```
### Neural Network (`model.py`)
`HeatPINN`: 5-layer fully connected, input `(x, t)` → output `T`.
**Output scaling** — the network predicts a dimensionless perturbation; the `forward()` applies:
```
T = T_AMB + (Q_VAL · L / K) · net(x, t)
```
This keeps `net` outputs in `[0, 1]` range and ensures gradients `∂T/∂x` are O(1) for the network to learn. Do not remove this scaling.
`heat_pinn_loss()` normalizes all three loss terms to O(1) using `T_char = Q_VAL·L/K` and `grad_char = (Q_VAL/K)²`. Changing physical parameters in `config.py` does not require re-tuning loss weights.
### Training (`engine.py`)
`prepare_data()` samples collocation points with **deliberate clustering**: extra points near `x=0` (steep Neumann gradient) and around `t=T_STEP` (flux step discontinuity). Increasing `N_f` / `N_bc` here is the first lever to pull if accuracy is low.
`train_model()` runs **Adam first, then L-BFGS fine-tuning**. L-BFGS uses a closure that captures loss components in `_last` dict (avoids calling `heat_pinn_loss` outside an active grad context).
`evaluate_model()` runs the FDM solver and downsamples its `(NX, NT)` output to the PINN prediction grid `(100, 100)` for L2 comparison.
### FDM Solver (`fdm/solver.py`)
Returns `(T_matrix[NX, NT], x_vals, t_vals)`. Uses:
- Ghost cell for Neumann: `T_ghost = T[1] + 2·dx·Q(t)/k`
- Explicit Robin at x=L: `T[N] = (T[N1] + dx·h/k·T_amb) / (1 + dx·h/k)` — uses `T_cur[-2]`, not `T_new[-2]`
- CFL check at startup (warns, does not crash)
### Loss Scaling Notes
If you change `Q_VAL`, `K`, `H_CONV`, or `L` in `config.py`, the normalization in `heat_pinn_loss()` adjusts automatically. If losses diverge, check that `T_char = Q_VAL·L/K` is not near zero.