# Rotors and blades

# Rotors and blades

Package `@ferret/physics-rotor`, capability `rotors`, phase `field`. It reads the medium of `physics-media` (density and the flow, which includes the [flow field](flow.md)) at the rotor, so wind, a mill race and a whirlpool drive it without any wiring.

## A rotor

```json
"physics": {
  "capabilities": ["media", "rotors"],
  "rotors": [
    { "name": "sails", "shaft": "MillShaft", "axis": [0, 0, 1], "at": [0, 10, 0], "radius": 2,
      "elements": { "kind": "blade", "count": 3, "area": 0.18, "pitch": "6deg" } },
    { "name": "wheel", "node": "WheelHub", "axis": [1, 0, 0], "radius": 2.4, "medium": "water",
      "elements": { "kind": "paddle", "count": 16, "area": 0.5, "depth": 0.5 } },
    { "name": "overshot", "shaft": "FlumeShaft", "axis": [1, 0, 0], "radius": 2.4,
      "elements": { "kind": "bucket", "count": 12, "capacity": 5, "fill": { "angle": 0.5, "width": 0.3, "rate": 2 }, "empty": { "from": 3.5 } } }
  ]
}
```

A rotor names a `shaft` (a shaft of the drivetrain: it becomes one more torque source of that shaft, so gears, clutches, the load and the housing reaction all follow) and/or a `node` (a body: the thrust, the weight of the water and the reaction go to it). With a node and no shaft the rotor spins by itself: `spin: { J, friction }` is a free rotor (a windmill on a boat), `spin: { speed }` holds a speed (a driven propeller). `axis` and `at` are in the body's frame with a node, in the world without one. Angle 0 of the elements points `up` (default world up); a positive turn goes from `up` towards `axis × up`.

| Element | Force from |
|---|---|
| `blade` | blade-element and momentum theory at the 0.7 R station: the flow along the axis and the speed give the angle of attack, lift and drag from a `polar` (`clSlope`, `clMax`, `cd0`, `cdMax`, or your own `cl` / `cd` functions); the induced flow and the tip loss are iterated, so the power never passes the Betz limit. `pitch` is the angle of the chord from the plane of rotation. Windmill sails, wind turbine, fan; a propeller is a blade pitched past the inflow angle (negative torque and thrust). `induction: false` turns the induced flow off (a propeller at the bollard) |
| `paddle` | the drag `½ρ·Cd·A·(v − ω·r)²` of the immersed part of flat paddles, sampled at four points along each paddle's `depth`, in the local water: undershot wheel, paddle steamer |
| `bucket` | the weight of the water in each bucket: it fills at `fill.angle` (within `width`, `rate` kg/s, scaled by the rotor's `command`: a sluice) and pours from `empty.from` on: overshot wheel |

`model: "lumped"` (blades only) is the cheap mode: the torque is `windPower(Cp(λ)) / ω` with `lumped: { cpMax, peak, ct }`, fitted to the elements (`fitLumped`) when you give none, or a propeller `lumped: { kt, kq, diameter }`.

## Readouts and commands

`rotor.state { name? }`: `omega`, `theta`, `torque`, `power`, `thrust`, `force`, `tipSpeedRatio`, `flow` (along the axis, against the rotor), `cp`, `pitch`, `command`, `fill` (kg per bucket). `rotor.pitch { name, pitch }` turns the blades (a windmill turned to the wind, a variable-pitch propeller), `rotor.command { name, command }` opens or shuts the sluice; editor: `edit.physics.rotor.set | remove | list`.

## The blade actuator

`{ "name": "oar", "node": "Boat", "kind": "blade", "point": "Oarlock_L", "area": 0.12, "normal": [0, 0, 1], "stroke": { "dir": [0, 0, -1], "speed": 1 } }`: a plate in the medium. The force comes from the plate's velocity against the local flow (`plateForce`: drag along the relative flow, lift across it); the profile drives the *stroke* (the plate moves relative to the body at `speed × profile`), not the force, so the same stroke gives less against the current. The kind is registered when `@ferret/physics-rotor` is loaded. How the stroke follows the oar's path and immersion comes with stage A7.

## Not here
Housing reactions of angle profiles (A10), the render of rotors (A9), the `.ferret` library build (M).
