@essrt/physics 23.3.2 → 23.6.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 +6 -1
- package/package.json +2 -2
- package/src/constants/coefficients.d.ts +5 -1
- package/src/constants/coefficients.js +3 -2
- package/src/constants/generated.d.ts +2 -3
- package/src/constants/generated.js +3 -4
- package/src/constants/units.cjs +4 -1
- package/src/deltat/deep-time.cjs +37 -72
- package/src/index.js +35 -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 +330 -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 +1 -1
- package/types/constants/coefficients.d.ts +5 -1
- package/types/constants/generated.d.ts +2 -3
- package/types/constants/units.d.cts +3 -0
- package/types/deltat/deep-time.d.cts +18 -24
- 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 +52 -0
- package/types/model/surface.d.ts +279 -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 +9 -81
- package/types/moon/arguments.d.cts +5 -11
- package/types/planets/keplerian-chain.d.cts +3 -1
|
@@ -0,0 +1,330 @@
|
|
|
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
|
+
solarLocalCircumstances: /** @param {number} jdGreatest @param {number} latDeg @param {number} lonDeg */ (jdGreatest, latDeg, lonDeg) => besselian.localCircumstances(jdGreatest, latDeg, lonDeg),
|
|
316
|
+
}),
|
|
317
|
+
climate: Object.freeze({
|
|
318
|
+
l1OrbitalPermil: evalClimateL1,
|
|
319
|
+
}),
|
|
320
|
+
planets: Object.freeze({
|
|
321
|
+
keys: Object.freeze([...PLANET_KEYS]),
|
|
322
|
+
record: /** @param {string} k @returns {Record<string, any>|undefined} */ (k) => PUBLISHED_PLANET_RECORDS[k],
|
|
323
|
+
perihelionLongitudeDeg: planetPerihelionDeg,
|
|
324
|
+
ascendingNodeInvPlaneDeg: planetAscNodeDeg,
|
|
325
|
+
invPlaneInclinationDeg: planetInclinationDeg,
|
|
326
|
+
eccentricity: planetEccentricity,
|
|
327
|
+
spin: planetSpin,
|
|
328
|
+
}),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
@@ -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 { C, 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 1296000 / C.earthOrbital.generalPrecessionJ2000_arcsecPerYr;
|
|
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 */
|