@essrt/physics 20.0.1 → 22.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.
Files changed (63) hide show
  1. package/README.md +4 -4
  2. package/package.json +4 -8
  3. package/src/cardinal/one-source-structure.cjs +3 -2
  4. package/src/chain-cycles/index.cjs +12 -30
  5. package/src/climate/l1-orbital.cjs +3 -1
  6. package/src/constants/coefficients.d.ts +17 -93
  7. package/src/constants/coefficients.js +7 -22
  8. package/src/constants/generated.d.ts +18 -156
  9. package/src/constants/generated.js +33 -168
  10. package/src/deltat/deep-time.cjs +36 -92
  11. package/src/deltat/recession-history.cjs +2 -1
  12. package/src/earth/deep-orbital-history.cjs +4 -4
  13. package/src/earth/frame-of-date.cjs +25 -1
  14. package/src/earth/precession-composed.cjs +3 -3
  15. package/src/earth/year-lengths.cjs +16 -1
  16. package/src/eclipse/sun-planetary-completion.cjs +11 -12
  17. package/src/index.js +28 -48
  18. package/src/layer0/derive-params.js +10 -5
  19. package/src/layer0/index.js +27 -73
  20. package/src/layer1/index.js +6 -37
  21. package/src/model.js +200 -225
  22. package/src/moon/arguments.cjs +57 -83
  23. package/src/moon/deep-modes-artifact.cjs +2 -2
  24. package/src/moon/month-chain.cjs +25 -59
  25. package/src/moon/series.cjs +14 -10
  26. package/src/phase/deep-calendar.cjs +35 -80
  27. package/src/planets/chain-artifact.js +2 -2
  28. package/src/planets/display-names.cjs +30 -0
  29. package/src/planets/geometry.cjs +79 -29
  30. package/src/planets/model.cjs +12 -11
  31. package/src/planets/spin-channel.cjs +46 -2
  32. package/types/chain-cycles/index.d.cts +9 -4
  33. package/types/climate/l1-orbital.d.cts +3 -1
  34. package/types/constants/coefficients.d.ts +17 -93
  35. package/types/constants/generated.d.ts +18 -156
  36. package/types/deltat/deep-time.d.cts +3 -16
  37. package/types/earth/frame-of-date.d.cts +9 -0
  38. package/types/earth/year-lengths.d.cts +12 -0
  39. package/types/eclipse/sun-planetary-completion.d.cts +0 -9
  40. package/types/index.d.ts +4 -13
  41. package/types/layer0/derive-params.d.ts +7 -4
  42. package/types/layer0/index.d.ts +6 -13
  43. package/types/layer1/index.d.ts +0 -2
  44. package/types/model.d.ts +8 -6
  45. package/types/moon/arguments.d.cts +23 -22
  46. package/types/moon/deep-modes-artifact.d.cts +3 -3
  47. package/types/moon/month-chain.d.cts +7 -16
  48. package/types/moon/series.d.cts +2 -4
  49. package/types/phase/deep-calendar.d.cts +14 -50
  50. package/types/planets/display-names.d.cts +2 -0
  51. package/types/planets/geometry.d.cts +36 -13
  52. package/types/planets/model.d.cts +7 -6
  53. package/types/planets/spin-channel.d.cts +4 -0
  54. package/src/cardinal/index.cjs +0 -324
  55. package/src/moon/ecc-channel.cjs +0 -141
  56. package/src/phase/index.cjs +0 -186
  57. package/src/planets/ecc-channel.cjs +0 -59
  58. package/src/sun/longitude-correction.cjs +0 -68
  59. package/types/cardinal/index.d.cts +0 -80
  60. package/types/moon/ecc-channel.d.cts +0 -30
  61. package/types/phase/index.d.cts +0 -38
  62. package/types/planets/ecc-channel.d.cts +0 -20
  63. package/types/sun/longitude-correction.d.cts +0 -41
@@ -47,7 +47,6 @@ const { moonSeriesExtensionDeg } = require('./series-extension.cjs');
47
47
  * moonDistanceJ2000Km: number,
48
48
  * j2000JD: number,
49
49
  * julianCenturyDays: number,
50
- * moonMeeusLpCorrectionDeg: number,
51
50
  * fwA2RateDegPerCy: number,
52
51
  * fwA3RateDegPerCy: number,
53
52
  * },
@@ -61,7 +60,7 @@ const { moonSeriesExtensionDeg } = require('./series-extension.cjs');
61
60
  * jdToSIyear: (jd: number) => number,
62
61
  * tropicalOrbitsBetween: (yearA: number, yearB: number) => (number | null),
63
62
  * apsidalOfDateCyclesBetween: (yearA: number, yearB: number) => (number | null),
64
- * cyclesBetween: (yearA: number, yearB: number, divisorN: number) => (number | null),
63
+ * siderealOrbitsBetween: (yearA: number, yearB: number) => (number | null),
65
64
  * jupiterOrbitsBetween: (yearA: number, yearB: number) => (number | null),
66
65
  * isDeepTime: () => boolean,
67
66
  * isFrameworkNative: () => boolean,
@@ -75,12 +74,12 @@ const { moonSeriesExtensionDeg } = require('./series-extension.cjs');
75
74
  function createMoonSeries({ constants, fns }) {
76
75
  const {
77
76
  moonL, moonB, moonR, moonRMeanKm, moonDistanceJ2000Km, j2000JD, julianCenturyDays,
78
- moonMeeusLpCorrectionDeg, fwA2RateDegPerCy, fwA3RateDegPerCy,
77
+ fwA2RateDegPerCy, fwA3RateDegPerCy,
79
78
  } = constants;
80
79
  const {
81
80
  argsAt, eFactorForD, eFactorAtJdTT, getMoonDistanceKm, getEccentricityBase, deltaTSeconds,
82
81
  jdToSIyear, tropicalOrbitsBetween, apsidalOfDateCyclesBetween,
83
- cyclesBetween, jupiterOrbitsBetween, isDeepTime, isFrameworkNative,
82
+ siderealOrbitsBetween, jupiterOrbitsBetween, isDeepTime, isFrameworkNative,
84
83
  } = fns;
85
84
 
86
85
  const D2R = Math.PI / 180;
@@ -97,10 +96,14 @@ function createMoonSeries({ constants, fns }) {
97
96
  const yA = jdToSIyear(j2000JD + dDaysTT);
98
97
  const nT = tropicalOrbitsBetween(yA0, yA);
99
98
  const nAps = apsidalOfDateCyclesBetween(yA0, yA);
100
- const nP13 = cyclesBetween(yA0, yA, 13);
99
+ // A3 is the STAR-referenced lunar longitude (Meeus' rate 481,266.484 °/cy
100
+ // ≡ 360°/sidereal month): the chain's sidereal-orbit count directly.
101
+ // Plan 09 step 5c — it was the tropical count minus the counter's 13/H
102
+ // precession turns (0.086 % slow on the precession).
103
+ const nSid = siderealOrbitsBetween(yA0, yA);
101
104
  const nJ = jupiterOrbitsBetween(yA0, yA);
102
- if (nT !== null && nAps !== null && nP13 !== null && nJ !== null) {
103
- a3Deg = 313.45 + 360 * (nT - nP13);
105
+ if (nT !== null && nAps !== null && nSid !== null && nJ !== null) {
106
+ a3Deg = 313.45 + 360 * nSid;
104
107
  a2Deg = 53.09 + 360 * (nT + nAps - 2 * nJ);
105
108
  }
106
109
  }
@@ -172,8 +175,9 @@ function createMoonSeries({ constants, fns }) {
172
175
  * Returns everything the scene blocks write:
173
176
  * thetaAddRad — the hierarchy θ increment (EoC-half-subtracted Σl);
174
177
  * lonDeg — full ecliptic longitude (GEOMETRIC, mean equinox of date)
175
- * incl. the derived series-extension tail and moonMeeusLpCorrection
176
- * (retired to 0 at plan 06 R3 item 1: measured against Horizons' apparent
178
+ * incl. the derived series-extension tail. (The fitted mean-longitude
179
+ * anchor moonMeeusLpCorrection was retired to 0 at plan 06 R3 item 1 and
180
+ * its parameter deleted at plan 11 step 2: measured against Horizons' apparent
177
181
  * Moon over 1970–2049 the series needs no anchor, −1.0″ ± 1.5″ flat in
178
182
  * elongation; the former +32.75″ was the eclipse tier's mean Sun
179
183
  * compensated — its aberration κ, the I2 long inequality and the trend-ΔT
@@ -216,7 +220,7 @@ function createMoonSeries({ constants, fns }) {
216
220
  // Full longitude re-adds the EoC half that θ absorbed.
217
221
  const fullSl = Sl + (2 * eocHalf / D2R * 1e6) * Math.sin(Mpr)
218
222
  + (1.25 * eocHalf * eocHalf / D2R * 1e6) * Math.sin(2 * Mpr);
219
- const lonDeg = Lp / D2R + fullSl * 1e-6 + moonMeeusLpCorrectionDeg;
223
+ const lonDeg = Lp / D2R + fullSl * 1e-6;
220
224
  const distKm = fullDistanceKm(Dr, Mr, Mpr, Fr, E, E2, j2000JD + d);
221
225
  return { thetaAddRad, lonDeg, latRad, latDeg, distKm, T };
222
226
  }
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Deep-time calendar — year ↔ JD under the drifting year length, and the
3
- * H-balanced event finder. ONE implementation for both engines.
2
+ * Deep-time calendar — year ↔ JD under the drifting year length. ONE
3
+ * implementation for both engines.
4
4
  *
5
- * Until the year/day collapse these five functions lived twice, hand-mirrored:
5
+ * Until the year/day collapse these functions lived twice, hand-mirrored:
6
6
  * `src/script.js` (the original) and `tools/lib/deep-time.js` (the port,
7
7
  * marked PHASE-B-DUPLICATE). The website's runtime twin was a third copy, and
8
8
  * both Phase E website bugs (Simpson-vs-trapezoid convention, the missing
@@ -10,26 +10,27 @@
10
10
  * VERBATIM from the browser copy — operation for operation — so the numerics
11
11
  * are the shipped ones:
12
12
  *
13
- * - the days-per-year integral rides the phase machinery's grid (10-kyr
14
- * cells, trapezoid rule, linear interpolation between cells) — the same
15
- * discretization the fitted coefficients were produced against;
13
+ * - the days-per-year integral rides the engines' deep-time grid (10-kyr
14
+ * cells over ±500 Myr, trapezoid rule, linear interpolation between
15
+ * cells — the discretization every year-keyed golden was produced
16
+ * against; until plan 09 step 7a the grid was the ∫dt/H phase table's,
17
+ * deleted with the unit's counting); the
18
+ * integrand is the tropical year of date over the day of date — since plan
19
+ * 09 step 5d one equinox turn per the composed precession period T_p(t),
20
+ * a movement, not the unit's count (the calendar's year is a tropical year);
16
21
  * - the table is built under the LATTICE α (R2): `withLatticeAlpha` is the
17
22
  * engine's pin, injected, so a table build can never see the climate-
18
23
  * modulated α(t);
19
24
  * - `yearToJD` CARRIES A KNOWN 0.6-d ZERO-POINT OFFSET (measured −0.600 d in
20
25
  * both engines): the anchor cell is seeded by linear extrapolation but read
21
- * back by interpolation across a 10-kyr cell. DO NOT "fix" it in
22
- * isolation — `balancedYearAtCycle` round-trips through `cyclesBetween`,
23
- * which absorbs the offset (that is why the bracket lands on
24
- * −302635.004 / 32682.268 exactly); normalising the table without
25
- * re-checking that round-trip moves the Step 6a window;
26
- * - `balancedYearAtCycle` round-trips through the JD deliberately, NOT as a
27
- * shortcut to bisecting `cyclesBetween` in calendar units: calendar-year
28
- * delta = H_J2000 exactly, but SI-year delta does not — they differ by
29
- * ~6.7 SI yr per H. Dropping the round-trip returns the SI label instead of
30
- * the calendar year. The Newton step uses H at J2000 (the browser stepped
31
- * with its live H; the iteration converges to 1e-12 cycles either way and
32
- * the two agree at J2000 scene state by construction).
26
+ * back by interpolation across a 10-kyr cell. A recorded property of the
27
+ * table — the Step 6a window and every year-keyed golden were produced
28
+ * against it; normalising it moves them.
29
+ * - (Plan 09 step 5d: the H-balanced event finder `balancedYearAtCycle` —
30
+ * the k-th year at which the unit's phase from J2000 is an integer, a
31
+ * Newton iteration on the ∫dt/H_era table — and the table's inverse
32
+ * `yearAtCumulIntegral` are deleted with the unit's counting; the Step 6a
33
+ * exporter reports a plain year window.)
33
34
  *
34
35
  * CommonJS on purpose, like `./index.cjs`: `tools/lib` is CJS and cannot
35
36
  * require an ESM module synchronously; ESM imports CJS natively.
@@ -37,14 +38,6 @@
37
38
 
38
39
  'use strict';
39
40
 
40
- /**
41
- * @typedef {Object} PhaseMachinery
42
- * @property {() => void} ensureTable
43
- * @property {(year: number) => (number | null)} cumulAtYear
44
- * @property {(targetCumul: number) => (number | null)} yearAtCumul
45
- * @property {() => {yearMin: number, yearMax: number, stepYears: number, j2000Idx: number, length: number}} grid
46
- */
47
-
48
41
  /**
49
42
  * @typedef {Object} DeepCalendar
50
43
  * @property {(jd: number) => number} jdToSIyear SI-tropical-year label for a
@@ -53,55 +46,49 @@
53
46
  * with the runtime by construction; the round-trip bias Y_SI − Y is −11.0 yr
54
47
  * at −302,635 and grows quadratically).
55
48
  * @property {(ySI: number) => number} siYearToJD the exact inverse of jdToSIyear.
56
- * @property {(targetCumul: number) => (number | null)} yearAtCumulIntegral
57
- * inverse of the phase machinery's cumulAtYear — null outside the table.
58
49
  * @property {() => void} ensureCumulDaysTable builds the ∫ daysPerYear dt table
59
50
  * (idempotent; under the lattice α).
60
51
  * @property {(year: number) => (number | null)} yearToJD calendar year → JD,
61
52
  * integrating days-per-year from startModelYear; null outside the table
62
53
  * domain or past the tidal-lock asymptote; startModelJD exactly at
63
54
  * year = startModelYear.
64
- * @property {(cycleOffset: number) => (number | null)} balancedYearAtCycle
65
- * calendar year of the k-th H-balanced event, k = 0 being `balancedYear`;
66
- * negative k = past; null outside the table domain.
67
55
  * @property {() => (number | null)} cumulDaysTableLength diagnostic — the
68
56
  * table length once built, null before.
69
57
  */
70
58
 
71
59
  /**
72
60
  * @param {{
73
- * phase: () => PhaseMachinery,
74
61
  * meanYearInDaysAtAgeMa: (tMa: number) => (number | null),
75
62
  * withLatticeAlpha: (build: () => void) => void,
76
63
  * startModelJD: number,
77
64
  * startModelYear: number,
78
65
  * startModelYearWithCorrection: number,
79
66
  * siTropicalYearDays: number,
80
- * balancedYear: number,
81
- * hJ2000: number,
82
- * cyclesBetween: (yearA: number, yearB: number, divisorN: number) => (number | null),
83
- * }} deps — `phase` is the engine's (lazily built) phase machinery, whose
84
- * grid the days table shares; `meanYearInDaysAtAgeMa` the engine's
85
- * days-per-year source (the LOD channel's `yearInDaysAtAge`);
86
- * `withLatticeAlpha` the engine's R2 pin; `cyclesBetween` the engine's
87
- * cycle counter (the browser passes its toggle-aware form, Node the
88
- * integrated form — the caller's convention, preserved); `startModelYear`
89
- * is the table zero (2000.5) and `startModelYearWithCorrection` the SI-axis
90
- * anchor (≈ 2000.4977) — two different constants, do not unify.
67
+ * yearMin?: number,
68
+ * yearMax?: number,
69
+ * stepYears?: number,
70
+ * }} deps — `meanYearInDaysAtAgeMa` is the engine's days-per-year source
71
+ * (the LOD channel's `yearInDaysAtAge`); `withLatticeAlpha` the engine's
72
+ * R2 pin; `startModelYear` is the table zero (2000.5) and
73
+ * `startModelYearWithCorrection` the SI-axis anchor (≈ 2000.4977) — two
74
+ * different constants, do not unify; the grid (±500 Myr, 10-kyr cells)
75
+ * is the engines' deep-time grid — the table zero sits at the cell
76
+ * nearest `startModelYear`.
91
77
  * @returns {DeepCalendar}
92
78
  */
93
79
  function createDeepCalendar({
94
- phase,
95
80
  meanYearInDaysAtAgeMa,
96
81
  withLatticeAlpha,
97
82
  startModelJD,
98
83
  startModelYear,
99
84
  startModelYearWithCorrection,
100
85
  siTropicalYearDays,
101
- balancedYear,
102
- hJ2000,
103
- cyclesBetween,
86
+ yearMin = -500e6,
87
+ yearMax = 500e6,
88
+ stepYears = 10000,
104
89
  }) {
90
+ const j2000Idx = Math.round((startModelYear - yearMin) / stepYears);
91
+ const N = Math.ceil((yearMax - yearMin) / stepYears) + 1;
105
92
  /** @type {(jd: number) => number} */
106
93
  const jdToSIyear = (jd) => startModelYearWithCorrection + (jd - startModelJD) / siTropicalYearDays;
107
94
  /** The exact inverse: SI-year label → JD (the Moon layers' argument clock
@@ -109,10 +96,7 @@ function createDeepCalendar({
109
96
  * @type {(ySI: number) => number} */
110
97
  const siYearToJD = (ySI) => startModelJD + (ySI - startModelYearWithCorrection) * siTropicalYearDays;
111
98
 
112
- /** @type {(targetCumul: number) => (number | null)} */
113
- const yearAtCumulIntegral = (targetCumul) => phase().yearAtCumul(targetCumul);
114
-
115
- /** ∫ daysPerYear dt from startModelYear, on the phase grid. @type {Float64Array | null} */
99
+ /** ∫ daysPerYear dt from startModelYear, on the deep-time grid. @type {Float64Array | null} */
116
100
  let cumulDaysTable = null;
117
101
 
118
102
  function ensureCumulDaysTable() {
@@ -121,9 +105,6 @@ function createDeepCalendar({
121
105
  }
122
106
 
123
107
  function buildCumulDaysTable() {
124
- const P = phase();
125
- P.ensureTable();
126
- const { yearMin, stepYears, j2000Idx, length: N } = P.grid();
127
108
  const table = new Float64Array(N);
128
109
 
129
110
  /** @type {(year: number) => (number | null)} */
@@ -159,7 +140,6 @@ function createDeepCalendar({
159
140
  if (!Number.isFinite(year)) return null;
160
141
  ensureCumulDaysTable();
161
142
  const table = /** @type {Float64Array} */ (cumulDaysTable);
162
- const { yearMin, yearMax, stepYears } = phase().grid();
163
143
  if (year < yearMin || year > yearMax) return null;
164
144
  const idx_f = (year - yearMin) / stepYears;
165
145
  const idx_lo = Math.floor(idx_f);
@@ -171,36 +151,11 @@ function createDeepCalendar({
171
151
  return startModelJD + daysFromStartModel;
172
152
  }
173
153
 
174
- /** @type {(cycleOffset: number) => (number | null)} */
175
- function balancedYearAtCycle(cycleOffset) {
176
- // No cycleOffset === 0 short-circuit: returning balancedYear directly
177
- // skips the JD round-trip below, misses the exact integer-cycle JD by
178
- // ~0.5 d and gives ~21″ obliquity drift + ~3e-9 e drift at cycle 0.
179
- const refCumul = phase().cumulAtYear(balancedYear);
180
- if (refCumul === null) return null;
181
- let Y = yearAtCumulIntegral(refCumul + cycleOffset);
182
- if (Y === null) return null;
183
- for (let iter = 0; iter < 5; iter++) {
184
- const jd = yearToJD(Y);
185
- if (jd === null) return Y;
186
- const Y_SI = jdToSIyear(jd);
187
- if (!Number.isFinite(Y_SI)) return Y;
188
- const corrected = cyclesBetween(balancedYear, Y_SI, 1);
189
- if (corrected === null) return Y;
190
- const error = corrected - cycleOffset;
191
- if (Math.abs(error) < 1e-12) break;
192
- Y = Y - error * hJ2000;
193
- }
194
- return Y;
195
- }
196
-
197
154
  return Object.freeze({
198
155
  jdToSIyear,
199
156
  siYearToJD,
200
- yearAtCumulIntegral,
201
157
  ensureCumulDaysTable,
202
158
  yearToJD,
203
- balancedYearAtCycle,
204
159
  cumulDaysTableLength: () => (cumulDaysTable === null ? null : cumulDaysTable.length),
205
160
  });
206
161
  }