Files
toroid/CLAUDE.md

121 lines
5.7 KiB
Markdown
Raw Permalink 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
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`)