@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 CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@essrt/physics",
3
- "version": "4.9.0",
3
+ "version": "5.0.0",
4
4
  "description": "ESSRT (Expanding Solar System Resonance Theory) physics core — pure, injectable-constants, no I/O, no globals, no DOM. The complete model incl. fitted coefficients; every published version immutably ships one recorded model identity.",
5
5
  "essrt": {
6
- "modelVersion": "v13.0",
6
+ "modelVersion": "v14.0",
7
7
  "_note": "The model identity this package version ships (IP-unified-architecture §10: package semver tracks the API axis; the model version + CONSTANTS_HASH/COEFFICIENTS_HASH in src/constants/ carry the scientific identity). The version-pinning gate enforces this pairing against public/input/model-version.json."
8
8
  },
9
9
  "type": "module",
@@ -40,6 +40,7 @@
40
40
  "./earth/deep-orbital-history": { "types": "./types/earth/deep-orbital-history.d.cts", "default": "./src/earth/deep-orbital-history.cjs" },
41
41
  "./earth/sidereal-year-channel": { "types": "./types/earth/sidereal-year-channel.d.cts", "default": "./src/earth/sidereal-year-channel.cjs" },
42
42
  "./earth/year-lengths": { "types": "./types/earth/year-lengths.d.cts", "default": "./src/earth/year-lengths.cjs" },
43
+ "./earth/precession-composed": { "types": "./types/earth/precession-composed.d.cts", "default": "./src/earth/precession-composed.cjs" },
43
44
  "./moon/month-chain": { "types": "./types/moon/month-chain.d.cts", "default": "./src/moon/month-chain.cjs" },
44
45
  "./chain-cycles": { "types": "./types/chain-cycles/index.d.cts", "default": "./src/chain-cycles/index.cjs" },
45
46
  "./moon/arguments": { "types": "./types/moon/arguments.d.cts", "default": "./src/moon/arguments.cjs" },
@@ -22,10 +22,11 @@
22
22
 
23
23
  /**
24
24
  * @typedef {Object} ClimateL1Regime
25
- * @property {Array<{n: number, a: number, b: number}>} l1Terms - 8H-lattice
26
- * harmonics (n = cycles per 8H)
25
+ * @property {Array<{period_kyr: number, a: number, b: number}>} l1Terms - the
26
+ * L1 lines: periods in kyr (the engine's own orbital lines + the 405-kyr
27
+ * family — data/l1-physical-lines.json, ONE home) with fitted cos/sin
28
+ * coefficients
27
29
  * @property {number} yStdDenormalization - the fit's y_std scale-back
28
- * @property {number} eightHKyr - 8H in kyr (the fit's period base)
29
30
  */
30
31
 
31
32
  /**
@@ -37,10 +38,80 @@ function evalClimateL1OrbitalPermil(year, regime) {
37
38
  const t_kyr_BP = (2000 - year) / 1000;
38
39
  let L1_sum = 0;
39
40
  for (const c of regime.l1Terms) {
40
- const omega = 2 * Math.PI * c.n / regime.eightHKyr;
41
+ const omega = (2 * Math.PI) / c.period_kyr;
41
42
  L1_sum += c.a * Math.cos(omega * t_kyr_BP) + c.b * Math.sin(omega * t_kyr_BP);
42
43
  }
43
44
  return L1_sum * regime.yStdDenormalization;
44
45
  }
45
46
 
46
- module.exports = { evalClimateL1OrbitalPermil };
47
+ /**
48
+ * The GIA channel — the polar moment's LAGGED response to the ice history the
49
+ * L1 layer proxies (holisticuniverse plan 06, D7). The solid Earth responds to
50
+ * an ice load through the mantle's viscoelastic relaxation, so
51
+ *
52
+ * α(t) = α₀ − k · [ L1(t) − ⟨L1⟩_τ(t) ]
53
+ *
54
+ * with ⟨L1⟩_τ the causal exponential average over the PAST (time constant τ).
55
+ * Every L1 line passes that filter as a line, Ĉ' = Ĉ · iωτ/(1 + iωτ) with
56
+ * Ĉ = a + ib in physical time, so the evaluator stays a sinusoid sum and each
57
+ * runtime's lattice-α pin and memo are untouched. k > 0 is the direct-load
58
+ * sign (an uncompensated ice load lowers α); after a rapid deglaciation
59
+ * L1 − ⟨L1⟩ < 0, α sits above equilibrium and relaxes for ~τ — today's
60
+ * −0.35 ms/cy non-tidal drift is that tail. k is DERIVED at construction so
61
+ * that dα/dt(J2000) equals the satellite-gravimetry rate (Cox & Chao 2002
62
+ * dJ₂/dt ÷ the Peltier J₂→α factor): no stored scale. τ was MEASURED against
63
+ * the historical ΔT record through the joint fitter (optimum 5–6 kyr,
64
+ * the degree-2 Maxwell estimate; plan 06 D7 record). Replaces the
65
+ * instantaneous α ∝ L1 law, which had the deglacial transient's sign and
66
+ * timing backwards and depended on fitted comb lines the T1 test retired.
67
+ *
68
+ * @param {Array<{period_kyr: number, a: number, b: number}>} l1Terms
69
+ * @param {number} relaxationKyr - τ in kyr
70
+ * @returns {Array<{period_kyr: number, a: number, b: number}>}
71
+ */
72
+ function laggedL1Terms(l1Terms, relaxationKyr) {
73
+ return l1Terms.map((c) => {
74
+ const wt = ((2 * Math.PI) / c.period_kyr) * relaxationKyr; // ωτ, dimensionless
75
+ const d = 1 + wt * wt;
76
+ const Hre = (wt * wt) / d, Him = wt / d; // H(ω) = iωτ / (1 + iωτ)
77
+ return { period_kyr: c.period_kyr, a: c.a * Hre - c.b * Him, b: c.a * Him + c.b * Hre };
78
+ });
79
+ }
80
+
81
+ /**
82
+ * @param {{
83
+ * l1Terms: Array<{period_kyr: number, a: number, b: number}>,
84
+ * yStdDenormalization: number,
85
+ * relaxationKyr: number,
86
+ * alphaGiaRateJ2000PerYr: number,
87
+ * alphaJ2000: number,
88
+ * }} cfg - relaxationKyr and alphaGiaRateJ2000PerYr are model-parameters
89
+ * deepTime constants; alphaJ2000 the IERS moment-of-inertia factor
90
+ * @returns {{
91
+ * alphaAt: (year: number) => number,
92
+ * laggedL1PermilAt: (year: number) => number,
93
+ * kPerPermille: number,
94
+ * relaxationKyr: number,
95
+ * laggedL1Terms: Array<{period_kyr: number, a: number, b: number}>,
96
+ * }}
97
+ */
98
+ function createAlphaGiaChannel({ l1Terms, yStdDenormalization, relaxationKyr, alphaGiaRateJ2000PerYr, alphaJ2000 }) {
99
+ const lagged = laggedL1Terms(l1Terms, relaxationKyr);
100
+ const regime = { l1Terms: lagged, yStdDenormalization };
101
+ // dL'/dyear at J2000 in closed form: with t = (2000 − year)/1000,
102
+ // d/dyear Σ[a cos ωt + b sin ωt] = −(1/1000)·Σ ω(−a sin ωt + b cos ωt) → at t = 0: −(1/1000)·Σ ω b
103
+ let sum = 0;
104
+ for (const c of lagged) sum += ((2 * Math.PI) / c.period_kyr) * c.b;
105
+ const slopeJ2000PermillePerYr = (-sum / 1000) * yStdDenormalization;
106
+ const kPerPermille = -alphaGiaRateJ2000PerYr / slopeJ2000PermillePerYr; // dα/dt = −k · dL'/dt
107
+ const laggedJ2000 = evalClimateL1OrbitalPermil(2000, regime);
108
+ return {
109
+ alphaAt: (year) => alphaJ2000 - kPerPermille * (evalClimateL1OrbitalPermil(year, regime) - laggedJ2000),
110
+ laggedL1PermilAt: (year) => evalClimateL1OrbitalPermil(year, regime),
111
+ kPerPermille,
112
+ relaxationKyr,
113
+ laggedL1Terms: lagged,
114
+ };
115
+ }
116
+
117
+ module.exports = { evalClimateL1OrbitalPermil, laggedL1Terms, createAlphaGiaChannel };
@@ -2,7 +2,7 @@
2
2
  // The fitted coefficients' shapes for TypeScript consumers (§2g); values live
3
3
  // in coefficients.js, emitted VERBATIM from fitted-coefficients.json.
4
4
 
5
- export declare const COEFFICIENTS_HASH: "9e0460662933228f";
5
+ export declare const COEFFICIENTS_HASH: "b8b18424a3435e20";
6
6
 
7
7
  export declare const FITTED_COEFFICIENTS: {
8
8
  readonly ANOMALISTIC_YEAR_HARMONICS: Array<[number, number, number]>;
@@ -71,9 +71,14 @@ export declare const FITTED_COEFFICIENTS: {
71
71
  };
72
72
  readonly CLIMATE_FORMULA_COEFFS: {
73
73
  "config": {
74
- "H_kyr": number;
75
- "eight_H_kyr": number;
76
- "L1_integers": number[];
74
+ "L1_lines": Array<{
75
+ "family": string;
76
+ "label": string;
77
+ "arcsecPerYr": number;
78
+ "periodKyr": number;
79
+ "relAmp": number;
80
+ }>;
81
+ "L1_source": string;
77
82
  "L2_periods_kyr": {
78
83
  "405-kyr (fundamental)": number;
79
84
  "202-kyr (2nd harmonic)": number;
@@ -97,16 +102,12 @@ export declare const FITTED_COEFFICIENTS: {
97
102
  "n_samples": number;
98
103
  "intercept": number;
99
104
  "L1": Array<{
100
- "n": number;
101
- "a": number;
102
- "b": number;
103
- }>;
104
- "L2": Array<{
105
- "p_kyr": number;
105
+ "period_kyr": number;
106
106
  "label": string;
107
107
  "a": number;
108
108
  "b": number;
109
109
  }>;
110
+ "L2": unknown[];
110
111
  "L3": unknown[];
111
112
  "denormalization": {
112
113
  "y_mean": number;
@@ -129,16 +130,12 @@ export declare const FITTED_COEFFICIENTS: {
129
130
  "n_samples": number;
130
131
  "intercept": number;
131
132
  "L1": Array<{
132
- "n": number;
133
- "a": number;
134
- "b": number;
135
- }>;
136
- "L2": Array<{
137
- "p_kyr": number;
133
+ "period_kyr": number;
138
134
  "label": string;
139
135
  "a": number;
140
136
  "b": number;
141
137
  }>;
138
+ "L2": unknown[];
142
139
  "L3": unknown[];
143
140
  "denormalization": {
144
141
  "y_mean": number;
@@ -161,16 +158,12 @@ export declare const FITTED_COEFFICIENTS: {
161
158
  "n_samples": number;
162
159
  "intercept": number;
163
160
  "L1": Array<{
164
- "n": number;
165
- "a": number;
166
- "b": number;
167
- }>;
168
- "L2": Array<{
169
- "p_kyr": number;
161
+ "period_kyr": number;
170
162
  "label": string;
171
163
  "a": number;
172
164
  "b": number;
173
165
  }>;
166
+ "L2": unknown[];
174
167
  "L3": unknown[];
175
168
  "denormalization": {
176
169
  "y_mean": number;
@@ -193,16 +186,12 @@ export declare const FITTED_COEFFICIENTS: {
193
186
  "n_samples": number;
194
187
  "intercept": number;
195
188
  "L1": Array<{
196
- "n": number;
197
- "a": number;
198
- "b": number;
199
- }>;
200
- "L2": Array<{
201
- "p_kyr": number;
189
+ "period_kyr": number;
202
190
  "label": string;
203
191
  "a": number;
204
192
  "b": number;
205
193
  }>;
194
+ "L2": unknown[];
206
195
  "L3": Array<{
207
196
  "label": string;
208
197
  "t_kyr": number;
@@ -229,16 +218,12 @@ export declare const FITTED_COEFFICIENTS: {
229
218
  "n_samples": number;
230
219
  "intercept": number;
231
220
  "L1": Array<{
232
- "n": number;
233
- "a": number;
234
- "b": number;
235
- }>;
236
- "L2": Array<{
237
- "p_kyr": number;
221
+ "period_kyr": number;
238
222
  "label": string;
239
223
  "a": number;
240
224
  "b": number;
241
225
  }>;
226
+ "L2": unknown[];
242
227
  "L3": Array<{
243
228
  "label": string;
244
229
  "t_kyr": number;
@@ -265,16 +250,12 @@ export declare const FITTED_COEFFICIENTS: {
265
250
  "n_samples": number;
266
251
  "intercept": number;
267
252
  "L1": Array<{
268
- "n": number;
269
- "a": number;
270
- "b": number;
271
- }>;
272
- "L2": Array<{
273
- "p_kyr": number;
253
+ "period_kyr": number;
274
254
  "label": string;
275
255
  "a": number;
276
256
  "b": number;
277
257
  }>;
258
+ "L2": unknown[];
278
259
  "L3": Array<{
279
260
  "label": string;
280
261
  "t_kyr": number;
@@ -301,16 +282,12 @@ export declare const FITTED_COEFFICIENTS: {
301
282
  "n_samples": number;
302
283
  "intercept": number;
303
284
  "L1": Array<{
304
- "n": number;
305
- "a": number;
306
- "b": number;
307
- }>;
308
- "L2": Array<{
309
- "p_kyr": number;
285
+ "period_kyr": number;
310
286
  "label": string;
311
287
  "a": number;
312
288
  "b": number;
313
289
  }>;
290
+ "L2": unknown[];
314
291
  "L3": unknown[];
315
292
  "denormalization": {
316
293
  "y_mean": number;
@@ -326,264 +303,196 @@ export declare const FITTED_COEFFICIENTS: {
326
303
  "delta_l3": number;
327
304
  };
328
305
  "carbon_amplification_ratios": {
329
- "9": {
330
- "n": number;
331
- "period_kyr": number;
332
- "lr04_post_mpt_amp": number;
333
- "epica_amp": number;
334
- "ratio": number;
335
- "label": string;
336
- };
337
- "12": {
338
- "n": number;
306
+ "19.0014": {
339
307
  "period_kyr": number;
340
308
  "lr04_post_mpt_amp": number;
341
309
  "epica_amp": number;
342
310
  "ratio": number;
343
311
  "label": string;
344
312
  };
345
- "14": {
346
- "n": number;
313
+ "19.1554": {
347
314
  "period_kyr": number;
348
315
  "lr04_post_mpt_amp": number;
349
316
  "epica_amp": number;
350
317
  "ratio": number;
351
318
  "label": string;
352
319
  };
353
- "16": {
354
- "n": number;
320
+ "22.4452": {
355
321
  "period_kyr": number;
356
322
  "lr04_post_mpt_amp": number;
357
323
  "epica_amp": number;
358
324
  "ratio": number;
359
325
  "label": string;
360
326
  };
361
- "18": {
362
- "n": number;
327
+ "23.1931": {
363
328
  "period_kyr": number;
364
329
  "lr04_post_mpt_amp": number;
365
330
  "epica_amp": number;
366
331
  "ratio": number;
367
332
  "label": string;
368
333
  };
369
- "20": {
370
- "n": number;
334
+ "23.7599": {
371
335
  "period_kyr": number;
372
336
  "lr04_post_mpt_amp": number;
373
337
  "epica_amp": number;
374
338
  "ratio": number;
375
339
  "label": string;
376
340
  };
377
- "21": {
378
- "n": number;
341
+ "27.4019": {
379
342
  "period_kyr": number;
380
343
  "lr04_post_mpt_amp": number;
381
344
  "epica_amp": number;
382
345
  "ratio": number;
383
346
  "label": string;
384
347
  };
385
- "22": {
386
- "n": number;
348
+ "28.9913": {
387
349
  "period_kyr": number;
388
350
  "lr04_post_mpt_amp": number;
389
351
  "epica_amp": number;
390
352
  "ratio": number;
391
353
  "label": string;
392
354
  };
393
- "24": {
394
- "n": number;
355
+ "29.1554": {
395
356
  "period_kyr": number;
396
357
  "lr04_post_mpt_amp": number;
397
358
  "epica_amp": number;
398
359
  "ratio": number;
399
360
  "label": string;
400
361
  };
401
- "25": {
402
- "n": number;
362
+ "29.7742": {
403
363
  "period_kyr": number;
404
364
  "lr04_post_mpt_amp": number;
405
365
  "epica_amp": number;
406
366
  "ratio": number;
407
367
  "label": string;
408
368
  };
409
- "28": {
410
- "n": number;
369
+ "29.9682": {
411
370
  "period_kyr": number;
412
371
  "lr04_post_mpt_amp": number;
413
372
  "epica_amp": number;
414
373
  "ratio": number;
415
374
  "label": string;
416
375
  };
417
- "30": {
418
- "n": number;
376
+ "39.8366": {
419
377
  "period_kyr": number;
420
378
  "lr04_post_mpt_amp": number;
421
379
  "epica_amp": number;
422
380
  "ratio": number;
423
381
  "label": string;
424
382
  };
425
- "31": {
426
- "n": number;
383
+ "40.5195": {
427
384
  "period_kyr": number;
428
385
  "lr04_post_mpt_amp": number;
429
386
  "epica_amp": number;
430
387
  "ratio": number;
431
388
  "label": string;
432
389
  };
433
- "35": {
434
- "n": number;
390
+ "41.2244": {
435
391
  "period_kyr": number;
436
392
  "lr04_post_mpt_amp": number;
437
393
  "epica_amp": number;
438
394
  "ratio": number;
439
395
  "label": string;
440
396
  };
441
- "38": {
442
- "n": number;
397
+ "41.9557": {
443
398
  "period_kyr": number;
444
399
  "lr04_post_mpt_amp": number;
445
400
  "epica_amp": number;
446
401
  "ratio": number;
447
402
  "label": string;
448
403
  };
449
- "39": {
450
- "n": number;
404
+ "54.1343": {
451
405
  "period_kyr": number;
452
406
  "lr04_post_mpt_amp": number;
453
407
  "epica_amp": number;
454
408
  "ratio": number;
455
409
  "label": string;
456
410
  };
457
- "48": {
458
- "n": number;
411
+ "94.8779": {
459
412
  "period_kyr": number;
460
413
  "lr04_post_mpt_amp": number;
461
414
  "epica_amp": number;
462
415
  "ratio": number;
463
416
  "label": string;
464
417
  };
465
- "50": {
466
- "n": number;
418
+ "96.8490": {
467
419
  "period_kyr": number;
468
420
  "lr04_post_mpt_amp": number;
469
421
  "epica_amp": number;
470
422
  "ratio": number;
471
423
  "label": string;
472
424
  };
473
- "53": {
474
- "n": number;
425
+ "98.8439": {
475
426
  "period_kyr": number;
476
427
  "lr04_post_mpt_amp": number;
477
428
  "epica_amp": number;
478
429
  "ratio": number;
479
430
  "label": string;
480
431
  };
481
- "65": {
482
- "n": number;
432
+ "101.0051": {
483
433
  "period_kyr": number;
484
434
  "lr04_post_mpt_amp": number;
485
435
  "epica_amp": number;
486
436
  "ratio": number;
487
437
  "label": string;
488
438
  };
489
- "66": {
490
- "n": number;
439
+ "103.1238": {
491
440
  "period_kyr": number;
492
441
  "lr04_post_mpt_amp": number;
493
442
  "epica_amp": number;
494
443
  "ratio": number;
495
444
  "label": string;
496
445
  };
497
- "68": {
498
- "n": number;
446
+ "105.1372": {
499
447
  "period_kyr": number;
500
448
  "lr04_post_mpt_amp": number;
501
449
  "epica_amp": number;
502
450
  "ratio": number;
503
451
  "label": string;
504
452
  };
505
- "73": {
506
- "n": number;
453
+ "110.0293": {
507
454
  "period_kyr": number;
508
455
  "lr04_post_mpt_amp": number;
509
456
  "epica_amp": number;
510
457
  "ratio": number;
511
458
  "label": string;
512
459
  };
513
- "76": {
514
- "n": number;
460
+ "123.8462": {
515
461
  "period_kyr": number;
516
462
  "lr04_post_mpt_amp": number;
517
463
  "epica_amp": number;
518
464
  "ratio": number;
519
465
  "label": string;
520
466
  };
521
- "96": {
522
- "n": number;
467
+ "130.6910": {
523
468
  "period_kyr": number;
524
469
  "lr04_post_mpt_amp": number;
525
470
  "epica_amp": number;
526
471
  "ratio": number;
527
472
  "label": string;
528
473
  };
529
- "107": {
530
- "n": number;
474
+ "134.4960": {
531
475
  "period_kyr": number;
532
476
  "lr04_post_mpt_amp": number;
533
477
  "epica_amp": number;
534
478
  "ratio": number;
535
479
  "label": string;
536
480
  };
537
- "110": {
538
- "n": number;
481
+ "405.6256": {
539
482
  "period_kyr": number;
540
483
  "lr04_post_mpt_amp": number;
541
484
  "epica_amp": number;
542
485
  "ratio": number;
543
486
  "label": string;
544
487
  };
545
- "113": {
546
- "n": number;
488
+ "202.8128": {
547
489
  "period_kyr": number;
548
490
  "lr04_post_mpt_amp": number;
549
491
  "epica_amp": number;
550
492
  "ratio": number;
551
493
  "label": string;
552
494
  };
553
- "120": {
554
- "n": number;
555
- "period_kyr": number;
556
- "lr04_post_mpt_amp": number;
557
- "epica_amp": number;
558
- "ratio": number;
559
- "label": string;
560
- };
561
- "134": {
562
- "n": number;
563
- "period_kyr": number;
564
- "lr04_post_mpt_amp": number;
565
- "epica_amp": number;
566
- "ratio": number;
567
- "label": string;
568
- };
569
- "141": {
570
- "n": number;
571
- "period_kyr": number;
572
- "lr04_post_mpt_amp": number;
573
- "epica_amp": number;
574
- "ratio": number;
575
- "label": string;
576
- };
577
- "152": {
578
- "n": number;
579
- "period_kyr": number;
580
- "lr04_post_mpt_amp": number;
581
- "epica_amp": number;
582
- "ratio": number;
583
- "label": string;
584
- };
585
- "185": {
586
- "n": number;
495
+ "135.2085": {
587
496
  "period_kyr": number;
588
497
  "lr04_post_mpt_amp": number;
589
498
  "epica_amp": number;
@@ -599,16 +508,12 @@ export declare const FITTED_COEFFICIENTS: {
599
508
  "n_samples": number;
600
509
  "intercept": number;
601
510
  "L1": Array<{
602
- "n": number;
603
- "a": number;
604
- "b": number;
605
- }>;
606
- "L2": Array<{
607
- "p_kyr": number;
511
+ "period_kyr": number;
608
512
  "label": string;
609
513
  "a": number;
610
514
  "b": number;
611
515
  }>;
516
+ "L2": unknown[];
612
517
  "L3": Array<{
613
518
  "label": string;
614
519
  "t_kyr": number;
@@ -655,6 +560,7 @@ export declare const FITTED_COEFFICIENTS: {
655
560
  "phi_locked_rad": number;
656
561
  "amp_s": number;
657
562
  "phase_convention": string;
563
+ "retired": string;
658
564
  }>;
659
565
  "rms_s": number;
660
566
  "raw_at_j2000_s": number;