@essrt/physics 4.9.0 → 5.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/package.json +3 -2
- package/src/climate/l1-orbital.cjs +76 -5
- package/src/constants/coefficients.d.ts +54 -148
- package/src/constants/coefficients.js +4 -4
- package/src/constants/generated.d.ts +4 -3
- package/src/constants/generated.js +6 -5
- package/src/deltat/deep-time.cjs +69 -2
- package/src/earth/deep-orbital-history.cjs +6 -5
- package/src/earth/precession-composed.cjs +120 -0
- package/src/earth/year-lengths.cjs +12 -1
- package/src/index.js +6 -2
- package/src/layer0/derive-params.js +21 -4
- package/src/layer0/index.js +35 -4
- package/src/model.js +165 -33
- package/src/planets/chain-artifact.js +2 -2
- package/types/climate/l1-orbital.d.cts +81 -10
- package/types/constants/coefficients.d.ts +54 -148
- package/types/constants/generated.d.ts +4 -3
- package/types/deltat/deep-time.d.cts +13 -0
- package/types/earth/precession-composed.d.cts +59 -0
- package/types/earth/year-lengths.d.cts +10 -0
- package/types/index.d.ts +3 -2
- package/types/layer0/derive-params.d.ts +10 -0
- package/types/layer0/index.d.ts +15 -0
- package/types/model.d.ts +28 -0
|
@@ -113,4 +113,15 @@ function createYearLengths({ sampleAt, massLossSiderealSecondsAtYearFn, apsidalS
|
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
/**
|
|
117
|
+
* The published of-date window (plan 06 Phase 3 S2): inside |year − 2000| ≤
|
|
118
|
+
* this span the one-family route is THE published year-length / precession
|
|
119
|
+
* family (the banked tiers — 100-yr and 1000-yr grids, no unbounded sampler
|
|
120
|
+
* growth); beyond it the published surfaces return the unit's SECULAR mean
|
|
121
|
+
* (H(t)/13 for the precession period, the tidal-chain mean year), because the
|
|
122
|
+
* of-date wobble is unresolved there and the deep sampler grows ~0.1 s per Myr
|
|
123
|
+
* of span. A displayed rate must name its window — this is the window.
|
|
124
|
+
*/
|
|
125
|
+
const ONE_FAMILY_WINDOW_YEARS = 2000000;
|
|
126
|
+
|
|
127
|
+
module.exports = { createYearLengths, ONE_FAMILY_WINDOW_YEARS };
|
package/src/index.js
CHANGED
|
@@ -138,7 +138,11 @@ export { createDeepOrbitalHistory } from './earth/deep-orbital-history.cjs';
|
|
|
138
138
|
// D6: the sidereal-year-of-date channel (banked λ̇ ratio × the caller's mass-loss law)
|
|
139
139
|
export { createSiderealYearChannel } from './earth/sidereal-year-channel.cjs';
|
|
140
140
|
// S2: THE ONE of-date year-length family (years + precession beats, SI seconds)
|
|
141
|
-
export { createYearLengths } from './earth/year-lengths.cjs';
|
|
141
|
+
export { createYearLengths, ONE_FAMILY_WINDOW_YEARS } from './earth/year-lengths.cjs';
|
|
142
|
+
// Plan 06 D6: THE ONE home of the composed lunisolar precession rate ψ̇(t)
|
|
143
|
+
// (spin ω(t) × [solar torque + lunar torque on the recession history]) —
|
|
144
|
+
// leg-1's physical rate; the structural H(t)/13 clock is its named diagnostic.
|
|
145
|
+
export { computeSolarTorqueShare, createComposedPrecession } from './earth/precession-composed.cjs';
|
|
142
146
|
export { createPredictivePrecession, calcPlanetPerihelionLongDeg } from './planets/predict.cjs';
|
|
143
147
|
// L10 — the composition front door: one law set, N body records. Thin by
|
|
144
148
|
// design; engines keep their direct call sites (see planets/model.cjs).
|
|
@@ -148,7 +152,7 @@ export { createDeltaTCycles } from './deltat/cycles.cjs';
|
|
|
148
152
|
export { createDeepTimeLod } from './deltat/deep-time.cjs';
|
|
149
153
|
export { createMoonRecessionHistory, createSolarChannelBudget } from './deltat/recession-history.cjs';
|
|
150
154
|
export { deltaTEspenakMeeusCanonSeconds } from './deltat/historical.cjs';
|
|
151
|
-
export { evalClimateL1OrbitalPermil } from './climate/l1-orbital.cjs';
|
|
155
|
+
export { evalClimateL1OrbitalPermil, laggedL1Terms, createAlphaGiaChannel } from './climate/l1-orbital.cjs';
|
|
152
156
|
// Phase 8.5 — eclipse geometry (single-copy: the browser had no Node twin).
|
|
153
157
|
export { createEclipseFinders } from './eclipse/finders.cjs';
|
|
154
158
|
// Phase 8.6 — the published reference curves (external comparison formulas
|
|
@@ -9,12 +9,16 @@
|
|
|
9
9
|
* If the two ever disagree, one of them changed and the other did not — which
|
|
10
10
|
* is the exact drift mode that produced five diverging implementations.
|
|
11
11
|
*
|
|
12
|
-
* Pure function
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* Pure function; its only import is the torque-share derivation (plan 06
|
|
13
|
+
* Phase 3: the unit H(t) = 13·T_p,composed needs the solar fraction of the
|
|
14
|
+
* J2000 precession torque, derived ONCE here from the shared constants).
|
|
15
|
+
* Lives in physics so the browser and the Node engine can both build Layer 0
|
|
16
|
+
* from ONE derivation (deep-time.js keeps its own inline copy only until
|
|
17
|
+
* Phase C rewrites it; until then the test is the enforcement).
|
|
16
18
|
*/
|
|
17
19
|
|
|
20
|
+
import { computeSolarTorqueShare } from '../earth/precession-composed.cjs';
|
|
21
|
+
|
|
18
22
|
/**
|
|
19
23
|
* @typedef {Object} RawEpochConstants
|
|
20
24
|
* @property {number} solarLuminosityW IAU 2015 nominal (W)
|
|
@@ -35,6 +39,10 @@
|
|
|
35
39
|
* @property {number} moonDistanceKm
|
|
36
40
|
* @property {number} moonOrbitalEccentricity
|
|
37
41
|
* @property {number} gmEarthMoonSystemKm3S2
|
|
42
|
+
* @property {number} gmSunKm3S2 GM☉ (km³/s²) — the solar precession torque
|
|
43
|
+
* @property {number} astronomicalUnitKm 1 AU (km)
|
|
44
|
+
* @property {number} earthOrbitalEccentricityJ2000
|
|
45
|
+
* @property {number} moonEclipticInclinationJ2000Deg
|
|
38
46
|
*/
|
|
39
47
|
|
|
40
48
|
/**
|
|
@@ -64,6 +72,14 @@ export const deriveEpochParams = (raw) => {
|
|
|
64
72
|
+ (moonMassKg * Math.sqrt(gmEarthMoonM3S2 * moonDistanceNowM) * moonEccentricityFactor);
|
|
65
73
|
const moonLockDistanceM = (totalAngularMomentumKgM2S / (moonMassKg * Math.sqrt(gmEarthMoonM3S2) * moonEccentricityFactor)) ** 2;
|
|
66
74
|
|
|
75
|
+
// The solar fraction of the J2000 precession torque (plan 06 Phase 3): the
|
|
76
|
+
// unit H(t) ≡ 13·T_p,composed = H_era(t) / [f_S + (1 − f_S)(a₀/a_M(t))³].
|
|
77
|
+
const precessionSolarShareJ2000 = computeSolarTorqueShare({
|
|
78
|
+
gmSunKm3S2: raw.gmSunKm3S2, auKm: raw.astronomicalUnitKm, earthEccentricity: raw.earthOrbitalEccentricityJ2000,
|
|
79
|
+
gmMoonKm3S2: raw.gmMoonAloneKm3S2, moonDistanceKm: raw.moonDistanceKm, moonEccentricity: raw.moonOrbitalEccentricity,
|
|
80
|
+
moonInclinationDeg: raw.moonEclipticInclinationJ2000Deg,
|
|
81
|
+
});
|
|
82
|
+
|
|
67
83
|
return Object.freeze({
|
|
68
84
|
epochYear: 2000,
|
|
69
85
|
alpha1PerMa: raw.alpha1PerMa,
|
|
@@ -81,5 +97,6 @@ export const deriveEpochParams = (raw) => {
|
|
|
81
97
|
lodNowH13Seconds,
|
|
82
98
|
siderealYearJ2000Seconds: raw.meanSiderealYearSeconds,
|
|
83
99
|
solarMassLossFracPerYear,
|
|
100
|
+
precessionSolarShareJ2000,
|
|
84
101
|
});
|
|
85
102
|
};
|
package/src/layer0/index.js
CHANGED
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
* @property {number} lodNowH13Seconds
|
|
48
48
|
* @property {number} siderealYearJ2000Seconds
|
|
49
49
|
* @property {number} solarMassLossFracPerYear
|
|
50
|
+
* @property {number} precessionSolarShareJ2000 f_S, the solar fraction of the J2000 precession torque
|
|
50
51
|
*/
|
|
51
52
|
|
|
52
53
|
/**
|
|
@@ -54,10 +55,12 @@
|
|
|
54
55
|
* @property {(year: number) => number} tMa
|
|
55
56
|
* @property {(year: number) => number} moonDistanceMetres
|
|
56
57
|
* @property {(year: number) => number|null} lodSeconds
|
|
57
|
-
* @property {(year: number) => number|null} holisticH
|
|
58
|
+
* @property {(year: number) => number|null} holisticH the UNIT: 13 × the composed lunisolar precession period
|
|
58
59
|
* @property {(year: number) => number} siderealYearSeconds
|
|
59
60
|
* @property {(year: number) => number} tropicalYearSeconds
|
|
60
61
|
* @property {(year: number) => number|null} anomalisticYearSeconds
|
|
62
|
+
* @property {(year: number) => number|null} eraClockH the frozen era clock's phase convention H₀·LOD/LOD₀ (device tier)
|
|
63
|
+
* @property {(year: number) => number} eraClockTropicalYearSeconds T_sid·(1 − 13/H_era) — the frozen comb family's base
|
|
61
64
|
*/
|
|
62
65
|
|
|
63
66
|
/**
|
|
@@ -98,16 +101,35 @@ export const createEpochPrimitives = ({ params: p, alphaAtAgeMa }) => {
|
|
|
98
101
|
};
|
|
99
102
|
|
|
100
103
|
/**
|
|
101
|
-
* The
|
|
102
|
-
*
|
|
104
|
+
* The frozen era clock's phase convention: H_era(t) = H₀·LOD(t)/LOD₀ —
|
|
105
|
+
* pure spin scaling. This is the counter the FROZEN devices (the cardinal
|
|
106
|
+
* era clock, the year-length comb family) were fitted against; it ships
|
|
107
|
+
* with their coefficients as a named device constant (plan 06 Phase 3,
|
|
108
|
+
* D8), never as "H(t)".
|
|
103
109
|
* @param {number} t age in Ma
|
|
104
110
|
* @returns {number|null} years
|
|
105
111
|
*/
|
|
106
|
-
const
|
|
112
|
+
const eraClockHCore = (t) => {
|
|
107
113
|
const lod = lodSecondsCore(t);
|
|
108
114
|
return lod === null ? null : p.holisticYearJ2000 * lod / p.lodNowH13Seconds;
|
|
109
115
|
};
|
|
110
116
|
|
|
117
|
+
/**
|
|
118
|
+
* The unit H(t) ≡ 13 × the composed lunisolar precession period:
|
|
119
|
+
* H_era(t) / [f_S + (1 − f_S)·(a₀/a_M(t))³] — the spin scaling AND the
|
|
120
|
+
* lunar torque growing on the recession history (plan 06 D6/Phase 3; the
|
|
121
|
+
* formula's home is earth/precession-composed, this is its Layer-0 twin,
|
|
122
|
+
* held bit-identical to deltat/deep-time.cjs by the layer0 gate).
|
|
123
|
+
* @param {number} t age in Ma
|
|
124
|
+
* @returns {number|null} years
|
|
125
|
+
*/
|
|
126
|
+
const holisticHCore = (t) => {
|
|
127
|
+
const hEra = eraClockHCore(t);
|
|
128
|
+
if (hEra === null) return null;
|
|
129
|
+
const lf = Math.pow(p.moonDistanceNowM / moonDistanceMetresCore(t), 3);
|
|
130
|
+
return hEra / (p.precessionSolarShareJ2000 + (1 - p.precessionSolarShareJ2000) * lf);
|
|
131
|
+
};
|
|
132
|
+
|
|
111
133
|
/**
|
|
112
134
|
* Sidereal year. Driver 2 alone — solar mass loss via Kepler, `dT/T = -2 dM/M`
|
|
113
135
|
* under the adiabatic `a*M = const` coupling. Carries NO alpha and NO LOD,
|
|
@@ -159,6 +181,13 @@ export const createEpochPrimitives = ({ params: p, alphaAtAgeMa }) => {
|
|
|
159
181
|
return sid * (H - 13) / H * H / (H - 16);
|
|
160
182
|
};
|
|
161
183
|
|
|
184
|
+
/** The frozen comb family's tropical base: T_sid·(1 − 13/H_era). @param {number} t */
|
|
185
|
+
const eraClockTropicalYearSecondsCore = (t) => {
|
|
186
|
+
const sid = siderealYearSecondsCore(t);
|
|
187
|
+
const H = eraClockHCore(t);
|
|
188
|
+
return H === null ? sid * (1 - 13 / p.holisticYearJ2000) : sid * (1 - 13 / H);
|
|
189
|
+
};
|
|
190
|
+
|
|
162
191
|
return Object.freeze({
|
|
163
192
|
tMa,
|
|
164
193
|
moonDistanceMetres: (year) => moonDistanceMetresCore(tMa(year)),
|
|
@@ -167,5 +196,7 @@ export const createEpochPrimitives = ({ params: p, alphaAtAgeMa }) => {
|
|
|
167
196
|
siderealYearSeconds: (year) => siderealYearSecondsCore(tMa(year)),
|
|
168
197
|
tropicalYearSeconds: (year) => tropicalYearSecondsCore(tMa(year)),
|
|
169
198
|
anomalisticYearSeconds: (year) => anomalisticYearSecondsCore(tMa(year)),
|
|
199
|
+
eraClockH: (year) => eraClockHCore(tMa(year)),
|
|
200
|
+
eraClockTropicalYearSeconds: (year) => eraClockTropicalYearSecondsCore(tMa(year)),
|
|
170
201
|
});
|
|
171
202
|
};
|
package/src/model.js
CHANGED
|
@@ -22,14 +22,14 @@ import * as FL from './planets/fibonacci-laws.cjs';
|
|
|
22
22
|
import * as planetOrientation from './planets/orientation.cjs';
|
|
23
23
|
import { createPhaseMachinery } from './phase/index.cjs';
|
|
24
24
|
import { createCardinalModel } from './cardinal/index.cjs';
|
|
25
|
-
import { createYearLengths } from './earth/year-lengths.cjs';
|
|
25
|
+
import { createYearLengths, ONE_FAMILY_WINDOW_YEARS } from './earth/year-lengths.cjs';
|
|
26
26
|
import { createDeepOrbitalHistory } from './earth/deep-orbital-history.cjs';
|
|
27
27
|
import { CHAIN_ARTIFACT } from './planets/chain-artifact.js';
|
|
28
28
|
import { buildPlanetChainsFromArtifactData, computeApsidalSecularDegPerYr } from './planets/keplerian-chain.cjs';
|
|
29
29
|
import { createDeltaTCycles } from './deltat/cycles.cjs';
|
|
30
30
|
import { createDeepTimeLod } from './deltat/deep-time.cjs';
|
|
31
31
|
import { createMoonRecessionHistory, createSolarChannelBudget } from './deltat/recession-history.cjs';
|
|
32
|
-
import { evalClimateL1OrbitalPermil } from './climate/l1-orbital.cjs';
|
|
32
|
+
import { evalClimateL1OrbitalPermil, createAlphaGiaChannel } from './climate/l1-orbital.cjs';
|
|
33
33
|
import { createMoonEccChannel } from './moon/ecc-channel.cjs';
|
|
34
34
|
import { createDeepEccChannel } from './moon/deep-ecc-channel.cjs';
|
|
35
35
|
import { DEEP_MODES_ARTIFACT } from './moon/deep-modes-artifact.cjs';
|
|
@@ -132,21 +132,27 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
132
132
|
const GM_SUN = GM_SUN_PLUS_EARTH - GM_EARTH_ALONE;
|
|
133
133
|
const M_SUN = GM_SUN / G_CONSTANT;
|
|
134
134
|
|
|
135
|
-
// ── α(t):
|
|
135
|
+
// ── α(t): the GIA channel — the LAGGED response to the L1 ice history, with the R2 lattice pin ──
|
|
136
136
|
const CLIMATE = F.CLIMATE_FORMULA_COEFFS;
|
|
137
137
|
const CLIMATE_REGIME = CLIMATE.regimes['lr04-post-mpt'];
|
|
138
|
-
const alphaClimateScale = C.deepTime.alphaClimateScalePerMille;
|
|
139
138
|
|
|
140
|
-
/** @param {number} year @returns {number} */
|
|
139
|
+
/** The climate formula's L1 (unlagged) — the orbital δ¹⁸O layer itself. @param {number} year @returns {number} */
|
|
141
140
|
const evalClimateL1 = (year) => evalClimateL1OrbitalPermil(year, {
|
|
142
141
|
l1Terms: CLIMATE_REGIME.L1,
|
|
143
142
|
yStdDenormalization: CLIMATE_REGIME.denormalization.y_std,
|
|
144
|
-
|
|
143
|
+
});
|
|
144
|
+
// ONE home (climate/l1-orbital.cjs): k derived from the Cox–Chao rate, τ the
|
|
145
|
+
// record-measured relaxation time (plan 06 D7). Same construction in
|
|
146
|
+
// src/script.js, tools/lib/deep-time.js and the website's essrt.ts.
|
|
147
|
+
const alphaGia = createAlphaGiaChannel({
|
|
148
|
+
l1Terms: CLIMATE_REGIME.L1,
|
|
149
|
+
yStdDenormalization: CLIMATE_REGIME.denormalization.y_std,
|
|
150
|
+
relaxationKyr: C.deepTime.alphaGiaRelaxationKyr,
|
|
151
|
+
alphaGiaRateJ2000PerYr: C.deepTime.alphaGiaRateJ2000PerYr,
|
|
152
|
+
alphaJ2000: earthMoiFactorJ2000,
|
|
145
153
|
});
|
|
146
154
|
|
|
147
155
|
let latticeAlphaPin = false;
|
|
148
|
-
/** @type {number|null} */
|
|
149
|
-
let alphaL1J2000 = null;
|
|
150
156
|
// Exact-argument memo (mirrors src/script.js + tools/lib/deep-time.js —
|
|
151
157
|
// the round-5 perf campaign): same tMa → bit-identical value; the pin
|
|
152
158
|
// branch bypasses the memo; bounded by wholesale clear.
|
|
@@ -157,9 +163,7 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
157
163
|
if (latticeAlphaPin) return earthMoiFactorJ2000;
|
|
158
164
|
let v = alphaMemo.get(tMa);
|
|
159
165
|
if (v === undefined) {
|
|
160
|
-
|
|
161
|
-
const L1at = evalClimateL1(2000 - tMa * 1e6);
|
|
162
|
-
v = earthMoiFactorJ2000 - alphaClimateScale * (L1at - alphaL1J2000);
|
|
166
|
+
v = alphaGia.alphaAt(2000 - tMa * 1e6);
|
|
163
167
|
if (alphaMemo.size >= 8192) alphaMemo.clear();
|
|
164
168
|
alphaMemo.set(tMa, v);
|
|
165
169
|
}
|
|
@@ -186,6 +190,11 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
186
190
|
moonDistanceKm,
|
|
187
191
|
moonOrbitalEccentricity: C.moonReference.moonOrbitalEccentricityBase,
|
|
188
192
|
gmEarthMoonSystemKm3S2: GM_EARTH_MOON_SYSTEM,
|
|
193
|
+
// the solar precession torque's inputs (plan 06 Phase 3: the unit H(t) = 13·T_p,composed)
|
|
194
|
+
gmSunKm3S2: GM_SUN,
|
|
195
|
+
astronomicalUnitKm: currentAUDistance,
|
|
196
|
+
earthOrbitalEccentricityJ2000: C.earthOrbital.earthEccentricityJ2000,
|
|
197
|
+
moonEclipticInclinationJ2000Deg: C.moonReference.moonEclipticInclinationJ2000,
|
|
189
198
|
});
|
|
190
199
|
|
|
191
200
|
// ── Driver 1½: regime-aware recession history + the solar channels ────────
|
|
@@ -272,6 +281,7 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
272
281
|
meanSiderealYearJ2000Seconds: meanSiderealYearSeconds,
|
|
273
282
|
solarMassLossFracPerYear: EPOCH_PARAMS.solarMassLossFracPerYear,
|
|
274
283
|
siderealYearDaysKinematicJ2000: meanSiderealYearDaysKinematic,
|
|
284
|
+
precessionSolarShareJ2000: EPOCH_PARAMS.precessionSolarShareJ2000,
|
|
275
285
|
},
|
|
276
286
|
moonDistanceMetresAtAge,
|
|
277
287
|
moiFactorAtAge: earthMoiFactorAtAge,
|
|
@@ -283,8 +293,12 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
283
293
|
});
|
|
284
294
|
|
|
285
295
|
// ── Integrated ∫1/H(t)dt phase (R2 α-pin honoured while building) ─────────
|
|
296
|
+
// The phase counter every FROZEN comb reads rides the frozen era clock's
|
|
297
|
+
// own convention H_era = H₀·LOD/LOD₀ (plan 06 D8: two named counters — the
|
|
298
|
+
// coefficients were fitted against this counter and ship with it), NOT the
|
|
299
|
+
// unit H(t) = 13·T_p,composed that the physics publishes.
|
|
286
300
|
const phaseM = createPhaseMachinery({
|
|
287
|
-
holisticHAtAgeMa: (tMa) => deepLod.
|
|
301
|
+
holisticHAtAgeMa: (tMa) => deepLod.eraClockHAtAge(tMa),
|
|
288
302
|
tableAnchorYear: startmodelYear,
|
|
289
303
|
driftRefYear: startModelYearWithCorrection,
|
|
290
304
|
hJ2000: H,
|
|
@@ -413,16 +427,19 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
413
427
|
if (lod === null) return meanSiderealYearDays;
|
|
414
428
|
return deepLod.siderealYearSecondsAtAge(tMa) / lod;
|
|
415
429
|
};
|
|
430
|
+
// The comb family's bases are the FROZEN era clock's forms (H_era; plan 06
|
|
431
|
+
// D8) — the combs were fitted on them. The physical year lengths ride the
|
|
432
|
+
// unit through yearLengths (family B) and the tidal-chain mean.
|
|
416
433
|
/** @param {number} year @returns {number} */
|
|
417
434
|
const tropicalYearDaysBase = (year) => {
|
|
418
|
-
const days = deepLod.
|
|
435
|
+
const days = deepLod.eraClockYearInDaysAtAge(yearToTMa(year));
|
|
419
436
|
return days === null ? meanSolarYearDays : days;
|
|
420
437
|
};
|
|
421
438
|
/** @param {number} year @returns {number} */
|
|
422
439
|
const anomalisticYearDaysBase = (year) => {
|
|
423
440
|
const tMa = yearToTMa(year);
|
|
424
|
-
const Ht = deepLod.
|
|
425
|
-
const tropD = deepLod.
|
|
441
|
+
const Ht = deepLod.eraClockHAtAge(tMa);
|
|
442
|
+
const tropD = deepLod.eraClockYearInDaysAtAge(tMa);
|
|
426
443
|
if (Ht === null || tropD === null) return meanAnomalisticYearDays;
|
|
427
444
|
return (tropD * (Ht / 16)) / (Ht / 16 - 1);
|
|
428
445
|
};
|
|
@@ -456,14 +473,16 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
456
473
|
},
|
|
457
474
|
fns: {
|
|
458
475
|
cyclesBetween: (a, b, n) => phase().cyclesBetween(a, b, n),
|
|
476
|
+
// The frozen era clock's deps ride ITS convention H_era (plan 06 D8):
|
|
477
|
+
// drift integrand, dc/dY and the real-LOD convention were fitted on it.
|
|
459
478
|
analyticTropicalDays: (year) => {
|
|
460
479
|
const tMa = (startmodelYear - year) / 1e6;
|
|
461
|
-
const Ht = deepLod.
|
|
480
|
+
const Ht = deepLod.eraClockHAtAge(tMa);
|
|
462
481
|
if (Ht === null) return null;
|
|
463
482
|
return (deepLod.siderealYearSecondsAtAge(tMa) / 86400) * (1 - 13 / Ht);
|
|
464
483
|
},
|
|
465
|
-
meanHAtAgeMa: (tMa) => deepLod.
|
|
466
|
-
meanYearRealLodDays: (tMa) => deepLod.
|
|
484
|
+
meanHAtAgeMa: (tMa) => deepLod.eraClockHAtAge(tMa),
|
|
485
|
+
meanYearRealLodDays: (tMa) => deepLod.eraClockYearInDaysAtAge(tMa),
|
|
467
486
|
eccentricityAt,
|
|
468
487
|
eccentricityRateAt,
|
|
469
488
|
},
|
|
@@ -474,9 +493,10 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
474
493
|
// package's embedded deep-modes artifact; the banked-series tier is the
|
|
475
494
|
// repo-data-bound instrument). Absolute dates deliberately absent — see
|
|
476
495
|
// cardinal/one-source-structure.cjs. The mean year is SI SECONDS: the
|
|
477
|
-
// sidereal year of date reduced by the SECULAR
|
|
478
|
-
// (axial0·H(t)/
|
|
479
|
-
//
|
|
496
|
+
// sidereal year of date reduced by the SECULAR equinox precession
|
|
497
|
+
// (axial0·H(t)/H₀ with H(t) the UNIT = 13·T_p,composed — plan 06 D6/Phase
|
|
498
|
+
// 3, the movement's leg-1 convention, NOT the H/13 kinematic identity at
|
|
499
|
+
// J2000; the two are a recorded 0.09% relation tension there).
|
|
480
500
|
// THE ONE of-date year-length family (owner: "move to 1 implementation")
|
|
481
501
|
// — createYearLengths owns tropical (equinox-rate mean, wobble included),
|
|
482
502
|
// sidereal (the D6 λ̇ channel), anomalistic (the cardinal structure on
|
|
@@ -489,7 +509,13 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
489
509
|
// path; the npm package alone has no 8 MB series), the movement runs the
|
|
490
510
|
// SERIES tier exactly like the browser — killing the mode-vs-series
|
|
491
511
|
// value split (measured: 6 s on the anomalistic year at J2000).
|
|
492
|
-
|
|
512
|
+
// The engine-D planet chains (ONE build; the one-family route's apsidal
|
|
513
|
+
// tangent and the lunisolar surface's n_aps read the same instance).
|
|
514
|
+
const kcChainsM = buildPlanetChainsFromArtifactData(CHAIN_ARTIFACT);
|
|
515
|
+
// The ONE-SOURCE movement: the hybrid's ε(t) (plan 06 Phase 3 S3b — THE
|
|
516
|
+
// published obliquity) and the one-family year lengths, on the same
|
|
517
|
+
// per-tier sampler.
|
|
518
|
+
const oneSourceM = (() => {
|
|
493
519
|
const AEarth = /** @type {any} */ (CHAIN_ARTIFACT).j2000AnchorElements.earth;
|
|
494
520
|
// The ψ̇ anchor: the CERTIFIED of-date laws at 2000 — identical to the
|
|
495
521
|
// engine/browser (computeSiderealYearDaysDirect / computeSolarYearDays
|
|
@@ -501,6 +527,12 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
501
527
|
const sidLaw2000 = evalYearFourier(2000, siderealYearDaysBase(2000), F.SIDEREAL_YEAR_HARMONICS);
|
|
502
528
|
const solLaw2000 = evalYearFourier(2000, tropicalYearDaysBase(2000), F.TROPICAL_YEAR_HARMONICS);
|
|
503
529
|
const axial0 = sidLaw2000 / (sidLaw2000 - solLaw2000);
|
|
530
|
+
// D6 → Phase 3 (plan 06): the deep-time ψ̇(t) the hybrid precesses on is
|
|
531
|
+
// the COMPOSED lunisolar rate, and since Phase 3 the unit H(t) IS
|
|
532
|
+
// 13 × that period (deltat/deep-time.cjs hAtAge), so the injection is
|
|
533
|
+
// the plain period₀·H(t)/H₀ again — on the unit, not on the frozen
|
|
534
|
+
// era clock's H_era (which misses the lunar 1/a³ growth: 70.9 vs
|
|
535
|
+
// Lantink 2022's 108.6 ± 8.5 ″/yr at 2.46 Ga; the unit reads 104.5).
|
|
504
536
|
const H0 = /** @type {number} */ (deepLod.hAtAge(0));
|
|
505
537
|
const seriesArt = /** @type {any} */ (secularSeriesArtifact);
|
|
506
538
|
const sb = seriesArt && seriesArt.bodies && seriesArt.bodies.earth;
|
|
@@ -516,7 +548,13 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
516
548
|
anchorInclEclipticDeg: AEarth.inclEclipticDeg,
|
|
517
549
|
anchorAscNodeEclipticDeg: AEarth.ascNodeEclipticDeg,
|
|
518
550
|
axialPrecessionYearsJ2000: axial0,
|
|
519
|
-
|
|
551
|
+
// Phase 3 S3b: the hybrid's initial condition is the OBSERVED J2000
|
|
552
|
+
// mean obliquity — the IAU 2006 input constant (84381.406″), the same
|
|
553
|
+
// anchor the browser's _deepHistSeries and the Node one-source movement
|
|
554
|
+
// use. It was the K comb's own J2000 value, 0.233″ above IAU: a
|
|
555
|
+
// rendering-device residual imported as the initial condition of the
|
|
556
|
+
// physics (found when the package began publishing the hybrid).
|
|
557
|
+
obliquityJ2000Deg: C.earthOrbital.obliquityJ2000_deg,
|
|
520
558
|
axialPrecessionYearsAtYearFn: (yr) => {
|
|
521
559
|
const h = deepLod.hAtAge((startmodelYear - yr) / 1e6);
|
|
522
560
|
return axial0 * (h === null ? 1 : h / H0);
|
|
@@ -545,13 +583,19 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
545
583
|
};
|
|
546
584
|
// The anomalistic rides the chain's SECULAR apsidal tangent (the same
|
|
547
585
|
// rate family the panel's Prec. cell shows) — ONE helper, keplerian-chain.
|
|
548
|
-
const kcChains =
|
|
549
|
-
|
|
586
|
+
const kcChains = kcChainsM;
|
|
587
|
+
const yearLengths = createYearLengths({
|
|
550
588
|
sampleAt,
|
|
551
589
|
massLossSiderealSecondsAtYearFn: (year) => deepLod.siderealYearSecondsAtAge(yearToTMa(year)),
|
|
552
590
|
apsidalSecularDegPerYrFn: (year) => computeApsidalSecularDegPerYr(year, kcChains.earth, kcChains),
|
|
553
591
|
});
|
|
592
|
+
return {
|
|
593
|
+
yearLengths,
|
|
594
|
+
/** The hybrid's obliquity at a decimal year, degrees — the banked series inside its span, the α(t)-coupled ζ-tail integration beyond (the deep sampler grows ~0.1 s/Myr). @param {number} year @returns {number} */
|
|
595
|
+
epsAt: (year) => sampleAt(year).epsDeg,
|
|
596
|
+
};
|
|
554
597
|
})();
|
|
598
|
+
const yearLengthsM = oneSourceM.yearLengths;
|
|
555
599
|
|
|
556
600
|
/** Tropical year: mean of the four cardinal intervals. @param {number} year @returns {number} */
|
|
557
601
|
const tropicalYearDays = (year) => cardinalM.computeTropicalYearLength(year);
|
|
@@ -1170,6 +1214,22 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
1170
1214
|
});
|
|
1171
1215
|
|
|
1172
1216
|
// ── The assembled surface ─────────────────────────────────────────────────
|
|
1217
|
+
// Plan 06 Phase 3 S2 — THE published of-date precession period and mean
|
|
1218
|
+
// tropical year: the one-family route (B) inside the banked tiers
|
|
1219
|
+
// (|Δyear| ≤ ONE_FAMILY_WINDOW_YEARS), the unit's secular mean beyond
|
|
1220
|
+
// (H(t)/13; the tidal-chain year). Shared by `epoch` and `lunisolar`.
|
|
1221
|
+
/** @param {number} year @returns {number} */
|
|
1222
|
+
const publishedAxialPrecessionYearsAtYear = (year) => {
|
|
1223
|
+
if (Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS) return yearLengthsM.axialPrecessionYearsAtYear(year);
|
|
1224
|
+
const h = deepLod.hAtAge(yearToTMa(year));
|
|
1225
|
+
return (h === null ? H : h) / 13;
|
|
1226
|
+
};
|
|
1227
|
+
/** @param {number} year @returns {number} */
|
|
1228
|
+
const publishedTropicalYearSecondsAtYear = (year) => {
|
|
1229
|
+
if (Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS) return yearLengthsM.tropicalYearSecondsAtYear(year);
|
|
1230
|
+
return deepLod.tropicalYearSecondsAtAge(yearToTMa(year));
|
|
1231
|
+
};
|
|
1232
|
+
|
|
1173
1233
|
return Object.freeze({
|
|
1174
1234
|
time: Object.freeze({
|
|
1175
1235
|
yearFromJD,
|
|
@@ -1187,22 +1247,94 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
1187
1247
|
siderealYearSecondsAtYear: /** @param {number} year @returns {number} */ (year) => yearLengthsM.siderealYearSecondsAtYear(year),
|
|
1188
1248
|
deltaTSecondsAtYear: deltaTSeconds,
|
|
1189
1249
|
cyclesBetween,
|
|
1190
|
-
//
|
|
1191
|
-
//
|
|
1192
|
-
//
|
|
1193
|
-
// the (
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1250
|
+
// Plan 06 Phase 3 S2 — THE published of-date precession period is the
|
|
1251
|
+
// one-family route (B): the hybrid's own equinox regression against
|
|
1252
|
+
// the λ̇-corrected sidereal year (~25,771 yr at J2000 ≈ IAU), inside
|
|
1253
|
+
// the banked tiers (|Δyear| ≤ ONE_FAMILY_WINDOW_YEARS); beyond, the
|
|
1254
|
+
// unit's SECULAR mean H(t)/13 = the composed lunisolar period (the
|
|
1255
|
+
// of-date wobble is unresolved there). The comb family's beat
|
|
1256
|
+
// sid/(sid − tropicalYearDirectDays) — the frozen era clock's
|
|
1257
|
+
// kinematic-day device — is no longer published here; it still
|
|
1258
|
+
// anchors the lunar chain's (d′) rate completion (pDynDegPerYearAt,
|
|
1259
|
+
// a MATCHED TRIPLE with the eclipse gates: M0(a) measured a 3–15 min
|
|
1260
|
+
// lunar-timing shift if it moved).
|
|
1261
|
+
axialPrecessionYearsAtYear: publishedAxialPrecessionYearsAtYear,
|
|
1262
|
+
// The same publication rule for the mean tropical year of date (SI s):
|
|
1263
|
+
// one-family inside the window, the tidal-chain mean beyond.
|
|
1264
|
+
tropicalYearSecondsAtYear: publishedTropicalYearSecondsAtYear,
|
|
1265
|
+
}),
|
|
1266
|
+
// Plan 06 Phase 3 S3 — the lunisolar precession clock as a first-class
|
|
1267
|
+
// surface: Earth's spin clock, ONE home for its published faces, spoken
|
|
1268
|
+
// in PERIODS and their RATIOS — no unit, no integer. T_p(t) is the
|
|
1269
|
+
// composed lunisolar period (calculation map 2.1 step 6; the internal
|
|
1270
|
+
// identifier H is 13·T_p by definition and is not a face here); the
|
|
1271
|
+
// composition's terms; the of-date beat (the published family, seamed
|
|
1272
|
+
// at ±2 Myr); the apsidal period from the engine-D chain's secular
|
|
1273
|
+
// tangent and the two ratios the owner found wandering by hand —
|
|
1274
|
+
// T_aps/T_p (4.33 at J2000, 0.84 … 9.5 across ±26 kyr) and T_peri/T_p
|
|
1275
|
+
// with T_peri = 1/(1/T_p + 1/T_aps) the perihelion-of-date period
|
|
1276
|
+
// (0.812 at J2000). That these read close to 13/3 and 13/16 today is
|
|
1277
|
+
// the J2000 reading, stated nowhere as structure.
|
|
1278
|
+
lunisolar: Object.freeze({
|
|
1279
|
+
/** The mean lunisolar precession period T_p(t), years — the composed torque rate's period. @param {number} year @returns {number} */
|
|
1280
|
+
meanPeriodYearsAtYear: (year) => { const h = deepLod.hAtAge(yearToTMa(year)); return (h === null ? H : h) / 13; },
|
|
1281
|
+
/** The composed rate ψ̇(t) = [ω/ω₀]·p₀·[f_S + (1 − f_S)(a₀/a_M)³], ″/yr. @param {number} year @returns {number} */
|
|
1282
|
+
meanRateArcsecPerYrAtYear: (year) => { const r = deepLod.lunisolarPrecessionRateArcsecPerYrAtAge(yearToTMa(year)); return r === null ? 1296000 / (H / 13) : r; },
|
|
1283
|
+
/** The of-date period — the one-family beat inside ±2 Myr, the mean beyond. @param {number} year @returns {number} */
|
|
1284
|
+
ofDatePeriodYearsAtYear: publishedAxialPrecessionYearsAtYear,
|
|
1285
|
+
/** f_S, the solar fraction of the J2000 precession torque. */
|
|
1286
|
+
solarShareJ2000: EPOCH_PARAMS.precessionSolarShareJ2000,
|
|
1287
|
+
/** (a₀/a_M(t))³ — the lunar torque's growth on the recession history. @param {number} year @returns {number} */
|
|
1288
|
+
lunarTorqueFactorAtYear: (year) => { const f = deepLod.lunarTorqueFactorAtAge(yearToTMa(year)); return f === null ? 1 : f; },
|
|
1289
|
+
/** f_S + (1 − f_S)(a₀/a_M)³ — the torque term the unit divides H_era by. @param {number} year @returns {number} */
|
|
1290
|
+
torqueTermAtYear: (year) => { const t = deepLod.precessionTorqueTermAtAge(yearToTMa(year)); return t === null ? 1 : t; },
|
|
1291
|
+
/** The hybrid's precession constant α = p₀ / cos ε₀, ″/yr (ε₀ the J2000 obliquity input). */
|
|
1292
|
+
torqueConstantJ2000ArcsecPerYr: (1296000 / (H / 13)) / Math.cos((C.earthOrbital.obliquityJ2000_deg * Math.PI) / 180),
|
|
1293
|
+
/** The apsidal (perihelion vs the stars) period from the engine-D chain's secular tangent, years — inside the published window only (the tangent is an extrapolation beyond the banked series: it turns negative at −5 Myr); null beyond. @param {number} year @returns {number|null} */
|
|
1294
|
+
apsidalPeriodYearsAtYear: (year) => (Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS ? 360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM) : null),
|
|
1295
|
+
/** T_aps(t) / T_p(t) — the apsidal period in mean precession periods (4.33 at J2000, a fitted reading; 0.84 … 9.5 across ±26 kyr, measured); null beyond the published window. @param {number} year @returns {number|null} */
|
|
1296
|
+
apsidalPerPrecessionAtYear: (year) => {
|
|
1297
|
+
if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
|
|
1298
|
+
const h = deepLod.hAtAge(yearToTMa(year));
|
|
1299
|
+
return (360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM)) / ((h === null ? H : h) / 13);
|
|
1300
|
+
},
|
|
1301
|
+
/** 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), years; null beyond the published window. @param {number} year @returns {number|null} */
|
|
1302
|
+
periOfDatePeriodYearsAtYear: (year) => {
|
|
1303
|
+
if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
|
|
1304
|
+
const h = deepLod.hAtAge(yearToTMa(year));
|
|
1305
|
+
const tp = (h === null ? H : h) / 13, taps = 360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM);
|
|
1306
|
+
return 1 / (1 / tp + 1 / taps);
|
|
1307
|
+
},
|
|
1308
|
+
/** T_peri(t) / T_p(t) (0.812 at J2000 — the J2000 reading); null beyond the published window. @param {number} year @returns {number|null} */
|
|
1309
|
+
periOfDatePerPrecessionAtYear: (year) => {
|
|
1310
|
+
if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
|
|
1311
|
+
const h = deepLod.hAtAge(yearToTMa(year));
|
|
1312
|
+
const tp = (h === null ? H : h) / 13, taps = 360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM);
|
|
1313
|
+
return (1 / (1 / tp + 1 / taps)) / tp;
|
|
1197
1314
|
},
|
|
1315
|
+
/** The published of-date window, years from 2000. */
|
|
1316
|
+
publishedWindowYears: ONE_FAMILY_WINDOW_YEARS,
|
|
1198
1317
|
}),
|
|
1199
1318
|
earth: Object.freeze({
|
|
1200
1319
|
perihelionLongitudeDeg: earthPerihelionDeg,
|
|
1201
|
-
|
|
1320
|
+
// Plan 06 Phase 3 S3b: THE published obliquity is the hybrid — one
|
|
1321
|
+
// torque law integrated on the dynamical orbit plane of the N-body
|
|
1322
|
+
// chain, zero fitted constants (≡ La2004 to ≤ 4″ over ±50 kyr). The
|
|
1323
|
+
// fitted 16-harmonic K comb, a device fitted to the scene's own
|
|
1324
|
+
// wheel geometry (0.005″ to it, 1.27° off La2004 at −20 kyr), keeps
|
|
1325
|
+
// its name below as the frozen era clock's device: it anchors the
|
|
1326
|
+
// hybrid at J2000, the kinematic-day stack and the lunar arguments.
|
|
1327
|
+
obliquityDeg: /** @param {number} year @returns {number} */ (year) => oneSourceM.epsAt(year),
|
|
1328
|
+
obliquityCombDeg: obliquityDeg,
|
|
1202
1329
|
eccentricity: eccentricityAt,
|
|
1203
1330
|
inclinationDeg,
|
|
1204
1331
|
ascendingNodeDeg,
|
|
1205
1332
|
}),
|
|
1333
|
+
// The DEVICE family (plan 06 Phase 3 S2): the frozen era clock's comb
|
|
1334
|
+
// year lengths (A), its cardinal 4-mean (A′) and the kinematic-day stack
|
|
1335
|
+
// built on them (the ΔT stack's Layer 3/4 basis, USNO-anchored). NOT the
|
|
1336
|
+
// published year lengths — those are `yearLengths` (the one-family
|
|
1337
|
+
// route) and the seamed `epoch.*AtYear` surfaces above.
|
|
1206
1338
|
lengths: Object.freeze({
|
|
1207
1339
|
tropicalYearDays,
|
|
1208
1340
|
tropicalYearDirectDays,
|