8.8 KiB
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
- User Input: Sets constraint on variable
x - Find Equations: Locates all equations referencing
x - 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)
- Update State: Newly-solved variables are added to known set
- Recurse: Repeat step 2 with newly-known variables
- Stop: When no new variables can be computed
Example
Given:
thrust = massFlowRate * exitVelocityexitVelocity = sqrt(2 * Cp * (T0 - Te))massFlowRate = densityO2 * densityFuel * burnRate
User Constraints:
thrust = 50000 NmassFlowRate = 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:
{
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 propertiesflow— Mass flow rate, burn ratethermal— Heat, temperaturestructural— Stress, strain, thickness
Equation Library
Equations are defined in src/engine/equations.js. Each equation:
- Specifies variables it relates
- Implements forward solver (compute output given inputs)
- Implements per-variable solvers (solve for each variable given others)
Example Equation
{
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:
// 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
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:
- Drag
specificImpulseonto workspace - Set
specificImpulse = 300 s - 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:
- Drag
thrust,throatDiameter,massFlowRateonto workspace - Set:
thrust = 50000 NthroatDiameter = 0.1 mmassFlowRate = 100 kg/s
- Solver finds equations with these variables
- Uses thrust equation to find thrust coefficient needed
- Inverts nozzle area ratio with bisection to find Mach
- Uses isentropic relations to find chamber pressure
- Displays
chamberPressure = X bar
Example 3: Design for Specific Isp
Goal: Find propellant combination for Isp = 350 s
Steps:
- Drag
specificImpulse,chamberTemperature,exhaustGammaonto workspace - Set
specificImpulse = 350 s - Click on knowledgebase to find propellant with T0 ≈ 3500 K
- Enter that temperature
- Solver computes
exitVelocity, then works backward to required conditions - 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
-
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
-
Insufficient Constraints: If variables are underdetermined (more unknowns than equations)
- Solver computes what it can, leaves rest as unknown
- User must provide more constraints
-
Overdetermined System: If too many constraints (conflicting values)
- Solver uses first constraint encountered
- Other constraints ignored (may warn in future)
-
Transcendental Equation Tolerance: Bisection has numerical error
- Default tolerance: 1e-6
- Results accurate to ~6 significant figures
- Adjust in
numerics.jsif 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
- Define variables in
variables.jsif needed - Implement equation in
equations.js:
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
}
})
- Test by:
- Setting constraints manually
- Verifying solver produces correct result
- Testing with known values
Debugging Solver
- Add console logs in
solver.jspropagation loop - Log variable state at each iteration
- Verify equation network is correct
Last Updated: 2025-02 | Status: Current