@essrt/physics 8.0.0 → 9.1.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.
@@ -1,12 +1,39 @@
1
1
  /**
2
+ * THE SLOPE ANCHOR (owner-approved model change, after the Moon panels).
3
+ * The 18-term table reproduces the attractor and the 405-kyr beat, but
4
+ * nothing constrained its local DERIVATIVE at J2000: measured, its ė read
5
+ * −5.00e-5/cy against the run's own −4.24e-5 (and the observed −4.20e-5),
6
+ * a 19 % slope error that the lunar chain multiplied straight into the
7
+ * perigee and node curvature (−44″/cy² against Meeus's −37″/cy² — the
8
+ * "18 % split" the Moon precession panels showed). Against the ±10-Myr
9
+ * series the table compresses, the error is a LINEAR vector drift of
10
+ * 2.25e-4 per kyr out to ±20 kyr (an unresolved ultra-long mode), then
11
+ * spectrum-class either way. So the anchored form gains a second,
12
+ * BOUNDED term of the same class as the constant remainder:
13
+ *
14
+ * z(t) = Σ … + (z_J2000 − Σ(0)) + (ż_J2000 − Σ̇(0))·I(t),
15
+ * I(t) = ∫₀ᵗ cos²(π τ / 2T_q) dτ (the arguments' taper: linear near
16
+ * J2000, saturating at ±T_q/2 beyond |t| ≥ T_q)
17
+ *
18
+ * — ż_J2000 is the run's own z-rate at J2000 (script-written into the
19
+ * artifact by generate.mjs from the banked series: "we are the source"),
20
+ * T_q the H/12 taper the arguments' rate anchors ride. Inside the canon it
21
+ * restores the run's slope exactly; beyond ±T_q it is a constant vector
22
+ * offset of ~3e-3, the size of the table's own spectrum-class scatter
23
+ * there, never a growing polynomial. Absent the two fields (an older
24
+ * artifact), the channel is the value-anchored form above, unchanged.
25
+ *
2
26
  * @param {{
3
27
  * earthZ: ReadonlyArray<{omegaRadPerYr: number, re: number, im: number}>,
4
28
  * anchorE: number,
5
29
  * anchorPeriEclipticDeg: number,
30
+ * anchorZDotPerYr?: ReadonlyArray<number>,
31
+ * slopeTaperYears?: number,
6
32
  * }} artifact — the embedded deep-modes artifact (earth z-modes + the J2000
7
- * anchor pair joined from the chain artifact's one home).
33
+ * anchor pair joined from the chain artifact's one home, + the J2000
34
+ * z-rate pair and the taper from the series' one home).
8
35
  */
9
- export function createDeepEccChannel({ earthZ, anchorE, anchorPeriEclipticDeg }: {
36
+ export function createDeepEccChannel({ earthZ, anchorE, anchorPeriEclipticDeg, anchorZDotPerYr, slopeTaperYears }: {
10
37
  earthZ: ReadonlyArray<{
11
38
  omegaRadPerYr: number;
12
39
  re: number;
@@ -14,6 +41,8 @@ export function createDeepEccChannel({ earthZ, anchorE, anchorPeriEclipticDeg }:
14
41
  }>;
15
42
  anchorE: number;
16
43
  anchorPeriEclipticDeg: number;
44
+ anchorZDotPerYr?: ReadonlyArray<number>;
45
+ slopeTaperYears?: number;
17
46
  }): {
18
47
  eccAt: (tYr: number) => number;
19
48
  eccRateAt: (tYr: number) => number;
@@ -136,5 +136,7 @@ export const DEEP_MODES_ARTIFACT: Readonly<{
136
136
  anchorPeriEclipticDeg: 462.9179213996577;
137
137
  anchorInclEclipticDeg: 0.00010345820355474172;
138
138
  anchorAscNodeEclipticDeg: 140.29217988414328;
139
+ anchorZDotPerYr: number[];
140
+ slopeTaperYears: 27943.083333333332;
139
141
  }>;
140
142
  export const DEEP_MODES_ARTIFACT_HASH: "77e0baf779e85de5";
@@ -14,6 +14,8 @@
14
14
  * nNodalOfDateJ2000: number,
15
15
  * moonApsidalJ2000Seconds: number,
16
16
  * moonNodalJ2000Seconds: number,
17
+ * moonApsidalOfDateJ2000Seconds: number,
18
+ * moonNodalOfDateJ2000Seconds: number,
17
19
  * moonSiderealMonthJ2000Seconds: number,
18
20
  * sPerigee: number,
19
21
  * sNode: number,
@@ -47,6 +49,8 @@ export function createMoonMonthChain({ constants, fns }: {
47
49
  nNodalOfDateJ2000: number;
48
50
  moonApsidalJ2000Seconds: number;
49
51
  moonNodalJ2000Seconds: number;
52
+ moonApsidalOfDateJ2000Seconds: number;
53
+ moonNodalOfDateJ2000Seconds: number;
50
54
  moonSiderealMonthJ2000Seconds: number;
51
55
  sPerigee: number;
52
56
  sNode: number;
@@ -25,35 +25,6 @@ export function computeInclinationLaw(b: {
25
25
  amplitude: number;
26
26
  mean: number;
27
27
  };
28
- /**
29
- * Wobble period: beat of axial precession and perihelion ICRF precession.
30
- * @param {number} periEclYr @param {number} axialYr @param {number} H
31
- * @returns {number} years */
32
- export function computeWobblePeriodYears(periEclYr: number, axialYr: number, H: number): number;
33
- /**
34
- * Obliquity cycle with the Venus/Neptune fallback: the record's cycle if
35
- * present, else |ICRF| (tidally damped — the two-component obliquity
36
- * formula cancels exactly, constant tilt).
37
- * @param {number | null | undefined} obliquityCycleYears
38
- * @param {number} periEclYr @param {number} H @returns {number} */
39
- export function resolveObliquityCycleYears(obliquityCycleYears: number | null | undefined, periEclYr: number, H: number): number;
40
- /**
41
- * Mean obliquity, SNAPSHOT form (the load-time law both engines ship):
42
- * mean = tiltJ2000 + amp·cos(ωᵢ·t₂₀₀₀) − amp·cos(ωₒ·t₂₀₀₀).
43
- * @param {{ axialTiltJ2000: number, invPlaneInclinationAmplitude: number,
44
- * perihelionEclipticYears: number }} b
45
- * @param {number | null | undefined} obliqCycleYears — falsy ⇒ static tilt
46
- * @param {{ H: number, t2000: number }} env — t2000 = 2000 − eccentricity
47
- * anchor (balancedYear − systemResetN·H)
48
- * @returns {number} degrees */
49
- export function computeObliquityMeanSnapshot(b: {
50
- axialTiltJ2000: number;
51
- invPlaneInclinationAmplitude: number;
52
- perihelionEclipticYears: number;
53
- }, obliqCycleYears: number | null | undefined, env: {
54
- H: number;
55
- t2000: number;
56
- }): number;
57
28
  /**
58
29
  * K constant from Earth's calibration. @param {{
59
30
  * eccentricityAmplitude: number, massEarthAlone: number, massSun: number,
@@ -10,8 +10,14 @@ export type PlanetModelBody = {
10
10
  inclinationCycleAnchor?: number | undefined;
11
11
  antiPhase?: boolean | undefined;
12
12
  perihelionEclipticYears?: number | undefined;
13
- axialPrecessionYears?: number | undefined;
14
- obliquityCycle?: number | null | undefined;
13
+ /**
14
+ * - carriers: the chain's g-mode beat (input since Phase 7 commit 2)
15
+ */
16
+ wobblePeriodYears?: number | undefined;
17
+ /**
18
+ * - carriers: the derived J2000 obliquity (input since Phase 7 commit 2)
19
+ */
20
+ obliquityMeanDeg?: number | undefined;
15
21
  axialTiltJ2000?: number | undefined;
16
22
  orbitalEccentricityJ2000?: number | undefined;
17
23
  ascendingNode?: number | undefined;
@@ -60,8 +66,8 @@ export type PlanetModelRecord = {
60
66
  * @property {number} [inclinationCycleAnchor]
61
67
  * @property {boolean} [antiPhase]
62
68
  * @property {number} [perihelionEclipticYears]
63
- * @property {number} [axialPrecessionYears]
64
- * @property {number|null} [obliquityCycle]
69
+ * @property {number} [wobblePeriodYears] - carriers: the chain's g-mode beat (input since Phase 7 commit 2)
70
+ * @property {number} [obliquityMeanDeg] - carriers: the derived J2000 obliquity (input since Phase 7 commit 2)
65
71
  * @property {number} [axialTiltJ2000]
66
72
  * @property {number} [orbitalEccentricityJ2000]
67
73
  * @property {number} [ascendingNode]
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @param {{ secularModes: Record<string, { z: ReadonlyArray<{omegaRadPerYr: number, re: number, im: number}> }> }} artifact
3
+ * @param {string} key
4
+ * @returns {{ dom: { arcsecPerYr: number, amp: number }, sub: { arcsecPerYr: number, amp: number },
5
+ * rest: { count: number, amp: number }, ampSumAll: number, beatYears: number }}
6
+ */
7
+ export function computeSecularShape(artifact: {
8
+ secularModes: Record<string, {
9
+ z: ReadonlyArray<{
10
+ omegaRadPerYr: number;
11
+ re: number;
12
+ im: number;
13
+ }>;
14
+ }>;
15
+ }, key: string): {
16
+ dom: {
17
+ arcsecPerYr: number;
18
+ amp: number;
19
+ };
20
+ sub: {
21
+ arcsecPerYr: number;
22
+ amp: number;
23
+ };
24
+ rest: {
25
+ count: number;
26
+ amp: number;
27
+ };
28
+ ampSumAll: number;
29
+ beatYears: number;
30
+ };
@@ -0,0 +1,193 @@
1
+ export type SpinSatellite = {
2
+ name?: string;
3
+ gmKm3S2: number;
4
+ semiMajorAxisKm: number;
5
+ orbitalPeriodDays: number;
6
+ retrograde?: boolean;
7
+ };
8
+ export type SpinInputs = {
9
+ j2: number;
10
+ j2ReferenceRadiusKm: number;
11
+ momentOfInertiaFactor: number;
12
+ momentOfInertiaFactorClass?: string;
13
+ rotationRateDegPerDay: number;
14
+ poleRaJ2000Deg: number;
15
+ poleDecJ2000Deg: number;
16
+ cassiniLocked?: boolean;
17
+ satellites: ReadonlyArray<SpinSatellite>;
18
+ };
19
+ /** @typedef {{ name?: string, gmKm3S2: number, semiMajorAxisKm: number, orbitalPeriodDays: number, retrograde?: boolean }} SpinSatellite */
20
+ /** @typedef {{ j2: number, j2ReferenceRadiusKm: number, momentOfInertiaFactor: number,
21
+ * momentOfInertiaFactorClass?: string, rotationRateDegPerDay: number,
22
+ * poleRaJ2000Deg: number, poleDecJ2000Deg: number, cassiniLocked?: boolean,
23
+ * satellites: ReadonlyArray<SpinSatellite> }} SpinInputs */
24
+ /**
25
+ * The precession constant from the planet's own torques.
26
+ * @param {{
27
+ * j2: number, j2ReferenceRadiusKm: number, momentOfInertiaFactor: number,
28
+ * rotationRateDegPerDay: number, satellites: ReadonlyArray<SpinSatellite>,
29
+ * gmPlanetSystemKm3S2: number, meanMotionRadPerYr: number, eccentricity: number,
30
+ * }} p
31
+ * @returns {{ alphaArcsecPerYr: number, alphaRadPerYr: number, q: number, l: number,
32
+ * spinRadPerYr: number, spinRetrograde: boolean, gmPlanetAloneKm3S2: number }}
33
+ */
34
+ export function computePlanetPrecessionConstant(p: {
35
+ j2: number;
36
+ j2ReferenceRadiusKm: number;
37
+ momentOfInertiaFactor: number;
38
+ rotationRateDegPerDay: number;
39
+ satellites: ReadonlyArray<SpinSatellite>;
40
+ gmPlanetSystemKm3S2: number;
41
+ meanMotionRadPerYr: number;
42
+ eccentricity: number;
43
+ }): {
44
+ alphaArcsecPerYr: number;
45
+ alphaRadPerYr: number;
46
+ q: number;
47
+ l: number;
48
+ spinRadPerYr: number;
49
+ spinRetrograde: boolean;
50
+ gmPlanetAloneKm3S2: number;
51
+ };
52
+ /**
53
+ * @param {{
54
+ * key: string,
55
+ * spin: SpinInputs,
56
+ * zetaModes: ReadonlyArray<{omegaRadPerYr: number, re: number, im: number}>,
57
+ * anchorInclEclipticDeg: number, anchorAscNodeEclipticDeg: number,
58
+ * semiMajorAxisAU: number, eccentricity: number, massFractionOfSun: number,
59
+ * gmSunKm3S2: number, obliquityJ2000Deg: number, stepYr?: number,
60
+ * }} deps — spin from the astro-reference planetSpinPhysical block; the ζ
61
+ * table and the J2000 anchor elements from the governed artifacts; the
62
+ * mass fraction (planet system / Sun) for the two-body mean motion
63
+ * n = 2π√((1 + μ)/a³); the J2000 obliquity of the ecliptic for the pole
64
+ * conversion.
65
+ */
66
+ export function createPlanetSpinChannel(deps: {
67
+ key: string;
68
+ spin: SpinInputs;
69
+ zetaModes: ReadonlyArray<{
70
+ omegaRadPerYr: number;
71
+ re: number;
72
+ im: number;
73
+ }>;
74
+ anchorInclEclipticDeg: number;
75
+ anchorAscNodeEclipticDeg: number;
76
+ semiMajorAxisAU: number;
77
+ eccentricity: number;
78
+ massFractionOfSun: number;
79
+ gmSunKm3S2: number;
80
+ obliquityJ2000Deg: number;
81
+ stepYr?: number;
82
+ }): Readonly<{
83
+ key: string;
84
+ cassiniLocked: boolean;
85
+ momentOfInertiaFactor: number;
86
+ momentOfInertiaFactorClass: string;
87
+ alphaArcsecPerYr: number;
88
+ satelliteQuadrupole: number;
89
+ satelliteAngularMomentum: number;
90
+ spinRetrograde: boolean;
91
+ meanMotionRadPerYr: number;
92
+ obliquityJ2000Deg: number;
93
+ spinPrecessionRateArcsecPerYrJ2000: number | null;
94
+ axialPrecessionPeriodYearsJ2000: number | null;
95
+ obliquityDegAtYear: (year: number) => number | null;
96
+ spinPrecessionRateArcsecPerYrAtYear: (year: number) => number | null;
97
+ obliquityEnvelopeDeg: (year: number, spanYr: number) => {
98
+ minDeg: number;
99
+ meanDeg: number;
100
+ maxDeg: number;
101
+ } | null;
102
+ stepYr: number;
103
+ maxSpanYr: 10000000;
104
+ }>;
105
+ /**
106
+ * The channel from the governed artifacts — the ONE construction every
107
+ * runtime shares (the package model, the Node scene engine, the browser
108
+ * through the model): the spin block, the chain's J2000 anchor elements and
109
+ * the deep ζ table for `key`.
110
+ * @param {{
111
+ * key: string,
112
+ * planetSpinPhysical: Record<string, SpinInputs>,
113
+ * chainAnchorElements: Record<string, { aAU: number, e: number, inclEclipticDeg: number, ascNodeEclipticDeg: number }>,
114
+ * planetZeta: Record<string, ReadonlyArray<{omegaRadPerYr: number, re: number, im: number}>>,
115
+ * massFractionOfSun: number, gmSunKm3S2: number, obliquityJ2000Deg: number,
116
+ * }} deps
117
+ */
118
+ export function createPlanetSpinChannelFromArtifacts(deps: {
119
+ key: string;
120
+ planetSpinPhysical: Record<string, SpinInputs>;
121
+ chainAnchorElements: Record<string, {
122
+ aAU: number;
123
+ e: number;
124
+ inclEclipticDeg: number;
125
+ ascNodeEclipticDeg: number;
126
+ }>;
127
+ planetZeta: Record<string, ReadonlyArray<{
128
+ omegaRadPerYr: number;
129
+ re: number;
130
+ im: number;
131
+ }>>;
132
+ massFractionOfSun: number;
133
+ gmSunKm3S2: number;
134
+ obliquityJ2000Deg: number;
135
+ }): Readonly<{
136
+ key: string;
137
+ cassiniLocked: boolean;
138
+ momentOfInertiaFactor: number;
139
+ momentOfInertiaFactorClass: string;
140
+ alphaArcsecPerYr: number;
141
+ satelliteQuadrupole: number;
142
+ satelliteAngularMomentum: number;
143
+ spinRetrograde: boolean;
144
+ meanMotionRadPerYr: number;
145
+ obliquityJ2000Deg: number;
146
+ spinPrecessionRateArcsecPerYrJ2000: number | null;
147
+ axialPrecessionPeriodYearsJ2000: number | null;
148
+ obliquityDegAtYear: (year: number) => number | null;
149
+ spinPrecessionRateArcsecPerYrAtYear: (year: number) => number | null;
150
+ obliquityEnvelopeDeg: (year: number, spanYr: number) => {
151
+ minDeg: number;
152
+ meanDeg: number;
153
+ maxDeg: number;
154
+ } | null;
155
+ stepYr: number;
156
+ maxSpanYr: 10000000;
157
+ }>;
158
+ /**
159
+ * The DERIVED J2000 obliquity to the planet's own orbit, degrees: the angle
160
+ * between the J2000 spin axis (angular-momentum sense — Venus ≈ 177°,
161
+ * Uranus ≈ 98°) and the chain's J2000 orbit plane. Needs no mode table and
162
+ * no integration — the load-time twins read it for the K device's
163
+ * "mean obliquity" slot (commit 2 of Phase 7); the acute form is
164
+ * `min(ε, 180 − ε)`.
165
+ * @param {{ spin: SpinInputs, anchorInclEclipticDeg: number,
166
+ * anchorAscNodeEclipticDeg: number, obliquityJ2000Deg: number }} p
167
+ * @returns {number}
168
+ */
169
+ export function computeObliquityJ2000Deg(p: {
170
+ spin: SpinInputs;
171
+ anchorInclEclipticDeg: number;
172
+ anchorAscNodeEclipticDeg: number;
173
+ obliquityJ2000Deg: number;
174
+ }): number;
175
+ /**
176
+ * The IAU pole (ICRF equatorial RA/Dec) as an ecliptic-J2000 unit vector.
177
+ * @param {number} raDeg @param {number} decDeg @param {number} obliquityJ2000Deg
178
+ * @returns {number[]}
179
+ */
180
+ export function poleEclipticJ2000(raDeg: number, decDeg: number, obliquityJ2000Deg: number): number[];
181
+ /**
182
+ * The planet's orbit normal n̂(t) in ecliptic J2000 from its deep ζ table,
183
+ * DC-anchored at the chain's J2000 plane (the Earth hybrid's ζ convention:
184
+ * ζ = sin(i/2)·e^{iΩ}; the anchor is the coordinate the modes wander around).
185
+ * @param {ReadonlyArray<{omegaRadPerYr: number, re: number, im: number}>} zetaModes
186
+ * @param {number} anchorInclEclipticDeg @param {number} anchorAscNodeEclipticDeg
187
+ * @returns {(tYr: number) => number[]}
188
+ */
189
+ export function createOrbitNormalEvaluator(zetaModes: ReadonlyArray<{
190
+ omegaRadPerYr: number;
191
+ re: number;
192
+ im: number;
193
+ }>, anchorInclEclipticDeg: number, anchorAscNodeEclipticDeg: number): (tYr: number) => number[];