@essrt/physics 1.7.0 → 1.9.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@essrt/physics",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "ESSRT (Expanding Solar System Resonance Theory) physics core \u2014 pure, injectable-constants, no I/O, no globals, no DOM. The complete model incl. fitted coefficients; every published version immutably ships one recorded model identity.",
|
|
5
5
|
"essrt": {
|
|
6
6
|
"modelVersion": "v11.0",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"./chain-cycles": "./src/chain-cycles/index.cjs",
|
|
37
37
|
"./moon/arguments": "./src/moon/arguments.cjs",
|
|
38
38
|
"./moon/series": "./src/moon/series.cjs",
|
|
39
|
+
"./moon/series-extension": "./src/moon/series-extension.cjs",
|
|
39
40
|
"./moon/apparent": "./src/moon/apparent.cjs",
|
|
40
41
|
"./planets/geometry": "./src/planets/geometry.cjs",
|
|
41
42
|
"./planets/fibonacci-laws": "./src/planets/fibonacci-laws.cjs",
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
"./deltat/recession-history": "./src/deltat/recession-history.cjs",
|
|
53
54
|
"./climate/l1-orbital": "./src/climate/l1-orbital.cjs",
|
|
54
55
|
"./eclipse/finders": "./src/eclipse/finders.cjs",
|
|
56
|
+
"./eclipse/sun-planetary-completion": "./src/eclipse/sun-planetary-completion.cjs",
|
|
55
57
|
"./reference/published-curves": "./src/reference/published-curves.cjs",
|
|
56
58
|
"./sun/longitude-correction": "./src/sun/longitude-correction.cjs"
|
|
57
59
|
},
|
|
@@ -57,6 +57,8 @@
|
|
|
57
57
|
* @property {(dDaysTT: number) => {lonDeg: number, latDeg: number, distKm: number}} moonFullAtDaysTT
|
|
58
58
|
* full-series Moon: ecliptic-of-date longitude/latitude (deg) + distance (km), TT axis (days since J2000)
|
|
59
59
|
* @property {(jdUT: number) => number} sunLonDegAt - geometric mean sun longitude (deg), JD(UT) axis with the finder's internal ΔT
|
|
60
|
+
* @property {(T: number) => number} sunCompletionDeg - planetary completion (deg) at T centuries TT, SUBTRACTED from the finder sun (see eclipse/sun-planetary-completion.cjs; the finders deliberately stay without it — their fitted anchors and certified canon statistics were produced on the bare form, and elongation-class timing absorbs the omission into the fitted phases)
|
|
61
|
+
* @property {(T: number) => {dLonDeg: number, dLatDeg: number}} moonExtensionAt - derived series-extension tail (deg) at T centuries TT, ADDED to the full-series Moon longitude/latitude (see moon/series-extension.cjs; same finder-scoping rationale as sunCompletionDeg — the finders stay on the bare series)
|
|
60
62
|
* @property {(jd: number) => number} deltaTSecondsAt - framework ΔT (J2000-zeroed convention)
|
|
61
63
|
* @property {(year: number) => number} obliquityDegAt - framework obliquity (deg) at calendar year
|
|
62
64
|
* @property {(year: number) => number} eccentricityAt - framework Earth-orbit eccentricity at calendar year
|
|
@@ -122,32 +124,44 @@ function createBesselian(deps) {
|
|
|
122
124
|
const jb = jdUT + K.ttBridgeSeconds / 86400; // finder-axis input → its internal ΔT lands on true TT
|
|
123
125
|
const year = deps.yearFromJD(jb);
|
|
124
126
|
const eps = deps.obliquityDegAt(year) * D2R;
|
|
125
|
-
const sunLon = deps.sunLonDegAt(jb);
|
|
126
127
|
const dTT = (jb - K.j2000JD) + deps.deltaTSecondsAt(jb) / 86400;
|
|
128
|
+
const sunLon = deps.sunLonDegAt(jb) - deps.sunCompletionDeg(dTT / K.julianCenturyDays);
|
|
127
129
|
const moon = deps.moonFullAtDaysTT(dTT);
|
|
130
|
+
const ext = deps.moonExtensionAt(dTT / K.julianCenturyDays);
|
|
128
131
|
return {
|
|
129
132
|
S: eclToEq(sunLon, 0, sunDistanceKm(year, sunLon), eps),
|
|
130
|
-
M: eclToEq(moon.lonDeg, moon.latDeg, moon.distKm, eps),
|
|
133
|
+
M: eclToEq(moon.lonDeg + ext.dLonDeg, moon.latDeg + ext.dLatDeg, moon.distKm, eps),
|
|
131
134
|
};
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
/** Umbra-axis ground intersection at JD(UT): geodetic latitude, east
|
|
135
138
|
* longitude — or null when the axis misses the ellipsoid.
|
|
139
|
+
* EXACT axis ∩ ellipsoid: scaling z by 1/(1−f) turns the WGS84 quadric
|
|
140
|
+
* into a sphere of radius R_E. The earlier R_E-SPHERE intersection put
|
|
141
|
+
* the hit up to R_E·f·sin²φ ≈ 21 km above the true surface, and the
|
|
142
|
+
* offset projects into the shadow-plane metric as ~height·cos(alt) —
|
|
143
|
+
* a latitude/sun-altitude-correlated phantom error (measured: 2021
|
|
144
|
+
* Antarctica 12.8″ → 6.9″, 2008 Arctic 7.3″ → 1.6″, 2026 Iberia
|
|
145
|
+
* low-sun 4.4″ → 1.2″; NASA path tables are ellipsoid-based). The
|
|
146
|
+
* geodetic latitude is then exact for the on-surface point:
|
|
147
|
+
* tan φ = z / ((1−f)²·ρ).
|
|
136
148
|
* @param {number} jdUT @returns {{latDeg: number, lonDeg: number} | null} */
|
|
137
149
|
function umbraGroundAt(jdUT) {
|
|
138
150
|
const { S, M } = bodiesAt(jdUT);
|
|
139
151
|
const dv = [M[0] - S[0], M[1] - S[1], M[2] - S[2]];
|
|
140
152
|
const dl = Math.hypot(dv[0], dv[1], dv[2]);
|
|
141
153
|
const d = [dv[0] / dl, dv[1] / dl, dv[2] / dl];
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
const
|
|
154
|
+
const w = 1 / (1 - F);
|
|
155
|
+
const Ms = [M[0], M[1], M[2] * w], ds = [d[0], d[1], d[2] * w];
|
|
156
|
+
const A = ds[0] * ds[0] + ds[1] * ds[1] + ds[2] * ds[2];
|
|
157
|
+
const B = Ms[0] * ds[0] + Ms[1] * ds[1] + Ms[2] * ds[2];
|
|
158
|
+
const Cq = Ms[0] * Ms[0] + Ms[1] * Ms[1] + Ms[2] * Ms[2] - R_E_KM * R_E_KM;
|
|
159
|
+
const disc = B * B - A * Cq;
|
|
145
160
|
if (disc < 0) return null;
|
|
146
|
-
const s = -
|
|
161
|
+
const s = (-B - Math.sqrt(disc)) / A;
|
|
147
162
|
const hit = [M[0] + s * d[0], M[1] + s * d[1], M[2] + s * d[2]];
|
|
148
|
-
const
|
|
149
|
-
const
|
|
150
|
-
const latDeg = Math.atan(Math.tan(latGc) / ((1 - F) * (1 - F))) / D2R;
|
|
163
|
+
const rho = Math.hypot(hit[0], hit[1]);
|
|
164
|
+
const latDeg = Math.atan2(hit[2], (1 - F) * (1 - F) * rho) / D2R;
|
|
151
165
|
let lonDeg = Math.atan2(hit[1], hit[0]) / D2R - gmstDeg(jdUT);
|
|
152
166
|
lonDeg = ((lonDeg + 540) % 360) - 180;
|
|
153
167
|
return { latDeg, lonDeg };
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sun planetary completion v2 — the DERIVED table (Stage D2, plan §12i
|
|
3
|
+
* item 10; supersedes the v1 fitted 10-term table).
|
|
4
|
+
*
|
|
5
|
+
* DERIVATION, not fit: the table is extracted from the framework's OWN
|
|
6
|
+
* physics — twin epoch-phased 8-body RK4 integrations (Sun, planets, EMB)
|
|
7
|
+
* built entirely from framework constants, planet phases taken from the
|
|
8
|
+
* engine scene graph, differenced full-vs-base3 to isolate the planetary
|
|
9
|
+
* signal, with the EMB secular-perihelion channel projected out (that
|
|
10
|
+
* channel belongs to the framework's own ϖ(t)/e(t) laws). The 68 terms
|
|
11
|
+
* below are the analytic reading of that derived signal: main synodic
|
|
12
|
+
* tones plus eccentricity-modulation sidebands (main ± mean anomaly of
|
|
13
|
+
* the modulating planet, main ± M_E). Table-vs-signal fidelity 0.64″.
|
|
14
|
+
* JPL Horizons enters only as VALIDATION, never as fit target: the
|
|
15
|
+
* derived signal matches JPL residuals at corr −0.997 / slope −0.999
|
|
16
|
+
* (0.60″ combined), and shipping it takes the all-phase Sun residual
|
|
17
|
+
* 3.48″ → 2.12″, the 179-eclipse syzygy fleet 5.51″ → 3.99″, and the
|
|
18
|
+
* NASA centerline reference set 5.30″ → 3.94″ shadow-plane (jointly
|
|
19
|
+
* with the derived Moon series extension, moon/series-extension.cjs —
|
|
20
|
+
* the pre-registered acceptance was all four gates, never a subset).
|
|
21
|
+
* Instruments: tools/explore/d2-derived-sun.mjs (signal),
|
|
22
|
+
* d2-sun-table-extraction.mjs (table), d2-joint-preview.mjs /
|
|
23
|
+
* d2-widened-centerlines.mjs (validation).
|
|
24
|
+
*
|
|
25
|
+
* DECLARED INPUTS (the three non-framework residues):
|
|
26
|
+
* (i) planet/Sun mass ratios — observed IAU constants (shared with the
|
|
27
|
+
* whole framework; nothing here fits them);
|
|
28
|
+
* (ii) argument polynomials — IAU-class instrument literals, phase
|
|
29
|
+
* carriers only; their framework-native derivation is research
|
|
30
|
+
* item 20.3e;
|
|
31
|
+
* (iii) the 2lE term (+1.42″ sin 2lE) — DECLARED FITTED, not derived: a
|
|
32
|
+
* finder-annual artifact of the current SUN_HARMONICS chain, to be
|
|
33
|
+
* absorbed at the next Step-0 refit. Everything else in this file
|
|
34
|
+
* is derived. The Earth-around-EMB wobble, fitted −6.64″ in v1, is
|
|
35
|
+
* now DERIVED: amplitude a_M·μ/AU with μ = 1/(1+M_E/M_M), injected
|
|
36
|
+
* by the factory below from live package constants (6.4399″ at the
|
|
37
|
+
* current constants), sign negative in the subtract convention.
|
|
38
|
+
*
|
|
39
|
+
* THE CONSTANT-ATTRIBUTION RULE (v1's 20.3h-lite trap, still honored):
|
|
40
|
+
* the table carries NO constant term — the constant is attributed to the
|
|
41
|
+
* tier's existing anchors, so the terms ship without the +6″ syzygy-mean
|
|
42
|
+
* penalty an eclipse-sample fit produced.
|
|
43
|
+
*
|
|
44
|
+
* Sign convention: unchanged from v1 — the evaluation models
|
|
45
|
+
* (framework − truth), so consumers SUBTRACT it from the finder Sun
|
|
46
|
+
* longitude. TERMS literals are stored in the extraction's native sign
|
|
47
|
+
* (d2-sun-table.local.json) and negated in the evaluator, exactly as the
|
|
48
|
+
* validated joint-preview instrument composes them.
|
|
49
|
+
*
|
|
50
|
+
* MATCHED PAIR: the amplitudes are the residual of the CURRENT finder
|
|
51
|
+
* Sun chain (framework rate + EoC + SUN_HARMONICS) and must be
|
|
52
|
+
* RE-DERIVED whenever that chain moves — a Step-0 SUN_HARMONICS refit,
|
|
53
|
+
* an eccentricity/perihelion definition change, or 20.3e. Re-derivation
|
|
54
|
+
* is the D2 instrument chain above (regenerate d2-sun-table.local.json,
|
|
55
|
+
* re-embed). ENFORCED: PAIRED_SUN_HARMONICS_SHA256 below is the
|
|
56
|
+
* fingerprint of the SUN_LONGITUDE_HARMONICS this table was derived
|
|
57
|
+
* under; the create-model parity gate (test:model, in `npm run check`)
|
|
58
|
+
* recomputes it from live constants and fails on mismatch. The api
|
|
59
|
+
* centerline gate (≤8″ shadow-plane) backstops gross staleness
|
|
60
|
+
* independently.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
'use strict';
|
|
64
|
+
|
|
65
|
+
/** Of-date mean-longitude polynomials, degrees per Julian century TT
|
|
66
|
+
* (IAU-class instrument literals — phase carriers, see header (ii)).
|
|
67
|
+
* Body order everywhere below: Mercury, Venus, Earth (EMB), Mars,
|
|
68
|
+
* Jupiter, Saturn. */
|
|
69
|
+
const ARG_L0 = [252.250906, 181.979801, 100.466457, 355.433000, 34.351519, 50.077444];
|
|
70
|
+
const ARG_L1 = [149472.674, 58517.815676, 36000.769780, 19141.696300, 3036.302389, 1223.511013];
|
|
71
|
+
/** J2000 perihelion longitudes (deg), same body order — mean anomaly
|
|
72
|
+
* M_X = l_X − ϖ_X; slow ϖ drift is absorbed by the sidebands over the
|
|
73
|
+
* valid window. */
|
|
74
|
+
const PERI = [77.456, 131.564, 102.937, 336.060, 14.331, 93.057];
|
|
75
|
+
/** Moon mean elongation (deg/cy TT) — the EMB-wobble carrier. */
|
|
76
|
+
const ARG_D = [297.8501921, 445267.1114034];
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The derived table, extraction-native sign (negated in the evaluator):
|
|
80
|
+
* [[6 mean-longitude multipliers lMe,lV,lE,lM,lJ,lS],
|
|
81
|
+
* [6 mean-anomaly multipliers MMe,MV,ME,MMa,MJ,MS], cos″, sin″].
|
|
82
|
+
* 68 terms ≥ 0.05″ from the D2 extraction (79-term LSQ, fidelity 0.64″).
|
|
83
|
+
* @type {Array<[number[], number[], number, number]>}
|
|
84
|
+
*/
|
|
85
|
+
const TERMS = [
|
|
86
|
+
[[0, 0, 1, 0, -1, 0], [0, 0, 0, 0, 0, 0], -0.0841, -11.6309],
|
|
87
|
+
[[0, 0, 2, 0, -2, 0], [0, 0, -1, 0, 0, 0], -0.3235, 8.2645],
|
|
88
|
+
[[0, 0, 1, -1, 0, 0], [0, 0, 0, -1, 0, 0], -2.9917, -6.8503],
|
|
89
|
+
[[0, 0, 2, -2, 0, 0], [0, 0, -1, 0, 0, 0], -6.2197, -2.1203],
|
|
90
|
+
[[0, 2, -2, 0, 0, 0], [0, 0, 0, 0, 0, 0], 0.0199, -6.4326],
|
|
91
|
+
[[0, 0, 1, 0, -2, 0], [0, 0, 1, 0, 0, 0], 1.7254, 4.5991],
|
|
92
|
+
[[0, 1, -1, 0, 0, 0], [0, 0, 0, 0, 0, 0], 0.1362, 4.8325],
|
|
93
|
+
[[0, 0, 1, 0, -2, 0], [0, 0, 0, 0, 1, 0], 1.1469, 4.2788],
|
|
94
|
+
[[0, 0, 1, 0, -2, 0], [0, 0, 0, 0, 0, 0], -3.8890, 1.2230],
|
|
95
|
+
[[0, 0, 2, 0, -2, 0], [0, 0, 0, 0, 0, 0], 3.3414, 1.5744],
|
|
96
|
+
[[0, 0, 1, 0, -1, 0], [0, 0, 0, 0, -1, 0], -2.6985, -1.2967],
|
|
97
|
+
[[0, 3, -4, 0, 0, 0], [0, 0, 0, 0, 0, 0], 2.9374, -0.5408],
|
|
98
|
+
[[0, 0, 1, 0, -1, 0], [0, 0, -1, 0, 0, 0], -2.5406, -0.1812],
|
|
99
|
+
[[0, 0, 2, -2, 0, 0], [0, 0, 0, 0, 0, 0], 1.3755, -2.0301],
|
|
100
|
+
[[0, 0, 2, -3, 0, 0], [0, 0, 0, 1, 0, 0], -2.2367, -0.4398],
|
|
101
|
+
[[0, 0, -1, 2, 0, 0], [0, 0, 0, 0, 0, 0], 1.8705, 0.3499],
|
|
102
|
+
[[0, 3, -3, 0, 0, 0], [0, -1, 0, 0, 0, 0], -1.3492, 1.2893],
|
|
103
|
+
[[0, 0, 2, 0, -3, 0], [0, 0, 0, 0, 1, 0], 1.5453, 0.1289],
|
|
104
|
+
[[0, 2, -3, 0, 0, 0], [0, 0, 0, 0, 0, 0], 1.3344, -0.4621],
|
|
105
|
+
[[0, 3, -3, 0, 0, 0], [0, 0, -1, 0, 0, 0], -0.0755, -1.4049],
|
|
106
|
+
[[0, 0, -2, 4, 0, 0], [0, 0, 0, 0, 0, 0], 0.2780, 1.2111],
|
|
107
|
+
[[0, 0, -1, 2, 0, 0], [0, 0, -1, 0, 0, 0], -0.7161, 0.8440],
|
|
108
|
+
[[0, 3, -4, 0, 0, 0], [0, 0, -1, 0, 0, 0], 0.9894, 0.3587],
|
|
109
|
+
[[0, 0, 2, 0, -3, 0], [0, 0, 0, 0, 0, 0], 0.0063, 1.0463],
|
|
110
|
+
[[0, 2, -3, 0, 0, 0], [0, 0, 1, 0, 0, 0], 0.9834, 0.1318],
|
|
111
|
+
[[0, 0, 2, -3, 0, 0], [0, 0, 0, -1, 0, 0], 0.4834, 0.8318],
|
|
112
|
+
[[0, 1, -1, 0, 0, 0], [0, -1, 0, 0, 0, 0], -0.5335, 0.5905],
|
|
113
|
+
[[0, 0, 2, -2, 0, 0], [0, 0, 0, -1, 0, 0], 0.5371, -0.5685],
|
|
114
|
+
[[0, 0, 2, -3, 0, 0], [0, 0, 0, 0, 0, 0], -0.7373, -0.0880],
|
|
115
|
+
[[0, 2, -2, 0, 0, 0], [0, 0, -1, 0, 0, 0], 0.0163, -0.7372],
|
|
116
|
+
[[0, 0, -1, 2, 0, 0], [0, 0, 0, -1, 0, 0], -0.0119, 0.6500],
|
|
117
|
+
[[0, 0, 2, 0, -2, 0], [0, 0, 0, 0, 1, 0], 0.0023, -0.6287],
|
|
118
|
+
[[0, 0, 1, 0, -1, 0], [0, 0, 1, 0, 0, 0], 0.5714, -0.1358],
|
|
119
|
+
[[0, 0, -2, 4, 0, 0], [0, 0, -1, 0, 0, 0], -0.5046, 0.2858],
|
|
120
|
+
[[0, 0, 1, 0, -1, 0], [0, 0, 0, 0, 1, 0], -0.5567, 0.1036],
|
|
121
|
+
[[0, 2, -3, 0, 0, 0], [0, 0, -1, 0, 0, 0], 0.5469, -0.0167],
|
|
122
|
+
[[0, 2, -3, 0, 0, 0], [0, 1, 0, 0, 0, 0], -0.4309, 0.2809],
|
|
123
|
+
[[0, 0, 2, 0, -2, 0], [0, 0, 0, 0, -1, 0], 0.2206, -0.4616],
|
|
124
|
+
[[0, 3, -4, 0, 0, 0], [0, -1, 0, 0, 0, 0], -0.4549, -0.2097],
|
|
125
|
+
[[0, 0, 2, 0, -3, 0], [0, 0, -1, 0, 0, 0], 0.2809, 0.3489],
|
|
126
|
+
[[0, 0, 1, -1, 0, 0], [0, 0, 0, 0, 0, 0], 0.2863, 0.3116],
|
|
127
|
+
[[0, 0, 2, -3, 0, 0], [0, 0, -1, 0, 0, 0], -0.4141, -0.0359],
|
|
128
|
+
[[0, 0, 1, 0, 0, -1], [0, 0, 0, 0, 0, 0], 0.0863, -0.4015],
|
|
129
|
+
[[0, 0, -1, 2, 0, 0], [0, 0, 0, 1, 0, 0], -0.2200, 0.3372],
|
|
130
|
+
[[0, 1, -1, 0, 0, 0], [0, 0, -1, 0, 0, 0], -0.2017, 0.2910],
|
|
131
|
+
[[0, 2, -2, 0, 0, 0], [0, -1, 0, 0, 0, 0], 0.2499, -0.1777],
|
|
132
|
+
[[0, 0, 1, 0, -2, 0], [0, 0, 0, 0, -1, 0], -0.2254, 0.1676],
|
|
133
|
+
[[0, 3, -3, 0, 0, 0], [0, 0, 0, 0, 0, 0], -0.1859, -0.1961],
|
|
134
|
+
[[0, 0, 1, 0, 0, -1], [0, 0, 0, 0, 0, 1], -0.0710, 0.2499],
|
|
135
|
+
[[0, 0, -2, 4, 0, 0], [0, 0, 0, -1, 0, 0], 0.2125, -0.1175],
|
|
136
|
+
[[0, 0, 1, 0, 0, -1], [0, 0, -1, 0, 0, 0], -0.0460, 0.2379],
|
|
137
|
+
[[0, 3, -4, 0, 0, 0], [0, 1, 0, 0, 0, 0], -0.1410, 0.1566],
|
|
138
|
+
[[0, 0, 1, -1, 0, 0], [0, 0, 0, 1, 0, 0], -0.0476, 0.1897],
|
|
139
|
+
[[0, 2, -2, 0, 0, 0], [0, 0, 1, 0, 0, 0], -0.1559, -0.1155],
|
|
140
|
+
[[0, 0, 2, 0, -3, 0], [0, 0, 1, 0, 0, 0], 0.1631, -0.0164],
|
|
141
|
+
[[0, 1, -1, 0, 0, 0], [0, 1, 0, 0, 0, 0], 0.1307, -0.0678],
|
|
142
|
+
[[0, 0, 2, -3, 0, 0], [0, 0, 1, 0, 0, 0], 0.1331, -0.0291],
|
|
143
|
+
[[0, 0, -2, 4, 0, 0], [0, 0, 1, 0, 0, 0], 0.1227, 0.0482],
|
|
144
|
+
[[0, 0, 2, 0, 0, -2], [0, 0, 0, 0, 0, 0], -0.0388, 0.1044],
|
|
145
|
+
[[0, 0, 1, 0, 0, -1], [0, 0, 0, 0, 0, -1], -0.0309, 0.1027],
|
|
146
|
+
[[0, 0, 1, 0, -2, 0], [0, 0, -1, 0, 0, 0], -0.0741, 0.0308],
|
|
147
|
+
[[0, 0, 2, 0, -3, 0], [0, 0, 0, 0, -1, 0], 0.0102, 0.0783],
|
|
148
|
+
[[0, 1, -1, 0, 0, 0], [0, 0, 1, 0, 0, 0], -0.0026, 0.0765],
|
|
149
|
+
[[0, 0, 2, 0, -2, 0], [0, 0, 1, 0, 0, 0], -0.0084, 0.0686],
|
|
150
|
+
[[0, 3, -4, 0, 0, 0], [0, 0, 1, 0, 0, 0], 0.0273, -0.0576],
|
|
151
|
+
[[0, 0, 1, -1, 0, 0], [0, 0, 1, 0, 0, 0], 0.0570, 0.0117],
|
|
152
|
+
[[0, 0, 2, -2, 0, 0], [0, 0, 0, 1, 0, 0], 0.0426, -0.0336],
|
|
153
|
+
[[0, 0, 1, -1, 0, 0], [0, 0, -1, 0, 0, 0], -0.0335, -0.0395],
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
/** The declared-fitted semiannual leftover (header (iii)): +1.42″ sin 2lE. */
|
|
157
|
+
const FITTED_2LE_ARCSEC = 1.42;
|
|
158
|
+
|
|
159
|
+
const D2R = Math.PI / 180;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @param {{ embWobbleArcsec: number }} opts - the DERIVED Earth-around-EMB
|
|
163
|
+
* wobble amplitude a_M·μ/AU in arcsec (μ = 1/(1+M_E/M_M)); computed
|
|
164
|
+
* from live constants by the model wiring so it tracks the constants.
|
|
165
|
+
* @returns {{ sunPlanetaryCompletionDeg: (T: number) => number }}
|
|
166
|
+
*/
|
|
167
|
+
function createSunPlanetaryCompletion({ embWobbleArcsec }) {
|
|
168
|
+
if (!Number.isFinite(embWobbleArcsec)) {
|
|
169
|
+
throw new Error('createSunPlanetaryCompletion: embWobbleArcsec must be a finite number (derived a_M·μ/AU in arcsec)');
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Planetary-completion correction to the finder Sun longitude.
|
|
173
|
+
* @param {number} T - Julian centuries TT from J2000
|
|
174
|
+
* @returns {number} degrees — SUBTRACT from the finder Sun longitude
|
|
175
|
+
*/
|
|
176
|
+
function sunPlanetaryCompletionDeg(T) {
|
|
177
|
+
const l = new Float64Array(6), M = new Float64Array(6);
|
|
178
|
+
for (let i = 0; i < 6; i++) {
|
|
179
|
+
l[i] = (ARG_L0[i] + ARG_L1[i] * T) * D2R;
|
|
180
|
+
M[i] = l[i] - PERI[i] * D2R;
|
|
181
|
+
}
|
|
182
|
+
let table = 0;
|
|
183
|
+
for (const [kl, kM, cA, sA] of TERMS) {
|
|
184
|
+
let th = 0;
|
|
185
|
+
for (let i = 0; i < 6; i++) th += kl[i] * l[i] + kM[i] * M[i];
|
|
186
|
+
table += cA * Math.cos(th) + sA * Math.sin(th);
|
|
187
|
+
}
|
|
188
|
+
const D = (ARG_D[0] + ARG_D[1] * T) * D2R;
|
|
189
|
+
const arcsec = -table - embWobbleArcsec * Math.sin(D)
|
|
190
|
+
+ FITTED_2LE_ARCSEC * Math.sin(2 * l[2]);
|
|
191
|
+
return arcsec / 3600;
|
|
192
|
+
}
|
|
193
|
+
return { sunPlanetaryCompletionDeg };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** sha256/16 of JSON.stringify(FITTED_COEFFICIENTS.SUN_LONGITUDE_HARMONICS)
|
|
197
|
+
* at derivation time — the matched-pair fingerprint asserted by test:model.
|
|
198
|
+
* Unchanged from v1: SUN_HARMONICS did not move in the D2 landing. */
|
|
199
|
+
const PAIRED_SUN_HARMONICS_SHA256 = 'e2cf42e9770c9e0a';
|
|
200
|
+
|
|
201
|
+
module.exports = { createSunPlanetaryCompletion, PAIRED_SUN_HARMONICS_SHA256 };
|
package/src/model.js
CHANGED
|
@@ -31,6 +31,8 @@ import { createMoonMonthChain } from './moon/month-chain.cjs';
|
|
|
31
31
|
import { createChainCycleIntegrator } from './chain-cycles/index.cjs';
|
|
32
32
|
import { createMoonArguments, jdToDecimalYear } from './moon/arguments.cjs';
|
|
33
33
|
import { createMoonSeries } from './moon/series.cjs';
|
|
34
|
+
import { createSunPlanetaryCompletion } from './eclipse/sun-planetary-completion.cjs';
|
|
35
|
+
import { moonSeriesExtensionDeg } from './moon/series-extension.cjs';
|
|
34
36
|
import { createEclipseFinders } from './eclipse/finders.cjs';
|
|
35
37
|
import { createBesselian } from './eclipse/besselian.cjs';
|
|
36
38
|
import { driver2PeriodSecondsAtAge } from './planets/orbit-chain.cjs';
|
|
@@ -855,12 +857,19 @@ export function assembleModel(C, F) {
|
|
|
855
857
|
// curve, the same convention every other ΔT consumer reads). Both axis
|
|
856
858
|
// conventions are measured against the NASA path-table centerlines —
|
|
857
859
|
// see eclipse/besselian.cjs.
|
|
860
|
+
// Derived Earth-around-EMB wobble for the Sun completion: a_M·μ/AU,
|
|
861
|
+
// μ = 1/(1+M_E/M_M) — 6.4399″ at current constants, tracks them live.
|
|
862
|
+
const embWobbleArcsec = (moonDistanceKm / (MASS_RATIO_EARTH_MOON + 1) / currentAUDistance)
|
|
863
|
+
* (648000 / Math.PI);
|
|
864
|
+
const { sunPlanetaryCompletionDeg } = createSunPlanetaryCompletion({ embWobbleArcsec });
|
|
858
865
|
const besselian = createBesselian({
|
|
859
866
|
moonFullAtDaysTT: /** @param {number} dDaysTT */ (dDaysTT) => {
|
|
860
867
|
const ev = moonSeries.sceneEvalAt(dDaysTT);
|
|
861
868
|
return { lonDeg: ev.lonDeg, latDeg: ev.latDeg, distKm: ev.distKm };
|
|
862
869
|
},
|
|
863
870
|
sunLonDegAt: /** @param {number} jdUT */ (jdUT) => eclipseFinders.sunLonDegAt(jdUT),
|
|
871
|
+
sunCompletionDeg: sunPlanetaryCompletionDeg,
|
|
872
|
+
moonExtensionAt: moonSeriesExtensionDeg,
|
|
864
873
|
deltaTSecondsAt: /** @param {number} jd */ (jd) => (jdTTFromUT(jd) - jd) * 86400,
|
|
865
874
|
obliquityDegAt: obliquityDeg,
|
|
866
875
|
eccentricityAt,
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Moon series extension — the DERIVED Delaunay tail beyond the shipped
|
|
3
|
+
* Meeus-60 head (Stage D2 Phase A, plan §12i item 10).
|
|
4
|
+
*
|
|
5
|
+
* DERIVATION, not fit: the amplitudes come from the Stage-D1 3-body lab
|
|
6
|
+
* (tools/explore/derive-meeus-amplitudes.js — RK4 on framework constants,
|
|
7
|
+
* IC calibration to the free elements), joint-LSQ over [Meeus-60 head +
|
|
8
|
+
* extended Delaunay catalog] on a 120-yr window. Head fidelity
|
|
9
|
+
* 100.00–100.03% (the derivation reproduces the shipped head, so the
|
|
10
|
+
* tail is the same physics one order deeper); dt-halving drift 0.000″.
|
|
11
|
+
* Extraction: tools/explore/d2-extension-extraction.mjs.
|
|
12
|
+
*
|
|
13
|
+
* JPL enters only as OUT-OF-SAMPLE VALIDATION (960 all-phase epochs):
|
|
14
|
+
* shipped-Moon residual λ 3.68″ → 3.12″ (predicted 3.08″) and
|
|
15
|
+
* β 1.04″ → 0.65″ (predicted 0.66″) with the extension ADDED; the
|
|
16
|
+
* sign-flipped control degrades both — the integrator predicted reality.
|
|
17
|
+
* Ships JOINTLY with the derived Sun completion v2
|
|
18
|
+
* (eclipse/sun-planetary-completion.cjs): the Moon-only form degrades
|
|
19
|
+
* the NASA centerline reference set (its tail was cancelling Sun-side
|
|
20
|
+
* leftover tones there), and the pre-registered acceptance was all four
|
|
21
|
+
* gates, never a subset.
|
|
22
|
+
*
|
|
23
|
+
* Arguments are the instrument-grade Delaunay polynomials (IAU/Meeus
|
|
24
|
+
* class, degrees/Julian-century TT) — phase carriers only, same
|
|
25
|
+
* epistemic status as the Sun completion's argument literals (their
|
|
26
|
+
* framework-native derivation is research item 20.3e).
|
|
27
|
+
*
|
|
28
|
+
* Sign convention: sine terms, ADDED to the full-series Moon longitude
|
|
29
|
+
* and latitude (the validated sense; see besselian.cjs bodiesAt).
|
|
30
|
+
*
|
|
31
|
+
* THE A2 PLANETARY TAIL (the second derived section below): the Moon's
|
|
32
|
+
* direct planetary perturbations, derived from epoch-phased twin 8-body
|
|
33
|
+
* integrations (full = planets+J2 vs base = J2-only; planet phases from
|
|
34
|
+
* the engine graph, the Moon at its true epoch Delaunay phases; fitted
|
|
35
|
+
* on the run's own arguments with a main-problem absorber catalog,
|
|
36
|
+
* absorbers discarded — instrument
|
|
37
|
+
* tools/explore/d2-planetary-moon-epoch.mjs). Cross-validated: V−E
|
|
38
|
+
* +0.849″ sin (independent JPL fit: +0.85), E−J −0.681″ (JPL: −0.69);
|
|
39
|
+
* content 0.896″. JPL out-of-sample (960 all-phase epochs): λ scatter
|
|
40
|
+
* 3.12″ → 3.03″ (the extraction predicted 2.98); the sign-flipped
|
|
41
|
+
* control degrades to 3.47″; the syzygy fleet improves 3.99″ → 3.82″
|
|
42
|
+
* in EVERY era. The β rows (0.074″ content) measurably do NOT help and
|
|
43
|
+
* are not shipped. RECORDED TENSION (owner-accepted at shipping): the
|
|
44
|
+
* 13-event NASA centerline scoreboard moves 2.22″ → 2.68″ mean — the
|
|
45
|
+
* A1-class correlated-subsample effect (the tracked events sit −1.6″
|
|
46
|
+
* below the +1.4″ fleet mean and sample the near-annual arguments at
|
|
47
|
+
* correlated phases; the era-split refutes anchor double-counting and
|
|
48
|
+
* the modern era improves most, 3.57 → 3.34). The ≤8″ api gate holds
|
|
49
|
+
* (max 6.2″). Coefficients are stored with the run→real argument
|
|
50
|
+
* mapping already applied (the extraction's heliocentric-planet vs
|
|
51
|
+
* geocentric-sun π-offset is folded into the signs).
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
'use strict';
|
|
55
|
+
|
|
56
|
+
/** Delaunay argument polynomials [deg at J2000, deg/cy, deg/cy²] TT. */
|
|
57
|
+
const DELAUNAY = {
|
|
58
|
+
D: [297.8501921, 445267.1114034, -0.0018819], // mean elongation
|
|
59
|
+
M: [357.5291092, 35999.0502909, -0.0001536], // Sun mean anomaly
|
|
60
|
+
Mp: [134.9633964, 477198.8675055, 0.0087414], // Moon mean anomaly
|
|
61
|
+
F: [93.2720950, 483202.0175233, -0.0036539], // argument of latitude
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** Longitude tail: [kD, kM, kMp, kF, sin″] — 47 derived terms ≥ 0.1″
|
|
65
|
+
* (RMS content 2.02″). */
|
|
66
|
+
const LON_TERMS = [
|
|
67
|
+
[2, 0, 1, 2, -0.9900],
|
|
68
|
+
[2, 0, -4, 0, 0.9465],
|
|
69
|
+
[2, -2, 1, 0, 0.7524],
|
|
70
|
+
[0, 1, -3, 0, -0.6704],
|
|
71
|
+
[4, 1, -1, 0, -0.6323],
|
|
72
|
+
[1, 0, 2, 0, -0.5864],
|
|
73
|
+
[1, 0, 0, -2, -0.5813],
|
|
74
|
+
[2, 0, -2, -2, -0.5631],
|
|
75
|
+
[1, -1, 0, 0, -0.5617],
|
|
76
|
+
[0, 1, 3, 0, -0.5455],
|
|
77
|
+
[2, 0, -2, 2, -0.5253],
|
|
78
|
+
[2, -1, -3, 0, 0.4674],
|
|
79
|
+
[2, 0, 2, -2, -0.4625],
|
|
80
|
+
[2, -1, -1, 2, -0.4271],
|
|
81
|
+
[0, 1, 0, 2, 0.4173],
|
|
82
|
+
[6, 0, -1, 0, 0.3954],
|
|
83
|
+
[2, -1, 1, -2, -0.3876],
|
|
84
|
+
[2, -1, 0, 2, -0.3816],
|
|
85
|
+
[2, 2, -1, -2, -0.3654],
|
|
86
|
+
[2, 2, 1, -2, -0.3615],
|
|
87
|
+
[4, 1, -2, 0, -0.3575],
|
|
88
|
+
[0, 0, 3, 2, -0.3281],
|
|
89
|
+
[4, -2, -1, 0, 0.3106],
|
|
90
|
+
[0, 1, -1, -2, 0.3016],
|
|
91
|
+
[2, -2, -2, 0, 0.2964],
|
|
92
|
+
[4, 0, -1, -2, 0.2963],
|
|
93
|
+
[2, 1, 2, 0, -0.2897],
|
|
94
|
+
[4, 1, 0, 0, -0.2887],
|
|
95
|
+
[4, -1, 1, 0, 0.2833],
|
|
96
|
+
[0, 1, 1, 2, 0.2643],
|
|
97
|
+
[2, 2, -2, 0, -0.2635],
|
|
98
|
+
[1, 1, -2, 0, 0.2569],
|
|
99
|
+
[1, 0, 0, 2, 0.2524],
|
|
100
|
+
[4, 0, 2, 0, 0.2190],
|
|
101
|
+
[4, 0, -1, 2, -0.2007],
|
|
102
|
+
[0, 2, -2, 0, -0.1813],
|
|
103
|
+
[0, 0, 3, -2, -0.1784],
|
|
104
|
+
[2, 2, 0, 0, -0.1684],
|
|
105
|
+
[2, 0, -1, -2, 0.1634],
|
|
106
|
+
[4, -2, 0, 0, 0.1549],
|
|
107
|
+
[2, 2, -3, 0, 0.1545],
|
|
108
|
+
[1, -1, -1, 0, -0.1479],
|
|
109
|
+
[2, 1, -3, 0, 0.1290],
|
|
110
|
+
[6, 0, 0, 0, 0.1268],
|
|
111
|
+
[1, 0, -3, 0, -0.1252],
|
|
112
|
+
[2, 0, 2, 2, -0.1236],
|
|
113
|
+
[1, -1, 1, 0, -0.1225],
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
/** Latitude tail: [kD, kM, kMp, kF, sin″] — 30 derived terms ≥ 0.1″
|
|
117
|
+
* (RMS content 0.80″). */
|
|
118
|
+
const LAT_TERMS = [
|
|
119
|
+
[4, -1, -1, 1, 0.3390],
|
|
120
|
+
[2, 0, -1, -3, 0.3282],
|
|
121
|
+
[2, -2, -1, 1, 0.3148],
|
|
122
|
+
[0, 1, 2, -1, -0.3050],
|
|
123
|
+
[0, 1, -2, 1, -0.2988],
|
|
124
|
+
[2, 0, 1, -3, -0.2919],
|
|
125
|
+
[2, -2, -1, -1, 0.2685],
|
|
126
|
+
[0, 0, 4, 1, 0.2636],
|
|
127
|
+
[2, 0, -3, 1, 0.2526],
|
|
128
|
+
[2, 0, -1, 3, -0.2447],
|
|
129
|
+
[2, 1, 1, 1, -0.2369],
|
|
130
|
+
[4, 0, 1, 1, 0.2128],
|
|
131
|
+
[2, 2, 0, -1, -0.1749],
|
|
132
|
+
[4, 1, -1, -1, -0.1737],
|
|
133
|
+
[4, -1, 0, 1, 0.1581],
|
|
134
|
+
[2, 0, 3, -1, 0.1465],
|
|
135
|
+
[0, 0, 2, -3, -0.1461],
|
|
136
|
+
[2, 0, 0, 3, -0.1444],
|
|
137
|
+
[1, 0, -1, 1, 0.1387],
|
|
138
|
+
[2, 0, 3, 1, 0.1381],
|
|
139
|
+
[2, 0, -4, -1, 0.1335],
|
|
140
|
+
[2, -1, 2, -1, 0.1283],
|
|
141
|
+
[2, -1, 2, 1, 0.1241],
|
|
142
|
+
[0, 2, -1, -1, -0.1208],
|
|
143
|
+
[0, 0, 2, 3, -0.1178],
|
|
144
|
+
[4, 1, 0, -1, -0.1128],
|
|
145
|
+
[2, 2, -1, -1, -0.1127],
|
|
146
|
+
[1, 0, -2, -1, -0.1093],
|
|
147
|
+
[2, 2, -1, 1, -0.1044],
|
|
148
|
+
[1, 1, 1, 1, 0.1014],
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
/** Planetary mean-longitude polynomials, degrees per Julian century TT
|
|
152
|
+
* (IAU-class instrument literals — same carriers as the Sun completion).
|
|
153
|
+
* Order: Venus, Earth (EMB), Mars, Jupiter, Saturn. */
|
|
154
|
+
const PLANET_L0 = [181.979801, 100.466457, 355.433000, 34.351519, 50.077444];
|
|
155
|
+
const PLANET_L1 = [58517.815676, 36000.769780, 19141.696300, 3036.302389, 1223.511013];
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* The A2 planetary longitude tail:
|
|
159
|
+
* [[kV, kE, kMa, kJ, kSa, kD, kMp], cos″, sin″] — 15 derived terms
|
|
160
|
+
* (content 0.896″), run→real argument mapping folded into the signs.
|
|
161
|
+
* @type {Array<[number[], number, number]>}
|
|
162
|
+
*/
|
|
163
|
+
const PLANETARY_LON_TERMS = [
|
|
164
|
+
[[1, -1, 0, 0, 0, 0, 0], -0.0056, -0.8488],
|
|
165
|
+
[[2, -2, 0, 0, 0, 0, 0], -0.0034, 0.3166],
|
|
166
|
+
[[3, -3, 0, 0, 0, 0, 0], -0.0051, -0.0387],
|
|
167
|
+
[[0, 1, 0, -1, 0, 0, 0], 0.0325, 0.6814],
|
|
168
|
+
[[0, 2, 0, -2, 0, 0, 0], -0.0084, -0.1835],
|
|
169
|
+
[[0, 2, -2, 0, 0, 0, 0], 0.0002, 0.2205],
|
|
170
|
+
[[0, 1, 0, 0, -1, 0, 0], 0.0078, 0.0463],
|
|
171
|
+
[[1, -1, 0, 0, 0, 2, 0], -0.0020, -0.0308],
|
|
172
|
+
[[1, -1, 0, 0, 0, -2, 0], 0.0045, -0.1193],
|
|
173
|
+
[[0, 1, 0, -1, 0, 2, 0], 0.0014, 0.0322],
|
|
174
|
+
[[0, 1, 0, -1, 0, -2, 0], 0.0161, 0.2141],
|
|
175
|
+
[[1, -1, 0, 0, 0, 0, 1], 0.0023, -0.1929],
|
|
176
|
+
[[1, -1, 0, 0, 0, 0, -1], -0.0029, -0.2306],
|
|
177
|
+
[[0, 1, 0, -1, 0, 0, 1], 0.0059, 0.1729],
|
|
178
|
+
[[0, 1, 0, -1, 0, 0, -1], -0.0077, 0.2235],
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
const D2R = Math.PI / 180;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Derived series-extension correction to the full-series Moon:
|
|
185
|
+
* the Delaunay tail plus the A2 planetary tail (longitude only).
|
|
186
|
+
* @param {number} T - Julian centuries TT from J2000
|
|
187
|
+
* @returns {{dLonDeg: number, dLatDeg: number}} degrees — ADD to the
|
|
188
|
+
* full-series Moon longitude/latitude
|
|
189
|
+
*/
|
|
190
|
+
function moonSeriesExtensionDeg(T) {
|
|
191
|
+
const poly = /** @param {number[]} p */ (p) => (p[0] + (p[1] + p[2] * T) * T) * D2R;
|
|
192
|
+
const D = poly(DELAUNAY.D), M = poly(DELAUNAY.M), Mp = poly(DELAUNAY.Mp), F = poly(DELAUNAY.F);
|
|
193
|
+
let lon = 0, lat = 0;
|
|
194
|
+
for (const [kD, kM, kMp, kF, s] of LON_TERMS) lon += s * Math.sin(kD * D + kM * M + kMp * Mp + kF * F);
|
|
195
|
+
for (const [kD, kM, kMp, kF, s] of LAT_TERMS) lat += s * Math.sin(kD * D + kM * M + kMp * Mp + kF * F);
|
|
196
|
+
const l = new Float64Array(5);
|
|
197
|
+
for (let i = 0; i < 5; i++) l[i] = (PLANET_L0[i] + PLANET_L1[i] * T) * D2R;
|
|
198
|
+
for (const [k, cA, sA] of PLANETARY_LON_TERMS) {
|
|
199
|
+
const th = k[0] * l[0] + k[1] * l[1] + k[2] * l[2] + k[3] * l[3] + k[4] * l[4] + k[5] * D + k[6] * Mp;
|
|
200
|
+
lon += cA * Math.cos(th) + sA * Math.sin(th);
|
|
201
|
+
}
|
|
202
|
+
return { dLonDeg: lon / 3600, dLatDeg: lat / 3600 };
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
module.exports = { moonSeriesExtensionDeg };
|