121 lines
5.7 KiB
Markdown
121 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
|
||
|
||
This is a Python/Flask web application for designing and simulating toroidal transformers. It provides a browser-based UI backed by several physics modules:
|
||
|
||
1. **Designer** ([designer.py](designer.py)) - Computes winding feasibility, layer counts, wire lengths, DC resistance, and weight for each winding segment given core geometry and wire specs
|
||
2. **Simulator** ([sim_toroid.py](sim_toroid.py)) - Evaluates operating points (flux density, currents, losses, efficiency) and sweeps across frequency/load combinations
|
||
3. **Drawing** ([draw_toroid.py](draw_toroid.py)) - Renders a top-down axial cross-section of the toroid (wire dots in bore, core annulus) as a PNG via matplotlib
|
||
4. **Web App** ([app.py](app.py)) - Flask server exposing REST API routes consumed by the browser UI
|
||
5. **Legacy simple model** ([model.py](model.py)) - Earlier physics-based model (taps, flux density, losses); still present but not used by the web app
|
||
6. **Legacy optimizer** ([optimizer.py](optimizer.py)) - Brute-force tap/voltage optimizer for the legacy model
|
||
7. **Impedance-Based Model** ([old/transformer_model.py](old/transformer_model.py)) - Uses measured open-circuit and short-circuit parameters for AC analysis
|
||
|
||
## Commands
|
||
|
||
### Running the Web App
|
||
|
||
```bash
|
||
# Activate venv first (Unix/Mac):
|
||
source .venv/bin/activate
|
||
|
||
# Start the Flask dev server (port 5010):
|
||
python app.py
|
||
# Then open http://localhost:5010 in a browser
|
||
```
|
||
|
||
### Running Legacy Simulations
|
||
|
||
```bash
|
||
# Run the simple transformer model with optimizer example
|
||
python sim.py
|
||
|
||
# Run the per-segment resistance example
|
||
python example_per_segment_resistance.py
|
||
|
||
# Run the impedance-based model example
|
||
python old/run_model_example.py
|
||
```
|
||
|
||
### Development Environment
|
||
|
||
```bash
|
||
# Virtual environment exists at .venv
|
||
# Activate it (Windows):
|
||
.venv\Scripts\activate
|
||
|
||
# Activate it (Unix/Mac):
|
||
source .venv/bin/activate
|
||
|
||
# Install dependencies:
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
## Code Architecture
|
||
|
||
### Web App (app.py)
|
||
|
||
Flask server with these routes:
|
||
|
||
| Route | Method | Description |
|
||
|---|---|---|
|
||
| `GET /` | GET | Serves the main HTML page (`templates/index.html`) |
|
||
| `/api/design` | POST | Runs `design_transformer()`, returns winding info + PNG drawing (base64) |
|
||
| `/api/simulate` | POST | Computes a single operating point via `ToroidSimulator.simulate()` |
|
||
| `/api/sweep` | POST | Runs `sweep_operating_points()` over a grid of frequencies × loads |
|
||
| `/api/presets/<type>` | GET | Lists saved presets for a category |
|
||
| `/api/presets/<type>/<name>` | GET/POST/DELETE | Load, save, or delete a named preset |
|
||
|
||
Preset categories: `core`, `windings`, `constraints`, `sim`. Presets are persisted as JSON files in the `presets/` directory.
|
||
|
||
### Designer (designer.py)
|
||
|
||
- **ToroidCore** dataclass: core geometry (`ID_mm`, `OD_mm`, `height_mm`, `Ae_mm2`, `Ve_mm3`, optional `Pv_func`)
|
||
- **WindingSpec** dataclass: `awg` (list of AWG per segment), `taps` (incremental turns list), `name`
|
||
- **WireSpec** dataclass: wire diameter (with insulation), resistance/m, weight/m; look up via `WireSpec.from_awg(awg)`
|
||
- **WindingResult** dataclass: per-segment results (`SegmentResult`) including layers, wire length, resistance, weight, fits flag
|
||
- `design_transformer(core, specs, fill_factor)`: returns list of `WindingResult`
|
||
|
||
**Tap format**: `taps` is a list of incremental turns. `[0, 25, 50]` means segment 1 = 25 turns, segment 2 = 50 turns; total turns = 75. Tap numbers are 1-indexed.
|
||
|
||
### Simulator (sim_toroid.py)
|
||
|
||
- **SimConstraints** dataclass: `B_max_T`, `Vp_max`, `Vs_max`, `Ip_max`, `Is_max`, `P_out_max_W`
|
||
- **ToroidSimulator**: takes `ToroidCore`, primary `WindingResult`, secondary `WindingResult`
|
||
- `simulate(Vp_rms, freq_hz, primary_tap, secondary_tap, Z_load, constraints)` → `SimResult`
|
||
- `SimResult` fields: `Np_eff`, `Ns_eff`, `turns_ratio`, `B_peak_T`, `Vp_rms_applied`, `Vs_rms`, `Ip_rms`, `Is_rms`, `P_out_W`, `P_cu_W`, `P_cu_primary_W`, `P_cu_secondary_W`, `P_core_W`, `P_in_W`, `efficiency`, `violations`
|
||
- **SweepEntry** / `sweep_operating_points()`: sweeps all tap combinations over a frequency × load grid, finding the best tap pair for each condition at the target power
|
||
- `SweepEntry.as_dict()` serialises to a flat dict for JSON responses
|
||
|
||
### Drawing (draw_toroid.py)
|
||
|
||
- `draw_toroid(core, results, output_path, dpi, fig_size_mm, actual_fill)`: renders top-down cross-section PNG using matplotlib
|
||
- View: looking down the toroid axis. Grey annulus = core; white disc = bore; coloured dots = wire cross-sections per winding/layer
|
||
|
||
### Legacy Simple Model (model.py)
|
||
|
||
- **TransformerModel** dataclass: core area (`Ae_mm2`), turn counts, tap lists, per-turn resistance (uniform or per-segment)
|
||
- `simulate(tap, Vp, freq, R_load)` → flux density, currents, powers, efficiency
|
||
|
||
### Legacy Optimizer (optimizer.py)
|
||
|
||
- **TransformerOptimizer**: brute-force search over all tap combinations + voltage sweep
|
||
- Returns **OptimizationResult** with optimal tap/voltage configuration
|
||
|
||
### Impedance Model (old/transformer_model.py)
|
||
|
||
- **TransformerModel**: interpolates measured OC/SC test data; frequency-dependent Rc/Lm; per-tap Req/L_leak
|
||
- `input_impedance()`, `transfer()` for AC analysis
|
||
|
||
## Important Implementation Details
|
||
|
||
- Loads are specified as complex impedance `(R, X)` pairs in ohms
|
||
- Flux density uses sinusoidal formula: `B_peak = Vp / (4.44 * f * N * Ae)`
|
||
- Core loss uses `Pv_func(f_hz, B_T)` if provided, else a simple Steinmetz fallback
|
||
- Tap numbering is 1-indexed throughout
|
||
- The `old/` directory contains the earlier impedance-based approach
|
||
- `presets/` directory is auto-created; stores JSON files (`core.json`, `windings.json`, `constraints.json`, `sim.json`)
|