The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.
evaluateMe02 · src/physics/reference/massEnergy.ts · this site’s source, as built · sha256:53f944320b3803166e6436ebdf1160ba135efb2df9770617dd19a3ec30d1c5fc
This function computes the listed outputs when it runs.
In words
Refuse unless the emitted energy and the speed of light are positive and the observer moves slower than light. Then compute the exact drop in kinetic energy, the emitted energy times the Lorentz factor minus one; its low-speed approximation, half the emitted energy times the square of the frame speed; and the limiting mass coefficient, the emitted energy divided by the square of the speed of light. At a finite speed, also divide the exact drop by half the square of the speed: that ratio is larger than the limit and approaches it as the speed goes to zero.
Mathematics
The conditional exact kinetic-energy drop
Explore The conditional exact kinetic-energy drop term by term, with this laboratory’s values
Why a finite-speed quotient is not the mass decrease
Identify the positive inertia decrease
Explore Identify the positive inertia decrease term by term, with this laboratory’s values
Keep only the second-order energy term
Explore Keep only the second-order energy term term by term, with this laboratory’s values
A signed change is the negative of a decrease
Explore A signed change is the negative of a decrease term by term, with this laboratory’s values
Implementation
export function evaluateMe02(input: Me02Input): Me02Snapshot {
const beta = input.beta;
const L = input.emittedEnergy;
const c = input.speedOfLight ?? C_SI;
const ids = {
exact: [
"kineticEnergyDifference",
"J",
"kinetic-energy-difference",
"massEnergy.exactDifference",
],
quad: [
"quadraticKineticDifference",
"J",
"quadratic-kinetic-energy",
"massEnergy.quadraticApproximation",
],
disc: [
"quadraticRelativeDiscrepancy",
"1",
"quadratic-relative-discrepancy",
"massEnergy.quadraticDiscrepancy",
],
proxy: ["finiteSpeedMassProxy", "kg", "finite-speed-mass-proxy", "massEnergy.finiteSpeedProxy"],
limit: [
"inertialMassDecrease",
"kg",
"limiting-mass-coefficient",
"massEnergy.limitingCoefficient",
],
excess: ["proxyExcessOverLimit", "1", "proxy-excess", "massEnergy.proxyExcess"],
lost: ["inertialMassDecrease", "kg", "positive-mass-lost", "massEnergy.inertialMassDecrease"],
signed: ["massChangeSigned", "kg", "signed-mass-change", "massEnergy.massChangeSigned"],
} as const;
const refuse = (reason: string, condition: string): Me02Snapshot => {
const out = (row: readonly [string, string, string, string]) =>
asOutside(row[0], row[1], row[2], row[3], condition, reason);
return Object.freeze({
beta,
emittedEnergy: L,
speedOfLight: c,
exactDifference: out(ids.exact),
quadraticApproximation: out(ids.quad),
quadraticDiscrepancy: out(ids.disc),
finiteSpeedProxy: out(ids.proxy),
limitingCoefficient: out(ids.limit),
proxyExcess: out(ids.excess),
inertialMassDecrease: out(ids.lost),
massChangeSigned: out(ids.signed),
naive: naiveGammaMinusOne(beta),
});
};
if (![beta, L, c].every(Number.isFinite) || L <= 0 || c <= 0) {
return refuse("Emitted energy and speed of light must be finite and positive.", "L > 0, c > 0");
}
if (Math.abs(beta) >= 1) {
return refuse("No inertial observer at |v| >= c.", "|beta| < 1");
}
const gmo = gammaMinusOne(beta);
if (gmo.status !== "value") {
return refuse(gmo.reason, gmo.condition);
}
const g = gamma(beta);
if (g.status !== "value") {
return refuse(g.reason, g.condition);
}
const exact = L * gmo.value;
const quadratic = 0.5 * L * beta * beta;
const limitValue = L / (c * c);
const discrepancy = exact === 0 ? 0 : (exact - quadratic) / exact;
const naive = naiveGammaMinusOne(beta);
const limit = asLimit(ids.limit[0], ids.limit[1], ids.limit[2], ids.limit[3], limitValue);
const lost = asValue(ids.lost[0], ids.lost[1], ids.lost[2], ids.lost[3], limitValue);
const signed = asValue(ids.signed[0], ids.signed[1], ids.signed[2], ids.signed[3], -limitValue);
if (beta === 0) {
return Object.freeze({
beta,
emittedEnergy: L,
speedOfLight: c,
exactDifference: asValue(ids.exact[0], ids.exact[1], ids.exact[2], ids.exact[3], 0),
quadraticApproximation: asValue(ids.quad[0], ids.quad[1], ids.quad[2], ids.quad[3], 0),
quadraticDiscrepancy: asNotApplicable(
ids.disc[0],
ids.disc[1],
ids.disc[2],
ids.disc[3],
"At vanishing speed both the exact and quadratic differences are zero.",
),
finiteSpeedProxy: asNotApplicable(
ids.proxy[0],
ids.proxy[1],
ids.proxy[2],
ids.proxy[3],
"The finite-speed proxy divides by v^2; at v = 0 the identified coefficient is the analytic limit.",
),
limitingCoefficient: limit,
proxyExcess: asNotApplicable(
ids.excess[0],
ids.excess[1],
ids.excess[2],
ids.excess[3],
"No proxy is defined at vanishing speed.",
),
inertialMassDecrease: lost,
massChangeSigned: signed,
naive,
});
}
const proxy = (2 * L * gmo.value) / (beta * beta * c * c);
const excess = proxy / limitValue - 1;
return Object.freeze({
beta,
emittedEnergy: L,
speedOfLight: c,
exactDifference: asValue(ids.exact[0], ids.exact[1], ids.exact[2], ids.exact[3], exact),
quadraticApproximation: asValue(ids.quad[0], ids.quad[1], ids.quad[2], ids.quad[3], quadratic),
quadraticDiscrepancy: asValue(ids.disc[0], ids.disc[1], ids.disc[2], ids.disc[3], discrepancy),
finiteSpeedProxy: asValue(ids.proxy[0], ids.proxy[1], ids.proxy[2], ids.proxy[3], proxy),
limitingCoefficient: limit,
proxyExcess: asValue(ids.excess[0], ids.excess[1], ids.excess[2], ids.excess[3], excess),
inertialMassDecrease: lost,
massChangeSigned: signed,
naive,
});
}