@essrt/physics 4.9.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- 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 +98 -3
- package/src/earth/deep-orbital-history.cjs +6 -5
- package/src/earth/precession-composed.cjs +144 -0
- package/src/earth/year-lengths.cjs +12 -1
- package/src/index.js +18 -11
- package/src/layer0/derive-params.js +21 -4
- package/src/layer0/index.js +39 -5
- package/src/model.js +205 -36
- 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 +29 -0
- package/types/earth/precession-composed.d.cts +62 -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 +34 -0
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,9 +281,13 @@ 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,
|
|
288
|
+
// S5: the composed clock's J2000 anchor — the certified year laws' beat
|
|
289
|
+
// at 2000 (ONE home below, shared with the hybrid's self-anchor); lazy.
|
|
290
|
+
precessionPeriodJ2000YearsFn: () => certifiedAxialPrecessionJ2000Years(),
|
|
278
291
|
siderealYearDaysFourierAt: (year) => evalSiderealYearFourierIAU(year),
|
|
279
292
|
cycleLodSumAt: dtCycleLodCorrectionSum,
|
|
280
293
|
swingLodAt: (year) => dtCycles.swingLodSecondsAt(year),
|
|
@@ -283,8 +296,12 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
283
296
|
});
|
|
284
297
|
|
|
285
298
|
// ── Integrated ∫1/H(t)dt phase (R2 α-pin honoured while building) ─────────
|
|
299
|
+
// The phase counter every FROZEN comb reads rides the frozen era clock's
|
|
300
|
+
// own convention H_era = H₀·LOD/LOD₀ (plan 06 D8: two named counters — the
|
|
301
|
+
// coefficients were fitted against this counter and ship with it), NOT the
|
|
302
|
+
// unit H(t) = 13·T_p,composed that the physics publishes.
|
|
286
303
|
const phaseM = createPhaseMachinery({
|
|
287
|
-
holisticHAtAgeMa: (tMa) => deepLod.
|
|
304
|
+
holisticHAtAgeMa: (tMa) => deepLod.eraClockHAtAge(tMa),
|
|
288
305
|
tableAnchorYear: startmodelYear,
|
|
289
306
|
driftRefYear: startModelYearWithCorrection,
|
|
290
307
|
hJ2000: H,
|
|
@@ -413,16 +430,37 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
413
430
|
if (lod === null) return meanSiderealYearDays;
|
|
414
431
|
return deepLod.siderealYearSecondsAtAge(tMa) / lod;
|
|
415
432
|
};
|
|
433
|
+
// The comb family's bases are the FROZEN era clock's forms (H_era; plan 06
|
|
434
|
+
// D8) — the combs were fitted on them. The physical year lengths ride the
|
|
435
|
+
// unit through yearLengths (family B) and the tidal-chain mean.
|
|
416
436
|
/** @param {number} year @returns {number} */
|
|
417
437
|
const tropicalYearDaysBase = (year) => {
|
|
418
|
-
const days = deepLod.
|
|
438
|
+
const days = deepLod.eraClockYearInDaysAtAge(yearToTMa(year));
|
|
419
439
|
return days === null ? meanSolarYearDays : days;
|
|
420
440
|
};
|
|
441
|
+
/** THE J2000 precession anchor (plan 06 S5 — one J2000 precession
|
|
442
|
+
* reading): the certified of-date year laws at 2000, sid/(sid − trop) =
|
|
443
|
+
* 25,771.4 yr = 50.2883 ″/yr (IAU 50.2879 to 8×10⁻⁶) — identical to the
|
|
444
|
+
* engine/browser Direct twins. ONE home: the composed clock's p₀, the
|
|
445
|
+
* hybrid's self-anchor and the lunisolar surface all read it. The former
|
|
446
|
+
* H/13 reading (25,793.6) is the fit anchor's, not a period. Memoized;
|
|
447
|
+
* hoisted so the deep-time factory's lazy dep can name it.
|
|
448
|
+
* @returns {number} */
|
|
449
|
+
function certifiedAxialPrecessionJ2000Years() {
|
|
450
|
+
if (certifiedAxial0Memo === undefined) {
|
|
451
|
+
const sidLaw2000 = evalYearFourier(2000, siderealYearDaysBase(2000), F.SIDEREAL_YEAR_HARMONICS);
|
|
452
|
+
const solLaw2000 = evalYearFourier(2000, tropicalYearDaysBase(2000), F.TROPICAL_YEAR_HARMONICS);
|
|
453
|
+
certifiedAxial0Memo = sidLaw2000 / (sidLaw2000 - solLaw2000);
|
|
454
|
+
}
|
|
455
|
+
return certifiedAxial0Memo;
|
|
456
|
+
}
|
|
457
|
+
/** @type {number|undefined} */
|
|
458
|
+
let certifiedAxial0Memo;
|
|
421
459
|
/** @param {number} year @returns {number} */
|
|
422
460
|
const anomalisticYearDaysBase = (year) => {
|
|
423
461
|
const tMa = yearToTMa(year);
|
|
424
|
-
const Ht = deepLod.
|
|
425
|
-
const tropD = deepLod.
|
|
462
|
+
const Ht = deepLod.eraClockHAtAge(tMa);
|
|
463
|
+
const tropD = deepLod.eraClockYearInDaysAtAge(tMa);
|
|
426
464
|
if (Ht === null || tropD === null) return meanAnomalisticYearDays;
|
|
427
465
|
return (tropD * (Ht / 16)) / (Ht / 16 - 1);
|
|
428
466
|
};
|
|
@@ -456,14 +494,16 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
456
494
|
},
|
|
457
495
|
fns: {
|
|
458
496
|
cyclesBetween: (a, b, n) => phase().cyclesBetween(a, b, n),
|
|
497
|
+
// The frozen era clock's deps ride ITS convention H_era (plan 06 D8):
|
|
498
|
+
// drift integrand, dc/dY and the real-LOD convention were fitted on it.
|
|
459
499
|
analyticTropicalDays: (year) => {
|
|
460
500
|
const tMa = (startmodelYear - year) / 1e6;
|
|
461
|
-
const Ht = deepLod.
|
|
501
|
+
const Ht = deepLod.eraClockHAtAge(tMa);
|
|
462
502
|
if (Ht === null) return null;
|
|
463
503
|
return (deepLod.siderealYearSecondsAtAge(tMa) / 86400) * (1 - 13 / Ht);
|
|
464
504
|
},
|
|
465
|
-
meanHAtAgeMa: (tMa) => deepLod.
|
|
466
|
-
meanYearRealLodDays: (tMa) => deepLod.
|
|
505
|
+
meanHAtAgeMa: (tMa) => deepLod.eraClockHAtAge(tMa),
|
|
506
|
+
meanYearRealLodDays: (tMa) => deepLod.eraClockYearInDaysAtAge(tMa),
|
|
467
507
|
eccentricityAt,
|
|
468
508
|
eccentricityRateAt,
|
|
469
509
|
},
|
|
@@ -474,9 +514,10 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
474
514
|
// package's embedded deep-modes artifact; the banked-series tier is the
|
|
475
515
|
// repo-data-bound instrument). Absolute dates deliberately absent — see
|
|
476
516
|
// 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
|
-
//
|
|
517
|
+
// sidereal year of date reduced by the SECULAR equinox precession
|
|
518
|
+
// (axial0·H(t)/H₀ with H(t) the UNIT = 13·T_p,composed — plan 06 D6/Phase
|
|
519
|
+
// 3, the movement's leg-1 convention, NOT the H/13 kinematic identity at
|
|
520
|
+
// J2000; the two are a recorded 0.09% relation tension there).
|
|
480
521
|
// THE ONE of-date year-length family (owner: "move to 1 implementation")
|
|
481
522
|
// — createYearLengths owns tropical (equinox-rate mean, wobble included),
|
|
482
523
|
// sidereal (the D6 λ̇ channel), anomalistic (the cardinal structure on
|
|
@@ -489,7 +530,13 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
489
530
|
// path; the npm package alone has no 8 MB series), the movement runs the
|
|
490
531
|
// SERIES tier exactly like the browser — killing the mode-vs-series
|
|
491
532
|
// value split (measured: 6 s on the anomalistic year at J2000).
|
|
492
|
-
|
|
533
|
+
// The engine-D planet chains (ONE build; the one-family route's apsidal
|
|
534
|
+
// tangent and the lunisolar surface's n_aps read the same instance).
|
|
535
|
+
const kcChainsM = buildPlanetChainsFromArtifactData(CHAIN_ARTIFACT);
|
|
536
|
+
// The ONE-SOURCE movement: the hybrid's ε(t) (plan 06 Phase 3 S3b — THE
|
|
537
|
+
// published obliquity) and the one-family year lengths, on the same
|
|
538
|
+
// per-tier sampler.
|
|
539
|
+
const oneSourceM = (() => {
|
|
493
540
|
const AEarth = /** @type {any} */ (CHAIN_ARTIFACT).j2000AnchorElements.earth;
|
|
494
541
|
// The ψ̇ anchor: the CERTIFIED of-date laws at 2000 — identical to the
|
|
495
542
|
// engine/browser (computeSiderealYearDaysDirect / computeSolarYearDays
|
|
@@ -498,9 +545,13 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
498
545
|
// movement's realized precession 25 yr off the certified value — the
|
|
499
546
|
// hidden split behind the API's 365.242204 tropical mean (found in the
|
|
500
547
|
// owner's one-implementation drive).
|
|
501
|
-
const
|
|
502
|
-
|
|
503
|
-
|
|
548
|
+
const axial0 = certifiedAxialPrecessionJ2000Years(); // S5: the ONE home
|
|
549
|
+
// D6 → Phase 3 (plan 06): the deep-time ψ̇(t) the hybrid precesses on is
|
|
550
|
+
// the COMPOSED lunisolar rate, and since Phase 3 the unit H(t) IS
|
|
551
|
+
// 13 × that period (deltat/deep-time.cjs hAtAge), so the injection is
|
|
552
|
+
// the plain period₀·H(t)/H₀ again — on the unit, not on the frozen
|
|
553
|
+
// era clock's H_era (which misses the lunar 1/a³ growth: 70.9 vs
|
|
554
|
+
// Lantink 2022's 108.6 ± 8.5 ″/yr at 2.46 Ga; the unit reads 104.5).
|
|
504
555
|
const H0 = /** @type {number} */ (deepLod.hAtAge(0));
|
|
505
556
|
const seriesArt = /** @type {any} */ (secularSeriesArtifact);
|
|
506
557
|
const sb = seriesArt && seriesArt.bodies && seriesArt.bodies.earth;
|
|
@@ -516,7 +567,13 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
516
567
|
anchorInclEclipticDeg: AEarth.inclEclipticDeg,
|
|
517
568
|
anchorAscNodeEclipticDeg: AEarth.ascNodeEclipticDeg,
|
|
518
569
|
axialPrecessionYearsJ2000: axial0,
|
|
519
|
-
|
|
570
|
+
// Phase 3 S3b: the hybrid's initial condition is the OBSERVED J2000
|
|
571
|
+
// mean obliquity — the IAU 2006 input constant (84381.406″), the same
|
|
572
|
+
// anchor the browser's _deepHistSeries and the Node one-source movement
|
|
573
|
+
// use. It was the K comb's own J2000 value, 0.233″ above IAU: a
|
|
574
|
+
// rendering-device residual imported as the initial condition of the
|
|
575
|
+
// physics (found when the package began publishing the hybrid).
|
|
576
|
+
obliquityJ2000Deg: C.earthOrbital.obliquityJ2000_deg,
|
|
520
577
|
axialPrecessionYearsAtYearFn: (yr) => {
|
|
521
578
|
const h = deepLod.hAtAge((startmodelYear - yr) / 1e6);
|
|
522
579
|
return axial0 * (h === null ? 1 : h / H0);
|
|
@@ -545,13 +602,19 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
545
602
|
};
|
|
546
603
|
// The anomalistic rides the chain's SECULAR apsidal tangent (the same
|
|
547
604
|
// rate family the panel's Prec. cell shows) — ONE helper, keplerian-chain.
|
|
548
|
-
const kcChains =
|
|
549
|
-
|
|
605
|
+
const kcChains = kcChainsM;
|
|
606
|
+
const yearLengths = createYearLengths({
|
|
550
607
|
sampleAt,
|
|
551
608
|
massLossSiderealSecondsAtYearFn: (year) => deepLod.siderealYearSecondsAtAge(yearToTMa(year)),
|
|
552
609
|
apsidalSecularDegPerYrFn: (year) => computeApsidalSecularDegPerYr(year, kcChains.earth, kcChains),
|
|
553
610
|
});
|
|
611
|
+
return {
|
|
612
|
+
yearLengths,
|
|
613
|
+
/** 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} */
|
|
614
|
+
epsAt: (year) => sampleAt(year).epsDeg,
|
|
615
|
+
};
|
|
554
616
|
})();
|
|
617
|
+
const yearLengthsM = oneSourceM.yearLengths;
|
|
555
618
|
|
|
556
619
|
/** Tropical year: mean of the four cardinal intervals. @param {number} year @returns {number} */
|
|
557
620
|
const tropicalYearDays = (year) => cardinalM.computeTropicalYearLength(year);
|
|
@@ -1170,6 +1233,34 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
1170
1233
|
});
|
|
1171
1234
|
|
|
1172
1235
|
// ── The assembled surface ─────────────────────────────────────────────────
|
|
1236
|
+
// Plan 06 Phase 3 S2 — THE published of-date precession period and mean
|
|
1237
|
+
// tropical year: the one-family route (B) inside the banked tiers
|
|
1238
|
+
// (|Δyear| ≤ ONE_FAMILY_WINDOW_YEARS), the composed lunisolar period
|
|
1239
|
+
// beyond (S5: on the derived J2000 anchor, so the two faces agree at
|
|
1240
|
+
// 25,771.4 at J2000 and the deep tail is the same clock scaled; the
|
|
1241
|
+
// tidal-chain year). Shared by `epoch` and `lunisolar`.
|
|
1242
|
+
/** @param {number} year @returns {number} */
|
|
1243
|
+
const publishedAxialPrecessionYearsAtYear = (year) => {
|
|
1244
|
+
if (Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS) return yearLengthsM.axialPrecessionYearsAtYear(year);
|
|
1245
|
+
const p = deepLod.lunisolarPrecessionPeriodYearsAtAge(yearToTMa(year));
|
|
1246
|
+
return p === null ? certifiedAxialPrecessionJ2000Years() : p;
|
|
1247
|
+
};
|
|
1248
|
+
/** @param {number} year @returns {number} */
|
|
1249
|
+
const publishedTropicalYearSecondsAtYear = (year) => {
|
|
1250
|
+
if (Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS) return yearLengthsM.tropicalYearSecondsAtYear(year);
|
|
1251
|
+
return deepLod.tropicalYearSecondsAtAge(yearToTMa(year));
|
|
1252
|
+
};
|
|
1253
|
+
// Plan 06 S6 — |s₃|, the dominant nodal mode of Earth's orbit: the
|
|
1254
|
+
// largest-amplitude ζ mode of the banked deep secular modes (the recipe
|
|
1255
|
+
// the registry's `eclPrecYears`/`obliqCycleYears` and the browser's
|
|
1256
|
+
// obliquity-beat helper use). ONE home here; the API reads it.
|
|
1257
|
+
const s3ArcsecPerYr = (() => {
|
|
1258
|
+
const z = DEEP_MODES_ARTIFACT.earthZeta
|
|
1259
|
+
.filter((m) => Math.abs(m.omegaRadPerYr) > 1e-9)
|
|
1260
|
+
.sort((a, b) => Math.hypot(b.re, b.im) - Math.hypot(a.re, a.im))[0];
|
|
1261
|
+
return Math.abs((z.omegaRadPerYr * 180) / Math.PI) * 3600;
|
|
1262
|
+
})();
|
|
1263
|
+
|
|
1173
1264
|
return Object.freeze({
|
|
1174
1265
|
time: Object.freeze({
|
|
1175
1266
|
yearFromJD,
|
|
@@ -1187,22 +1278,100 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
|
|
|
1187
1278
|
siderealYearSecondsAtYear: /** @param {number} year @returns {number} */ (year) => yearLengthsM.siderealYearSecondsAtYear(year),
|
|
1188
1279
|
deltaTSecondsAtYear: deltaTSeconds,
|
|
1189
1280
|
cyclesBetween,
|
|
1190
|
-
//
|
|
1191
|
-
//
|
|
1192
|
-
//
|
|
1193
|
-
// the (
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1281
|
+
// Plan 06 Phase 3 S2 — THE published of-date precession period is the
|
|
1282
|
+
// one-family route (B): the hybrid's own equinox regression against
|
|
1283
|
+
// the λ̇-corrected sidereal year (~25,771 yr at J2000 ≈ IAU), inside
|
|
1284
|
+
// the banked tiers (|Δyear| ≤ ONE_FAMILY_WINDOW_YEARS); beyond, the
|
|
1285
|
+
// composed lunisolar period on the same J2000 anchor (S5; the
|
|
1286
|
+
// of-date wobble is unresolved there). The comb family's beat
|
|
1287
|
+
// sid/(sid − tropicalYearDirectDays) — the frozen era clock's
|
|
1288
|
+
// kinematic-day device — is no longer published here; it still
|
|
1289
|
+
// anchors the lunar chain's (d′) rate completion (pDynDegPerYearAt,
|
|
1290
|
+
// a MATCHED TRIPLE with the eclipse gates: M0(a) measured a 3–15 min
|
|
1291
|
+
// lunar-timing shift if it moved).
|
|
1292
|
+
axialPrecessionYearsAtYear: publishedAxialPrecessionYearsAtYear,
|
|
1293
|
+
// The same publication rule for the mean tropical year of date (SI s):
|
|
1294
|
+
// one-family inside the window, the tidal-chain mean beyond.
|
|
1295
|
+
tropicalYearSecondsAtYear: publishedTropicalYearSecondsAtYear,
|
|
1296
|
+
}),
|
|
1297
|
+
// Plan 06 Phase 3 S3 → S5 — the lunisolar precession clock as a
|
|
1298
|
+
// first-class surface: Earth's spin clock, ONE home for its published
|
|
1299
|
+
// faces, spoken in PERIODS and their RATIOS — no unit, no integer.
|
|
1300
|
+
// ONE J2000 reading (S5): every face reads 25,771.4 yr at J2000 — the
|
|
1301
|
+
// of-date period (the published family, seamed at ±2 Myr) and the
|
|
1302
|
+
// composed mean T_p(t) (the deep-time clock, anchored on the same
|
|
1303
|
+
// derived value). The composition's terms; the apsidal period from the
|
|
1304
|
+
// engine-D chain's secular tangent; the two ratios the owner found
|
|
1305
|
+
// wandering by hand — T_aps/T_p (4.33 at J2000, 0.84 … 9.9 across
|
|
1306
|
+
// ±26 kyr) and T_peri/T_p with T_peri = 1/(1/T_p + 1/T_aps) the
|
|
1307
|
+
// perihelion-of-date period (0.812 at J2000) — on the of-date T_p.
|
|
1308
|
+
lunisolar: Object.freeze({
|
|
1309
|
+
/** The mean lunisolar precession period T_p(t), years — the composed torque rate's period on the derived J2000 anchor (25,771.4 at J2000). @param {number} year @returns {number} */
|
|
1310
|
+
meanPeriodYearsAtYear: (year) => { const p = deepLod.lunisolarPrecessionPeriodYearsAtAge(yearToTMa(year)); return p === null ? certifiedAxialPrecessionJ2000Years() : p; },
|
|
1311
|
+
/** The composed rate ψ̇(t) = [ω/ω₀]·p₀·[f_S + (1 − f_S)(a₀/a_M)³], ″/yr (p₀ = 50.2883, derived). @param {number} year @returns {number} */
|
|
1312
|
+
meanRateArcsecPerYrAtYear: (year) => { const r = deepLod.lunisolarPrecessionRateArcsecPerYrAtAge(yearToTMa(year)); return r === null ? 1296000 / certifiedAxialPrecessionJ2000Years() : r; },
|
|
1313
|
+
/** The of-date period — the one-family beat inside ±2 Myr, the composed mean beyond. @param {number} year @returns {number} */
|
|
1314
|
+
ofDatePeriodYearsAtYear: publishedAxialPrecessionYearsAtYear,
|
|
1315
|
+
/** f_S, the solar fraction of the J2000 precession torque. */
|
|
1316
|
+
solarShareJ2000: EPOCH_PARAMS.precessionSolarShareJ2000,
|
|
1317
|
+
/** (a₀/a_M(t))³ — the lunar torque's growth on the recession history. @param {number} year @returns {number} */
|
|
1318
|
+
lunarTorqueFactorAtYear: (year) => { const f = deepLod.lunarTorqueFactorAtAge(yearToTMa(year)); return f === null ? 1 : f; },
|
|
1319
|
+
/** f_S + (1 − f_S)(a₀/a_M)³ — the torque term the unit divides H_era by. @param {number} year @returns {number} */
|
|
1320
|
+
torqueTermAtYear: (year) => { const t = deepLod.precessionTorqueTermAtAge(yearToTMa(year)); return t === null ? 1 : t; },
|
|
1321
|
+
/** The hybrid's precession constant α = p₀ / cos ε₀, ″/yr (p₀ the derived J2000 rate, ε₀ the J2000 obliquity input; 54.81). */
|
|
1322
|
+
torqueConstantJ2000ArcsecPerYr: (1296000 / certifiedAxialPrecessionJ2000Years()) / Math.cos((C.earthOrbital.obliquityJ2000_deg * Math.PI) / 180),
|
|
1323
|
+
/** |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. */
|
|
1324
|
+
nodalModeS3ArcsecPerYr: s3ArcsecPerYr,
|
|
1325
|
+
/** The ecliptic (nodal) precession period 1,296,000/|s₃|, years (68,751) — an orbital quantity, fixed at every epoch at the two-body level. */
|
|
1326
|
+
nodalPeriodYears: 1296000 / s3ArcsecPerYr,
|
|
1327
|
+
/** The obliquity beat 2π/(ψ̇(t) − |s₃|), years — the SHIPPED deep-time obliquity period (falsification leg 1; 41,224 at J2000, on the composed rate). @param {number} year @returns {number} */
|
|
1328
|
+
obliquityBeatYearsAtYear: (year) => {
|
|
1329
|
+
const r = deepLod.lunisolarPrecessionRateArcsecPerYrAtAge(yearToTMa(year));
|
|
1330
|
+
const psiDot = r === null ? 1296000 / certifiedAxialPrecessionJ2000Years() : r;
|
|
1331
|
+
return 1296000 / (psiDot - s3ArcsecPerYr);
|
|
1332
|
+
},
|
|
1333
|
+
/** 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} */
|
|
1334
|
+
apsidalPeriodYearsAtYear: (year) => (Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS ? 360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM) : null),
|
|
1335
|
+
/** 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} */
|
|
1336
|
+
apsidalPerPrecessionAtYear: (year) => {
|
|
1337
|
+
if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
|
|
1338
|
+
return (360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM)) / publishedAxialPrecessionYearsAtYear(year);
|
|
1339
|
+
},
|
|
1340
|
+
/** 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, on the of-date T_p; null beyond the published window. @param {number} year @returns {number|null} */
|
|
1341
|
+
periOfDatePeriodYearsAtYear: (year) => {
|
|
1342
|
+
if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
|
|
1343
|
+
const tp = publishedAxialPrecessionYearsAtYear(year), taps = 360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM);
|
|
1344
|
+
return 1 / (1 / tp + 1 / taps);
|
|
1345
|
+
},
|
|
1346
|
+
/** T_peri(t) / T_p(t) (0.812 at J2000 — the J2000 reading); null beyond the published window. @param {number} year @returns {number|null} */
|
|
1347
|
+
periOfDatePerPrecessionAtYear: (year) => {
|
|
1348
|
+
if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
|
|
1349
|
+
const tp = publishedAxialPrecessionYearsAtYear(year), taps = 360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM);
|
|
1350
|
+
return (1 / (1 / tp + 1 / taps)) / tp;
|
|
1197
1351
|
},
|
|
1352
|
+
/** The published of-date window, years from 2000. */
|
|
1353
|
+
publishedWindowYears: ONE_FAMILY_WINDOW_YEARS,
|
|
1198
1354
|
}),
|
|
1199
1355
|
earth: Object.freeze({
|
|
1200
1356
|
perihelionLongitudeDeg: earthPerihelionDeg,
|
|
1201
|
-
|
|
1357
|
+
// Plan 06 Phase 3 S3b: THE published obliquity is the hybrid — one
|
|
1358
|
+
// torque law integrated on the dynamical orbit plane of the N-body
|
|
1359
|
+
// chain, zero fitted constants (≡ La2004 to ≤ 4″ over ±50 kyr). The
|
|
1360
|
+
// fitted 16-harmonic K comb, a device fitted to the scene's own
|
|
1361
|
+
// wheel geometry (0.005″ to it, 1.27° off La2004 at −20 kyr), keeps
|
|
1362
|
+
// its name below as the frozen era clock's device: it anchors the
|
|
1363
|
+
// hybrid at J2000, the kinematic-day stack and the lunar arguments.
|
|
1364
|
+
obliquityDeg: /** @param {number} year @returns {number} */ (year) => oneSourceM.epsAt(year),
|
|
1365
|
+
obliquityCombDeg: obliquityDeg,
|
|
1202
1366
|
eccentricity: eccentricityAt,
|
|
1203
1367
|
inclinationDeg,
|
|
1204
1368
|
ascendingNodeDeg,
|
|
1205
1369
|
}),
|
|
1370
|
+
// The DEVICE family (plan 06 Phase 3 S2): the frozen era clock's comb
|
|
1371
|
+
// year lengths (A), its cardinal 4-mean (A′) and the kinematic-day stack
|
|
1372
|
+
// built on them (the ΔT stack's Layer 3/4 basis, USNO-anchored). NOT the
|
|
1373
|
+
// published year lengths — those are `yearLengths` (the one-family
|
|
1374
|
+
// route) and the seamed `epoch.*AtYear` surfaces above.
|
|
1206
1375
|
lengths: Object.freeze({
|
|
1207
1376
|
tropicalYearDays,
|
|
1208
1377
|
tropicalYearDirectDays,
|