Right pane tabs Jobs/Planes market + 5 new plane types with tech-spec panels + sell-plane cargo guard (ISS-047 part A)
CI / build + unit + e2e (pull_request) Successful in 8m56s
CI / build + unit + e2e (pull_request) Successful in 8m56s
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
burnRateConstant,
|
||||
FUEL_DENSITY_KG_PER_L,
|
||||
fuelAtWeighted,
|
||||
maxRangeKm,
|
||||
positionAt,
|
||||
progressAt,
|
||||
requiredFuelFor,
|
||||
@@ -164,3 +165,24 @@ describe('weighted burn model (v0.16.0)', () => {
|
||||
expect(fuelAtWeighted(TANK, BURN, WE, TANK, KM, progressAt(DEP, KM, SPEED, clock))).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('maxRangeKm (v0.28.0)', () => {
|
||||
it('ATR 72-600 full tank ≈ 4439 km (±5%)', () => {
|
||||
const r = maxRangeKm(BURN, WE, TANK);
|
||||
expect(r).toBeGreaterThan(4439 * 0.95);
|
||||
expect(r).toBeLessThan(4439 * 1.05);
|
||||
});
|
||||
|
||||
it('increases with tank size and decreases with burn rate', () => {
|
||||
expect(maxRangeKm(BURN, WE, TANK * 2)).toBeGreaterThan(maxRangeKm(BURN, WE, TANK));
|
||||
expect(maxRangeKm(3, WE, TANK)).toBeLessThan(maxRangeKm(BURN, WE, TANK));
|
||||
});
|
||||
|
||||
it('zero fuel → zero range', () => {
|
||||
expect(maxRangeKm(BURN, WE, 0)).toBe(0);
|
||||
});
|
||||
|
||||
it('rejects a non-positive empty weight', () => {
|
||||
expect(() => maxRangeKm(BURN, 0, TANK)).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -118,3 +118,13 @@ export function requiredFuelFor(
|
||||
const rho = FUEL_DENSITY_KG_PER_L;
|
||||
return (emptyWeightKg / rho) * (Math.exp(k * rho * distanceKm) - 1);
|
||||
}
|
||||
|
||||
// Max range from a FULL tank under the weighted model — solve requiredFuelFor(d) = maxFuel for d:
|
||||
// (We/ρ)(e^{kρd} − 1) = F → d = ln(1 + ρF/We) · (We + ρF)/(ρ·burnPerKm).
|
||||
// Returns raw km (call sites round); zero fuel gives exactly 0. Pure — display-only, the sim
|
||||
// itself does not model range exhaustion (see fuelAtWeighted).
|
||||
export function maxRangeKm(burnPerKm: number, emptyWeightKg: number, maxFuel: number): number {
|
||||
if (!(emptyWeightKg > 0)) throw new Error('emptyWeightKg must be > 0');
|
||||
const rho = FUEL_DENSITY_KG_PER_L;
|
||||
return Math.log(1 + (rho * maxFuel) / emptyWeightKg) * ((emptyWeightKg + rho * maxFuel) / (rho * burnPerKm));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user