@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
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The composed lunisolar precession rate — ONE home (holisticuniverse plan 06,
|
|
3
|
+
* D6: the physical ψ̇(t) of falsification leg 1).
|
|
4
|
+
*
|
|
5
|
+
* Earth's axial precession rate is the two tiers composed: the spin ω(t) from
|
|
6
|
+
* the tidal chain (LOD history) carries BOTH torques, and the lunar torque
|
|
7
|
+
* additionally grows with the recession history as (a₀/a_M(t))³:
|
|
8
|
+
*
|
|
9
|
+
* ψ̇(t) = [ω(t)/ω₀] · p₀ · [ f_S + (1 − f_S) · (a₀/a_M(t))³ ]
|
|
10
|
+
*
|
|
11
|
+
* with p₀ the J2000 rate and f_S the solar fraction of the J2000 torque,
|
|
12
|
+
* derived from the shared constants (two-body point-mass torques with the
|
|
13
|
+
* (1 − e²)^(−3/2) eccentricity factors and the lunar-inclination factor
|
|
14
|
+
* 1 − 3/2·sin² i_M; ≈ 0.316, the textbook value). At J2000 every factor is 1.
|
|
15
|
+
*
|
|
16
|
+
* THE ANCHOR p₀ (plan 06 S5 — one J2000 precession reading): p₀ is the
|
|
17
|
+
* model's DERIVED J2000 rate, 1,296,000/axial0 with axial0 the certified
|
|
18
|
+
* year-length laws' beat at 2000 (sid/(sid − trop) = 25,771.4 yr = 50.2883
|
|
19
|
+
* ″/yr, IAU 50.2879 to 8×10⁻⁶) — the SAME anchor the hybrid obliquity
|
|
20
|
+
* self-anchors on. It is NOT 1,296,000/(H/13): H₀ = 335,317 was fitted on
|
|
21
|
+
* the 1246 AD perihelion–solstice alignment (the perihelion-of-date beat),
|
|
22
|
+
* so H₀/13 = 25,793.6 yr is the fit anchor's reading, 0.086 % slow, and
|
|
23
|
+
* is not a period of anything the model computes (nor a window mean: the
|
|
24
|
+
* published period averages 25,598 yr over ±26 kyr). The unit H(t) =
|
|
25
|
+
* H_era/[torque term] (deltat/deep-time.cjs hAtAge) scales WITH the
|
|
26
|
+
* composed period — H(t)/T_p(t) = H₀/axial0 = 13.011 at every epoch — but
|
|
27
|
+
* is not 13 of them; the 13 is a fit-era label that leaves the physics.
|
|
28
|
+
* The pre-Phase-3 structural clock 13·1,296,000/H_era(t) (pure ω-scaling,
|
|
29
|
+
* H_era = H₀·LOD/LOD₀) survives only as the FROZEN ERA CLOCK's named phase
|
|
30
|
+
* convention (eraClockHAtAge) and in docs/retired-record.md, with its
|
|
31
|
+
* record: it read 70.9 ″/yr against Lantink et al. 2022's 108.6 ± 8.5 at
|
|
32
|
+
* 2.46 Ga and 65.2 against Meyers & Malinverno 2018's 85.79 ± 2.72 at
|
|
33
|
+
* 1.4 Ga, where the composed rate reads 104.6 and 86.6.
|
|
34
|
+
*
|
|
35
|
+
* Pure factory: the tidal chain is injected (each runtime's own LOD and
|
|
36
|
+
* moon-distance evaluators), no artifact reads, no globals.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
'use strict';
|
|
40
|
+
|
|
41
|
+
const D2R = Math.PI / 180;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Solar fraction of the J2000 precession torque from the shared constants.
|
|
45
|
+
* @param {{
|
|
46
|
+
* gmSunKm3S2: number, auKm: number, earthEccentricity: number,
|
|
47
|
+
* gmMoonKm3S2: number, moonDistanceKm: number, moonEccentricity: number, moonInclinationDeg: number,
|
|
48
|
+
* }} c
|
|
49
|
+
* @returns {number} f_S in [0, 1]
|
|
50
|
+
*/
|
|
51
|
+
function computeSolarTorqueShare(c) {
|
|
52
|
+
const sol = (c.gmSunKm3S2 / c.auKm ** 3) * Math.pow(1 - c.earthEccentricity * c.earthEccentricity, -1.5);
|
|
53
|
+
const lun = (c.gmMoonKm3S2 / c.moonDistanceKm ** 3) * Math.pow(1 - c.moonEccentricity * c.moonEccentricity, -1.5)
|
|
54
|
+
* (1 - 1.5 * Math.sin(c.moonInclinationDeg * D2R) ** 2);
|
|
55
|
+
return sol / (sol + lun);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {{
|
|
60
|
+
* p0ArcsecPerYr: number | (() => number),
|
|
61
|
+
* solarShare: number,
|
|
62
|
+
* lodSecondsAtAge: (tMa: number) => (number | null),
|
|
63
|
+
* lodJ2000Seconds: number,
|
|
64
|
+
* moonDistanceMetresAtAge: (tMa: number) => (number | null),
|
|
65
|
+
* moonDistanceJ2000Metres: number,
|
|
66
|
+
* yearToTMa: (year: number) => number,
|
|
67
|
+
* }} deps - p0 = the model's derived J2000 rate, 1,296,000/axial0 (S5; a
|
|
68
|
+
* number or a LAZY getter — the callers' certified year laws read the
|
|
69
|
+
* deep-time factory this is built inside, so the anchor is resolved on
|
|
70
|
+
* the first RATE use, never at construction; the torque term needs no
|
|
71
|
+
* anchor); lodJ2000Seconds the SAME day basis lodSecondsAtAge(0) returns.
|
|
72
|
+
* @returns {{
|
|
73
|
+
* composedRateArcsecPerYrAtAge: (tMa: number) => (number | null),
|
|
74
|
+
* composedPeriodYearsAtAge: (tMa: number) => (number | null),
|
|
75
|
+
* composedRateArcsecPerYrAtYear: (year: number) => (number | null),
|
|
76
|
+
* composedPeriodYearsAtYear: (year: number) => (number | null),
|
|
77
|
+
* composedRateRatioAtAge: (tMa: number) => (number | null),
|
|
78
|
+
* torqueTermAtAge: (tMa: number) => (number | null),
|
|
79
|
+
* lunarTorqueFactorAtAge: (tMa: number) => (number | null),
|
|
80
|
+
* solarShare: number,
|
|
81
|
+
* p0ArcsecPerYr: number,
|
|
82
|
+
* }}
|
|
83
|
+
*/
|
|
84
|
+
function createComposedPrecession(deps) {
|
|
85
|
+
const { solarShare: fS } = deps;
|
|
86
|
+
/** @type {number|undefined} */
|
|
87
|
+
let p0Memo;
|
|
88
|
+
/** The J2000 anchor, resolved once on first use (lazy getter allowed). */
|
|
89
|
+
const p0 = () => {
|
|
90
|
+
if (p0Memo === undefined) {
|
|
91
|
+
const v = typeof deps.p0ArcsecPerYr === 'function' ? deps.p0ArcsecPerYr() : deps.p0ArcsecPerYr;
|
|
92
|
+
if (!(v > 0)) throw new Error(`createComposedPrecession: p0ArcsecPerYr must resolve to a positive rate, got ${v}`);
|
|
93
|
+
p0Memo = v;
|
|
94
|
+
}
|
|
95
|
+
return p0Memo;
|
|
96
|
+
};
|
|
97
|
+
/** @param {number} tMa */
|
|
98
|
+
const lunarTorqueFactorAtAge = (tMa) => {
|
|
99
|
+
const a = deps.moonDistanceMetresAtAge(tMa);
|
|
100
|
+
return a === null || !(a > 0) ? null : Math.pow(deps.moonDistanceJ2000Metres / a, 3);
|
|
101
|
+
};
|
|
102
|
+
/** The torque term f_S + (1 − f_S)·(a₀/a_M)³ — the factor the unit H(t)
|
|
103
|
+
* divides the spin-scaled H_era by (deltat/deep-time.cjs; layer0 spells the
|
|
104
|
+
* SAME operations, the layer0 gate holds them bit-identical).
|
|
105
|
+
* @param {number} tMa */
|
|
106
|
+
const torqueTermAtAge = (tMa) => {
|
|
107
|
+
const lf = lunarTorqueFactorAtAge(tMa);
|
|
108
|
+
return lf === null ? null : fS + (1 - fS) * lf;
|
|
109
|
+
};
|
|
110
|
+
/** @param {number} tMa */
|
|
111
|
+
const composedRateArcsecPerYrAtAge = (tMa) => {
|
|
112
|
+
const lod = deps.lodSecondsAtAge(tMa);
|
|
113
|
+
const term = torqueTermAtAge(tMa);
|
|
114
|
+
if (lod === null || !(lod > 0) || term === null) return null;
|
|
115
|
+
return (deps.lodJ2000Seconds / lod) * p0() * term;
|
|
116
|
+
};
|
|
117
|
+
/** @param {number} tMa */
|
|
118
|
+
const composedPeriodYearsAtAge = (tMa) => {
|
|
119
|
+
const r = composedRateArcsecPerYrAtAge(tMa);
|
|
120
|
+
return r === null ? null : 1296000 / r;
|
|
121
|
+
};
|
|
122
|
+
/** ψ̇(t)/ψ̇₀ — the factor a consumer scales ITS OWN certified J2000
|
|
123
|
+
* anchor by (since S5 p₀ and the hybrids' anchor are the same derived
|
|
124
|
+
* value, 25,771.4 yr; the ratio is what D6 changes). ≡ 1 at J2000; null
|
|
125
|
+
* out of the tidal chain's domain.
|
|
126
|
+
* @param {number} tMa */
|
|
127
|
+
const composedRateRatioAtAge = (tMa) => {
|
|
128
|
+
const r = composedRateArcsecPerYrAtAge(tMa);
|
|
129
|
+
return r === null ? null : r / p0();
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
composedRateArcsecPerYrAtAge,
|
|
133
|
+
composedPeriodYearsAtAge,
|
|
134
|
+
composedRateArcsecPerYrAtYear: (year) => composedRateArcsecPerYrAtAge(deps.yearToTMa(year)),
|
|
135
|
+
composedPeriodYearsAtYear: (year) => composedPeriodYearsAtAge(deps.yearToTMa(year)),
|
|
136
|
+
composedRateRatioAtAge,
|
|
137
|
+
torqueTermAtAge,
|
|
138
|
+
lunarTorqueFactorAtAge,
|
|
139
|
+
solarShare: fS,
|
|
140
|
+
get p0ArcsecPerYr() { return p0(); },
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
module.exports = { computeSolarTorqueShare, createComposedPrecession };
|
|
@@ -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
|
|
@@ -223,19 +227,22 @@ export const createModel = (constants = GENERATED, opts = {}) => {
|
|
|
223
227
|
hash,
|
|
224
228
|
|
|
225
229
|
/**
|
|
226
|
-
*
|
|
230
|
+
* The fit-era lattice identities H/13, H/3, H/16, in years — DEVICE tier.
|
|
227
231
|
*
|
|
228
|
-
* PURE ALGEBRA OVER THE CONTEXT. No epoch, no formula, no fit.
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
* Something has to READ the context and return a number for injection to be
|
|
233
|
-
* demonstrated end to end.
|
|
232
|
+
* PURE ALGEBRA OVER THE CONTEXT. No epoch, no formula, no fit. They exist
|
|
233
|
+
* here for one reason: a hash-only counterfactual test would still pass if
|
|
234
|
+
* `createModel` ignored its argument entirely. Something has to READ the
|
|
235
|
+
* context and return a number for injection to be demonstrated end to end.
|
|
234
236
|
*
|
|
235
|
-
*
|
|
237
|
+
* These are NOT the published periods (plan 06 S5): the axial precession
|
|
238
|
+
* period is `epoch.axialPrecessionYearsAtYear` (25,771.4 yr at J2000, the
|
|
239
|
+
* of-date year laws' beat); H/13 = 25,793.6 is the fit anchor's reading,
|
|
240
|
+
* 0.086 % slow — H₀ was fitted on the perihelion-of-date beat. Likewise
|
|
241
|
+
* H/3 and H/16 against the chain's apsidal and perihelion-of-date periods.
|
|
242
|
+
* The property names keep their historical form (plan 06 P4).
|
|
236
243
|
*
|
|
237
244
|
* `divisor` and `period` are never interchangeable (CLAUDE.md): 13 is the
|
|
238
|
-
* divisor, H/13 years is the
|
|
245
|
+
* divisor, H/13 years is the identity's value. The names say which.
|
|
239
246
|
*
|
|
240
247
|
* @returns {{axialPrecessionPeriodYears: number, inclinationPrecessionPeriodYears: number, perihelionPrecessionPeriodYears: number}}
|
|
241
248
|
*/
|
|
@@ -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,
|
|
@@ -127,7 +149,10 @@ export const createEpochPrimitives = ({ params: p, alphaAtAgeMa }) => {
|
|
|
127
149
|
};
|
|
128
150
|
|
|
129
151
|
/**
|
|
130
|
-
* Tropical year — sidereal less one
|
|
152
|
+
* Tropical year — sidereal less one calendar turn of the unit, 13/H(t): the
|
|
153
|
+
* unit's CALENDAR convention (plan 06 S5 — a device identity, 0.086 % from
|
|
154
|
+
* one turn per the published precession period; D2 decided: it stays a
|
|
155
|
+
* named device, never re-based).
|
|
131
156
|
* Falls back to the J2000 H past the asymptote, matching the shipped chain.
|
|
132
157
|
* @param {number} t age in Ma
|
|
133
158
|
* @returns {number} seconds
|
|
@@ -159,6 +184,13 @@ export const createEpochPrimitives = ({ params: p, alphaAtAgeMa }) => {
|
|
|
159
184
|
return sid * (H - 13) / H * H / (H - 16);
|
|
160
185
|
};
|
|
161
186
|
|
|
187
|
+
/** The frozen comb family's tropical base: T_sid·(1 − 13/H_era). @param {number} t */
|
|
188
|
+
const eraClockTropicalYearSecondsCore = (t) => {
|
|
189
|
+
const sid = siderealYearSecondsCore(t);
|
|
190
|
+
const H = eraClockHCore(t);
|
|
191
|
+
return H === null ? sid * (1 - 13 / p.holisticYearJ2000) : sid * (1 - 13 / H);
|
|
192
|
+
};
|
|
193
|
+
|
|
162
194
|
return Object.freeze({
|
|
163
195
|
tMa,
|
|
164
196
|
moonDistanceMetres: (year) => moonDistanceMetresCore(tMa(year)),
|
|
@@ -167,5 +199,7 @@ export const createEpochPrimitives = ({ params: p, alphaAtAgeMa }) => {
|
|
|
167
199
|
siderealYearSeconds: (year) => siderealYearSecondsCore(tMa(year)),
|
|
168
200
|
tropicalYearSeconds: (year) => tropicalYearSecondsCore(tMa(year)),
|
|
169
201
|
anomalisticYearSeconds: (year) => anomalisticYearSecondsCore(tMa(year)),
|
|
202
|
+
eraClockH: (year) => eraClockHCore(tMa(year)),
|
|
203
|
+
eraClockTropicalYearSeconds: (year) => eraClockTropicalYearSecondsCore(tMa(year)),
|
|
170
204
|
});
|
|
171
205
|
};
|