universal-physics-tensor 0.5.1 → 0.7.1
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 +66 -105
- package/dist/bridges/catalog-adapter.d.ts +116 -0
- package/dist/bridges/catalog-adapter.d.ts.map +1 -0
- package/dist/bridges/catalog-adapter.js +302 -0
- package/dist/bridges/catalog-adapter.js.map +1 -0
- package/dist/bridges/equations/_be-helpers.d.ts +145 -0
- package/dist/bridges/equations/_be-helpers.d.ts.map +1 -0
- package/dist/bridges/equations/_be-helpers.js +179 -0
- package/dist/bridges/equations/_be-helpers.js.map +1 -0
- package/dist/bridges/equations/be-11-decoherence-master.d.ts +1 -2
- package/dist/bridges/equations/be-11-decoherence-master.d.ts.map +1 -1
- package/dist/bridges/equations/be-11-decoherence-master.js +9 -20
- package/dist/bridges/equations/be-11-decoherence-master.js.map +1 -1
- package/dist/bridges/equations/be-12-coherence-length.d.ts +7 -1
- package/dist/bridges/equations/be-12-coherence-length.d.ts.map +1 -1
- package/dist/bridges/equations/be-12-coherence-length.js +8 -16
- package/dist/bridges/equations/be-12-coherence-length.js.map +1 -1
- package/dist/bridges/equations/be-13-einstein-trace.d.ts +51 -3
- package/dist/bridges/equations/be-13-einstein-trace.d.ts.map +1 -1
- package/dist/bridges/equations/be-13-einstein-trace.js +74 -17
- package/dist/bridges/equations/be-13-einstein-trace.js.map +1 -1
- package/dist/bridges/equations/be-14-ryu-takayanagi.d.ts +10 -4
- package/dist/bridges/equations/be-14-ryu-takayanagi.d.ts.map +1 -1
- package/dist/bridges/equations/be-14-ryu-takayanagi.js +6 -17
- package/dist/bridges/equations/be-14-ryu-takayanagi.js.map +1 -1
- package/dist/bridges/equations/be-15-emergence.d.ts +7 -1
- package/dist/bridges/equations/be-15-emergence.d.ts.map +1 -1
- package/dist/bridges/equations/be-15-emergence.js +12 -22
- package/dist/bridges/equations/be-15-emergence.js.map +1 -1
- package/dist/bridges/equations/be-16-landauer.d.ts +7 -1
- package/dist/bridges/equations/be-16-landauer.d.ts.map +1 -1
- package/dist/bridges/equations/be-16-landauer.js +5 -13
- package/dist/bridges/equations/be-16-landauer.js.map +1 -1
- package/dist/bridges/equations/be-17-einstein-cartan.d.ts +26 -13
- package/dist/bridges/equations/be-17-einstein-cartan.d.ts.map +1 -1
- package/dist/bridges/equations/be-17-einstein-cartan.js +28 -31
- package/dist/bridges/equations/be-17-einstein-cartan.js.map +1 -1
- package/dist/bridges/equations/be-18-higgs-mass.d.ts +7 -1
- package/dist/bridges/equations/be-18-higgs-mass.d.ts.map +1 -1
- package/dist/bridges/equations/be-18-higgs-mass.js +5 -16
- package/dist/bridges/equations/be-18-higgs-mass.js.map +1 -1
- package/dist/bridges/equations/be-19-quantum-bounce.d.ts +38 -3
- package/dist/bridges/equations/be-19-quantum-bounce.d.ts.map +1 -1
- package/dist/bridges/equations/be-19-quantum-bounce.js +69 -20
- package/dist/bridges/equations/be-19-quantum-bounce.js.map +1 -1
- package/dist/bridges/equations/be-20-vacuum-energy.d.ts +20 -1
- package/dist/bridges/equations/be-20-vacuum-energy.d.ts.map +1 -1
- package/dist/bridges/equations/be-20-vacuum-energy.js +36 -15
- package/dist/bridges/equations/be-20-vacuum-energy.js.map +1 -1
- package/dist/bridges/equations/be-21-kss-bound.d.ts +2 -0
- package/dist/bridges/equations/be-21-kss-bound.d.ts.map +1 -1
- package/dist/bridges/equations/be-21-kss-bound.js +4 -10
- package/dist/bridges/equations/be-21-kss-bound.js.map +1 -1
- package/dist/bridges/equations/be-22-topological-entanglement.d.ts +6 -9
- package/dist/bridges/equations/be-22-topological-entanglement.d.ts.map +1 -1
- package/dist/bridges/equations/be-22-topological-entanglement.js +9 -21
- package/dist/bridges/equations/be-22-topological-entanglement.js.map +1 -1
- package/dist/bridges/equations/be-23-syk-planckian.d.ts +7 -1
- package/dist/bridges/equations/be-23-syk-planckian.d.ts.map +1 -1
- package/dist/bridges/equations/be-23-syk-planckian.js +11 -25
- package/dist/bridges/equations/be-23-syk-planckian.js.map +1 -1
- package/dist/bridges/equations/be-24-foerster-fret.d.ts +7 -1
- package/dist/bridges/equations/be-24-foerster-fret.d.ts.map +1 -1
- package/dist/bridges/equations/be-24-foerster-fret.js +8 -16
- package/dist/bridges/equations/be-24-foerster-fret.js.map +1 -1
- package/dist/bridges/equations/be-25-iit-phi.d.ts +7 -1
- package/dist/bridges/equations/be-25-iit-phi.d.ts.map +1 -1
- package/dist/bridges/equations/be-25-iit-phi.js +12 -16
- package/dist/bridges/equations/be-25-iit-phi.js.map +1 -1
- package/dist/bridges/equations/be-25-orch-or.d.ts +6 -3
- package/dist/bridges/equations/be-25-orch-or.d.ts.map +1 -1
- package/dist/bridges/equations/be-25-orch-or.js +8 -17
- package/dist/bridges/equations/be-25-orch-or.js.map +1 -1
- package/dist/bridges/equations/be-26-dna-tunneling.d.ts +6 -3
- package/dist/bridges/equations/be-26-dna-tunneling.d.ts.map +1 -1
- package/dist/bridges/equations/be-26-dna-tunneling.js +11 -26
- package/dist/bridges/equations/be-26-dna-tunneling.js.map +1 -1
- package/dist/bridges/equations/be-27-effective-temperature.d.ts +7 -1
- package/dist/bridges/equations/be-27-effective-temperature.d.ts.map +1 -1
- package/dist/bridges/equations/be-27-effective-temperature.js +8 -16
- package/dist/bridges/equations/be-27-effective-temperature.js.map +1 -1
- package/dist/bridges/equations/be-28-onsager-entropy-production.d.ts +7 -1
- package/dist/bridges/equations/be-28-onsager-entropy-production.d.ts.map +1 -1
- package/dist/bridges/equations/be-28-onsager-entropy-production.js +9 -13
- package/dist/bridges/equations/be-28-onsager-entropy-production.js.map +1 -1
- package/dist/bridges/equations/be-29-jarzynski.d.ts +7 -1
- package/dist/bridges/equations/be-29-jarzynski.d.ts.map +1 -1
- package/dist/bridges/equations/be-29-jarzynski.js +8 -13
- package/dist/bridges/equations/be-29-jarzynski.js.map +1 -1
- package/dist/bridges/equations/be-30-flm-first-law.d.ts +11 -2
- package/dist/bridges/equations/be-30-flm-first-law.d.ts.map +1 -1
- package/dist/bridges/equations/be-30-flm-first-law.js +10 -21
- package/dist/bridges/equations/be-30-flm-first-law.js.map +1 -1
- package/dist/bridges/equations/be-31-causal-set-bd.d.ts +7 -1
- package/dist/bridges/equations/be-31-causal-set-bd.d.ts.map +1 -1
- package/dist/bridges/equations/be-31-causal-set-bd.js +11 -25
- package/dist/bridges/equations/be-31-causal-set-bd.js.map +1 -1
- package/dist/bridges/equations/be-32-quantum-reference-frame.d.ts +6 -9
- package/dist/bridges/equations/be-32-quantum-reference-frame.d.ts.map +1 -1
- package/dist/bridges/equations/be-32-quantum-reference-frame.js +8 -18
- package/dist/bridges/equations/be-32-quantum-reference-frame.js.map +1 -1
- package/dist/bridges/equations/be-33-hertz-millis.d.ts +53 -28
- package/dist/bridges/equations/be-33-hertz-millis.d.ts.map +1 -1
- package/dist/bridges/equations/be-33-hertz-millis.js +55 -51
- package/dist/bridges/equations/be-33-hertz-millis.js.map +1 -1
- package/dist/bridges/equations/be-34-kibble-zurek.d.ts +6 -3
- package/dist/bridges/equations/be-34-kibble-zurek.d.ts.map +1 -1
- package/dist/bridges/equations/be-34-kibble-zurek.js +15 -26
- package/dist/bridges/equations/be-34-kibble-zurek.js.map +1 -1
- package/dist/bridges/equations/be-35-conformal-bootstrap.d.ts +6 -9
- package/dist/bridges/equations/be-35-conformal-bootstrap.d.ts.map +1 -1
- package/dist/bridges/equations/be-35-conformal-bootstrap.js +9 -21
- package/dist/bridges/equations/be-35-conformal-bootstrap.js.map +1 -1
- package/dist/bridges/equations/be-36-gw-speed-bound.d.ts +7 -1
- package/dist/bridges/equations/be-36-gw-speed-bound.d.ts.map +1 -1
- package/dist/bridges/equations/be-36-gw-speed-bound.js +5 -13
- package/dist/bridges/equations/be-36-gw-speed-bound.js.map +1 -1
- package/dist/bridges/equations/be-37-shapiro-delay.d.ts +4 -2
- package/dist/bridges/equations/be-37-shapiro-delay.d.ts.map +1 -1
- package/dist/bridges/equations/be-37-shapiro-delay.js +15 -28
- package/dist/bridges/equations/be-37-shapiro-delay.js.map +1 -1
- package/dist/bridges/equations/be-38-mond.d.ts +7 -1
- package/dist/bridges/equations/be-38-mond.d.ts.map +1 -1
- package/dist/bridges/equations/be-38-mond.js +9 -19
- package/dist/bridges/equations/be-38-mond.js.map +1 -1
- package/dist/bridges/equations/be-39-asymptotic-safety.d.ts +66 -2
- package/dist/bridges/equations/be-39-asymptotic-safety.d.ts.map +1 -1
- package/dist/bridges/equations/be-39-asymptotic-safety.js +128 -20
- package/dist/bridges/equations/be-39-asymptotic-safety.js.map +1 -1
- package/dist/bridges/equations/be-40-composite-higgs.d.ts +7 -1
- package/dist/bridges/equations/be-40-composite-higgs.d.ts.map +1 -1
- package/dist/bridges/equations/be-40-composite-higgs.js +10 -22
- package/dist/bridges/equations/be-40-composite-higgs.js.map +1 -1
- package/dist/bridges/equations/be-41-swampland.d.ts +6 -3
- package/dist/bridges/equations/be-41-swampland.d.ts.map +1 -1
- package/dist/bridges/equations/be-41-swampland.js +11 -23
- package/dist/bridges/equations/be-41-swampland.js.map +1 -1
- package/dist/bridges/equations/be-42-hawking-temperature.d.ts +2 -0
- package/dist/bridges/equations/be-42-hawking-temperature.d.ts.map +1 -1
- package/dist/bridges/equations/be-42-hawking-temperature.js +5 -13
- package/dist/bridges/equations/be-42-hawking-temperature.js.map +1 -1
- package/dist/bridges/equations/be-43-er-epr.d.ts +7 -1
- package/dist/bridges/equations/be-43-er-epr.d.ts.map +1 -1
- package/dist/bridges/equations/be-43-er-epr.js +5 -13
- package/dist/bridges/equations/be-43-er-epr.js.map +1 -1
- package/dist/bridges/equations/be-44-soft-hair.d.ts +7 -1
- package/dist/bridges/equations/be-44-soft-hair.d.ts.map +1 -1
- package/dist/bridges/equations/be-44-soft-hair.js +5 -13
- package/dist/bridges/equations/be-44-soft-hair.js.map +1 -1
- package/dist/bridges/equations/be-45-tcc.d.ts +7 -1
- package/dist/bridges/equations/be-45-tcc.d.ts.map +1 -1
- package/dist/bridges/equations/be-45-tcc.js +10 -22
- package/dist/bridges/equations/be-45-tcc.js.map +1 -1
- package/dist/bridges/equations/be-46-multiverse-measure.d.ts +7 -1
- package/dist/bridges/equations/be-46-multiverse-measure.d.ts.map +1 -1
- package/dist/bridges/equations/be-46-multiverse-measure.js +9 -19
- package/dist/bridges/equations/be-46-multiverse-measure.js.map +1 -1
- package/dist/bridges/equations/be-47-bbn-dark-sector.d.ts +7 -1
- package/dist/bridges/equations/be-47-bbn-dark-sector.d.ts.map +1 -1
- package/dist/bridges/equations/be-47-bbn-dark-sector.js +14 -16
- package/dist/bridges/equations/be-47-bbn-dark-sector.js.map +1 -1
- package/dist/bridges/equations/be-48-grw-localization.d.ts +7 -1
- package/dist/bridges/equations/be-48-grw-localization.d.ts.map +1 -1
- package/dist/bridges/equations/be-48-grw-localization.js +15 -20
- package/dist/bridges/equations/be-48-grw-localization.js.map +1 -1
- package/dist/bridges/equations/be-49-quantum-darwinism.d.ts +7 -1
- package/dist/bridges/equations/be-49-quantum-darwinism.d.ts.map +1 -1
- package/dist/bridges/equations/be-49-quantum-darwinism.js +10 -22
- package/dist/bridges/equations/be-49-quantum-darwinism.js.map +1 -1
- package/dist/bridges/equations/be-50-wheeler-feynman.d.ts +42 -12
- package/dist/bridges/equations/be-50-wheeler-feynman.d.ts.map +1 -1
- package/dist/bridges/equations/be-50-wheeler-feynman.js +84 -20
- package/dist/bridges/equations/be-50-wheeler-feynman.js.map +1 -1
- package/dist/bridges/equations/be-53-yang-mills-beta.d.ts +158 -0
- package/dist/bridges/equations/be-53-yang-mills-beta.d.ts.map +1 -0
- package/dist/bridges/equations/be-53-yang-mills-beta.js +175 -0
- package/dist/bridges/equations/be-53-yang-mills-beta.js.map +1 -0
- package/dist/bridges/equations/be-54-randall-sundrum-brane.d.ts +117 -0
- package/dist/bridges/equations/be-54-randall-sundrum-brane.d.ts.map +1 -0
- package/dist/bridges/equations/be-54-randall-sundrum-brane.js +213 -0
- package/dist/bridges/equations/be-54-randall-sundrum-brane.js.map +1 -0
- package/dist/bridges/index.d.ts +40 -1
- package/dist/bridges/index.d.ts.map +1 -1
- package/dist/bridges/index.js +130 -48
- package/dist/bridges/index.js.map +1 -1
- package/dist/bridges/perihelion-precession-labeled.d.ts +46 -0
- package/dist/bridges/perihelion-precession-labeled.d.ts.map +1 -0
- package/dist/bridges/perihelion-precession-labeled.js +54 -0
- package/dist/bridges/perihelion-precession-labeled.js.map +1 -0
- package/dist/core/axes-registry.d.ts +67 -0
- package/dist/core/axes-registry.d.ts.map +1 -0
- package/dist/core/axes-registry.js +75 -0
- package/dist/core/axes-registry.js.map +1 -0
- package/dist/core/cell.d.ts +176 -0
- package/dist/core/cell.d.ts.map +1 -0
- package/dist/core/cell.js +166 -0
- package/dist/core/cell.js.map +1 -0
- package/dist/core/flux-rules.d.ts +176 -0
- package/dist/core/flux-rules.d.ts.map +1 -0
- package/dist/core/flux-rules.js +329 -0
- package/dist/core/flux-rules.js.map +1 -0
- package/dist/core/labeled-tensor.d.ts +143 -0
- package/dist/core/labeled-tensor.d.ts.map +1 -0
- package/dist/core/labeled-tensor.js +275 -0
- package/dist/core/labeled-tensor.js.map +1 -0
- package/dist/core/regime-registry.d.ts +169 -0
- package/dist/core/regime-registry.d.ts.map +1 -0
- package/dist/core/regime-registry.js +174 -0
- package/dist/core/regime-registry.js.map +1 -0
- package/dist/core/regime-rule-install.d.ts +26 -0
- package/dist/core/regime-rule-install.d.ts.map +1 -0
- package/dist/core/regime-rule-install.js +90 -0
- package/dist/core/regime-rule-install.js.map +1 -0
- package/dist/core/regimes-builtins.d.ts +22 -0
- package/dist/core/regimes-builtins.d.ts.map +1 -0
- package/dist/core/regimes-builtins.js +96 -0
- package/dist/core/regimes-builtins.js.map +1 -0
- package/dist/core/tensor.d.ts +112 -0
- package/dist/core/tensor.d.ts.map +1 -1
- package/dist/core/tensor.js +366 -0
- package/dist/core/tensor.js.map +1 -1
- package/dist/core/types.d.ts +7 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/universal-index.d.ts +97 -0
- package/dist/core/universal-index.d.ts.map +1 -0
- package/dist/core/universal-index.js +70 -0
- package/dist/core/universal-index.js.map +1 -0
- package/dist/diff/bridge-gradient.d.ts +94 -0
- package/dist/diff/bridge-gradient.d.ts.map +1 -0
- package/dist/diff/bridge-gradient.js +83 -0
- package/dist/diff/bridge-gradient.js.map +1 -0
- package/dist/diff/bridge-specs.d.ts +68 -0
- package/dist/diff/bridge-specs.d.ts.map +1 -0
- package/dist/diff/bridge-specs.js +96 -0
- package/dist/diff/bridge-specs.js.map +1 -0
- package/dist/dimensional/bridge-check.d.ts.map +1 -1
- package/dist/dimensional/bridge-check.js +8 -0
- package/dist/dimensional/bridge-check.js.map +1 -1
- package/dist/dimensional/connection-validators.d.ts +12 -5
- package/dist/dimensional/connection-validators.d.ts.map +1 -1
- package/dist/dimensional/connection-validators.js.map +1 -1
- package/dist/dimensional/curvature-composite.d.ts +90 -0
- package/dist/dimensional/curvature-composite.d.ts.map +1 -0
- package/dist/dimensional/curvature-composite.js +57 -0
- package/dist/dimensional/curvature-composite.js.map +1 -0
- package/dist/dimensional/curvature-invariants.d.ts +90 -0
- package/dist/dimensional/curvature-invariants.d.ts.map +1 -0
- package/dist/dimensional/curvature-invariants.js +64 -0
- package/dist/dimensional/curvature-invariants.js.map +1 -0
- package/dist/dimensional/curvature.d.ts +46 -30
- package/dist/dimensional/curvature.d.ts.map +1 -1
- package/dist/dimensional/curvature.js.map +1 -1
- package/dist/dimensional/einstein-equation.d.ts +126 -0
- package/dist/dimensional/einstein-equation.d.ts.map +1 -0
- package/dist/dimensional/einstein-equation.js +122 -0
- package/dist/dimensional/einstein-equation.js.map +1 -0
- package/dist/dimensional/field-equation-helpers.d.ts +82 -0
- package/dist/dimensional/field-equation-helpers.d.ts.map +1 -0
- package/dist/dimensional/field-equation-helpers.js +123 -0
- package/dist/dimensional/field-equation-helpers.js.map +1 -0
- package/dist/dimensional/friedmann-equation.d.ts +148 -0
- package/dist/dimensional/friedmann-equation.d.ts.map +1 -0
- package/dist/dimensional/friedmann-equation.js +150 -0
- package/dist/dimensional/friedmann-equation.js.map +1 -0
- package/dist/dimensional/gauge-field.d.ts +182 -0
- package/dist/dimensional/gauge-field.d.ts.map +1 -0
- package/dist/dimensional/gauge-field.js +134 -0
- package/dist/dimensional/gauge-field.js.map +1 -0
- package/dist/dimensional/killing-validators.d.ts +94 -0
- package/dist/dimensional/killing-validators.d.ts.map +1 -0
- package/dist/dimensional/killing-validators.js +66 -0
- package/dist/dimensional/killing-validators.js.map +1 -0
- package/dist/dimensional/klein-gordon-equation.d.ts +113 -0
- package/dist/dimensional/klein-gordon-equation.d.ts.map +1 -0
- package/dist/dimensional/klein-gordon-equation.js +98 -0
- package/dist/dimensional/klein-gordon-equation.js.map +1 -0
- package/dist/dimensional/rg-flow.d.ts +156 -0
- package/dist/dimensional/rg-flow.d.ts.map +1 -0
- package/dist/dimensional/rg-flow.js +150 -0
- package/dist/dimensional/rg-flow.js.map +1 -0
- package/dist/dimensional/stress-energy-validators.d.ts +74 -0
- package/dist/dimensional/stress-energy-validators.d.ts.map +1 -0
- package/dist/dimensional/stress-energy-validators.js +47 -0
- package/dist/dimensional/stress-energy-validators.js.map +1 -0
- package/dist/dimensional/tensor-trace.d.ts +128 -0
- package/dist/dimensional/tensor-trace.d.ts.map +1 -0
- package/dist/dimensional/tensor-trace.js +95 -0
- package/dist/dimensional/tensor-trace.js.map +1 -0
- package/dist/dimensional/tensor.d.ts +6 -8
- package/dist/dimensional/tensor.d.ts.map +1 -1
- package/dist/dimensional/tensor.js +3 -1
- package/dist/dimensional/tensor.js.map +1 -1
- package/dist/dimensional/validator-registry.d.ts +90 -0
- package/dist/dimensional/validator-registry.d.ts.map +1 -0
- package/dist/dimensional/validator-registry.js +131 -0
- package/dist/dimensional/validator-registry.js.map +1 -0
- package/dist/dimensional/validator.d.ts +12 -2
- package/dist/dimensional/validator.d.ts.map +1 -1
- package/dist/dimensional/validator.js +60 -75
- package/dist/dimensional/validator.js.map +1 -1
- package/dist/dimensional/weyl-validators.d.ts +84 -0
- package/dist/dimensional/weyl-validators.d.ts.map +1 -0
- package/dist/dimensional/weyl-validators.js +84 -0
- package/dist/dimensional/weyl-validators.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -1
- package/dist/numerical/be37-covariant-eikonal.d.ts +19 -0
- package/dist/numerical/be37-covariant-eikonal.d.ts.map +1 -1
- package/dist/numerical/be37-covariant-eikonal.js +29 -9
- package/dist/numerical/be37-covariant-eikonal.js.map +1 -1
- package/dist/numerical/christoffel-flat.d.ts +49 -0
- package/dist/numerical/christoffel-flat.d.ts.map +1 -0
- package/dist/numerical/christoffel-flat.js +86 -0
- package/dist/numerical/christoffel-flat.js.map +1 -0
- package/dist/numerical/curvature-lowering-helpers.d.ts +49 -57
- package/dist/numerical/curvature-lowering-helpers.d.ts.map +1 -1
- package/dist/numerical/curvature-lowering-helpers.js +109 -4
- package/dist/numerical/curvature-lowering-helpers.js.map +1 -1
- package/dist/numerical/derivative-lowering.d.ts +67 -0
- package/dist/numerical/derivative-lowering.d.ts.map +1 -0
- package/dist/numerical/derivative-lowering.js +243 -0
- package/dist/numerical/derivative-lowering.js.map +1 -0
- package/dist/numerical/einstein-equation.d.ts +106 -0
- package/dist/numerical/einstein-equation.d.ts.map +1 -0
- package/dist/numerical/einstein-equation.js +172 -0
- package/dist/numerical/einstein-equation.js.map +1 -0
- package/dist/numerical/geodesic-integrator.d.ts +7 -4
- package/dist/numerical/geodesic-integrator.d.ts.map +1 -1
- package/dist/numerical/geodesic-integrator.js +5 -1
- package/dist/numerical/geodesic-integrator.js.map +1 -1
- package/dist/numerical/gl4-integrator.d.ts +4 -2
- package/dist/numerical/gl4-integrator.d.ts.map +1 -1
- package/dist/numerical/gl4-integrator.js +24 -8
- package/dist/numerical/gl4-integrator.js.map +1 -1
- package/dist/numerical/killing.d.ts +157 -0
- package/dist/numerical/killing.d.ts.map +1 -0
- package/dist/numerical/killing.js +242 -0
- package/dist/numerical/killing.js.map +1 -0
- package/dist/numerical/kretschmann.d.ts +62 -0
- package/dist/numerical/kretschmann.d.ts.map +1 -0
- package/dist/numerical/kretschmann.js +88 -0
- package/dist/numerical/kretschmann.js.map +1 -0
- package/dist/numerical/lowering-utils.d.ts +47 -0
- package/dist/numerical/lowering-utils.d.ts.map +1 -0
- package/dist/numerical/lowering-utils.js +64 -0
- package/dist/numerical/lowering-utils.js.map +1 -0
- package/dist/numerical/lowering.d.ts +1 -29
- package/dist/numerical/lowering.d.ts.map +1 -1
- package/dist/numerical/lowering.js +219 -415
- package/dist/numerical/lowering.js.map +1 -1
- package/dist/numerical/null-ic.d.ts +40 -0
- package/dist/numerical/null-ic.d.ts.map +1 -0
- package/dist/numerical/null-ic.js +50 -0
- package/dist/numerical/null-ic.js.map +1 -0
- package/dist/numerical/null-ray-integrator.d.ts +3 -2
- package/dist/numerical/null-ray-integrator.d.ts.map +1 -1
- package/dist/numerical/painleve-gullstrand-metric.d.ts +74 -0
- package/dist/numerical/painleve-gullstrand-metric.d.ts.map +1 -0
- package/dist/numerical/painleve-gullstrand-metric.js +121 -0
- package/dist/numerical/painleve-gullstrand-metric.js.map +1 -0
- package/dist/numerical/pderiv.d.ts +17 -9
- package/dist/numerical/pderiv.d.ts.map +1 -1
- package/dist/numerical/pderiv.js +6 -3
- package/dist/numerical/pderiv.js.map +1 -1
- package/dist/numerical/perihelion-finder.d.ts +30 -0
- package/dist/numerical/perihelion-finder.d.ts.map +1 -1
- package/dist/numerical/perihelion-finder.js +30 -0
- package/dist/numerical/perihelion-finder.js.map +1 -1
- package/dist/numerical/tensor-engine.d.ts +2 -2
- package/dist/numerical/tensor-engine.d.ts.map +1 -1
- package/dist/numerical/weyl-lowering.d.ts +60 -0
- package/dist/numerical/weyl-lowering.d.ts.map +1 -0
- package/dist/numerical/weyl-lowering.js +111 -0
- package/dist/numerical/weyl-lowering.js.map +1 -0
- package/package.json +9 -7
|
@@ -10,24 +10,23 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @module numerical/lowering
|
|
12
12
|
*/
|
|
13
|
-
import { validate } from '../dimensional/validator.js';
|
|
14
13
|
import { computeContraction, validateTensorSymbol } from '../dimensional/tensor.js';
|
|
15
|
-
import { pderivGrid, pderivNumericalFn, pderivSymbolic } from './pderiv.js';
|
|
16
14
|
import { validateMetricTensor, validateKroneckerDelta, validatePartialDerivative, } from '../dimensional/metric-validators.js';
|
|
17
15
|
import { NumericalBackendError } from './errors.js';
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
16
|
+
import { christoffelAt, dGammaAt, buildRiemann, contractRiemannJS,
|
|
17
|
+
// v0.6.1 Phase 2: the bianchi-residual + weyl-tensor arms moved into
|
|
18
|
+
// these two helpers (full FD pipeline + result-wrap).
|
|
19
|
+
lowerBianchiResidual, lowerWeylTensor, } from './curvature-lowering-helpers.js';
|
|
20
|
+
// v0.7 follow-up to v0.6.1's LOC-target miss: the four private helpers
|
|
21
|
+
// (isMetricTensorNode, dimensionOf, requireValue, flattenNestedArray)
|
|
22
|
+
// live in lowering-utils.ts so the new derivative-lowering.ts can
|
|
23
|
+
// share them without a forward-import cycle.
|
|
24
|
+
import { dimensionOf, requireValue, flattenNestedArray, } from './lowering-utils.js';
|
|
25
|
+
// v0.7 follow-up: tensor-partial-derivative + covariant-derivative
|
|
26
|
+
// case arms extracted (was lines 523-820, ~298 LOC). The recursive
|
|
27
|
+
// lowerNode call is threaded as a thunk to keep the module graph
|
|
28
|
+
// acyclic.
|
|
29
|
+
import { lowerTensorPartialDerivative, lowerCovariantDerivative, } from './derivative-lowering.js';
|
|
31
30
|
function isContractable(node) {
|
|
32
31
|
return node.kind === 'tensor-symbol'
|
|
33
32
|
|| node.kind === 'metric-tensor'
|
|
@@ -50,26 +49,6 @@ function operandIndices(node) {
|
|
|
50
49
|
}
|
|
51
50
|
return node.indices;
|
|
52
51
|
}
|
|
53
|
-
function dimensionOf(inputs) {
|
|
54
|
-
return inputs.dimension ?? 4;
|
|
55
|
-
}
|
|
56
|
-
/** Look up a named tensor's concrete value, or throw. */
|
|
57
|
-
function requireValue(name, inputs) {
|
|
58
|
-
const v = inputs.tensors.get(name);
|
|
59
|
-
if (v === undefined) {
|
|
60
|
-
throw new NumericalBackendError(`lowering: no value supplied for "${name}" in inputs.tensors`);
|
|
61
|
-
}
|
|
62
|
-
return v;
|
|
63
|
-
}
|
|
64
|
-
/** Flatten a NestedArray to a plain number[] and check expected size.
|
|
65
|
-
* Delegates to the canonical flattenNA() from connection-lowering-helpers. */
|
|
66
|
-
function flattenNestedArray(data, expectedSize) {
|
|
67
|
-
const out = flattenNA(data);
|
|
68
|
-
if (out.length !== expectedSize) {
|
|
69
|
-
throw new NumericalBackendError(`lowering: flattenNestedArray: got ${out.length} elements, expected ${expectedSize}`);
|
|
70
|
-
}
|
|
71
|
-
return out;
|
|
72
|
-
}
|
|
73
52
|
/**
|
|
74
53
|
* Build the EinsumSpec for a flat tensor-product.
|
|
75
54
|
*
|
|
@@ -80,9 +59,10 @@ function flattenNestedArray(data, expectedSize) {
|
|
|
80
59
|
* labels to their (operand, axis) sites. There is exactly one
|
|
81
60
|
* contraction-decision implementation in the codebase.
|
|
82
61
|
*
|
|
83
|
-
*
|
|
62
|
+
* v0.6.1: dropped export — was @internal-tagged with no external consumer.
|
|
63
|
+
* `lowerTensorProduct` (this file) is the only call site.
|
|
84
64
|
*/
|
|
85
|
-
|
|
65
|
+
function buildEinsumSpec(operands, contractionPairs, freeIndices) {
|
|
86
66
|
// Map every label to its (operand, axis) sites — via operandIndices() so a
|
|
87
67
|
// tensor-partial-derivative operand contributes its [...of.indices, wrtIndex]
|
|
88
68
|
// effective axes.
|
|
@@ -131,349 +111,19 @@ function lowerContractable(node, inputs, engine) {
|
|
|
131
111
|
const shape = node.indices.map(() => N);
|
|
132
112
|
return engine.fromNested(requireValue(node.name, inputs), shape);
|
|
133
113
|
}
|
|
134
|
-
/**
|
|
135
|
-
*
|
|
136
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Dispatcher for the six curvature-composite AST kinds.
|
|
116
|
+
*
|
|
117
|
+
* v0.6.0 Task 3.10e: extracted from `lowerNode`'s switch so all curvature
|
|
118
|
+
* lowering logic lives in one named helper. `CURVATURE_KIND_REGISTRY[node.kind]`
|
|
119
|
+
* supplies the per-kind shape/dim spec; the actual numerical paths are
|
|
120
|
+
* preserved verbatim from the prior per-kind arms — no logic changes.
|
|
121
|
+
*
|
|
122
|
+
* Called from `lowerNode` for all `CurvatureKind` discriminants.
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
function lowerCurvature(node, inputs, engine) {
|
|
137
126
|
switch (node.kind) {
|
|
138
|
-
case 'symbol':
|
|
139
|
-
return engine.fromNested(requireValue(node.name, inputs), []);
|
|
140
|
-
case 'tensor-symbol':
|
|
141
|
-
case 'metric-tensor':
|
|
142
|
-
case 'kronecker-delta':
|
|
143
|
-
return lowerContractable(node, inputs, engine);
|
|
144
|
-
case 'op': {
|
|
145
|
-
if (node.op === '+' || node.op === '-') {
|
|
146
|
-
if (node.args.length === 0)
|
|
147
|
-
return engine.fromNested(0, []);
|
|
148
|
-
let acc = lowerNode(node.args[0], inputs, engine);
|
|
149
|
-
for (let i = 1; i < node.args.length; i++) {
|
|
150
|
-
const next = lowerNode(node.args[i], inputs, engine);
|
|
151
|
-
acc = node.op === '+' ? engine.add(acc, next) : engine.sub(acc, next);
|
|
152
|
-
}
|
|
153
|
-
return acc;
|
|
154
|
-
}
|
|
155
|
-
// '*' / '/' / '^' are scalar-only. Guard arity so an unvalidated AST
|
|
156
|
-
// surfaces a clean NumericalBackendError instead of a raw TypeError
|
|
157
|
-
// (zero-operand '/') or a silent NaN (wrong-arity '^'). The '*' case
|
|
158
|
-
// with zero args is already fine — reduce(..., 1) returns 1.
|
|
159
|
-
if (node.op === '/' && node.args.length === 0) {
|
|
160
|
-
throw new NumericalBackendError("lowering: op '/' requires at least one operand");
|
|
161
|
-
}
|
|
162
|
-
if (node.op === '^' && node.args.length !== 2) {
|
|
163
|
-
throw new NumericalBackendError(`lowering: op '^' requires exactly 2 operands (base, exponent), got ${node.args.length}`);
|
|
164
|
-
}
|
|
165
|
-
// '*' / '/' / '^' are scalar-only (the validator rejects tensor
|
|
166
|
-
// operands). Lower each to rank-0, do the arithmetic in JS, lift back.
|
|
167
|
-
const scalars = node.args.map((a) => {
|
|
168
|
-
const t = lowerNode(a, inputs, engine);
|
|
169
|
-
if (t.shape.length !== 0) {
|
|
170
|
-
throw new NumericalBackendError(`lowering: op '${node.op}' got a rank-${t.shape.length} operand — scalar ops require rank-0`);
|
|
171
|
-
}
|
|
172
|
-
return engine.toNested(t);
|
|
173
|
-
});
|
|
174
|
-
let value;
|
|
175
|
-
if (node.op === '*')
|
|
176
|
-
value = scalars.reduce((a, b) => a * b, 1);
|
|
177
|
-
else if (node.op === '/')
|
|
178
|
-
value = scalars.reduce((a, b) => a / b);
|
|
179
|
-
else
|
|
180
|
-
value = Math.pow(scalars[0], scalars[1]); // '^'
|
|
181
|
-
return engine.fromNested(value, []);
|
|
182
|
-
}
|
|
183
|
-
case 'tensor-product': {
|
|
184
|
-
for (const arg of node.args) {
|
|
185
|
-
if (arg.kind === 'tensor-product') {
|
|
186
|
-
throw new NumericalBackendError('lowering: nested tensor-product numerical evaluation is not supported in v0.3.5 — '
|
|
187
|
-
+ 'flatten the contraction into a single product');
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
// Contractable operands (tensor-symbol / metric-tensor / kronecker-delta
|
|
191
|
-
// / tensor-partial-derivative) participate in the einsum; everything
|
|
192
|
-
// else must be a rank-0 scalar factor.
|
|
193
|
-
const operands = node.args.filter(isContractable);
|
|
194
|
-
const scalarArgs = node.args.filter((a) => !isContractable(a));
|
|
195
|
-
// computeContraction is the single authority on WHICH indices contract
|
|
196
|
-
// (variance-aware, implicit-metric rule). See buildEinsumSpec JSDoc.
|
|
197
|
-
// The recursive validateContractionChild resolves tensor-partial-derivative
|
|
198
|
-
// operands via validatePartialDerivative.
|
|
199
|
-
function validateContractionChild(child) {
|
|
200
|
-
if (child.kind === 'tensor-symbol')
|
|
201
|
-
return validateTensorSymbol(child);
|
|
202
|
-
if (child.kind === 'metric-tensor')
|
|
203
|
-
return validateMetricTensor(child);
|
|
204
|
-
if (child.kind === 'kronecker-delta')
|
|
205
|
-
return validateKroneckerDelta(child);
|
|
206
|
-
if (child.kind === 'tensor-partial-derivative') {
|
|
207
|
-
const r = validatePartialDerivative(child, (g) => validateContractionChild(g));
|
|
208
|
-
return { dim: r.dim, freeIndices: r.freeIndices };
|
|
209
|
-
}
|
|
210
|
-
throw new NumericalBackendError(`lowering: unexpected operand '${child.kind}' in tensor-product einsum`);
|
|
211
|
-
}
|
|
212
|
-
const { contractionPairs, freeIndices } = computeContraction(operands, validateContractionChild);
|
|
213
|
-
const spec = buildEinsumSpec(operands, contractionPairs, freeIndices);
|
|
214
|
-
const operandTensors = operands.map((n) => lowerContractable(n, inputs, engine));
|
|
215
|
-
let result = engine.einsum(spec, ...operandTensors);
|
|
216
|
-
// Scalar operands multiply the whole contraction.
|
|
217
|
-
for (const s of scalarArgs) {
|
|
218
|
-
const st = lowerNode(s, inputs, engine);
|
|
219
|
-
if (st.shape.length !== 0) {
|
|
220
|
-
throw new NumericalBackendError('lowering: non-scalar non-contractable operand in tensor-product');
|
|
221
|
-
}
|
|
222
|
-
result = engine.scale(result, engine.toNested(st));
|
|
223
|
-
}
|
|
224
|
-
return result;
|
|
225
|
-
}
|
|
226
|
-
case 'tensor-partial-derivative': {
|
|
227
|
-
// v0.3.5/v0.4.0 scope: `of` is a tensor-symbol or metric-tensor.
|
|
228
|
-
// ∂_μ(of) adds the wrtIndex as a trailing axis — the result shape is
|
|
229
|
-
// [...ofShape, N], NOT ofShape. (For BE-37, `of` = the scalar S is
|
|
230
|
-
// rank-0, so ∂_μ S is the rank-1 wave covector k_μ, shape [N].)
|
|
231
|
-
const of = node.of;
|
|
232
|
-
// v0.4.0 extension: metric-tensor pderiv dispatch.
|
|
233
|
-
if (of.kind === 'metric-tensor') {
|
|
234
|
-
const mNode = of;
|
|
235
|
-
const strategy = mNode.derivativeStrategy ?? 'computed';
|
|
236
|
-
const N = dimensionOf(inputs);
|
|
237
|
-
const coordLabel = node.wrtIndex.label;
|
|
238
|
-
const ofShape = mNode.indices.map(() => N);
|
|
239
|
-
const resultShape = [...ofShape, N];
|
|
240
|
-
if (strategy === 'zero') {
|
|
241
|
-
// ∂g = 0 everywhere (constant/flat metric).
|
|
242
|
-
return zeroTensor(resultShape, engine);
|
|
243
|
-
}
|
|
244
|
-
if (strategy === 'supplied') {
|
|
245
|
-
// Look up the N slices ∂_mu g for mu=0..N-1 and stack them as the
|
|
246
|
-
// trailing axis. Key format: `${metricName}/${coordLabel}_${mu}`.
|
|
247
|
-
// Result shape: [...ofShape, N] = [N, N, N] for a rank-2 metric.
|
|
248
|
-
// Build as a flat array then convert to nested for engine.fromNested().
|
|
249
|
-
const size = resultShape.reduce((a, b) => a * b, 1);
|
|
250
|
-
const flat = new Array(size).fill(0);
|
|
251
|
-
// ofShape = [N, N], resultShape = [N, N, N]
|
|
252
|
-
// flat[i*N*N + j*N + mu] = (∂_mu g)[i][j]
|
|
253
|
-
for (let mu = 0; mu < N; mu++) {
|
|
254
|
-
const key = `${mNode.name}/${coordLabel}_${mu}`;
|
|
255
|
-
const slice = inputs.metricDerivatives?.get(key);
|
|
256
|
-
if (slice === undefined) {
|
|
257
|
-
throw new NumericalBackendError(`lowering: metric-tensor pderiv with strategy='supplied': ` +
|
|
258
|
-
`no metricDerivatives entry for "${key}"`);
|
|
259
|
-
}
|
|
260
|
-
// Flatten the slice (shape [N,N]) and write into flat at stride N (last axis)
|
|
261
|
-
const flatSlice = flattenNestedArray(slice, N * N);
|
|
262
|
-
for (let ij = 0; ij < N * N; ij++) {
|
|
263
|
-
flat[ij * N + mu] = flatSlice[ij];
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
return engine.fromNested(flatToNested(flat, resultShape), resultShape);
|
|
267
|
-
}
|
|
268
|
-
// strategy === 'computed': treat as zero for constant-tensor metrics
|
|
269
|
-
// (the raw metric supplied via inputs.tensors has no coordinate dependence).
|
|
270
|
-
return zeroTensor(resultShape, engine);
|
|
271
|
-
}
|
|
272
|
-
if (of.kind !== 'tensor-symbol') {
|
|
273
|
-
throw new NumericalBackendError(`lowering: tensor-partial-derivative numerical eval requires a tensor-symbol `
|
|
274
|
-
+ `or metric-tensor 'of' operand in v0.3.5/v0.4.0 — got '${of.kind}'`);
|
|
275
|
-
}
|
|
276
|
-
const sym = of;
|
|
277
|
-
const form = sym.numericalForm ?? 'symbolic';
|
|
278
|
-
const coordLabel = node.wrtIndex.label;
|
|
279
|
-
const N = dimensionOf(inputs);
|
|
280
|
-
const ofShape = sym.indices.map(() => N);
|
|
281
|
-
const resultShape = [...ofShape, N];
|
|
282
|
-
if (form === 'symbolic') {
|
|
283
|
-
// pderivSymbolic returns the caller-supplied full ∂_μ(of) tensor,
|
|
284
|
-
// which must already be of shape [...ofShape, N].
|
|
285
|
-
const d = pderivSymbolic(sym.name, coordLabel, inputs.derivatives ?? new Map());
|
|
286
|
-
return engine.fromNested(d, resultShape);
|
|
287
|
-
}
|
|
288
|
-
if (form === 'numerical-fn') {
|
|
289
|
-
// v0.3.5: 'numerical-fn' lowering is scoped to a rank-0 `of` (scalar
|
|
290
|
-
// field). ∂_μ ranges over all N coordinate axes — stack the N
|
|
291
|
-
// single-axis derivatives into the rank-1 result. Higher-rank fields
|
|
292
|
-
// under 'numerical-fn' are a v0.4.0 concern.
|
|
293
|
-
if (ofShape.length !== 0) {
|
|
294
|
-
throw new NumericalBackendError(`lowering: 'numerical-fn' pderiv lowering supports a rank-0 'of' in v0.3.5; `
|
|
295
|
-
+ `"${sym.name}" is rank ${ofShape.length}`);
|
|
296
|
-
}
|
|
297
|
-
const fn = inputs.fields?.get(sym.name);
|
|
298
|
-
if (!fn) {
|
|
299
|
-
throw new NumericalBackendError(`lowering: 'numerical-fn' tensor-symbol "${sym.name}" has no field fn in inputs.fields`);
|
|
300
|
-
}
|
|
301
|
-
const coordValues = inputs.coords ? [...inputs.coords.values()] : [];
|
|
302
|
-
const components = [];
|
|
303
|
-
for (let axis = 0; axis < N; axis++) {
|
|
304
|
-
components.push(pderivNumericalFn(fn, coordValues, axis));
|
|
305
|
-
}
|
|
306
|
-
return engine.fromNested(components, [N]);
|
|
307
|
-
}
|
|
308
|
-
// form === 'grid': the GridField is the field sampled over space, and
|
|
309
|
-
// pderivGrid returns the derivative field sampled on that same grid —
|
|
310
|
-
// result shape is grid.shape. This is a distinct semantic from
|
|
311
|
-
// symbolic/numerical-fn (a sampled derivative field, not a single
|
|
312
|
-
// tensor), kept as the v0.5.0 BSSN forward-compat path. v0.3.5 has no
|
|
313
|
-
// release test driving 'grid' through lowering; pderivGrid itself is
|
|
314
|
-
// unit-tested in Task 10's pderiv.test.ts.
|
|
315
|
-
const grid = inputs.grids?.get(sym.name);
|
|
316
|
-
if (!grid) {
|
|
317
|
-
throw new NumericalBackendError(`lowering: 'grid' tensor-symbol "${sym.name}" has no GridField in inputs.grids`);
|
|
318
|
-
}
|
|
319
|
-
const gridAxis = inputs.coords ? [...inputs.coords.keys()].indexOf(coordLabel) : 0;
|
|
320
|
-
const flat = pderivGrid(grid, gridAxis < 0 ? 0 : gridAxis);
|
|
321
|
-
return engine.fromNested(flat.length === 1 ? flat[0] : flat, grid.shape);
|
|
322
|
-
}
|
|
323
|
-
case 'covariant-derivative': {
|
|
324
|
-
// S2(a) fix: `of.freeIndices` does NOT exist on the raw ExprNode.
|
|
325
|
-
// Re-validate the `of` subtree to obtain its free-index structure.
|
|
326
|
-
const covNode = node;
|
|
327
|
-
const ofExpr = covNode.of;
|
|
328
|
-
// TS-2 runtime guard: `covNode.of` is typed as `unknown` (module-cycle
|
|
329
|
-
// prevents ExprNode import in connection-validators.ts). The cast above
|
|
330
|
-
// is unchecked — a malformed AST bypassing validate() would produce a
|
|
331
|
-
// cryptic TypeError at `ofExpr.kind` below. Throw a clear message now.
|
|
332
|
-
if (typeof ofExpr.kind !== 'string') {
|
|
333
|
-
throw new NumericalBackendError(`lowering: CovariantDerivativeNode.of must have a string 'kind' field ` +
|
|
334
|
-
`(got ${JSON.stringify(ofExpr.kind)}). ` +
|
|
335
|
-
`Always call validate() before evaluateNumericalRaw().`);
|
|
336
|
-
}
|
|
337
|
-
const ofValidation = validate(ofExpr);
|
|
338
|
-
// Build ordered list of free indices: [{label, variance}].
|
|
339
|
-
// Iterate of.indices (NOT validation.freeIndices Map) — declaration order IS
|
|
340
|
-
// the axis layout. For tensor-symbol and metric-tensor, of.indices is the
|
|
341
|
-
// canonical axis order; the freeIndices Map insertion order is also
|
|
342
|
-
// of.indices order (validateTensorSymbol iterates node.indices), but relying
|
|
343
|
-
// on that is an undocumented invariant. Iterating of.indices directly makes
|
|
344
|
-
// the axis ordering guarantee explicit and safe for future of-kinds.
|
|
345
|
-
const ofFreeIndices = [];
|
|
346
|
-
const ofIndices = ofExpr.indices;
|
|
347
|
-
if (ofIndices) {
|
|
348
|
-
// tensor-symbol / metric-tensor: iterate the declared indices in order.
|
|
349
|
-
// Each index is either free (present in ofValidation.freeIndices) or
|
|
350
|
-
// contracted (absent — skip). In practice, of.indices for a simple
|
|
351
|
-
// tensor-symbol or metric-tensor has no contracted indices, but we
|
|
352
|
-
// guard with the Map lookup for safety.
|
|
353
|
-
for (const idx of ofIndices) {
|
|
354
|
-
const counts = ofValidation.freeIndices.get(idx.label);
|
|
355
|
-
if (counts === undefined)
|
|
356
|
-
continue; // contracted — not a free axis
|
|
357
|
-
ofFreeIndices.push({
|
|
358
|
-
label: idx.label,
|
|
359
|
-
variance: idx.variance,
|
|
360
|
-
pos: ofFreeIndices.length,
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
// Fallback for future of-kinds without .indices (e.g. tensor-product).
|
|
366
|
-
// Map iteration order is insertion order — a best-effort axis ordering.
|
|
367
|
-
let axisPos = 0;
|
|
368
|
-
for (const [label, counts] of ofValidation.freeIndices) {
|
|
369
|
-
for (let i = 0; i < counts.upper; i++) {
|
|
370
|
-
ofFreeIndices.push({ label, variance: 'upper', pos: axisPos++ });
|
|
371
|
-
}
|
|
372
|
-
for (let i = 0; i < counts.lower; i++) {
|
|
373
|
-
ofFreeIndices.push({ label, variance: 'lower', pos: axisPos++ });
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
// Lower the operand tensor.
|
|
378
|
-
const ofTensor = lowerNode(ofExpr, inputs, engine);
|
|
379
|
-
const N = dimensionOf(inputs);
|
|
380
|
-
// TS-2 runtime guard: gLower must be a metric-tensor node (validated
|
|
381
|
-
// upstream). A malformed AST bypassing validate() could reach here with
|
|
382
|
-
// a wrong kind, causing a silent wrong-path execution. The type
|
|
383
|
-
// predicate narrows covNode.gLower to MetricTensorNode for the rest of
|
|
384
|
-
// this branch — no follow-up cast needed.
|
|
385
|
-
if (!isMetricTensorNode(covNode.gLower)) {
|
|
386
|
-
throw new NumericalBackendError(`lowering: CovariantDerivativeNode.gLower must be a metric-tensor node ` +
|
|
387
|
-
`(got kind='${covNode.gLower.kind}')`);
|
|
388
|
-
}
|
|
389
|
-
const strategy = covNode.gLower.derivativeStrategy ?? 'computed';
|
|
390
|
-
// S2(b): strategy='zero' → flat space, Γ=0, ∇_μ T = ∂_μ T.
|
|
391
|
-
// For constant tensors (like a flat metric), ∂_μ T = 0, so result is all zeros.
|
|
392
|
-
// We return a zero tensor of shape [...ofShape, N] (wrt axis appended last).
|
|
393
|
-
if (strategy === 'zero') {
|
|
394
|
-
const outShape = [...ofTensor.shape, N];
|
|
395
|
-
return zeroTensor(outShape, engine);
|
|
396
|
-
}
|
|
397
|
-
// v0.4.0 CRITICAL FIX (Finding #1): 'computed' on a raw-tensor metric means
|
|
398
|
-
// constant metric → Γ = 0 → covariant-derivative = partial derivative only.
|
|
399
|
-
// v0.5.0 will replace this with coordinate-grid finite-difference.
|
|
400
|
-
// This early return MUST come before the Christoffel construction below,
|
|
401
|
-
// because getMetricDerivFlat only accepts 'zero' | 'supplied'; if 'computed'
|
|
402
|
-
// fell through, the type cast was silently wrong at runtime and the function
|
|
403
|
-
// threw NumericalBackendError for every coordinate.
|
|
404
|
-
//
|
|
405
|
-
// Compute partial first so we can return it directly.
|
|
406
|
-
// (partial is also needed by the 'supplied' path below, so we compute it
|
|
407
|
-
// unconditionally and use the early return only for 'computed'.)
|
|
408
|
-
//
|
|
409
|
-
// UC-2 (v0.4.6): `of` is always tensor-symbol or metric-tensor at this
|
|
410
|
-
// point. validateCovariantDerivative (connection-validators.ts) only
|
|
411
|
-
// accepts those kinds for the 'of' field; any other kind fails dimensional
|
|
412
|
-
// validation before evaluateNumerical reaches lowerNode. A covariant-
|
|
413
|
-
// derivative with a scalar 'of' (ofFreeIndices.length === 0) already
|
|
414
|
-
// returned at the early-return below. The old else-branch ("Scalar or
|
|
415
|
-
// other: partial is zero") was therefore unreachable and is removed here;
|
|
416
|
-
// replaced with an explicit throw to make the invariant visible if a
|
|
417
|
-
// bypass-validate AST construction ever violates it.
|
|
418
|
-
if (ofExpr.kind !== 'tensor-symbol' && ofExpr.kind !== 'metric-tensor') {
|
|
419
|
-
throw new NumericalBackendError(`lowering: covariant-derivative 'of' must be tensor-symbol or metric-tensor ` +
|
|
420
|
-
`(got '${ofExpr.kind}') — validated nodes cannot reach this point`);
|
|
421
|
-
}
|
|
422
|
-
const pdNode = {
|
|
423
|
-
kind: 'tensor-partial-derivative',
|
|
424
|
-
of: ofExpr,
|
|
425
|
-
wrt: covNode.wrt,
|
|
426
|
-
wrtIndex: covNode.wrtIndex,
|
|
427
|
-
};
|
|
428
|
-
const partial = lowerNode(pdNode, inputs, engine);
|
|
429
|
-
// v0.4.0 spec: 'computed' on a raw-tensor metric = constant metric → Γ = 0.
|
|
430
|
-
// The covariant-derivative reduces to the ordinary partial derivative.
|
|
431
|
-
// v0.5.0 will add coordinate-grid finite-difference here.
|
|
432
|
-
if (strategy === 'computed') {
|
|
433
|
-
return partial;
|
|
434
|
-
}
|
|
435
|
-
// S2(c) + S2(d): Build Christoffel Γ^α_{μν} from metric data and apply
|
|
436
|
-
// the sign rule to all free indices of `of`:
|
|
437
|
-
// ∇_μ T^α_β = ∂_μ T^α_β + Γ^α_{μλ} T^λ_β − Γ^λ_{μβ} T^α_λ
|
|
438
|
-
//
|
|
439
|
-
// If `of` has no free indices (scalar), no correction needed.
|
|
440
|
-
if (ofFreeIndices.length === 0) {
|
|
441
|
-
return partial;
|
|
442
|
-
}
|
|
443
|
-
// Get metric and inverse metric data. gLower is already narrowed to
|
|
444
|
-
// MetricTensorNode by the isMetricTensorNode guard above (TS-2);
|
|
445
|
-
// gInverse retains its existing cast because no analogous predicate
|
|
446
|
-
// exists for the inverse-metric kind yet.
|
|
447
|
-
const gLowerNode = covNode.gLower;
|
|
448
|
-
const gInverseNode = covNode.gInverse;
|
|
449
|
-
const gInverseData = flattenNestedArray(requireValue(gInverseNode.name, inputs), N * N);
|
|
450
|
-
// coordLabel for metricDerivatives keys (wrtIndex.label of the covariant derivative)
|
|
451
|
-
const coordLabel = covNode.wrtIndex.label;
|
|
452
|
-
// getMetricDeriv(mu): returns flat [N*N] of ∂_{mu} g
|
|
453
|
-
const getMetricDeriv = (mu) => getMetricDerivFlat(gLowerNode.name, coordLabel, mu, 'supplied',
|
|
454
|
-
// ^ strategy can only be 'supplied' here: 'zero' returned at line 457-459,
|
|
455
|
-
// 'computed' returned at line 491-493, scalar 'of' returned at line 500-502.
|
|
456
|
-
// Safe per audit UC-1: 'zero' strategy is short-circuited in earlier guard.
|
|
457
|
-
N, inputs.metricDerivatives);
|
|
458
|
-
// Compute Γ^α_{μν} from metric data.
|
|
459
|
-
const GammaTensor = computeChristoffelTensor(gInverseData, getMetricDeriv, N, engine);
|
|
460
|
-
const GammaFlat = flattenNestedArray(engine.toNested(GammaTensor), N * N * N);
|
|
461
|
-
// Apply the Christoffel correction for each free index of `of`.
|
|
462
|
-
// S2(d) sign rule: upper → +Γ, lower → −Γ.
|
|
463
|
-
const ofFlat = flattenNestedArray(engine.toNested(ofTensor), ofTensor.shape.reduce((a, b) => a * b, 1));
|
|
464
|
-
const ofShapeArr = [...ofTensor.shape];
|
|
465
|
-
let correction = zeroTensorLike(partial, engine);
|
|
466
|
-
for (const freeIdx of ofFreeIndices) {
|
|
467
|
-
const term = contractChristoffelWithOperand(GammaFlat, ofFlat, ofShapeArr, freeIdx.pos, freeIdx.variance, N, engine);
|
|
468
|
-
const sign = freeIdx.variance === 'upper' ? 1 : -1;
|
|
469
|
-
correction = tensorAddScaled(correction, term, sign, engine);
|
|
470
|
-
}
|
|
471
|
-
return tensorAdd(partial, correction, engine);
|
|
472
|
-
}
|
|
473
|
-
case 'integral':
|
|
474
|
-
case 'derivative':
|
|
475
|
-
throw new NumericalBackendError(`lowering: '${node.kind}' is not numerically evaluated in v0.3.5 — `
|
|
476
|
-
+ 'use tensor-partial-derivative for differentiation');
|
|
477
127
|
case 'ricci-tensor': {
|
|
478
128
|
// v0.5.0 Task 7 — Ricci R_μν = R^λ_{μλν} (Carroll Eq. 3.91). Lowers
|
|
479
129
|
// the embedded Riemann tensor via the 'riemann-tensor' case (so all
|
|
@@ -503,7 +153,8 @@ export function lowerNode(node, inputs, engine) {
|
|
|
503
153
|
// composite node directly, no rewrite into a tensor-product.)
|
|
504
154
|
const ricciNode = node;
|
|
505
155
|
const N = dimensionOf(inputs);
|
|
506
|
-
|
|
156
|
+
// RiemannTensorNode is a member of ExprNode and CurvatureKind — cast is safe.
|
|
157
|
+
const innerR = lowerCurvature(ricciNode.riemann, inputs, engine);
|
|
507
158
|
const flatR = flattenNestedArray(engine.toNested(innerR), N * N * N * N);
|
|
508
159
|
// Contract R[λ][μ_out][λ][ν_out] → Ricci[μ_out][ν_out] via the shared
|
|
509
160
|
// `contractRiemannJS` helper (AS-1, v0.5.1). On R^ρ_{σμν} stored as
|
|
@@ -540,7 +191,7 @@ export function lowerNode(node, inputs, engine) {
|
|
|
540
191
|
const ricciNodeInner = {
|
|
541
192
|
kind: 'ricci-tensor', riemann: eNode.riemann,
|
|
542
193
|
};
|
|
543
|
-
const innerR =
|
|
194
|
+
const innerR = lowerCurvature(ricciNodeInner, inputs, engine);
|
|
544
195
|
const Ric = engine.toNested(innerR);
|
|
545
196
|
// Step 2: g_μν and g^μν from inputs.tensors (raw constant matrices at
|
|
546
197
|
// the test coordinate point). Mirrors how ricci-tensor's de-Sitter
|
|
@@ -566,40 +217,9 @@ export function lowerNode(node, inputs, engine) {
|
|
|
566
217
|
}
|
|
567
218
|
case 'bianchi-residual': {
|
|
568
219
|
// v0.5.0 Task 9 — Bianchi-identity residual B_{λμνρσ}.
|
|
569
|
-
//
|
|
570
|
-
//
|
|
571
|
-
|
|
572
|
-
// where each ∇_λ R_{μνρσ} is computed with the four Christoffel-
|
|
573
|
-
// correction terms (one per lower index of R). All FD/contraction
|
|
574
|
-
// arithmetic happens in the helper module — this case just wires
|
|
575
|
-
// x / metric closures from `inputs` to `bianchiResidualAt`.
|
|
576
|
-
//
|
|
577
|
-
// The result is a 5-deep nested array [N][N][N][N][N] with index order
|
|
578
|
-
// B[λ][μ][ν][ρ][σ]. Returned as an EngineTensor of shape [N,N,N,N,N];
|
|
579
|
-
// callers (typically bianchiResidual().evaluate) materialise via
|
|
580
|
-
// engine.toNested.
|
|
581
|
-
//
|
|
582
|
-
// Walks the node directly — no AST rewrite into an op('+') of pderiv
|
|
583
|
-
// products. Matches Task 6/7/8 walk-directly philosophy.
|
|
584
|
-
const bNode = node;
|
|
585
|
-
const rNode = bNode.riemann;
|
|
586
|
-
const N = dimensionOf(inputs);
|
|
587
|
-
// Coordinate value: same convention as the riemann-tensor case.
|
|
588
|
-
const xCoordName = rNode.xCoord.name;
|
|
589
|
-
const xRaw = requireValue(xCoordName, inputs);
|
|
590
|
-
const x = flattenNestedArray(xRaw, N);
|
|
591
|
-
// Coordinate-dependent metric closures.
|
|
592
|
-
const gName = rNode.gLower.name;
|
|
593
|
-
const gInvName = rNode.gInverse.name;
|
|
594
|
-
const gFn = inputs.fields?.get(gName);
|
|
595
|
-
const gInverseFn = inputs.fields?.get(gInvName);
|
|
596
|
-
if (!gFn || !gInverseFn) {
|
|
597
|
-
throw new NumericalBackendError(`lowering: bianchi-residual numerical evaluation requires coordinate-` +
|
|
598
|
-
`dependent metric closures in inputs.fields for "${gName}" and "${gInvName}". ` +
|
|
599
|
-
`Got fields=[${[...(inputs.fields?.keys() ?? [])].join(',')}].`);
|
|
600
|
-
}
|
|
601
|
-
const B = bianchiResidualAt(x, gFn, gInverseFn, N, engine);
|
|
602
|
-
return engine.fromNested(B, [N, N, N, N, N]);
|
|
220
|
+
// Extracted into `lowerBianchiResidual` in v0.6.1 Phase 2; the body
|
|
221
|
+
// here is just the type-narrowed dispatch.
|
|
222
|
+
return lowerBianchiResidual(node, inputs, engine);
|
|
603
223
|
}
|
|
604
224
|
case 'riemann-tensor': {
|
|
605
225
|
// v0.5.0 Task 6 (Phase 1c-ii). Walks the node directly (no AST rewrite
|
|
@@ -634,6 +254,190 @@ export function lowerNode(node, inputs, engine) {
|
|
|
634
254
|
// Materialise back into an EngineTensor in [N,N,N,N] shape.
|
|
635
255
|
return engine.fromNested(R, [N, N, N, N]);
|
|
636
256
|
}
|
|
257
|
+
case 'weyl-tensor': {
|
|
258
|
+
// v0.6.0 Task 3.2 — Weyl C^ρ_{σμν}.
|
|
259
|
+
// Extracted into `lowerWeylTensor` in v0.6.1 Phase 2; the body here
|
|
260
|
+
// is just the type-narrowed dispatch.
|
|
261
|
+
return lowerWeylTensor(node, inputs, engine);
|
|
262
|
+
}
|
|
263
|
+
case 'kretschmann-scalar': {
|
|
264
|
+
// v0.6.0 Task 3.5/3.6 — KretschmannScalarNode: K = R_{ρσμν} R^{ρσμν}.
|
|
265
|
+
//
|
|
266
|
+
// The full lowering arm (Riemann→lower + computeKretschmann) is deferred
|
|
267
|
+
// to Task 3.7 where the Schwarzschild closed-form test pins it. Callers
|
|
268
|
+
// can invoke `computeKretschmann` directly with a sampled riemannLower
|
|
269
|
+
// array (see tests/numerical/kretschmann-schwarzschild.test.ts).
|
|
270
|
+
//
|
|
271
|
+
// Raises a descriptive error so callers get a clear signal instead of
|
|
272
|
+
// the generic 'unknown kind' exhaustiveness message.
|
|
273
|
+
void node;
|
|
274
|
+
throw new NumericalBackendError(`lowering: 'kretschmann-scalar' end-to-end lowering is not yet implemented ` +
|
|
275
|
+
`(Task 3.7). Use computeKretschmann() from src/numerical/kretschmann.ts ` +
|
|
276
|
+
`with a pre-computed riemannLower array and invertMetric().`);
|
|
277
|
+
}
|
|
278
|
+
default: {
|
|
279
|
+
const _exhaustive = node;
|
|
280
|
+
void _exhaustive;
|
|
281
|
+
throw new NumericalBackendError(`lowerCurvature: unhandled curvature kind ${JSON.stringify(node.kind)}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/** Lower a validated ExprNode to an EngineTensor.
|
|
286
|
+
* @internal — cross-module/test use only; not part of the consumer surface. */
|
|
287
|
+
export function lowerNode(node, inputs, engine) {
|
|
288
|
+
switch (node.kind) {
|
|
289
|
+
case 'symbol':
|
|
290
|
+
return engine.fromNested(requireValue(node.name, inputs), []);
|
|
291
|
+
case 'tensor-symbol':
|
|
292
|
+
case 'metric-tensor':
|
|
293
|
+
case 'kronecker-delta':
|
|
294
|
+
return lowerContractable(node, inputs, engine);
|
|
295
|
+
case 'op': {
|
|
296
|
+
if (node.op === '+' || node.op === '-') {
|
|
297
|
+
if (node.args.length === 0)
|
|
298
|
+
return engine.fromNested(0, []);
|
|
299
|
+
let acc = lowerNode(node.args[0], inputs, engine);
|
|
300
|
+
for (let i = 1; i < node.args.length; i++) {
|
|
301
|
+
const next = lowerNode(node.args[i], inputs, engine);
|
|
302
|
+
acc = node.op === '+' ? engine.add(acc, next) : engine.sub(acc, next);
|
|
303
|
+
}
|
|
304
|
+
return acc;
|
|
305
|
+
}
|
|
306
|
+
// '*' / '/' / '^' are scalar-only. Guard arity so an unvalidated AST
|
|
307
|
+
// surfaces a clean NumericalBackendError instead of a raw TypeError
|
|
308
|
+
// (zero-operand '/') or a silent NaN (wrong-arity '^'). The '*' case
|
|
309
|
+
// with zero args is already fine — reduce(..., 1) returns 1.
|
|
310
|
+
if (node.op === '/' && node.args.length === 0) {
|
|
311
|
+
throw new NumericalBackendError("lowering: op '/' requires at least one operand");
|
|
312
|
+
}
|
|
313
|
+
if (node.op === '^' && node.args.length !== 2) {
|
|
314
|
+
throw new NumericalBackendError(`lowering: op '^' requires exactly 2 operands (base, exponent), got ${node.args.length}`);
|
|
315
|
+
}
|
|
316
|
+
// '*' / '/' / '^' are scalar-only (the validator rejects tensor
|
|
317
|
+
// operands). Lower each to rank-0, do the arithmetic in JS, lift back.
|
|
318
|
+
const scalars = node.args.map((a) => {
|
|
319
|
+
const t = lowerNode(a, inputs, engine);
|
|
320
|
+
if (t.shape.length !== 0) {
|
|
321
|
+
throw new NumericalBackendError(`lowering: op '${node.op}' got a rank-${t.shape.length} operand — scalar ops require rank-0`);
|
|
322
|
+
}
|
|
323
|
+
return engine.toNested(t);
|
|
324
|
+
});
|
|
325
|
+
let value;
|
|
326
|
+
if (node.op === '*')
|
|
327
|
+
value = scalars.reduce((a, b) => a * b, 1);
|
|
328
|
+
else if (node.op === '/')
|
|
329
|
+
value = scalars.reduce((a, b) => a / b);
|
|
330
|
+
else
|
|
331
|
+
value = Math.pow(scalars[0], scalars[1]); // '^'
|
|
332
|
+
return engine.fromNested(value, []);
|
|
333
|
+
}
|
|
334
|
+
case 'tensor-product': {
|
|
335
|
+
for (const arg of node.args) {
|
|
336
|
+
if (arg.kind === 'tensor-product') {
|
|
337
|
+
throw new NumericalBackendError('lowering: nested tensor-product numerical evaluation is not supported in v0.3.5 — '
|
|
338
|
+
+ 'flatten the contraction into a single product');
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// Contractable operands (tensor-symbol / metric-tensor / kronecker-delta
|
|
342
|
+
// / tensor-partial-derivative) participate in the einsum; everything
|
|
343
|
+
// else must be a rank-0 scalar factor.
|
|
344
|
+
const operands = node.args.filter(isContractable);
|
|
345
|
+
const scalarArgs = node.args.filter((a) => !isContractable(a));
|
|
346
|
+
// computeContraction is the single authority on WHICH indices contract
|
|
347
|
+
// (variance-aware, implicit-metric rule). See buildEinsumSpec JSDoc.
|
|
348
|
+
// The recursive validateContractionChild resolves tensor-partial-derivative
|
|
349
|
+
// operands via validatePartialDerivative.
|
|
350
|
+
function validateContractionChild(child) {
|
|
351
|
+
if (child.kind === 'tensor-symbol')
|
|
352
|
+
return validateTensorSymbol(child);
|
|
353
|
+
if (child.kind === 'metric-tensor')
|
|
354
|
+
return validateMetricTensor(child);
|
|
355
|
+
if (child.kind === 'kronecker-delta')
|
|
356
|
+
return validateKroneckerDelta(child);
|
|
357
|
+
if (child.kind === 'tensor-partial-derivative') {
|
|
358
|
+
const r = validatePartialDerivative(child, (g) => validateContractionChild(g));
|
|
359
|
+
return { dim: r.dim, freeIndices: r.freeIndices };
|
|
360
|
+
}
|
|
361
|
+
throw new NumericalBackendError(`lowering: unexpected operand '${child.kind}' in tensor-product einsum`);
|
|
362
|
+
}
|
|
363
|
+
const { contractionPairs, freeIndices } = computeContraction(operands, validateContractionChild);
|
|
364
|
+
const spec = buildEinsumSpec(operands, contractionPairs, freeIndices);
|
|
365
|
+
const operandTensors = operands.map((n) => lowerContractable(n, inputs, engine));
|
|
366
|
+
let result = engine.einsum(spec, ...operandTensors);
|
|
367
|
+
// Scalar operands multiply the whole contraction.
|
|
368
|
+
for (const s of scalarArgs) {
|
|
369
|
+
const st = lowerNode(s, inputs, engine);
|
|
370
|
+
if (st.shape.length !== 0) {
|
|
371
|
+
throw new NumericalBackendError('lowering: non-scalar non-contractable operand in tensor-product');
|
|
372
|
+
}
|
|
373
|
+
result = engine.scale(result, engine.toNested(st));
|
|
374
|
+
}
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
case 'tensor-partial-derivative':
|
|
378
|
+
// v0.7 follow-up to v0.6.1 LOC miss: body extracted to
|
|
379
|
+
// derivative-lowering.ts. No recursive lowerNode call from
|
|
380
|
+
// this arm, so the thunk parameter is not needed.
|
|
381
|
+
return lowerTensorPartialDerivative(node, inputs, engine);
|
|
382
|
+
case 'covariant-derivative':
|
|
383
|
+
// v0.7 follow-up to v0.6.1 LOC miss: body extracted to
|
|
384
|
+
// derivative-lowering.ts. Recursive lowerNode call threaded
|
|
385
|
+
// via thunk to keep the module graph acyclic.
|
|
386
|
+
return lowerCovariantDerivative(node, inputs, engine, lowerNode);
|
|
387
|
+
case 'integral':
|
|
388
|
+
case 'derivative':
|
|
389
|
+
throw new NumericalBackendError(`lowering: '${node.kind}' is not numerically evaluated in v0.3.5 — `
|
|
390
|
+
+ 'use tensor-partial-derivative for differentiation');
|
|
391
|
+
// v0.6.0 Task 3.10e: ricci-tensor, einstein-tensor, bianchi-residual,
|
|
392
|
+
// riemann-tensor, weyl-tensor, kretschmann-scalar all delegate to
|
|
393
|
+
// lowerCurvature — the extracted curvature-composite dispatcher.
|
|
394
|
+
case 'ricci-tensor':
|
|
395
|
+
case 'einstein-tensor':
|
|
396
|
+
case 'bianchi-residual':
|
|
397
|
+
case 'riemann-tensor':
|
|
398
|
+
case 'weyl-tensor':
|
|
399
|
+
case 'kretschmann-scalar':
|
|
400
|
+
return lowerCurvature(node, inputs, engine);
|
|
401
|
+
case 'killing-vector': {
|
|
402
|
+
// v0.6.0 Task 1.1: KillingVectorNode symbolic AST added. Numerical
|
|
403
|
+
// evaluation (verifyKillingEquation / evaluateConservedCharge) is
|
|
404
|
+
// deferred to Task 1.3 (src/numerical/killing.ts). Until then, the
|
|
405
|
+
// lowering layer raises a descriptive error so callers get a clear
|
|
406
|
+
// signal instead of the generic 'unknown kind' message.
|
|
407
|
+
throw new NumericalBackendError(`lowering: 'killing-vector' numerical evaluation is not yet implemented ` +
|
|
408
|
+
`(Task 1.3). Use verifyKillingEquation() from src/numerical/killing.ts.`);
|
|
409
|
+
}
|
|
410
|
+
case 'conserved-charge': {
|
|
411
|
+
// v0.6.0 Task 1.2: ConservedChargeNode symbolic AST added. Numerical
|
|
412
|
+
// evaluation (evaluateConservedCharge) is deferred to Task 1.3
|
|
413
|
+
// (src/numerical/killing.ts). Raises a descriptive error so callers
|
|
414
|
+
// get a clear signal instead of the generic 'unknown kind' message.
|
|
415
|
+
throw new NumericalBackendError(`lowering: 'conserved-charge' numerical evaluation is not yet implemented ` +
|
|
416
|
+
`(Task 1.3). Use evaluateConservedCharge() from src/numerical/killing.ts.`);
|
|
417
|
+
}
|
|
418
|
+
case 'stress-energy': {
|
|
419
|
+
// v0.6.0 Task 2.1: StressEnergyTensorNode symbolic AST added. Full
|
|
420
|
+
// numerical evaluation (T_μν from a perfect-fluid or explicit component
|
|
421
|
+
// map) is deferred to Task 2.4 (src/numerical/einstein-equation.ts).
|
|
422
|
+
// Raises a descriptive error so callers get a clear signal instead of
|
|
423
|
+
// the generic 'unknown kind' message from the exhaustiveness guard.
|
|
424
|
+
throw new NumericalBackendError(`lowering: 'stress-energy' numerical evaluation is not yet implemented ` +
|
|
425
|
+
`(Task 2.4). Use the Einstein-equation evaluator in src/numerical/einstein-equation.ts.`);
|
|
426
|
+
}
|
|
427
|
+
case 'cosmological-constant': {
|
|
428
|
+
// v0.6.0 Task 2.1: CosmologicalConstantNode symbolic AST added. Numerical
|
|
429
|
+
// evaluation (inject Λ as a scalar into the Einstein equation) is deferred
|
|
430
|
+
// to Task 2.4 (src/numerical/einstein-equation.ts).
|
|
431
|
+
throw new NumericalBackendError(`lowering: 'cosmological-constant' numerical evaluation is not yet implemented ` +
|
|
432
|
+
`(Task 2.4). Use the Einstein-equation evaluator in src/numerical/einstein-equation.ts.`);
|
|
433
|
+
}
|
|
434
|
+
case 'einstein-equation': {
|
|
435
|
+
// v0.6.0 Task 2.3: EinsteinFieldEquationNode predicate AST added. Numerical
|
|
436
|
+
// evaluation (G_μν + Λ g_μν = κ T_μν residual tensor) is deferred to
|
|
437
|
+
// Task 2.4 (src/numerical/einstein-equation.ts).
|
|
438
|
+
throw new NumericalBackendError(`lowering: 'einstein-equation' numerical evaluation is not yet implemented ` +
|
|
439
|
+
`(Task 2.4). Use the Einstein-equation evaluator in src/numerical/einstein-equation.ts.`);
|
|
440
|
+
}
|
|
637
441
|
default: {
|
|
638
442
|
const _exhaustive = node;
|
|
639
443
|
void _exhaustive;
|