Trajectories

This commit is contained in:
2026-03-04 20:29:19 +00:00
parent 6af56f478f
commit 1b15384c10
20 changed files with 4825 additions and 71 deletions

319
docs/SOLVER.md Normal file
View File

@@ -0,0 +1,319 @@
# Solver Guide
## Overview
The **Equation Solver** is a constraint-based computational engine that automatically solves rocket propulsion equations. Rather than manually plugging numbers into formulas, users specify constraints (inputs), and the solver propagates solutions through an interconnected equation network.
**Key Concept**: Drag variables onto the workspace, set values, and the solver automatically computes unknowns.
## User Interface
### Variable Palette (Left)
- Searchable list of all variables
- Organized by category (thrust, Isp, chamber, etc.)
- Drag variables onto workspace
### Workspace (Center)
- Drop zone for constraint cards
- Cards show variable name, unit, input field
- Set constraint by entering value
- Results auto-compute below
### Results Panel (Right)
- Shows all computed values
- Organized by category
- Clickable to copy values
- Unit selector for each variable
## Constraint Propagation Algorithm
The solver implements **greedy propagation**:
### Step-by-Step
1. **User Input**: Sets constraint on variable `x`
2. **Find Equations**: Locates all equations referencing `x`
3. **Attempt Solve**: For each equation, tries to solve for unknowns
- If equation has 1 unknown: solve directly
- If equation has 2+ unknowns: skip (not enough constraints)
4. **Update State**: Newly-solved variables are added to known set
5. **Recurse**: Repeat step 2 with newly-known variables
6. **Stop**: When no new variables can be computed
### Example
**Given:**
- `thrust = massFlowRate * exitVelocity`
- `exitVelocity = sqrt(2 * Cp * (T0 - Te))`
- `massFlowRate = densityO2 * densityFuel * burnRate`
**User Constraints:**
- `thrust = 50000 N`
- `massFlowRate = 100 kg/s`
**Solver Flow:**
```
1. Set thrust = 50000
2. Find equations with thrust: Eq1
3. Eq1 has 2 unknowns (massFlowRate, exitVelocity) → skip
4. Set massFlowRate = 100
5. Find equations with massFlowRate: Eq1, Eq3
6. Eq1 now has 1 unknown (exitVelocity) → solve: exitVelocity = 500 m/s
7. Find equations with exitVelocity: Eq2
8. Eq2 has 2 unknowns (T0, Te) → skip
9. No new variables → done
```
## Variable Definitions
Variables are defined in `src/engine/variables.js` with metadata:
```javascript
{
id: 'thrust',
name: 'Thrust',
unit: 'N',
category: 'performance',
type: 'number'
}
```
**Categories:**
- `thrust` — Force (N, lbf)
- `isp` — Specific impulse (s, m/s)
- `chamber` — Chamber conditions (P, T, density)
- `nozzle` — Nozzle geometry (area, diameter, angle)
- `propellant` — Fuel/oxidizer properties
- `flow` — Mass flow rate, burn rate
- `thermal` — Heat, temperature
- `structural` — Stress, strain, thickness
## Equation Library
Equations are defined in `src/engine/equations.js`. Each equation:
1. **Specifies variables** it relates
2. **Implements forward solver** (compute output given inputs)
3. **Implements per-variable solvers** (solve for each variable given others)
### Example Equation
```javascript
{
id: 'thrustEquation',
name: 'Thrust (Momentum)',
variables: ['thrust', 'massFlowRate', 'exitVelocity'],
equation: 'thrust = massFlowRate * exitVelocity',
forward: (inputs) => {
return inputs.massFlowRate * inputs.exitVelocity
},
solvers: {
exitVelocity: (inputs) => {
return inputs.thrust / inputs.massFlowRate
},
thrust: (inputs) => {
return inputs.massFlowRate * inputs.exitVelocity
}
}
}
```
### Transcendental Equations (Bisection)
For equations with no closed-form solution (e.g., Mach from area ratio), the solver uses **bisection**:
```javascript
// In numerics.js
function bisection(fn, target, min, max, tolerance) {
while (max - min > tolerance) {
const mid = (min + max) / 2
const fMid = fn(mid)
if (fMid < target) {
min = mid
} else {
max = mid
}
}
return (min + max) / 2
}
```
Example: Finding Mach number from area ratio
```javascript
solvers: {
machNumber: (inputs) => {
const fn = (M) => isentropicAreaRatio(M, inputs.gamma)
return bisection(fn, inputs.areaRatio, 0.01, 10, 1e-6)
}
}
```
## Common Equations
### Thrust
```
thrust = mass_flow_rate * exit_velocity
thrust = chamber_pressure * throat_area * CF
```
### Specific Impulse
```
Isp = exit_velocity / g
Isp_vac = exit_velocity / g
Isp_sl = (exit_velocity - P_exit / mass_flow_rate * area_exit) / g
```
### Chamber Conditions (Isentropic Flow)
```
T_exit = T_chamber * (P_exit / P_chamber)^((gamma - 1) / gamma)
rho_exit = rho_chamber * (P_exit / P_chamber)^(1 / gamma)
```
### Nozzle Area Ratio
```
A_exit / A_throat = (2 / (gamma + 1)) * (1 + (gamma - 1)/2 * M_exit^2))^((gamma + 1) / (2 * (gamma - 1))) / M_exit
```
(requires bisection to invert for M)
### Characteristic Velocity
```
c_star = P_chamber * A_throat / mass_flow_rate
```
### Thrust Coefficient
```
CF = sqrt(2 * gamma^2 / (gamma - 1) * (2 / (gamma + 1))^((gamma + 1) / (gamma - 1)) * (1 - (P_exit / P_chamber)^((gamma - 1) / gamma)))
```
## Workflow Examples
### Example 1: Determine Exit Velocity from Isp
**Goal:** Calculate exit velocity given Isp
**Steps:**
1. Drag `specificImpulse` onto workspace
2. Set `specificImpulse = 300 s`
3. Solver computes `exitVelocity = 300 * 9.81 ≈ 2943 m/s`
### Example 2: Find Chamber Pressure from Thrust
**Goal:** Find chamber pressure needed for 50 kN thrust
**Steps:**
1. Drag `thrust`, `throatDiameter`, `massFlowRate` onto workspace
2. Set:
- `thrust = 50000 N`
- `throatDiameter = 0.1 m`
- `massFlowRate = 100 kg/s`
3. Solver finds equations with these variables
4. Uses thrust equation to find thrust coefficient needed
5. Inverts nozzle area ratio with bisection to find Mach
6. Uses isentropic relations to find chamber pressure
7. Displays `chamberPressure = X bar`
### Example 3: Design for Specific Isp
**Goal:** Find propellant combination for Isp = 350 s
**Steps:**
1. Drag `specificImpulse`, `chamberTemperature`, `exhaustGamma` onto workspace
2. Set `specificImpulse = 350 s`
3. Click on knowledgebase to find propellant with T0 ≈ 3500 K
4. Enter that temperature
5. Solver computes `exitVelocity`, then works backward to required conditions
6. Compare against available propellants
## Advanced Features
### Unit Conversion
Every variable card has a unit selector. Setting a variable automatically converts:
```
thrust = 50000 N → 11240.44 lbf
thrust = 11240.44 lbf → 50000 N
```
### Importing Engine Design
Engine design results can be fed into the solver:
- File → Import Engine JSON
- Automatically populates thrust, Isp, chamber pressure, etc.
- Enables end-to-end rocket design workflow
### Variable Categories
Filter variables by category to reduce clutter:
- Thrust (F, Isp, c*)
- Chamber (P, T, density)
- Nozzle (area, geometry)
- Propellant (fuel/oxidizer properties)
- Flow (mass flow, burn rate)
## Limitations & Gotchas
1. **No Circular Dependencies**: If equations form a cycle, solver may loop infinitely
- Solver stops after N iterations to prevent this
- Design equations to be acyclic where possible
2. **Insufficient Constraints**: If variables are underdetermined (more unknowns than equations)
- Solver computes what it can, leaves rest as unknown
- User must provide more constraints
3. **Overdetermined System**: If too many constraints (conflicting values)
- Solver uses first constraint encountered
- Other constraints ignored (may warn in future)
4. **Transcendental Equation Tolerance**: Bisection has numerical error
- Default tolerance: 1e-6
- Results accurate to ~6 significant figures
- Adjust in `numerics.js` if higher precision needed
## Troubleshooting
### Solver not computing?
- Ensure at least one constraint is set
- Check that equation network connects the variables you're trying to solve
- Look for missing material properties (fuel, oxidizer data)
### Result seems wrong?
- Verify input units match variable definition
- Check variable category (is it the right variable?)
- Try solving step-by-step with intermediate variables
### Equation not available?
- Not all rocketry equations are implemented
- Submit a feature request to add more
- Or add the equation yourself in `src/engine/equations.js`
## Development Guide
### Adding a New Equation
1. **Define variables** in `variables.js` if needed
2. **Implement equation** in `equations.js`:
```javascript
equations.push({
id: 'myEquation',
name: 'My Equation',
variables: ['var1', 'var2', 'var3'],
equation: 'var1 = var2 * var3',
solvers: {
var1: (inputs) => inputs.var2 * inputs.var3,
var2: (inputs) => inputs.var1 / inputs.var3,
var3: (inputs) => inputs.var1 / inputs.var2
}
})
```
3. **Test** by:
- Setting constraints manually
- Verifying solver produces correct result
- Testing with known values
### Debugging Solver
- Add console logs in `solver.js` propagation loop
- Log variable state at each iteration
- Verify equation network is correct
---
**Last Updated**: 2025-02 | **Status**: Current