@essrt/physics 23.3.3 → 24.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/package.json +2 -2
- package/src/cardinal/one-source-structure.cjs +3 -1
- package/src/constants/coefficients.d.ts +5 -1
- package/src/constants/coefficients.js +3 -2
- package/src/constants/generated.d.ts +13 -14
- package/src/constants/generated.js +14 -15
- package/src/constants/units.cjs +4 -1
- package/src/deltat/deep-time.cjs +37 -72
- package/src/earth/deep-orbital-history.cjs +48 -34
- package/src/earth/year-lengths.cjs +2 -1
- package/src/eclipse/besselian.cjs +24 -11
- package/src/index.js +30 -48
- package/src/model/cardinal-instants.js +101 -0
- package/src/model/context.js +54 -0
- package/src/model/deep-time-chain.js +79 -0
- package/src/model/delta-t.js +38 -0
- package/src/model/derived-constants.js +58 -0
- package/src/model/earth-scalars.js +47 -0
- package/src/model/inv-plane-elements.js +56 -0
- package/src/model/lunar-theory.js +216 -0
- package/src/model/moon-epoch.js +28 -0
- package/src/model/one-source-movement.js +192 -0
- package/src/model/planet-elements-of-date.js +61 -0
- package/src/model/planet-records.js +63 -0
- package/src/model/planet-spin-channel.js +41 -0
- package/src/model/published-periods.js +38 -0
- package/src/model/sun-and-eclipses.js +199 -0
- package/src/model/surface.js +332 -0
- package/src/model/time-axis.js +24 -0
- package/src/model/year-day-lengths.js +42 -0
- package/src/model.js +62 -1612
- package/src/moon/arguments.cjs +27 -43
- package/src/planets/chain-artifact.js +2 -2
- package/src/planets/keplerian-chain.cjs +3 -3
- package/src/planets/model.cjs +2 -2
- package/types/constants/coefficients.d.ts +5 -1
- package/types/constants/generated.d.ts +13 -14
- package/types/constants/units.d.cts +3 -0
- package/types/deltat/deep-time.d.cts +18 -24
- package/types/earth/deep-orbital-history.d.cts +23 -0
- package/types/eclipse/besselian.d.cts +37 -18
- package/types/index.d.ts +1 -1
- package/types/model/cardinal-instants.d.ts +14 -0
- package/types/model/context.d.ts +87 -0
- package/types/model/deep-time-chain.d.ts +288 -0
- package/types/model/delta-t.d.ts +11 -0
- package/types/model/derived-constants.d.ts +25 -0
- package/types/model/earth-scalars.d.ts +14 -0
- package/types/model/inv-plane-elements.d.ts +6 -0
- package/types/model/lunar-theory.d.ts +72 -0
- package/types/model/moon-epoch.d.ts +10 -0
- package/types/model/one-source-movement.d.ts +74 -0
- package/types/model/planet-elements-of-date.d.ts +9 -0
- package/types/model/planet-records.d.ts +7 -0
- package/types/model/planet-spin-channel.d.ts +29 -0
- package/types/model/published-periods.d.ts +7 -0
- package/types/model/sun-and-eclipses.d.ts +53 -0
- package/types/model/surface.d.ts +281 -0
- package/types/model/time-axis.d.ts +12 -0
- package/types/model/year-day-lengths.d.ts +8 -0
- package/types/model.d.ts +10 -81
- package/types/moon/arguments.d.cts +5 -11
- package/types/planets/keplerian-chain.d.cts +4 -2
- package/types/planets/model.d.cts +3 -3
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The certified Sun and the eclipse tier — the mean longitude of date, the finders, the planetary completion, the besselian location tier.
|
|
3
|
+
*
|
|
4
|
+
* One slice of `assembleModel` (../model.js): receives the context the earlier slices built, returns the bindings the later ones read.
|
|
5
|
+
*/
|
|
6
|
+
import { ONE_FAMILY_WINDOW_YEARS } from '../earth/year-lengths.cjs';
|
|
7
|
+
import { createBesselian } from '../eclipse/besselian.cjs';
|
|
8
|
+
import { createEclipseFinders } from '../eclipse/finders.cjs';
|
|
9
|
+
import { computeCarrierRatesDegPerCy, createSunPlanetaryCompletion } from '../eclipse/sun-planetary-completion.cjs';
|
|
10
|
+
|
|
11
|
+
/** @param {import('./lunar-theory.js').Ctx} ctx @returns the bindings the later slices read */
|
|
12
|
+
export function assembleSunAndEclipses(ctx) {
|
|
13
|
+
const {
|
|
14
|
+
C, F, late, MASS_RATIO_EARTH_MOON, currentAUDistance, frameworkDeltaTSecondsAtJD, j2000JD, jdTTFromUT,
|
|
15
|
+
julianCenturyDays, meanSiderealYearDays, meanSolarYearDays, moonArgs, moonDistanceKm, moonSeries,
|
|
16
|
+
moonSiderealMonthInput, moonSynodicMonthDays, obliquityDeg, oneFamilyTropicalYearSeconds, sunEccentricityAt,
|
|
17
|
+
sunPerihelionDegAt, yearFromJD,
|
|
18
|
+
} = ctx;
|
|
19
|
+
// The certified Sun — assembled from the model's own laws, ZERO fitted Sun
|
|
20
|
+
// constants: e(t) and ϖ(t) are the eclipse Sun's mean elements of date
|
|
21
|
+
// (earth-scalars.js: the one-source series plus the derived mean offset);
|
|
22
|
+
// L(t) is the integral of the one-family tropical year (below). The
|
|
23
|
+
// finders, the derived planetary completion and the besselian location
|
|
24
|
+
// tier are wired on it; the sun-vs-horizons gate banks its modern-window
|
|
25
|
+
// residual, the eclipse audit the finders' canon statistics.
|
|
26
|
+
const sunL0Deg = C.earthOrbital.sunMeanLongitudeJ2000_deg;
|
|
27
|
+
const sunTropicalRateDegPerCy = 360 * julianCenturyDays / meanSolarYearDays;
|
|
28
|
+
const sunMeanLongitudeDegAt = (() => {
|
|
29
|
+
// The Sun's mean longitude of date is the INTEGRAL of the one-source
|
|
30
|
+
// tropical year: L(t) = L0 + 360·∫_{2000}^{t} dt′/T_trop(t′), T_trop the
|
|
31
|
+
// one-family tropical year of date in SI seconds (one-source-movement.js).
|
|
32
|
+
// MEASURED: it equals the IAU/Laskar drift expression to 0.1 s over
|
|
33
|
+
// −1000..+3000. The smooth year cannot carry the Earth–Mars–Jupiter long
|
|
34
|
+
// inequality (1783 yr, 6.3″); derived on the model's own N-body and
|
|
35
|
+
// shipped in the planetary completion, the JPL instrument reads 1.03″
|
|
36
|
+
// all-phase sd (Horizons ±3000 yr: modern-window mean +0.8″).
|
|
37
|
+
// NUMERICS (rate vs point value): a cumulative trapezoid table of
|
|
38
|
+
// cycles, yearly inside ±20,000 yr and per century beyond, grown on
|
|
39
|
+
// demand from 2000 in both directions and interpolated inside a cell —
|
|
40
|
+
// never a rate multiplied by a span. Beyond the one-family window the
|
|
41
|
+
// tidal-chain year continues the integrand (the scene overlay ends at
|
|
42
|
+
// 20,000 yr; the finders refuse out-of-domain epochs upstream).
|
|
43
|
+
const JULIAN_YEAR_S = 365.25 * 86400;
|
|
44
|
+
const tropSec = oneFamilyTropicalYearSeconds;
|
|
45
|
+
const FINE_SPAN = 20000, COARSE_STEP = 100;
|
|
46
|
+
/** cycles from 2000 to 2000 ± i·step (fwd/bwd tiers) */
|
|
47
|
+
/** @type {number[]} */ const fwdFine = [0];
|
|
48
|
+
/** @type {number[]} */ const bwdFine = [0];
|
|
49
|
+
/** @type {number[]} */ const fwdCoarse = [];
|
|
50
|
+
/** @type {number[]} */ const bwdCoarse = [];
|
|
51
|
+
/** UNSIGNED trapezoid cycles over the span between two years (Julian
|
|
52
|
+
* years → SI seconds over the one-family year); the caller applies the
|
|
53
|
+
* direction sign. @param {number} ya @param {number} yb @returns {number} */
|
|
54
|
+
const segAbs = (ya, yb) => 0.5 * (Math.abs(yb - ya) * JULIAN_YEAR_S) * (1 / tropSec(ya) + 1 / tropSec(yb));
|
|
55
|
+
/** signed cycles from 2000 to `year` @param {number} year @returns {number} */
|
|
56
|
+
const cyclesTo = (year) => {
|
|
57
|
+
const dy = year - 2000;
|
|
58
|
+
const s = dy >= 0 ? 1 : -1, a = Math.abs(dy);
|
|
59
|
+
// WARM THE SAMPLER TO THE TARGET FIRST (plan 06 R4, measured): the
|
|
60
|
+
// table below grows outward in 1-yr / 100-yr steps, and every step
|
|
61
|
+
// beyond ~1.6 Myr enlarged the one-family sampler's >2-Myr tier just
|
|
62
|
+
// past its span, rebuilding the whole deep integration about every 32
|
|
63
|
+
// steps — ~125 rebuilds and 22 s for the first deep-epoch call (the
|
|
64
|
+
// scene's first jump to −5 Myr), 0.4 ms once built. One read at the
|
|
65
|
+
// clamped target builds the tier at its final span; the grid stores
|
|
66
|
+
// are endpoint-independent, so every value is bit-identical.
|
|
67
|
+
tropSec(2000 + s * Math.min(a, ONE_FAMILY_WINDOW_YEARS));
|
|
68
|
+
const fine = s > 0 ? fwdFine : bwdFine;
|
|
69
|
+
const growFine = (/** @type {number} */ upto) => { while (fine.length <= upto) { const k = fine.length; fine.push(fine[k - 1] + s * segAbs(2000 + s * (k - 1), 2000 + s * k)); } };
|
|
70
|
+
if (a <= FINE_SPAN) {
|
|
71
|
+
const i = Math.floor(a), f = a - i;
|
|
72
|
+
growFine(i + 1);
|
|
73
|
+
return fine[i] + f * (fine[i + 1] - fine[i]);
|
|
74
|
+
}
|
|
75
|
+
growFine(FINE_SPAN);
|
|
76
|
+
const coarse = s > 0 ? fwdCoarse : bwdCoarse;
|
|
77
|
+
if (coarse.length === 0) coarse.push(fine[FINE_SPAN]);
|
|
78
|
+
const c = (a - FINE_SPAN) / COARSE_STEP, ci = Math.floor(c), cf = c - ci;
|
|
79
|
+
while (coarse.length <= ci + 1) { const k = coarse.length; const y0 = 2000 + s * (FINE_SPAN + (k - 1) * COARSE_STEP); coarse.push(coarse[k - 1] + s * segAbs(y0, y0 + s * COARSE_STEP)); }
|
|
80
|
+
return coarse[ci] + cf * (coarse[ci + 1] - coarse[ci]);
|
|
81
|
+
};
|
|
82
|
+
return /** @param {number} year @returns {number} */ (year) => sunL0Deg + 360 * cyclesTo(year);
|
|
83
|
+
})();
|
|
84
|
+
// The lunar arguments' Sun perihelion of date is the eclipse Sun's mean
|
|
85
|
+
// perihelion (`sunPerihelionDegAt`) read DIRECTLY, wrapped.
|
|
86
|
+
// Every consumer wraps the argument it enters (M = Lsun − ϖ − 180) or
|
|
87
|
+
// differences it over ±25 days (the rate anchors, wrapped to ±180°), so
|
|
88
|
+
// no continuous angle is needed. MEASURED: a 100-yr unwrapping ladder
|
|
89
|
+
// (two series reads per rung, 53,400 rungs at −5.34 Myr) cost the cold
|
|
90
|
+
// deep jump 1,062 s — 343× the in-table jump against the perf gate's 8× —
|
|
91
|
+
// for a value the consumers reduced mod 360 anyway.
|
|
92
|
+
|
|
93
|
+
// Eclipse finders — wired like the engine probe (tools/verify/
|
|
94
|
+
// eclipse-audit.js). The finder axis is JD(UT): the series wrapper applies
|
|
95
|
+
// UT→TT internally. Ground-track/umbra paths deliberately absent: the
|
|
96
|
+
// scene-umbra projection navigates the Tychosium-derived scaffold, which
|
|
97
|
+
// never enters this package (§2h).
|
|
98
|
+
const eclipseFinders = createEclipseFinders({
|
|
99
|
+
moonLonDegAt: /** @param {number} jd */ (jd) => moonSeries.truncatedLonDeg(jd),
|
|
100
|
+
moonBetaDegAt: /** @param {number} jd */ (jd) => moonSeries.truncatedBetaDeg(jd),
|
|
101
|
+
moonDistanceKmAt: /** @param {number} jd */ (jd) => moonSeries.truncatedDistanceKm(jd),
|
|
102
|
+
deltaTSecondsAt: frameworkDeltaTSecondsAtJD,
|
|
103
|
+
getSynodicMonthDays: () => moonSynodicMonthDays,
|
|
104
|
+
getSunDistanceKm: () => currentAUDistance,
|
|
105
|
+
frameworkSun: {
|
|
106
|
+
sunMeanLongitudeJ2000Deg: sunL0Deg,
|
|
107
|
+
tropicalRateDegPerCy: sunTropicalRateDegPerCy,
|
|
108
|
+
eccentricityAt: sunEccentricityAt,
|
|
109
|
+
perihelionLongitudeDegAt: sunPerihelionDegAt,
|
|
110
|
+
meanLongitudeDegAt: sunMeanLongitudeDegAt,
|
|
111
|
+
},
|
|
112
|
+
constants: {
|
|
113
|
+
rEarthMetres: (C.bodyDiametersKm.earth / 2) * 1000,
|
|
114
|
+
moonDiameterKm: C.bodyDiametersKm.moon,
|
|
115
|
+
sunDiameterKm: C.bodyDiametersKm.sun,
|
|
116
|
+
j2000JD,
|
|
117
|
+
julianCenturyDays,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// 20.3g — the solar-eclipse LOCATION tier: shadow geometry on the FULL
|
|
122
|
+
// series (sceneEvalAt — the truncated finder forms omit the fitted Lp
|
|
123
|
+
// anchor and the −2235·sin(Lp) β family, deliberate for finder
|
|
124
|
+
// statistics, required here) at the model's ABSOLUTE TT (deltaTStart +
|
|
125
|
+
// curve, the same convention every other ΔT consumer reads). Both axis
|
|
126
|
+
// conventions are measured against the NASA path-table centerlines —
|
|
127
|
+
// see eclipse/besselian.cjs.
|
|
128
|
+
// Derived Earth-around-EMB wobble for the Sun completion: a_M·μ/AU,
|
|
129
|
+
// μ = 1/(1+M_E/M_M) — 6.4399″ at current constants, tracks them live.
|
|
130
|
+
const embWobbleArcsec = (moonDistanceKm / (MASS_RATIO_EARTH_MOON + 1) / currentAUDistance)
|
|
131
|
+
* (648000 / Math.PI);
|
|
132
|
+
// FQ-5 N3 — the completion's carriers are FRAMEWORK-derived from the
|
|
133
|
+
// model's own planet period records (the Moon-elongation rate from the
|
|
134
|
+
// sidereal month/year identity). Plan 06 I2 — the carriers are SIDEREAL
|
|
135
|
+
// (measured): the records' orbitalPeriodInputDays are OF-DATE periods (their
|
|
136
|
+
// rates sit +1.39..1.62°/cy above the VSOP sidereal mean motions — the
|
|
137
|
+
// framework precession plus input rounding), and a perturbation argument
|
|
138
|
+
// is inertial (D'Alembert: only Σk = 0 arguments are frame-free), so on
|
|
139
|
+
// of-date carriers every Σk ≠ 0 argument drifted by Σk·ψ(t) — 42..52° at
|
|
140
|
+
// −3000 for the table's Σk = −1 terms (their ancient scatter against
|
|
141
|
+
// Horizons 6.4 → 4.4″ on sidereal carriers), and 6 % of frequency for the
|
|
142
|
+
// 1783-yr long inequality (1683 yr on the of-date carriers). Constant-free:
|
|
143
|
+
// the record rate minus the model's own J2000 precession p₀ =
|
|
144
|
+
// 360·36525·(1/T_trop − 1/T_sid) for the planets, the framework sidereal
|
|
145
|
+
// year for Earth; identical to the N3 carriers at J2000 (same phase
|
|
146
|
+
// anchors), ≤ 1.4°·|Σk| apart at the 200-yr extraction window's edges
|
|
147
|
+
// (the composed table reproduces the N3 one there: JPL 1900–2100
|
|
148
|
+
// all-phase sd unchanged to 0.01″). The parity gate's fingerprint mirrors
|
|
149
|
+
// this arithmetic (test/create-model-parity.test.mjs).
|
|
150
|
+
// PLAN 06 I3 — the carriers are the model's own banked J2000 sidereal mean
|
|
151
|
+
// motions (the embedded sun-completion artifact; ONE home,
|
|
152
|
+
// computeCarrierRatesDegPerCy — the former record-based arithmetic sat
|
|
153
|
+
// 4.1″/yr off for Venus, 1.7″/yr for Jupiter: 83° of the Venus–Earth
|
|
154
|
+
// argument at ±9000 yr), Earth the framework sidereal year, the Moon
|
|
155
|
+
// elongation from the sidereal month/year identity. The long-period rows
|
|
156
|
+
// ride the embedded e-vectors of date, and the lunar equation rides the
|
|
157
|
+
// framework's own Moon elongation of date (ṅ included) — the constant-rate
|
|
158
|
+
// carrier ran ~29° off it at ±9000 yr.
|
|
159
|
+
const carrierRatesDegPerCy = computeCarrierRatesDegPerCy({ meanSiderealYearDays, moonSiderealMonthDays: moonSiderealMonthInput });
|
|
160
|
+
const { sunPlanetaryCompletionDeg } = createSunPlanetaryCompletion({
|
|
161
|
+
embWobbleArcsec,
|
|
162
|
+
carrierRatesDegPerCy,
|
|
163
|
+
moonElongationDegAtT: /** @param {number} T */ (T) => moonArgs.argsAt(j2000JD + T * julianCenturyDays).D,
|
|
164
|
+
});
|
|
165
|
+
const besselian = createBesselian({
|
|
166
|
+
moonFullAtDaysTT: /** @param {number} dDaysTT */ (dDaysTT) => {
|
|
167
|
+
const ev = moonSeries.sceneEvalAt(dDaysTT);
|
|
168
|
+
return { lonDeg: ev.lonDeg, latDeg: ev.latDeg, distKm: ev.distKm };
|
|
169
|
+
},
|
|
170
|
+
sunLonDegAt: /** @param {number} jdUT */ (jdUT) => eclipseFinders.sunLonDegAt(jdUT),
|
|
171
|
+
sunCompletionDeg: sunPlanetaryCompletionDeg,
|
|
172
|
+
// plan 06 R3 item 1: the location tier on APPARENT places — the Sun's derived κ
|
|
173
|
+
// (the same helper the cardinal instants use), the Moon's relative light-time
|
|
174
|
+
// inside the besselian; the series-extension tail now lives in sceneEvalAt.
|
|
175
|
+
sunAberrationDegAt: /** @param {number} year */ (year) => late.sunAberrationArcsecAt(year) / 3600,
|
|
176
|
+
deltaTSecondsAt: /** @param {number} jd */ (jd) => (jdTTFromUT(jd) - jd) * 86400,
|
|
177
|
+
obliquityDegAt: obliquityDeg,
|
|
178
|
+
eccentricityAt: sunEccentricityAt,
|
|
179
|
+
perihelionLongitudeDegAt: sunPerihelionDegAt,
|
|
180
|
+
yearFromJD,
|
|
181
|
+
constants: {
|
|
182
|
+
j2000JD,
|
|
183
|
+
julianCenturyDays,
|
|
184
|
+
earthDiameterKm: C.bodyDiametersKm.earth,
|
|
185
|
+
moonDiameterKm: C.bodyDiametersKm.moon,
|
|
186
|
+
sunDiameterKm: C.bodyDiametersKm.sun,
|
|
187
|
+
sunDistanceKm: currentAUDistance,
|
|
188
|
+
earthFlatteningInverse: C.physicalConstants.earthFlatteningInverseWGS84,
|
|
189
|
+
ttBridgeSeconds: F.DT_ANCHOR.deltaTStartSeconds,
|
|
190
|
+
gmstMeanSiderealT0Deg: C.physicalConstants.gmstMeanSiderealT0Deg,
|
|
191
|
+
gmstMeanSiderealRateDegPerDay: C.physicalConstants.gmstMeanSiderealRateDegPerDay,
|
|
192
|
+
gmstMeanSiderealT2Deg: C.physicalConstants.gmstMeanSiderealT2Deg,
|
|
193
|
+
speedOfLightKmS: C.physicalConstants.speedOfLight,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
return { besselian, eclipseFinders, sunL0Deg, sunMeanLongitudeDegAt, sunPlanetaryCompletionDeg, sunTropicalRateDegPerCy };
|
|
198
|
+
}
|
|
199
|
+
/** @typedef {import('./lunar-theory.js').Ctx & ReturnType<typeof assembleSunAndEclipses>} Ctx */
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The assembled surface — the frozen object createModel() returns.
|
|
3
|
+
*
|
|
4
|
+
* The last slice of `assembleModel` (../model.js): reads the bindings every earlier slice built and returns the published surface.
|
|
5
|
+
*/
|
|
6
|
+
import { ONE_FAMILY_WINDOW_YEARS } from '../earth/year-lengths.cjs';
|
|
7
|
+
|
|
8
|
+
/** @param {import('./cardinal-instants.js').Ctx} ctx @returns the published surface (frozen) */
|
|
9
|
+
export function assembleSurface(ctx) {
|
|
10
|
+
const {
|
|
11
|
+
C, F, EPOCH_PARAMS, GM_EARTH_ALONE, GM_EARTH_MOON_SYSTEM, GM_MOON_ALONE, GM_SUN, GM_SUN_PLUS_EARTH, G_CONSTANT,
|
|
12
|
+
MASS_RATIO_EARTH_MOON, M_SUN, PLANET_KEYS, PUBLISHED_PLANET_RECORDS, anomalisticYearDays, ascendingNodeDeg,
|
|
13
|
+
besselian, cardinalCrossingJdUT, cardinalCrossingNearJdUT, cardinalTargetDeg, certifiedAxialPrecessionJ2000Years,
|
|
14
|
+
chain, dayLengthSeconds, deepLod, deltaTSeconds, earthMoiFactorAtAge, earthPerihelionDeg, eccentricityAt,
|
|
15
|
+
eclipseFinders, evalClimateL1, frameworkDeltaTSecondsAtJD, inclinationDeg, j2000JD, jdFromYear, jdTTFromUT,
|
|
16
|
+
julianCenturyDays, lodRealSeconds, meanLengthOfDay, meanSiderealYearDays, moonDistanceCorrected, moonDistanceKm,
|
|
17
|
+
moonDistanceKmAtYearOrNaN, moonOrbitalShift, moonSeries, moonSiderealMonth, moonSiderealMonthDaysAt,
|
|
18
|
+
moonSynodicMonthDays, oneSourceM, planetAscNodeDeg, planetEccentricity, planetInclinationDeg, planetPerihelionDeg,
|
|
19
|
+
planetSpin, publishedAxialPrecessionYearsAtYear, publishedTropicalYearSecondsAtYear, s3ArcsecPerYr,
|
|
20
|
+
siTropicalYearDays, siderealDaySeconds, siderealYearDays, spinAxisInertialRateMeanArcsecPerYr, stellarDaySeconds,
|
|
21
|
+
sunApparentLonDegAtJdUT, sunEccentricityAt, sunL0Deg, sunMeanLongitudeDegAt, sunPerihelionDegAt,
|
|
22
|
+
sunPlanetaryCompletionDeg, sunTropicalRateDegPerCy, tropicalYearDays, yearFromJD, yearLengthsM, yearToTMa,
|
|
23
|
+
} = ctx;
|
|
24
|
+
return Object.freeze({
|
|
25
|
+
time: Object.freeze({
|
|
26
|
+
yearFromJD,
|
|
27
|
+
jdFromYear,
|
|
28
|
+
siTropicalYearDays,
|
|
29
|
+
}),
|
|
30
|
+
// The Moon-Kepler mass chain — the J2000 derivation docs 24 / the website's
|
|
31
|
+
// "mass from the Moon" page narrate, published from the one place that
|
|
32
|
+
// computes it (physics 22.1.0; the pages used to carry its numbers as
|
|
33
|
+
// hand-typed literals): Kepler III on the Moon's orbit with the
|
|
34
|
+
// solar-tidal shift Δa = a·μ·m (μ the Moon's mass fraction, m the lunar
|
|
35
|
+
// small parameter T_M/T_sidereal-year), the Earth/Moon split on the
|
|
36
|
+
// DE440 mass ratio, and GM_Sun from Earth's heliocentric orbit minus
|
|
37
|
+
// GM_Earth. Every value is the J2000 snapshot the rest of the model runs
|
|
38
|
+
// on; the of-date Moon distance is the recession history (epoch.*).
|
|
39
|
+
massChain: Object.freeze({
|
|
40
|
+
moonDistanceKm,
|
|
41
|
+
moonSiderealMonthDays: moonSiderealMonth,
|
|
42
|
+
siderealYearDays: meanSiderealYearDays,
|
|
43
|
+
dayLengthSeconds: meanLengthOfDay,
|
|
44
|
+
massRatioEarthMoon: MASS_RATIO_EARTH_MOON,
|
|
45
|
+
lunarSmallParameter: moonSiderealMonth / meanSiderealYearDays,
|
|
46
|
+
moonMassFraction: 1 / (MASS_RATIO_EARTH_MOON + 1),
|
|
47
|
+
solarTidalShiftKm: moonOrbitalShift,
|
|
48
|
+
moonDistanceCorrectedKm: moonDistanceCorrected,
|
|
49
|
+
gmEarthMoonSystemKm3S2: GM_EARTH_MOON_SYSTEM,
|
|
50
|
+
gmEarthKm3S2: GM_EARTH_ALONE,
|
|
51
|
+
gmMoonKm3S2: GM_MOON_ALONE,
|
|
52
|
+
gmSunPlusEarthKm3S2: GM_SUN_PLUS_EARTH,
|
|
53
|
+
gmSunKm3S2: GM_SUN,
|
|
54
|
+
sunMassKg: M_SUN,
|
|
55
|
+
earthMassKg: GM_EARTH_ALONE / G_CONSTANT,
|
|
56
|
+
gravitationalConstantKm3KgS2: G_CONSTANT,
|
|
57
|
+
}),
|
|
58
|
+
// The ONE certified Sun's mean elements of date — the lunar arguments of
|
|
59
|
+
// every runtime build their Sun from these two (the Node scene twin and
|
|
60
|
+
// the browser read them here).
|
|
61
|
+
sun: Object.freeze({
|
|
62
|
+
/** Mean longitude of date, degrees, unwrapped — L0 + 360·∫dt/T_trop (the one-family tropical year). @param {number} year @returns {number} */
|
|
63
|
+
meanLongitudeDegAt: sunMeanLongitudeDegAt,
|
|
64
|
+
/** The Sun's mean perihelion longitude of date (Earth's ϖ, mean elements), degrees, wrapped to [0, 360). @param {number} year @returns {number} */
|
|
65
|
+
perihelionLongitudeDegAt: sunPerihelionDegAt,
|
|
66
|
+
}),
|
|
67
|
+
epoch: Object.freeze({
|
|
68
|
+
yearToTMa,
|
|
69
|
+
// The Layer-2 mean day of date — the tidal + GIA base the deep-time law
|
|
70
|
+
// gives at any age (86,399.9997 s at J2000): the day the paleo anchors
|
|
71
|
+
// and the ΔT integrand ride. NOT the observable solar day of date —
|
|
72
|
+
// that is lodRealSecondsAtYear below (plan 08 storyline sweep).
|
|
73
|
+
lodSecondsAtYear: /** @param {number} year @returns {number|null} */ (year) => deepLod.lodSecondsAtAge(yearToTMa(year)),
|
|
74
|
+
// LOD_real of date — the Layer-4 observable (the simulator's Solar Day,
|
|
75
|
+
// the registry's lodRealPhysical): the kinematic day + the ecliptic term
|
|
76
|
+
// + the calibrated ΔT cycle stack. 86,400.001780 s at J2000.
|
|
77
|
+
lodRealSecondsAtYear: /** @param {number} year @returns {number} */ (year) => lodRealSeconds(year),
|
|
78
|
+
alphaAtYear: /** @param {number} year @returns {number} */ (year) => earthMoiFactorAtAge(yearToTMa(year)),
|
|
79
|
+
moonDistanceKmAtYear: /** @param {number} year @returns {number} */ (year) => moonDistanceKmAtYearOrNaN(year),
|
|
80
|
+
// D6: OF-DATE — mass-loss law / the banked planetary λ̇ ratio
|
|
81
|
+
// (identical at J2000 where the ratio ≡ 1 by construction)
|
|
82
|
+
siderealYearSecondsAtYear: /** @param {number} year @returns {number} */ (year) => yearLengthsM.siderealYearSecondsAtYear(year),
|
|
83
|
+
deltaTSecondsAtYear: deltaTSeconds,
|
|
84
|
+
// THE published of-date precession period is the one-family route: the
|
|
85
|
+
// hybrid's own equinox regression against the λ̇-corrected sidereal year
|
|
86
|
+
// (~25,771 yr at J2000 ≈ IAU), inside the banked tiers (|Δyear| ≤
|
|
87
|
+
// ONE_FAMILY_WINDOW_YEARS); beyond, the composed lunisolar period on
|
|
88
|
+
// the same J2000 anchor (the of-date wobble is unresolved there). The
|
|
89
|
+
// lunar chain's (d′) rate completion (pDynDegPerYearAt) rides THIS
|
|
90
|
+
// published period — a MATCHED TRIPLE with the eclipse gates (a
|
|
91
|
+
// 3–15 min lunar-timing shift was measured when it moved).
|
|
92
|
+
axialPrecessionYearsAtYear: publishedAxialPrecessionYearsAtYear,
|
|
93
|
+
// The same publication rule for the mean tropical year of date (SI s):
|
|
94
|
+
// one-family inside the window, the tidal-chain mean beyond.
|
|
95
|
+
tropicalYearSecondsAtYear: publishedTropicalYearSecondsAtYear,
|
|
96
|
+
}),
|
|
97
|
+
// Plan 06 Phase 3 S3 → S5 — the lunisolar precession clock as a
|
|
98
|
+
// first-class surface: Earth's spin clock, ONE home for its published
|
|
99
|
+
// faces, spoken in PERIODS and their RATIOS — no unit, no integer.
|
|
100
|
+
// ONE J2000 reading: every face reads 25,771.6 yr at J2000 — the
|
|
101
|
+
// of-date period (the published family, seamed at ±2 Myr) and the
|
|
102
|
+
// composed mean T_p(t) (the deep-time clock, anchored on the same
|
|
103
|
+
// derived value). The composition's terms; the apsidal period from the
|
|
104
|
+
// one family's own apsidal rate; the two ratios the owner found
|
|
105
|
+
// wandering by hand — T_aps/T_p (4.33 at J2000, 0.84 … 9.9 across
|
|
106
|
+
// ±26 kyr) and T_peri/T_p with T_peri = 1/(1/T_p + 1/T_aps) the
|
|
107
|
+
// perihelion-of-date period (0.812 at J2000) — on the of-date T_p.
|
|
108
|
+
lunisolar: Object.freeze({
|
|
109
|
+
/** The mean lunisolar precession period T_p(t), years — 1,296,000/the precession RATE of date (25,771.6 at J2000): THE published deep-time clock. @param {number} year @returns {number} */
|
|
110
|
+
meanPeriodYearsAtYear: (year) => { const p = deepLod.lunisolarPrecessionPeriodYearsAtAge(yearToTMa(year)); return p === null ? certifiedAxialPrecessionJ2000Years() : p; },
|
|
111
|
+
/** THE PRECESSION RATE OF DATE ψ̇(t) = [ω/ω₀]·p₀·[f_S + (1 − f_S)(a₀/a_M)³] × cos ε̄(t)/cos ε̄(0), ″/yr — the constant's scaling on the spin and the lunar torque times the cited mean obliquity's cosine (plan 12 §8 option (a); p₀ = 50.2880, the IAU 2006 input). @param {number} year @returns {number} */
|
|
112
|
+
meanRateArcsecPerYrAtYear: (year) => { const r = deepLod.lunisolarPrecessionRateArcsecPerYrAtAge(yearToTMa(year)); return r === null ? 1296000 / certifiedAxialPrecessionJ2000Years() : r; },
|
|
113
|
+
/** THE PRECESSION CONSTANT OF DATE as a rate on the J2000 obliquity, ″/yr — the spin and torque scaling alone (the hybrid obliquity integration's integrand: its own ŝ·n̂ carries the cosine). @param {number} year @returns {number} */
|
|
114
|
+
torqueRateArcsecPerYrAtYear: (year) => { const r = deepLod.lunisolarTorqueRateArcsecPerYrAtAge(yearToTMa(year)); return r === null ? 1296000 / certifiedAxialPrecessionJ2000Years() : r; },
|
|
115
|
+
/** 1,296,000/the torque rate, years. @param {number} year @returns {number} */
|
|
116
|
+
torquePeriodYearsAtYear: (year) => { const p = deepLod.lunisolarTorquePeriodYearsAtAge(yearToTMa(year)); return p === null ? certifiedAxialPrecessionJ2000Years() : p; },
|
|
117
|
+
/** cos ε̄(t)/cos ε̄(0) — the rate of date's obliquity factor on the constant (1 at J2000; 1.0075 at the Devonian, 1.0245 at 2.46 Ga). @param {number} year @returns {number} */
|
|
118
|
+
precessionObliquityFactorAtYear: (year) => { const f = deepLod.precessionObliquityFactorAtAge(yearToTMa(year)); return f === null ? 1 : f; },
|
|
119
|
+
/** THE CITED MEAN OBLIQUITY OF DATE ε̄(t), degrees — Farhat et al. 2022's own column of the Earth–Moon history (a Myr-scale MEAN: 23.25° at age 0 against the J2000 instant 23.44°; 22.23° Devonian, 19.73° at 2.46 Ga); read as the shape cos ε̄(t)/cos ε̄(0) on the precession rate. NaN beyond the input's span (4,429 Ma); forward of J2000 the J2000 slope is held. @param {number} year @returns {number} */
|
|
120
|
+
meanObliquityCitedDegAtYear: (year) => { const e = chain.meanObliquityCitedDegAtAge(yearToTMa(year)); return e === null ? NaN : e; },
|
|
121
|
+
/** The of-date period — the one-family beat inside ±2 Myr, the composed mean beyond. @param {number} year @returns {number} */
|
|
122
|
+
ofDatePeriodYearsAtYear: publishedAxialPrecessionYearsAtYear,
|
|
123
|
+
/** f_S, the solar fraction of the J2000 precession torque. */
|
|
124
|
+
solarShareJ2000: EPOCH_PARAMS.precessionSolarShareJ2000,
|
|
125
|
+
/** THE PRECESSION OF DATE — the solar-torque factor 1 + f_S·([(1 − e²)/(1 − e₀²)]^(−3/2) − 1) at the eccentricity of date (1 at J2000; +3.2·10⁻⁴ on the million-year mean). The spin integration multiplies it into the secular rate. @param {number} year @returns {number} */
|
|
126
|
+
solarTorqueFactorOfDateAtYear: (year) => oneSourceM.precessionOfDateFactorsAt(year).solarTorque,
|
|
127
|
+
/** THE PRECESSION OF DATE — J₂(t)/J₂₀, the oblateness of date from the GIA channel (ψ̇ ∝ J₂; 1 at J2000, bounded ±5·10⁻⁴; dJ₂/dt at J2000 = the observed satellite rate). @param {number} year @returns {number} */
|
|
128
|
+
ellipticityRatioOfDateAtYear: (year) => oneSourceM.precessionOfDateFactorsAt(year).ellipticity,
|
|
129
|
+
/** (a₀/a_M(t))³ — the lunar torque's growth on the recession history. @param {number} year @returns {number} */
|
|
130
|
+
lunarTorqueFactorAtYear: (year) => { const f = deepLod.lunarTorqueFactorAtAge(yearToTMa(year)); return f === null ? 1 : f; },
|
|
131
|
+
/** f_S + (1 − f_S)(a₀/a_M)³ — the torque term of the composed precession rate. @param {number} year @returns {number} */
|
|
132
|
+
torqueTermAtYear: (year) => { const t = deepLod.precessionTorqueTermAtAge(yearToTMa(year)); return t === null ? 1 : t; },
|
|
133
|
+
/** The hybrid's precession constant α = p₀ / cos ε₀, ″/yr (p₀ the derived J2000 rate, ε₀ the J2000 obliquity input; 54.81). */
|
|
134
|
+
torqueConstantJ2000ArcsecPerYr: (1296000 / certifiedAxialPrecessionJ2000Years()) / Math.cos((C.earthOrbital.obliquityJ2000_deg * Math.PI) / 180),
|
|
135
|
+
/** |s₃|, the dominant nodal mode of Earth's orbit — the largest-amplitude ζ mode of the banked deep secular modes, ″/yr (18.85; the obliquity beat's partner). ONE home for the registry, the browser and the API. */
|
|
136
|
+
nodalModeS3ArcsecPerYr: s3ArcsecPerYr,
|
|
137
|
+
/** The ecliptic (nodal) precession period 1,296,000/|s₃|, years (68,751) — an orbital quantity, fixed at every epoch at the two-body level. */
|
|
138
|
+
nodalPeriodYears: 1296000 / s3ArcsecPerYr,
|
|
139
|
+
/** THE SPIN AXIS'S INERTIAL PRECESSION RATE OF DATE, ″/yr — the composed rate scaled by the
|
|
140
|
+
* hybrid's self-anchor factor (the inertial-to-general ratio at J2000, the multiplicative form
|
|
141
|
+
* the obliquity integration itself applies): 50.385 at J2000 (series-driven). The obliquity beat and the
|
|
142
|
+
* obliquity lines ride THIS rate; the general precession (meanRateArcsecPerYrAtYear) is the
|
|
143
|
+
* equinox along the ecliptic of date. @param {number} year @returns {number} */
|
|
144
|
+
spinAxisInertialRateArcsecPerYrAtYear: (year) => {
|
|
145
|
+
const r = deepLod.lunisolarPrecessionRateArcsecPerYrAtAge(yearToTMa(year));
|
|
146
|
+
const psiDot = r === null ? 1296000 / certifiedAxialPrecessionJ2000Years() : r;
|
|
147
|
+
return psiDot * (certifiedAxialPrecessionJ2000Years() / oneSourceM.axialPrecessionYearsLunisolarJ2000);
|
|
148
|
+
},
|
|
149
|
+
/** The obliquity beat 2π/(ψ̇ᵢₙ(t) − |s₃|), years — the SHIPPED deep-time obliquity period at an INSTANT
|
|
150
|
+
* (falsification leg 1; 41,098 at J2000). ψ̇ᵢₙ is the spin axis's INERTIAL rate (above): the equator
|
|
151
|
+
* against the ecliptic's nodal mode in the inertial frame, the rate the hybrid obliquity integration
|
|
152
|
+
* self-anchors on — not the general precession, which reads the beat 0.3 % long (41,224). v23.0: a
|
|
153
|
+
* dated record sees the beat of the pole rate's mean over its own window, with the pole's of-date
|
|
154
|
+
* factors (obliquityPeriodRealizedYears below: 40,927 over the LR04 record, the climate formula's p+s₀
|
|
155
|
+
* line; La2004's own series reads 40,900 on the same window — compare realized with realized, never
|
|
156
|
+
* this instant with Laskar's long-window precession frequency 50.476). @param {number} year @returns {number} */
|
|
157
|
+
obliquityBeatYearsAtYear: (year) => {
|
|
158
|
+
const r = deepLod.lunisolarPrecessionRateArcsecPerYrAtAge(yearToTMa(year));
|
|
159
|
+
const psiDot = r === null ? 1296000 / certifiedAxialPrecessionJ2000Years() : r;
|
|
160
|
+
const psiDotInertial = psiDot * (certifiedAxialPrecessionJ2000Years() / oneSourceM.axialPrecessionYearsLunisolarJ2000);
|
|
161
|
+
return 1296000 / (psiDotInertial - s3ArcsecPerYr);
|
|
162
|
+
},
|
|
163
|
+
/** THE REALIZED POLE RATE OVER A WINDOW, ″/yr — see the one home above (the mean of the inertial rate of
|
|
164
|
+
* date with its three of-date factors); the rate the obliquity lines of a record spanning the window carry. */
|
|
165
|
+
spinAxisInertialRateMeanArcsecPerYr,
|
|
166
|
+
/** THE REALIZED OBLIQUITY PERIOD OVER A WINDOW, years — 1,296,000/(⟨ψ̇ᵢₙ⟩_window − |s₃|): the period a record
|
|
167
|
+
* spanning [yearFrom, yearTo] sees (40,930 over the LR04 record 0–5.32 Ma, 41,018 over the last Myr); the
|
|
168
|
+
* J2000 beat (obliquityBeatYearsAtYear) is its instantaneous limit.
|
|
169
|
+
* @param {number} yearFrom @param {number} yearTo @returns {number} */
|
|
170
|
+
obliquityPeriodRealizedYears: (yearFrom, yearTo) => 1296000 / (spinAxisInertialRateMeanArcsecPerYr(yearFrom, yearTo) - s3ArcsecPerYr),
|
|
171
|
+
/** The apsidal (perihelion vs the stars) period of date, JULIAN years — the ONE movement's own apsidal rate (the scene's perihelion; anom/(anom − sid) of the one family, ≡ 360°/apsidalRateFixedArcsecPerJulianYr), inside the published window only; null beyond. Before 2026-09 this rode the planet chain's secular tangent, which parted from the scene's perihelion passages by seconds of anomalistic year within a few millennia (year-lengths.cjs). @param {number} year @returns {number|null} */
|
|
172
|
+
apsidalPeriodYearsAtYear: (year) => (Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS ? yearLengthsM.inclinationPrecessionYearsAtYear(year) : null),
|
|
173
|
+
/** T_aps(t) / T_p(t) — the apsidal period in of-date precession periods (4.33 at J2000, a reading; 0.84 … 9.9 across ±26 kyr, measured); null beyond the published window. @param {number} year @returns {number|null} */
|
|
174
|
+
apsidalPerPrecessionAtYear: (year) => {
|
|
175
|
+
if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
|
|
176
|
+
return yearLengthsM.inclinationPrecessionYearsAtYear(year) / publishedAxialPrecessionYearsAtYear(year);
|
|
177
|
+
},
|
|
178
|
+
/** T_peri(t) = 1/(1/T_p + 1/T_aps) — the perihelion-of-date period (equinox precession + inertial perihelion motion, frame arithmetic at every epoch), JULIAN years, on the of-date T_p — ≡ the one family's anom/(anom − trop); null beyond the published window. @param {number} year @returns {number|null} */
|
|
179
|
+
periOfDatePeriodYearsAtYear: (year) => {
|
|
180
|
+
if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
|
|
181
|
+
const tp = publishedAxialPrecessionYearsAtYear(year), taps = yearLengthsM.inclinationPrecessionYearsAtYear(year);
|
|
182
|
+
return 1 / (1 / tp + 1 / taps);
|
|
183
|
+
},
|
|
184
|
+
/** T_peri(t) / T_p(t) (0.812 at J2000 — the J2000 reading); null beyond the published window. @param {number} year @returns {number|null} */
|
|
185
|
+
periOfDatePerPrecessionAtYear: (year) => {
|
|
186
|
+
if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
|
|
187
|
+
const tp = publishedAxialPrecessionYearsAtYear(year), taps = yearLengthsM.inclinationPrecessionYearsAtYear(year);
|
|
188
|
+
return (1 / (1 / tp + 1 / taps)) / tp;
|
|
189
|
+
},
|
|
190
|
+
/** The published of-date window, years from 2000. */
|
|
191
|
+
publishedWindowYears: ONE_FAMILY_WINDOW_YEARS,
|
|
192
|
+
/** THE SPIN AXIS'S INERTIAL PRECESSION PERIOD at J2000, years (25,722 in the shipped,
|
|
193
|
+
* series-driven configuration) — the rate the hybrid obliquity integration self-anchors
|
|
194
|
+
* ŝ on (earth/deep-orbital-history, D4e): the general-precession anchor p₀ PLUS the
|
|
195
|
+
* planetary mean the N-body ecliptic's own motion carries (+0.097 ″/yr ≡ IAU's planetary
|
|
196
|
+
* precession ψ_A − p_A; the bare 18-mode table anchors 0.18 — the g₂-gap trap: pass the
|
|
197
|
+
* secular series). Two rates, two uses — the obliquity line frequencies p + s_i (the
|
|
198
|
+
* spin axis against the ecliptic's nodal modes, in the inertial frame) carry THIS
|
|
199
|
+
* rate; the climatic-precession lines p + g_i (the perihelion from the equinox along
|
|
200
|
+
* the ecliptic of date) carry p₀. */
|
|
201
|
+
spinAxisInertialPeriodYearsJ2000: oneSourceM.axialPrecessionYearsLunisolarJ2000,
|
|
202
|
+
/** The same as a rate, ″/yr (50.385 at J2000 with the series; p₀ = 50.288 is the general precession). */
|
|
203
|
+
spinAxisInertialRateArcsecPerYrJ2000: 1296000 / oneSourceM.axialPrecessionYearsLunisolarJ2000,
|
|
204
|
+
}),
|
|
205
|
+
earth: Object.freeze({
|
|
206
|
+
perihelionLongitudeDeg: earthPerihelionDeg,
|
|
207
|
+
// THE published obliquity is the hybrid — one torque law integrated on
|
|
208
|
+
// the dynamical orbit plane of the N-body chain, zero fitted constants
|
|
209
|
+
// (≡ La2004 to ≤ 4″ over ±50 kyr).
|
|
210
|
+
// Beyond the ζ series' span (±10 Myr) the hybrid carries NO tidal evolution
|
|
211
|
+
// of the mean obliquity (nothing in ds/dt = α(ŝ·n̂)(ŝ×n̂) moves ŝ·n̂'s mean):
|
|
212
|
+
// its deep mean is the Quaternary mean on the tail's mean plane (plan 12
|
|
213
|
+
// §8.3). The cited mean obliquity of date is `meanObliquityCitedDeg`.
|
|
214
|
+
obliquityDeg: /** @param {number} year @returns {number} */ (year) => oneSourceM.epsAt(year),
|
|
215
|
+
/** The hybrid's own domain, [yearFrom, yearTo] — the banked ζ series' span, ±10 Myr about J2000 (plan 12 §8.5: the published surfaces serve `obliquityDeg` inside it only; null without a series, i.e. a bare createModel()). */
|
|
216
|
+
obliquityHybridDomainYears: oneSourceM.obliquityHybridDomainYears,
|
|
217
|
+
/** The cited mean obliquity of date ε̄(t) (Farhat et al. 2022's column; plan 12 §8 option (a)), degrees — a Myr-scale mean; NaN beyond 4,429 Ma. @param {number} year @returns {number} */
|
|
218
|
+
meanObliquityCitedDeg: /** @param {number} year @returns {number} */ (year) => { const e = chain.meanObliquityCitedDegAtAge(yearToTMa(year)); return e === null ? NaN : e; },
|
|
219
|
+
eccentricity: eccentricityAt,
|
|
220
|
+
inclinationDeg,
|
|
221
|
+
ascendingNodeDeg,
|
|
222
|
+
}),
|
|
223
|
+
// The year lengths of date in DAYS OF THE EPOCH (the published SI years
|
|
224
|
+
// over the kinematic day of date — year-day-lengths.js) and the day
|
|
225
|
+
// lengths of date in SI seconds (one-source-movement.js). The published
|
|
226
|
+
// SI year lengths themselves are `yearLengths` (the one-family route) and
|
|
227
|
+
// the seamed `epoch.*AtYear` surfaces above.
|
|
228
|
+
lengths: Object.freeze({
|
|
229
|
+
tropicalYearDays,
|
|
230
|
+
siderealYearDays,
|
|
231
|
+
anomalisticYearDays,
|
|
232
|
+
dayLengthSeconds,
|
|
233
|
+
lodRealSeconds,
|
|
234
|
+
siderealDaySeconds,
|
|
235
|
+
stellarDaySeconds,
|
|
236
|
+
}),
|
|
237
|
+
// Plan 06 R1: the instants are the crossings of the ONE Sun (the
|
|
238
|
+
// certified completed Sun the scene renders), UT model-JD; the RA at a
|
|
239
|
+
// crossing is the target longitude by construction (λ = 0/90/180/270 ⇒
|
|
240
|
+
// RA = 0/90/180/270, any obliquity); the per-type year length is the
|
|
241
|
+
// interval between successive crossings (SI days).
|
|
242
|
+
cardinal: Object.freeze({
|
|
243
|
+
jd: /** @param {number} year @param {string} type @returns {number} */ (year, type) => cardinalCrossingJdUT(year, type),
|
|
244
|
+
// R4c: the crossing nearest a UT instant (a JD seed — for callers whose
|
|
245
|
+
// year coordinate is not the model year, e.g. a calendar year's midpoint).
|
|
246
|
+
jdNearUT: /** @param {number} jdUT @param {string} type @returns {number} */ (jdUT, type) => cardinalCrossingNearJdUT(jdUT, type),
|
|
247
|
+
raDeg: /** @param {number} year @param {string} type @returns {number} */ (year, type) => { void year; return cardinalTargetDeg(type); },
|
|
248
|
+
yearLengthDays: /** @param {number} year @param {string} type @returns {number} */ (year, type) => cardinalCrossingJdUT(year + 1, type) - cardinalCrossingJdUT(year, type),
|
|
249
|
+
}),
|
|
250
|
+
// The one-source cardinal STRUCTURE — the EoC layer on the movement's own
|
|
251
|
+
// e(t)/ϖ(t), valid at every epoch (mode tier). Absolute dates deliberately
|
|
252
|
+
// absent; `cardinal` above serves the instants.
|
|
253
|
+
cardinalStructure: Object.freeze({
|
|
254
|
+
// D6: year LENGTHS gain the λ̇ drift coherently (rate-form
|
|
255
|
+
// correction — beats stay invariant); offsets/spreads keep the raw
|
|
256
|
+
// form (μs-class / second-order there).
|
|
257
|
+
yearLengthSeconds: /** @param {number} year @param {'VE'|'SS'|'AE'|'WS'} type @returns {number} */ (year, type) => yearLengthsM.cardinal.yearLengthSeconds(year, type),
|
|
258
|
+
eocOffsetSeconds: /** @param {number} year @param {'VE'|'SS'|'AE'|'WS'} type @returns {number} */ (year, type) => yearLengthsM.cardinal.eocOffsetSeconds(year, type),
|
|
259
|
+
spreadSeconds: /** @param {number} year */ (year) => yearLengthsM.cardinal.spreadSeconds(year),
|
|
260
|
+
anomalisticYearSeconds: /** @param {number} year @returns {number} */ (year) => yearLengthsM.anomalisticYearSecondsAtYear(year),
|
|
261
|
+
}),
|
|
262
|
+
// THE ONE of-date year-length family + its beats (S2; SI seconds) —
|
|
263
|
+
// the single surface the panel, charts, API and website consume.
|
|
264
|
+
yearLengths: yearLengthsM,
|
|
265
|
+
moon: Object.freeze({
|
|
266
|
+
distanceKmAtYear: /** @param {number} year @returns {number} */ (year) => moonDistanceKmAtYearOrNaN(year),
|
|
267
|
+
siderealMonthDaysAtYear: moonSiderealMonthDaysAt,
|
|
268
|
+
synodicMonthDays: moonSynodicMonthDays,
|
|
269
|
+
// The apparent-position chain (truncated Meeus Ch. 47 series on
|
|
270
|
+
// framework-native arguments). JD(UT) axis — UT→TT applied internally.
|
|
271
|
+
lonDegAtJD: /** @param {number} jd @returns {number} */ (jd) => moonSeries.truncatedLonDeg(jd),
|
|
272
|
+
betaDegAtJD: /** @param {number} jd @returns {number} */ (jd) => moonSeries.truncatedBetaDeg(jd),
|
|
273
|
+
distanceKmAtJD: /** @param {number} jd @returns {number} */ (jd) => moonSeries.truncatedDistanceKm(jd),
|
|
274
|
+
}),
|
|
275
|
+
eclipse: Object.freeze({
|
|
276
|
+
sunLonDegAtJD: /** @param {number} jd @returns {number} */ (jd) => eclipseFinders.sunLonDegAt(jd),
|
|
277
|
+
// The COMPLETED tier Sun (K8b follow-up, owner-approved injection):
|
|
278
|
+
// the bare finder Sun minus the DERIVED planetary-completion table —
|
|
279
|
+
// 70 framework-carrier terms plus the 6.44″ Earth-around-EMB wobble
|
|
280
|
+
// (the "lunar equation"; eclipse/sun-planetary-completion.cjs, zero
|
|
281
|
+
// fitted constants). The finders themselves deliberately stay bare
|
|
282
|
+
// (their certified canon statistics were produced on the bare form;
|
|
283
|
+
// besselian.cjs applies the same subtraction internally). This
|
|
284
|
+
// surface exists for the SCENE tier's E5 wheel-Sun bridge, so the
|
|
285
|
+
// rendered Sun carries the model's own derived apparent-class terms.
|
|
286
|
+
// Clock: the completion argument rides TT centuries from the same
|
|
287
|
+
// framework ΔT the besselian composition uses.
|
|
288
|
+
sunLonCompletedDegAtJD: /** @param {number} jd @returns {number} */ (jd) =>
|
|
289
|
+
eclipseFinders.sunLonDegAt(jd)
|
|
290
|
+
- sunPlanetaryCompletionDeg((jdTTFromUT(jd) - j2000JD) / julianCenturyDays),
|
|
291
|
+
/** The APPARENT Sun (completed geometric − the derived aberration constant + the leading nutation terms on the model's own arguments) — the quantity Horizons' observer ecliptic longitude is; the cardinal instants are its crossings (plan 06 R1/I1). @param {number} jdUT @returns {number} */
|
|
292
|
+
sunApparentLonDegAtJD: /** @param {number} jdUT @returns {number} */ (jdUT) => sunApparentLonDegAtJdUT(jdUT),
|
|
293
|
+
findLunarInRange: /** @param {number} jdStart @param {number} jdEnd */ (jdStart, jdEnd) => eclipseFinders.findLunarEclipsesInRange(jdStart, jdEnd),
|
|
294
|
+
findSolarInRange: /** @param {number} jdStart @param {number} jdEnd */ (jdStart, jdEnd) => eclipseFinders.findSolarEclipsesInRange(jdStart, jdEnd),
|
|
295
|
+
deltaTSecondsAtJD: frameworkDeltaTSecondsAtJD,
|
|
296
|
+
/** The ΔT trend anchor at J2000 (seconds): the TT − UT bridge every finder axis adds to a
|
|
297
|
+
* true-UT JD. The joint ΔT fit's output, shipped in its own artifact (FIT.DT_ANCHOR —
|
|
298
|
+
* plan 14: never a constants-file input), exposed here so no consumer reaches into the
|
|
299
|
+
* constants for it. */
|
|
300
|
+
ttBridgeSeconds: F.DT_ANCHOR.deltaTStartSeconds,
|
|
301
|
+
// E4 — the framework-native Sun deps, exported so the OTHER finder
|
|
302
|
+
// construction sites (tools/verify/eclipse-audit.js, the browser
|
|
303
|
+
// _eclipse twins) spread the SAME assembly into their own
|
|
304
|
+
// createEclipseFinders call instead of triplicating it (the
|
|
305
|
+
// three-runtimes rule — cf. moon-distance-history):
|
|
306
|
+
frameworkSunDeps: Object.freeze({
|
|
307
|
+
sunMeanLongitudeJ2000Deg: sunL0Deg,
|
|
308
|
+
tropicalRateDegPerCy: sunTropicalRateDegPerCy,
|
|
309
|
+
eccentricityAt: sunEccentricityAt,
|
|
310
|
+
perihelionLongitudeDegAt: sunPerihelionDegAt,
|
|
311
|
+
meanLongitudeDegAt: sunMeanLongitudeDegAt,
|
|
312
|
+
}),
|
|
313
|
+
// 20.3g location tier (see eclipse/besselian.cjs):
|
|
314
|
+
umbraGroundAtJD: /** @param {number} jd @returns {{latDeg: number, lonDeg: number} | null} */ (jd) => besselian.umbraGroundAt(jd),
|
|
315
|
+
/** THE ONE GMST — mean sidereal time at Greenwich, degrees, at a UT JD (eclipse/besselian.cjs computeGmstDeg; the observer tier's hour angle). @param {number} jdUT @returns {number} */
|
|
316
|
+
gmstDegAtJD: (jdUT) => besselian.gmstDeg(jdUT),
|
|
317
|
+
solarLocalCircumstances: /** @param {number} jdGreatest @param {number} latDeg @param {number} lonDeg */ (jdGreatest, latDeg, lonDeg) => besselian.localCircumstances(jdGreatest, latDeg, lonDeg),
|
|
318
|
+
}),
|
|
319
|
+
climate: Object.freeze({
|
|
320
|
+
l1OrbitalPermil: evalClimateL1,
|
|
321
|
+
}),
|
|
322
|
+
planets: Object.freeze({
|
|
323
|
+
keys: Object.freeze([...PLANET_KEYS]),
|
|
324
|
+
record: /** @param {string} k @returns {Record<string, any>|undefined} */ (k) => PUBLISHED_PLANET_RECORDS[k],
|
|
325
|
+
perihelionLongitudeDeg: planetPerihelionDeg,
|
|
326
|
+
ascendingNodeInvPlaneDeg: planetAscNodeDeg,
|
|
327
|
+
invPlaneInclinationDeg: planetInclinationDeg,
|
|
328
|
+
eccentricity: planetEccentricity,
|
|
329
|
+
spin: planetSpin,
|
|
330
|
+
}),
|
|
331
|
+
});
|
|
332
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The time axis — exact JD ↔ model-year conversion on the SI axis.
|
|
3
|
+
*
|
|
4
|
+
* One slice of `assembleModel` (../model.js): receives the context the earlier slices built, returns the bindings the later ones read.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** @param {import('./inv-plane-elements.js').Ctx} ctx @returns the bindings the later slices read */
|
|
8
|
+
export function assembleTimeAxis(ctx) {
|
|
9
|
+
const { meanTropicalYearJ2000Seconds, startmodelJD, startmodelYear } = ctx;
|
|
10
|
+
// The model's `year` inputs live on the SI axis (the axis the fits were
|
|
11
|
+
// anchored on — tools/lib `_jdToSIyear`): linear in SI 86400-s days from the
|
|
12
|
+
// model start, so the JD↔year map is closed-form and exact to double
|
|
13
|
+
// precision. Callers holding an exact JD (e.g. 2058768.5385006 TT) convert
|
|
14
|
+
// here and NEVER roll their own — a caller-side linear-vs-calendar mix once
|
|
15
|
+
// put the eclipse umbra twin 8 km off (§12h; ≤1 m once unified).
|
|
16
|
+
const siTropicalYearDays = meanTropicalYearJ2000Seconds / 86400;
|
|
17
|
+
/** Model year (SI axis) at a JD(TT). @param {number} jd @returns {number} */
|
|
18
|
+
const yearFromJD = (jd) => startmodelYear + (jd - startmodelJD) / siTropicalYearDays;
|
|
19
|
+
/** JD(TT) at a model year (SI axis). @param {number} year @returns {number} */
|
|
20
|
+
const jdFromYear = (year) => startmodelJD + (year - startmodelYear) * siTropicalYearDays;
|
|
21
|
+
|
|
22
|
+
return { jdFromYear, siTropicalYearDays, yearFromJD };
|
|
23
|
+
}
|
|
24
|
+
/** @typedef {import('./inv-plane-elements.js').Ctx & ReturnType<typeof assembleTimeAxis>} Ctx */
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The J2000 precession anchor p₀; the kinematic day of date and the year lengths in days of the epoch.
|
|
3
|
+
*
|
|
4
|
+
* One slice of `assembleModel` (../model.js): receives the context the earlier slices built, returns the bindings the later ones read.
|
|
5
|
+
*/
|
|
6
|
+
import { ONE_FAMILY_WINDOW_YEARS } from '../earth/year-lengths.cjs';
|
|
7
|
+
|
|
8
|
+
/** @param {import('./earth-scalars.js').Ctx} ctx @returns the bindings the later slices read */
|
|
9
|
+
export function assembleYearDayLengths(ctx) {
|
|
10
|
+
const { chain, late, deepLod, meanLengthOfDay, yearToTMa } = ctx;
|
|
11
|
+
// The year lengths of date in DAYS are the published SI year lengths over
|
|
12
|
+
// the kinematic day of date; the kinematic day of date is the Layer-0 tidal
|
|
13
|
+
// mean LOD, exactly ω₀ (the SI day) at J2000.
|
|
14
|
+
/** THE J2000 precession anchor p₀: the IAU 2006 general precession in
|
|
15
|
+
* longitude at J2000 (astro-reference.json
|
|
16
|
+
* earthOrbital.generalPrecessionJ2000_arcsecPerYr = 50.28796195 ″/yr),
|
|
17
|
+
* stated as the period 1,296,000/p_A = 25,771.575 Julian years. ONE home:
|
|
18
|
+
* the composed clock's p₀, the hybrid's self-anchor and the lunisolar
|
|
19
|
+
* surface all read it (the identifier predates the anchor's move onto the
|
|
20
|
+
* IAU input). @returns {number} */
|
|
21
|
+
function certifiedAxialPrecessionJ2000Years() {
|
|
22
|
+
return chain.certifiedAxialPrecessionJ2000Years(); // the ONE home: the deep-time chain's export (1,296,000 / p_A on the same constants)
|
|
23
|
+
}
|
|
24
|
+
/** Kinematic day of date (Layer 0 tidal mean LOD; ω₀ at J2000). Past the
|
|
25
|
+
* tidal-lock asymptote the chain is null — the J2000 day stands in.
|
|
26
|
+
* @param {number} year @returns {number} */
|
|
27
|
+
const dayLengthSeconds = (year) => deepLod.lodSecondsAtAge(yearToTMa(year)) ?? meanLengthOfDay;
|
|
28
|
+
/** Sidereal year of date in days of the epoch — the published SI sidereal
|
|
29
|
+
* year (the λ̇ channel inside the one-family window, the mass-loss law
|
|
30
|
+
* beyond) over the kinematic day of date. @param {number} year @returns {number} */
|
|
31
|
+
const siderealYearDays = (year) => late.publishedSiderealYearSecondsAtYear(year) / dayLengthSeconds(year);
|
|
32
|
+
/** Anomalistic year of date in days of the epoch — the published SI
|
|
33
|
+
* anomalistic year (one-family inside its window; NaN beyond, where the
|
|
34
|
+
* movement's apsidal line is not resolved). @param {number} year @returns {number} */
|
|
35
|
+
const anomalisticYearDays = (year) => {
|
|
36
|
+
const s = Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS ? late.yearLengthsM.anomalisticYearSecondsAtYear(year) : NaN;
|
|
37
|
+
return s / dayLengthSeconds(year);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return { anomalisticYearDays, certifiedAxialPrecessionJ2000Years, dayLengthSeconds, siderealYearDays };
|
|
41
|
+
}
|
|
42
|
+
/** @typedef {import('./earth-scalars.js').Ctx & ReturnType<typeof assembleYearDayLengths>} Ctx */
|