@classytic/stage 0.2.0 → 0.4.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/LICENSE +1 -1
- package/README.md +5 -1
- package/dist/_virtual/_rolldown/runtime.mjs +18 -0
- package/dist/assets/index.mjs +0 -1
- package/dist/atomic/aufbau.d.mts +144 -0
- package/dist/atomic/aufbau.mjs +384 -0
- package/dist/atomic/elements.d.mts +67 -0
- package/dist/atomic/elements.mjs +785 -0
- package/dist/atomic/emission.d.mts +112 -0
- package/dist/atomic/emission.mjs +179 -0
- package/dist/atomic/index.d.mts +8 -0
- package/dist/atomic/index.mjs +9 -0
- package/dist/atomic/periodic.d.mts +82 -0
- package/dist/atomic/periodic.mjs +231 -0
- package/dist/atomic/properties.d.mts +100 -0
- package/dist/atomic/properties.mjs +574 -0
- package/dist/atomic/shells.d.mts +137 -0
- package/dist/atomic/shells.mjs +170 -0
- package/dist/atomic/trends.d.mts +148 -0
- package/dist/atomic/trends.mjs +225 -0
- package/dist/builder/Palette.mjs +50 -89
- package/dist/builder/SceneBuilder.mjs +15 -73
- package/dist/chem/chromatography.d.mts +66 -0
- package/dist/chem/chromatography.mjs +63 -0
- package/dist/chem/complex.d.mts +114 -0
- package/dist/chem/complex.mjs +234 -0
- package/dist/chem/cycle.d.mts +75 -0
- package/dist/chem/cycle.mjs +145 -0
- package/dist/chem/equation.d.mts +86 -0
- package/dist/chem/equation.mjs +168 -0
- package/dist/chem/formula.d.mts +90 -0
- package/dist/chem/formula.mjs +201 -0
- package/dist/chem/functional-groups.d.mts +31 -0
- package/dist/chem/functional-groups.mjs +187 -0
- package/dist/chem/hazard.d.mts +94 -0
- package/dist/chem/hazard.mjs +329 -0
- package/dist/chem/index.d.mts +34 -33
- package/dist/chem/index.mjs +34 -28
- package/dist/chem/ionic.d.mts +98 -0
- package/dist/chem/ionic.mjs +156 -0
- package/dist/chem/layout.d.mts +46 -0
- package/dist/chem/layout.mjs +342 -0
- package/dist/chem/lewis.d.mts +79 -0
- package/dist/chem/lewis.mjs +163 -0
- package/dist/chem/molecular-orbital.d.mts +114 -0
- package/dist/chem/molecular-orbital.mjs +201 -0
- package/dist/chem/molecule.d.mts +154 -0
- package/dist/chem/molecule.mjs +282 -0
- package/dist/chem/nmr.d.mts +153 -0
- package/dist/chem/nmr.mjs +165 -0
- package/dist/chem/polymer.d.mts +65 -0
- package/dist/chem/polymer.mjs +179 -0
- package/dist/chem/redox.d.mts +138 -0
- package/dist/chem/redox.mjs +328 -0
- package/dist/chem/relations.d.mts +183 -0
- package/dist/chem/relations.mjs +299 -0
- package/dist/chem/skeleton.d.mts +51 -0
- package/dist/chem/skeleton.mjs +186 -0
- package/dist/chem/solution.d.mts +116 -0
- package/dist/chem/solution.mjs +186 -0
- package/dist/chem/species.d.mts +47 -0
- package/dist/chem/species.mjs +128 -0
- package/dist/chem/stereo.d.mts +108 -0
- package/dist/chem/stereo.mjs +286 -0
- package/dist/chem/stoichiometry.d.mts +95 -0
- package/dist/chem/stoichiometry.mjs +145 -0
- package/dist/chem/synthesis.d.mts +113 -0
- package/dist/chem/synthesis.mjs +281 -0
- package/dist/chem/vsepr.d.mts +80 -0
- package/dist/chem/vsepr.mjs +247 -0
- package/dist/circuit/ac.d.mts +163 -0
- package/dist/circuit/ac.mjs +452 -0
- package/dist/circuit/dc.d.mts +92 -0
- package/dist/circuit/dc.mjs +333 -0
- package/dist/circuit/index.d.mts +5 -92
- package/dist/circuit/index.mjs +5 -332
- package/dist/circuit/network.d.mts +99 -0
- package/dist/circuit/network.mjs +440 -0
- package/dist/circuit/topology.d.mts +102 -0
- package/dist/circuit/topology.mjs +143 -0
- package/dist/colour/absorption.d.mts +79 -0
- package/dist/colour/absorption.mjs +137 -0
- package/dist/colour/index.d.mts +6 -0
- package/dist/colour/index.mjs +7 -0
- package/dist/colour/name.d.mts +14 -0
- package/dist/colour/name.mjs +76 -0
- package/dist/colour/observer.d.mts +31 -0
- package/dist/colour/observer.mjs +46 -0
- package/dist/colour/spectrum.d.mts +61 -0
- package/dist/colour/spectrum.mjs +108 -0
- package/dist/colour/srgb.d.mts +49 -0
- package/dist/colour/srgb.mjs +108 -0
- package/dist/core/constants.d.mts +138 -0
- package/dist/core/constants.mjs +139 -0
- package/dist/core/index.d.mts +4 -1
- package/dist/core/index.mjs +4 -1
- package/dist/core/math.d.mts +26 -0
- package/dist/core/math.mjs +37 -0
- package/dist/core/vec3.d.mts +94 -0
- package/dist/core/vec3.mjs +123 -0
- package/dist/core/worked.d.mts +35 -0
- package/dist/core/worked.mjs +44 -0
- package/dist/electro/cell.d.mts +102 -0
- package/dist/electro/cell.mjs +170 -0
- package/dist/electro/conductivity.d.mts +157 -0
- package/dist/electro/conductivity.mjs +156 -0
- package/dist/electro/couples.d.mts +114 -0
- package/dist/electro/couples.mjs +334 -0
- package/dist/electro/electrolysis.d.mts +96 -0
- package/dist/electro/electrolysis.mjs +274 -0
- package/dist/electro/faraday.d.mts +150 -0
- package/dist/electro/faraday.mjs +118 -0
- package/dist/electro/index.d.mts +6 -0
- package/dist/electro/index.mjs +7 -0
- package/dist/finance/accounting/adjustments.d.mts +17 -0
- package/dist/finance/accounting/adjustments.mjs +202 -0
- package/dist/finance/accounting/analysis.d.mts +8 -0
- package/dist/finance/accounting/analysis.mjs +205 -0
- package/dist/finance/accounting/clubs.d.mts +21 -0
- package/dist/finance/accounting/clubs.mjs +217 -0
- package/dist/finance/accounting/company-statements.d.mts +7 -0
- package/dist/finance/accounting/company-statements.mjs +150 -0
- package/dist/finance/accounting/harness.d.mts +7 -0
- package/dist/finance/accounting/harness.mjs +45 -0
- package/dist/finance/accounting/index.d.mts +18 -0
- package/dist/finance/accounting/index.mjs +18 -0
- package/dist/finance/accounting/journalize.d.mts +16 -0
- package/dist/finance/accounting/journalize.mjs +128 -0
- package/dist/finance/accounting/manufacturing.d.mts +8 -0
- package/dist/finance/accounting/manufacturing.mjs +236 -0
- package/dist/finance/accounting/partnership.d.mts +7 -0
- package/dist/finance/accounting/partnership.mjs +152 -0
- package/dist/finance/accounting/period-case.d.mts +6 -0
- package/dist/finance/accounting/period-case.mjs +71 -0
- package/dist/finance/accounting/post.d.mts +9 -0
- package/dist/finance/accounting/post.mjs +84 -0
- package/dist/finance/accounting/precision.d.mts +9 -0
- package/dist/finance/accounting/precision.mjs +15 -0
- package/dist/finance/accounting/rules.d.mts +21 -0
- package/dist/finance/accounting/rules.mjs +37 -0
- package/dist/finance/accounting/solve.d.mts +28 -0
- package/dist/finance/accounting/solve.mjs +92 -0
- package/dist/finance/accounting/statements.d.mts +7 -0
- package/dist/finance/accounting/statements.mjs +142 -0
- package/dist/finance/accounting/types.d.mts +649 -0
- package/dist/finance/accounting/validate.d.mts +7 -0
- package/dist/finance/accounting/validate.mjs +67 -0
- package/dist/finance/accounting/verification.d.mts +24 -0
- package/dist/finance/accounting/verification.mjs +386 -0
- package/dist/finance/bizsim.d.mts +75 -0
- package/dist/finance/bizsim.mjs +296 -0
- package/dist/finance/index.d.mts +95 -0
- package/dist/finance/index.mjs +145 -0
- package/dist/finance/investment-math.d.mts +7 -0
- package/dist/finance/investment-math.mjs +18 -0
- package/dist/finance/management-accounting/budgeting.d.mts +7 -0
- package/dist/finance/management-accounting/budgeting.mjs +189 -0
- package/dist/finance/management-accounting/cash-budget.d.mts +7 -0
- package/dist/finance/management-accounting/cash-budget.mjs +154 -0
- package/dist/finance/management-accounting/costing.d.mts +8 -0
- package/dist/finance/management-accounting/costing.mjs +175 -0
- package/dist/finance/management-accounting/decisions.d.mts +8 -0
- package/dist/finance/management-accounting/decisions.mjs +164 -0
- package/dist/finance/management-accounting/index.d.mts +13 -0
- package/dist/finance/management-accounting/index.mjs +13 -0
- package/dist/finance/management-accounting/integrated-budget.d.mts +8 -0
- package/dist/finance/management-accounting/integrated-budget.mjs +67 -0
- package/dist/finance/management-accounting/inventory-costing.d.mts +7 -0
- package/dist/finance/management-accounting/inventory-costing.mjs +173 -0
- package/dist/finance/management-accounting/investment-appraisal.d.mts +7 -0
- package/dist/finance/management-accounting/investment-appraisal.mjs +148 -0
- package/dist/finance/management-accounting/management-case.d.mts +8 -0
- package/dist/finance/management-accounting/management-case.mjs +91 -0
- package/dist/finance/management-accounting/master-budget.d.mts +7 -0
- package/dist/finance/management-accounting/master-budget.mjs +137 -0
- package/dist/finance/management-accounting/production-costing.d.mts +8 -0
- package/dist/finance/management-accounting/production-costing.mjs +214 -0
- package/dist/finance/management-accounting/types.d.mts +644 -0
- package/dist/finance/management-accounting/variances.d.mts +7 -0
- package/dist/finance/management-accounting/variances.mjs +150 -0
- package/dist/index.d.mts +9 -8
- package/dist/index.mjs +5 -5
- package/dist/interaction/MovableDot.mjs +19 -0
- package/dist/interaction/useDraggable.mjs +24 -4
- package/dist/math/analysis.d.mts +61 -0
- package/dist/math/analysis.mjs +187 -0
- package/dist/math/answer-check.d.mts +50 -0
- package/dist/math/answer-check.mjs +106 -0
- package/dist/math/calculus.d.mts +17 -1
- package/dist/math/calculus.mjs +365 -2
- package/dist/math/complex.d.mts +93 -0
- package/dist/math/complex.mjs +239 -0
- package/dist/math/expr.d.mts +23 -0
- package/dist/math/expr.mjs +36 -0
- package/dist/math/index.d.mts +9 -23
- package/dist/math/index.mjs +9 -38
- package/dist/math/latex.mjs +10 -1
- package/dist/math/parse.mjs +1 -1
- package/dist/math/poly.d.mts +55 -0
- package/dist/math/poly.mjs +273 -0
- package/dist/math/rearrange.d.mts +14 -0
- package/dist/math/rearrange.mjs +125 -0
- package/dist/math/solve.d.mts +21 -0
- package/dist/math/solve.mjs +75 -0
- package/dist/networking/addressing.d.mts +26 -0
- package/dist/networking/addressing.mjs +33 -0
- package/dist/networking/cloud/access.d.mts +36 -0
- package/dist/networking/cloud/access.mjs +95 -0
- package/dist/networking/cloud/containers.d.mts +43 -0
- package/dist/networking/cloud/containers.mjs +54 -0
- package/dist/networking/cloud/edge.d.mts +17 -0
- package/dist/networking/cloud/edge.mjs +31 -0
- package/dist/networking/cloud/failure-domains.d.mts +19 -0
- package/dist/networking/cloud/failure-domains.mjs +22 -0
- package/dist/networking/cloud/geo-routing.d.mts +22 -0
- package/dist/networking/cloud/geo-routing.mjs +64 -0
- package/dist/networking/cloud/index.d.mts +18 -0
- package/dist/networking/cloud/index.mjs +19 -0
- package/dist/networking/cloud/inference-reliability.d.mts +30 -0
- package/dist/networking/cloud/inference-reliability.mjs +76 -0
- package/dist/networking/cloud/inference.d.mts +118 -0
- package/dist/networking/cloud/inference.mjs +179 -0
- package/dist/networking/cloud/infrastructure.d.mts +45 -0
- package/dist/networking/cloud/infrastructure.mjs +96 -0
- package/dist/networking/cloud/observability.d.mts +24 -0
- package/dist/networking/cloud/observability.mjs +34 -0
- package/dist/networking/cloud/orchestration.d.mts +32 -0
- package/dist/networking/cloud/orchestration.mjs +38 -0
- package/dist/networking/cloud/recovery.d.mts +21 -0
- package/dist/networking/cloud/recovery.mjs +27 -0
- package/dist/networking/cloud/releases.d.mts +42 -0
- package/dist/networking/cloud/releases.mjs +135 -0
- package/dist/networking/cloud/scaling.d.mts +25 -0
- package/dist/networking/cloud/scaling.mjs +65 -0
- package/dist/networking/cloud/secrets.d.mts +39 -0
- package/dist/networking/cloud/secrets.mjs +68 -0
- package/dist/networking/cloud/server-deployment.d.mts +29 -0
- package/dist/networking/cloud/server-deployment.mjs +72 -0
- package/dist/networking/cloud/storage.d.mts +16 -0
- package/dist/networking/cloud/storage.mjs +58 -0
- package/dist/networking/cloud/vpc.d.mts +18 -0
- package/dist/networking/cloud/vpc.mjs +100 -0
- package/dist/networking/delivery.d.mts +34 -0
- package/dist/networking/delivery.mjs +52 -0
- package/dist/networking/index.d.mts +47 -0
- package/dist/networking/index.mjs +47 -0
- package/dist/networking/ipv6.d.mts +28 -0
- package/dist/networking/ipv6.mjs +17 -0
- package/dist/networking/journeys.d.mts +83 -0
- package/dist/networking/journeys.mjs +161 -0
- package/dist/networking/models/airtime.d.mts +87 -0
- package/dist/networking/models/airtime.mjs +130 -0
- package/dist/networking/models/cellular.d.mts +157 -0
- package/dist/networking/models/cellular.mjs +252 -0
- package/dist/networking/models/encapsulation.d.mts +98 -0
- package/dist/networking/models/encapsulation.mjs +132 -0
- package/dist/networking/models/handover.d.mts +116 -0
- package/dist/networking/models/handover.mjs +209 -0
- package/dist/networking/models/handshake.d.mts +90 -0
- package/dist/networking/models/handshake.mjs +122 -0
- package/dist/networking/models/index.d.mts +14 -0
- package/dist/networking/models/index.mjs +15 -0
- package/dist/networking/models/media.d.mts +82 -0
- package/dist/networking/models/media.mjs +188 -0
- package/dist/networking/models/satellite.d.mts +86 -0
- package/dist/networking/models/satellite.mjs +121 -0
- package/dist/networking/models/spectrum.d.mts +83 -0
- package/dist/networking/models/spectrum.mjs +235 -0
- package/dist/networking/models/switch.d.mts +80 -0
- package/dist/networking/models/switch.mjs +155 -0
- package/dist/networking/models/vlan.d.mts +62 -0
- package/dist/networking/models/vlan.mjs +100 -0
- package/dist/networking/models/vpn.d.mts +66 -0
- package/dist/networking/models/vpn.mjs +125 -0
- package/dist/networking/models/wifi-privacy.d.mts +82 -0
- package/dist/networking/models/wifi-privacy.mjs +130 -0
- package/dist/networking/models/wifi.d.mts +240 -0
- package/dist/networking/models/wifi.mjs +562 -0
- package/dist/networking/nat-traversal.d.mts +24 -0
- package/dist/networking/nat-traversal.mjs +38 -0
- package/dist/networking/protocols.d.mts +17 -0
- package/dist/networking/protocols.mjs +57 -0
- package/dist/networking/queue.d.mts +12 -0
- package/dist/networking/queue.mjs +18 -0
- package/dist/networking/route-learning.d.mts +23 -0
- package/dist/networking/route-learning.mjs +43 -0
- package/dist/networking/routing.d.mts +11 -0
- package/dist/networking/routing.mjs +25 -0
- package/dist/networking/signals.d.mts +26 -0
- package/dist/networking/signals.mjs +35 -0
- package/dist/networking/subnet.d.mts +49 -0
- package/dist/networking/subnet.mjs +89 -0
- package/dist/networking/tcp-reliability.d.mts +24 -0
- package/dist/networking/tcp-reliability.mjs +38 -0
- package/dist/networking/topology/contract.d.mts +123 -0
- package/dist/networking/topology/index.d.mts +4 -0
- package/dist/networking/topology/index.mjs +4 -0
- package/dist/networking/topology/presets.d.mts +7 -0
- package/dist/networking/topology/presets.mjs +302 -0
- package/dist/networking/topology/simulation.d.mts +8 -0
- package/dist/networking/topology/simulation.mjs +179 -0
- package/dist/networking/wireless.d.mts +11 -0
- package/dist/networking/wireless.mjs +17 -0
- package/dist/optics/imaging.d.mts +218 -0
- package/dist/optics/imaging.mjs +276 -0
- package/dist/optics/index.d.mts +7 -0
- package/dist/optics/index.mjs +8 -0
- package/dist/optics/laws.d.mts +70 -0
- package/dist/optics/laws.mjs +195 -0
- package/dist/optics/prism.d.mts +148 -0
- package/dist/optics/prism.mjs +197 -0
- package/dist/optics/refraction.d.mts +201 -0
- package/dist/optics/refraction.mjs +270 -0
- package/dist/optics/wave-optics.d.mts +171 -0
- package/dist/optics/wave-optics.mjs +259 -0
- package/dist/physics/ac/index.d.mts +183 -0
- package/dist/physics/ac/index.mjs +203 -0
- package/dist/physics/dynamics/forces.d.mts +98 -0
- package/dist/physics/dynamics/forces.mjs +153 -0
- package/dist/physics/dynamics/friction.d.mts +76 -0
- package/dist/physics/dynamics/friction.mjs +119 -0
- package/dist/physics/dynamics/system.d.mts +68 -0
- package/dist/physics/dynamics/system.mjs +125 -0
- package/dist/physics/electrostatics/index.d.mts +169 -0
- package/dist/physics/electrostatics/index.mjs +249 -0
- package/dist/physics/energy/centre-of-mass.d.mts +115 -0
- package/dist/physics/energy/centre-of-mass.mjs +180 -0
- package/dist/physics/energy/conservation.d.mts +81 -0
- package/dist/physics/energy/conservation.mjs +129 -0
- package/dist/physics/energy/power.d.mts +90 -0
- package/dist/physics/energy/power.mjs +167 -0
- package/dist/physics/energy/spring.d.mts +73 -0
- package/dist/physics/energy/spring.mjs +129 -0
- package/dist/physics/energy/store.d.mts +63 -0
- package/dist/physics/energy/store.mjs +108 -0
- package/dist/physics/energy/theorem.d.mts +65 -0
- package/dist/physics/energy/theorem.mjs +113 -0
- package/dist/physics/energy/work.d.mts +114 -0
- package/dist/physics/energy/work.mjs +219 -0
- package/dist/physics/gravitation/body.d.mts +85 -0
- package/dist/physics/gravitation/body.mjs +168 -0
- package/dist/physics/gravitation/kepler.d.mts +127 -0
- package/dist/physics/gravitation/kepler.mjs +216 -0
- package/dist/physics/gravitation/law.d.mts +117 -0
- package/dist/physics/gravitation/law.mjs +175 -0
- package/dist/physics/gravitation/orbit.d.mts +119 -0
- package/dist/physics/gravitation/orbit.mjs +202 -0
- package/dist/physics/gravitation/potential.d.mts +114 -0
- package/dist/physics/gravitation/potential.mjs +202 -0
- package/dist/physics/gravitation/variation.d.mts +97 -0
- package/dist/physics/gravitation/variation.mjs +175 -0
- package/dist/physics/index.d.mts +35 -0
- package/dist/physics/index.mjs +36 -0
- package/dist/physics/integral-sweep.d.mts +63 -0
- package/dist/physics/integral-sweep.mjs +126 -0
- package/dist/physics/kinematics/equations.d.mts +47 -0
- package/dist/physics/kinematics/equations.mjs +126 -0
- package/dist/physics/kinematics/free-fall.d.mts +53 -0
- package/dist/physics/kinematics/free-fall.mjs +71 -0
- package/dist/physics/kinematics/given.d.mts +16 -0
- package/dist/physics/kinematics/given.mjs +55 -0
- package/dist/physics/kinematics/roots.d.mts +41 -0
- package/dist/physics/kinematics/roots.mjs +72 -0
- package/dist/physics/kinematics/solve.d.mts +52 -0
- package/dist/physics/kinematics/solve.mjs +172 -0
- package/dist/physics/magnetism/biot-savart.d.mts +161 -0
- package/dist/physics/magnetism/biot-savart.mjs +353 -0
- package/dist/physics/magnetism/flux.d.mts +94 -0
- package/dist/physics/magnetism/flux.mjs +313 -0
- package/dist/physics/magnetism/geomagnetism.d.mts +151 -0
- package/dist/physics/magnetism/geomagnetism.mjs +184 -0
- package/dist/physics/magnetism/index.d.mts +12 -0
- package/dist/physics/magnetism/index.mjs +74 -0
- package/dist/physics/magnetism/lorentz.d.mts +28 -0
- package/dist/physics/magnetism/lorentz.mjs +88 -0
- package/dist/physics/magnetism/magnetic-force.d.mts +102 -0
- package/dist/physics/magnetism/magnetic-force.mjs +169 -0
- package/dist/physics/momentum/collide.d.mts +77 -0
- package/dist/physics/momentum/collide.mjs +115 -0
- package/dist/physics/momentum/impulse.d.mts +89 -0
- package/dist/physics/momentum/impulse.mjs +159 -0
- package/dist/physics/momentum/planar.d.mts +60 -0
- package/dist/physics/momentum/planar.mjs +110 -0
- package/dist/physics/projectile.d.mts +107 -0
- package/dist/physics/projectile.mjs +185 -0
- package/dist/physics/rotation/angular.d.mts +85 -0
- package/dist/physics/rotation/angular.mjs +130 -0
- package/dist/physics/rotation/circular.d.mts +79 -0
- package/dist/physics/rotation/circular.mjs +131 -0
- package/dist/physics/rotation/inertia.d.mts +164 -0
- package/dist/physics/rotation/inertia.mjs +332 -0
- package/dist/physics/rotation/torque.d.mts +65 -0
- package/dist/physics/rotation/torque.mjs +134 -0
- package/dist/physics/vectors.d.mts +64 -0
- package/dist/physics/vectors.mjs +114 -0
- package/dist/primitives/Dot.d.mts +2 -15
- package/dist/primitives/Dot.mjs +6 -4
- package/dist/primitives/Grid.d.mts +33 -17
- package/dist/primitives/Grid.mjs +89 -17
- package/dist/primitives/Label.d.mts +1 -14
- package/dist/primitives/Label.mjs +3 -2
- package/dist/primitives/Lines.d.mts +4 -32
- package/dist/primitives/Lines.mjs +10 -8
- package/dist/primitives/Shapes.d.mts +5 -43
- package/dist/primitives/Shapes.mjs +12 -10
- package/dist/primitives/index.d.mts +2 -2
- package/dist/primitives/index.mjs +2 -2
- package/dist/primitives/props.mjs +31 -0
- package/dist/quantity/index.d.mts +119 -0
- package/dist/quantity/index.mjs +417 -0
- package/dist/relation/derive.d.mts +74 -0
- package/dist/relation/derive.mjs +73 -0
- package/dist/relation/index.d.mts +56 -0
- package/dist/relation/index.mjs +234 -0
- package/dist/scene/Scene.d.mts +6 -1
- package/dist/scene/Scene.mjs +15 -40
- package/dist/scene/evaluators.mjs +1 -1
- package/dist/sim/thermal.mjs +45 -20
- package/dist/thermo/calorimetry.d.mts +207 -0
- package/dist/thermo/calorimetry.mjs +345 -0
- package/dist/thermo/cycles.d.mts +142 -0
- package/dist/thermo/cycles.mjs +256 -0
- package/dist/thermo/entropy.d.mts +87 -0
- package/dist/thermo/entropy.mjs +140 -0
- package/dist/thermo/expansion.d.mts +130 -0
- package/dist/thermo/expansion.mjs +178 -0
- package/dist/thermo/gas.d.mts +197 -0
- package/dist/thermo/gas.mjs +279 -0
- package/dist/thermo/heat-transfer.d.mts +164 -0
- package/dist/thermo/heat-transfer.mjs +217 -0
- package/dist/thermo/index.d.mts +9 -82
- package/dist/thermo/index.mjs +9 -132
- package/dist/thermo/processes.d.mts +95 -0
- package/dist/thermo/processes.mjs +154 -0
- package/dist/thermo/temperature.d.mts +174 -0
- package/dist/thermo/temperature.mjs +236 -0
- package/dist/view/Stage.mjs +4 -11
- package/dist/waves/damping.d.mts +224 -0
- package/dist/waves/damping.mjs +317 -0
- package/dist/waves/doppler.d.mts +72 -0
- package/dist/waves/doppler.mjs +125 -0
- package/dist/waves/index.d.mts +10 -0
- package/dist/waves/index.mjs +10 -0
- package/dist/waves/pendulum.d.mts +130 -0
- package/dist/waves/pendulum.mjs +211 -0
- package/dist/waves/pitch.d.mts +125 -0
- package/dist/waves/pitch.mjs +158 -0
- package/dist/waves/shm.d.mts +170 -0
- package/dist/waves/shm.mjs +279 -0
- package/dist/waves/springs.d.mts +103 -0
- package/dist/waves/springs.mjs +176 -0
- package/dist/waves/superposition.d.mts +124 -0
- package/dist/waves/superposition.mjs +196 -0
- package/dist/waves/wave.d.mts +154 -0
- package/dist/waves/wave.mjs +178 -0
- package/package.json +103 -23
- package/styles.css +125 -8
- package/dist/assets/kit/index.mjs +0 -4
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { JOULES_PER_CALORIE, STANDARD_GRAVITY } from "../core/constants.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/thermo/calorimetry.ts
|
|
4
|
+
/**
|
|
5
|
+
* Calorimetry: heat in, temperature and phase out.
|
|
6
|
+
*
|
|
7
|
+
* THE MODEL. Energy delivered to a body goes into exactly one of two things at
|
|
8
|
+
* any moment, and which one depends only on whether it is sitting at a
|
|
9
|
+
* transition temperature:
|
|
10
|
+
*
|
|
11
|
+
* warming a phase q = m·c·Δθ temperature rises
|
|
12
|
+
* changing phase q = m·L temperature is FLAT
|
|
13
|
+
*
|
|
14
|
+
* Everything here follows from putting those two in a row. A body's ENTHALPY
|
|
15
|
+
* LADDER is the alternating sequence of sloped runs and flat plateaus from a
|
|
16
|
+
* cold datum up to any temperature, and once you have the ladder you can ask
|
|
17
|
+
* either direction: how much heat to reach this temperature, or what
|
|
18
|
+
* temperature this much heat reaches.
|
|
19
|
+
*
|
|
20
|
+
* THE METHOD, and why it is exact. Total enthalpy H(θ) is piecewise LINEAR in
|
|
21
|
+
* temperature, with an upward jump of m·L at each transition. So the mixture
|
|
22
|
+
* problem, find the θ at which the bodies' enthalpies sum to what they started
|
|
23
|
+
* with, is the inversion of a piecewise-linear monotone function. That is
|
|
24
|
+
* solved by walking the brackets and doing one division, with no iteration and
|
|
25
|
+
* no tolerance. Bisection would also work and would be worse: it converges
|
|
26
|
+
* slowly exactly where the interesting answers are, at the plateaus, because
|
|
27
|
+
* there the function is flat in the inverse direction.
|
|
28
|
+
*
|
|
29
|
+
* This matters because it is what lets the solver answer the question a student
|
|
30
|
+
* actually cannot do by hand: mix ice below freezing with water above it, and
|
|
31
|
+
* the outcome is a case analysis (all ice, ice and water at 0 °C, all water)
|
|
32
|
+
* that the algebra hides. Here it falls out of which bracket the answer lands
|
|
33
|
+
* in.
|
|
34
|
+
*
|
|
35
|
+
* UNITS: SI. Mass in kg, specific heat capacity in J/(kg·K), latent heat in
|
|
36
|
+
* J/kg, energy in joules. Temperatures are in DEGREES CELSIUS, because every
|
|
37
|
+
* transition point a lesson names is quoted that way and the differences that
|
|
38
|
+
* appear in m·c·Δθ are identical in either scale.
|
|
39
|
+
*
|
|
40
|
+
* SCOPE. One-dimensional in temperature: no pressure dependence, so the boiling
|
|
41
|
+
* point is a constant rather than a function of the ambient pressure, and
|
|
42
|
+
* sublimation is not modelled. Specific heats are constant within a phase.
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* Materials that appear in the standard problems.
|
|
46
|
+
*
|
|
47
|
+
* Water's numbers are worth reading as a set: the latent heat of vaporisation
|
|
48
|
+
* is 2.26 MJ/kg against 4.18 kJ/(kg·K) for warming, so boiling a kilogram away
|
|
49
|
+
* costs the same as heating it through 540 °C. That ratio is the whole reason
|
|
50
|
+
* sweating works and the reason a steam burn is worse than a boiling-water
|
|
51
|
+
* burn, and it is visible in the table before any lab draws it.
|
|
52
|
+
*/
|
|
53
|
+
const MATERIALS = {
|
|
54
|
+
water: {
|
|
55
|
+
name: "Water",
|
|
56
|
+
cSolid: 2090,
|
|
57
|
+
cLiquid: 4180,
|
|
58
|
+
cGas: 2010,
|
|
59
|
+
latentFusion: 334e3,
|
|
60
|
+
latentVaporisation: 226e4,
|
|
61
|
+
meltingPointC: 0,
|
|
62
|
+
boilingPointC: 100
|
|
63
|
+
},
|
|
64
|
+
ethanol: {
|
|
65
|
+
name: "Ethanol",
|
|
66
|
+
cSolid: 1200,
|
|
67
|
+
cLiquid: 2440,
|
|
68
|
+
cGas: 1420,
|
|
69
|
+
latentFusion: 108e3,
|
|
70
|
+
latentVaporisation: 855e3,
|
|
71
|
+
meltingPointC: -114,
|
|
72
|
+
boilingPointC: 78
|
|
73
|
+
},
|
|
74
|
+
lead: {
|
|
75
|
+
name: "Lead",
|
|
76
|
+
cSolid: 130,
|
|
77
|
+
cLiquid: 140,
|
|
78
|
+
cGas: 140,
|
|
79
|
+
latentFusion: 24500,
|
|
80
|
+
latentVaporisation: 866e3,
|
|
81
|
+
meltingPointC: 327,
|
|
82
|
+
boilingPointC: 1749
|
|
83
|
+
},
|
|
84
|
+
iron: {
|
|
85
|
+
name: "Iron",
|
|
86
|
+
cSolid: 450,
|
|
87
|
+
cLiquid: 820,
|
|
88
|
+
cGas: 820,
|
|
89
|
+
latentFusion: 247e3,
|
|
90
|
+
latentVaporisation: 609e4,
|
|
91
|
+
meltingPointC: 1538,
|
|
92
|
+
boilingPointC: 2862
|
|
93
|
+
},
|
|
94
|
+
copper: {
|
|
95
|
+
name: "Copper",
|
|
96
|
+
cSolid: 385,
|
|
97
|
+
cLiquid: 495,
|
|
98
|
+
cGas: 495,
|
|
99
|
+
latentFusion: 209e3,
|
|
100
|
+
latentVaporisation: 473e4,
|
|
101
|
+
meltingPointC: 1085,
|
|
102
|
+
boilingPointC: 2562
|
|
103
|
+
},
|
|
104
|
+
aluminium: {
|
|
105
|
+
name: "Aluminium",
|
|
106
|
+
cSolid: 900,
|
|
107
|
+
cLiquid: 1180,
|
|
108
|
+
cGas: 1180,
|
|
109
|
+
latentFusion: 397e3,
|
|
110
|
+
latentVaporisation: 105e5,
|
|
111
|
+
meltingPointC: 660,
|
|
112
|
+
boilingPointC: 2470
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const finite = (value, what) => {
|
|
116
|
+
if (!Number.isFinite(value)) throw new RangeError(`${what} must be a finite number.`);
|
|
117
|
+
return value;
|
|
118
|
+
};
|
|
119
|
+
const positive = (value, what) => {
|
|
120
|
+
if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${what} must be positive.`);
|
|
121
|
+
return value;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Heat to warm a mass through a temperature change: q = m·c·Δθ.
|
|
125
|
+
*
|
|
126
|
+
* Δθ is SIGNED, so cooling returns a negative number rather than an absolute
|
|
127
|
+
* one. That is what makes the mixture bookkeeping add up to zero instead of
|
|
128
|
+
* needing a hand-placed minus sign on whichever body happened to be hotter.
|
|
129
|
+
*/
|
|
130
|
+
function heatToWarmJ(massKg, specificHeat, deltaT) {
|
|
131
|
+
return positive(massKg, "Mass") * positive(specificHeat, "Specific heat capacity") * finite(deltaT, "A temperature change");
|
|
132
|
+
}
|
|
133
|
+
/** Heat to change the state of a mass at its transition temperature: q = m·L. */
|
|
134
|
+
function heatToChangeStateJ(massKg, latentHeat) {
|
|
135
|
+
return positive(massKg, "Mass") * positive(latentHeat, "Latent heat");
|
|
136
|
+
}
|
|
137
|
+
/** The inverse of q = m·c·Δθ, solved for the temperature change. */
|
|
138
|
+
function temperatureRiseK(heatJ, massKg, specificHeat) {
|
|
139
|
+
return finite(heatJ, "Heat") / (positive(massKg, "Mass") * positive(specificHeat, "Specific heat capacity"));
|
|
140
|
+
}
|
|
141
|
+
/** The inverse of q = m·c·Δθ, solved for the specific heat capacity. */
|
|
142
|
+
function specificHeatFromJ(heatJ, massKg, deltaT) {
|
|
143
|
+
const dT = finite(deltaT, "A temperature change");
|
|
144
|
+
if (dT === 0) throw new RangeError("No temperature change, so this measurement cannot determine a specific heat capacity.");
|
|
145
|
+
return finite(heatJ, "Heat") / (positive(massKg, "Mass") * dT);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* The water equivalent of a calorimeter, kg: the mass of water with the same
|
|
149
|
+
* heat capacity.
|
|
150
|
+
*
|
|
151
|
+
* Lets a calorimeter be folded into a mixture as if it were more water, which
|
|
152
|
+
* is exactly how the textbook method handles it.
|
|
153
|
+
*/
|
|
154
|
+
function waterEquivalentKg(massKg, specificHeat) {
|
|
155
|
+
return positive(massKg, "Mass") * positive(specificHeat, "Specific heat capacity") / MATERIALS.water.cLiquid;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The enthalpy of a mass of material at temperature θ, J, measured from a datum
|
|
159
|
+
* of absolute zero with the material solid.
|
|
160
|
+
*
|
|
161
|
+
* The datum is arbitrary and cancels out of every difference, which is the only
|
|
162
|
+
* reason it is allowed to be as unphysical as "solid water at −273 °C". What
|
|
163
|
+
* matters is that the SAME datum is used for every body in a mixture.
|
|
164
|
+
*
|
|
165
|
+
* At a transition temperature this returns the value approached from BELOW, so
|
|
166
|
+
* `enthalpyJ(m, water, 0)` is solid ice at 0 °C with none of it melted. The
|
|
167
|
+
* jump of m·L lives between this value and `enthalpyJ` an epsilon higher, and
|
|
168
|
+
* the mixture solver resolves partial melting by landing inside that jump
|
|
169
|
+
* rather than by nudging the temperature.
|
|
170
|
+
*/
|
|
171
|
+
function enthalpyJ(massKg, material, celsius) {
|
|
172
|
+
const m = positive(massKg, "Mass");
|
|
173
|
+
const theta = finite(celsius, "A temperature");
|
|
174
|
+
const datum = -273.15;
|
|
175
|
+
const { meltingPointC: mp, boilingPointC: bp } = material;
|
|
176
|
+
if (theta <= mp) return m * material.cSolid * (theta - datum);
|
|
177
|
+
let total = m * material.cSolid * (mp - datum) + m * material.latentFusion;
|
|
178
|
+
if (theta <= bp) return total + m * material.cLiquid * (theta - mp);
|
|
179
|
+
total += m * material.cLiquid * (bp - mp) + m * material.latentVaporisation;
|
|
180
|
+
return total + m * material.cGas * (theta - bp);
|
|
181
|
+
}
|
|
182
|
+
/** The phase a material is in at a temperature, taking a transition point as the lower phase. */
|
|
183
|
+
function phaseAt(material, celsius) {
|
|
184
|
+
if (celsius <= material.meltingPointC) return "solid";
|
|
185
|
+
if (celsius <= material.boilingPointC) return "liquid";
|
|
186
|
+
return "gas";
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* The equilibrium temperature of bodies placed in a perfectly insulated
|
|
190
|
+
* container, and what state each ends in.
|
|
191
|
+
*
|
|
192
|
+
* Solves ΣH_i(θ) = ΣH_i(θ_i) exactly, by walking the piecewise-linear total
|
|
193
|
+
* enthalpy curve bracket by bracket. The brackets are the distinct transition
|
|
194
|
+
* temperatures of the materials present; inside one, every body is in a fixed
|
|
195
|
+
* phase and the total is linear, so the crossing point is one division.
|
|
196
|
+
*
|
|
197
|
+
* ASSUMES the container itself has no heat capacity. Fold a real calorimeter in
|
|
198
|
+
* as an extra body, or use `waterEquivalentKg` to express it as more water.
|
|
199
|
+
*/
|
|
200
|
+
function mixtureEquilibrium(bodies) {
|
|
201
|
+
if (bodies.length === 0) throw new RangeError("A mixture needs at least one body.");
|
|
202
|
+
const target = bodies.reduce((sum, b) => sum + enthalpyJ(b.massKg, b.material, finite(b.temperatureC, "A starting temperature")), 0);
|
|
203
|
+
const breaks = [...new Set(bodies.flatMap((b) => [b.material.meltingPointC, b.material.boilingPointC]))].sort((a, b) => a - b);
|
|
204
|
+
const totalAt = (theta) => bodies.reduce((sum, b) => sum + enthalpyJ(b.massKg, b.material, theta), 0);
|
|
205
|
+
const totalJustAbove = (theta) => bodies.reduce((sum, b) => {
|
|
206
|
+
let h = enthalpyJ(b.massKg, b.material, theta);
|
|
207
|
+
if (b.material.meltingPointC === theta) h += b.massKg * b.material.latentFusion;
|
|
208
|
+
if (b.material.boilingPointC === theta) h += b.massKg * b.material.latentVaporisation;
|
|
209
|
+
return sum + h;
|
|
210
|
+
}, 0);
|
|
211
|
+
let finalTemperatureC = null;
|
|
212
|
+
let lower = Number.NEGATIVE_INFINITY;
|
|
213
|
+
for (const theta of breaks) {
|
|
214
|
+
if (target < totalAt(theta)) {
|
|
215
|
+
finalTemperatureC = solveWithin(bodies, target, lower, theta);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
if (target <= totalJustAbove(theta)) {
|
|
219
|
+
finalTemperatureC = theta;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
lower = theta;
|
|
223
|
+
}
|
|
224
|
+
if (finalTemperatureC === null) finalTemperatureC = solveWithin(bodies, target, lower, Number.POSITIVE_INFINITY);
|
|
225
|
+
const results = bodies.map((b) => {
|
|
226
|
+
const start = enthalpyJ(b.massKg, b.material, b.temperatureC);
|
|
227
|
+
const end = shareOfJump(b, bodies, target, finalTemperatureC);
|
|
228
|
+
return {
|
|
229
|
+
label: b.label,
|
|
230
|
+
heatGainedJ: end.enthalpy - start,
|
|
231
|
+
startPhase: phaseAt(b.material, b.temperatureC),
|
|
232
|
+
endPhase: end.phase,
|
|
233
|
+
transitionFraction: end.fraction
|
|
234
|
+
};
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
finalTemperatureC,
|
|
238
|
+
bodies: results,
|
|
239
|
+
netHeatJ: results.reduce((sum, r) => sum + r.heatGainedJ, 0),
|
|
240
|
+
partialTransition: results.some((r) => r.transitionFraction !== null)
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Solve for the temperature within one sloped run of the enthalpy curve, given
|
|
245
|
+
* the bracket `(lower, upper)` the answer lies in.
|
|
246
|
+
*
|
|
247
|
+
* Inside a run every body's phase is fixed, so the slope is Σ m·c over the
|
|
248
|
+
* current phases and the total enthalpy is a straight line. The slope is read
|
|
249
|
+
* off the materials directly rather than by differencing the curve: a finite
|
|
250
|
+
* difference would need a step small enough not to cross the next break, and
|
|
251
|
+
* "small enough" is a tolerance this problem does not otherwise need.
|
|
252
|
+
*
|
|
253
|
+
* One end of the bracket is always finite, because every material contributes
|
|
254
|
+
* two breaks, so the run is anchored at whichever end exists. The outermost
|
|
255
|
+
* runs are unbounded on one side and that side is never the anchor.
|
|
256
|
+
*/
|
|
257
|
+
function solveWithin(bodies, target, lower, upper) {
|
|
258
|
+
const at = (theta) => bodies.reduce((sum, b) => sum + enthalpyJ(b.massKg, b.material, theta), 0);
|
|
259
|
+
const probe = Number.isFinite(lower) ? Number.isFinite(upper) ? (lower + upper) / 2 : lower + 1 : upper - 1;
|
|
260
|
+
const slope = bodies.reduce((sum, b) => {
|
|
261
|
+
const phase = phaseAt(b.material, probe);
|
|
262
|
+
const c = phase === "solid" ? b.material.cSolid : phase === "liquid" ? b.material.cLiquid : b.material.cGas;
|
|
263
|
+
return sum + b.massKg * c;
|
|
264
|
+
}, 0);
|
|
265
|
+
if (slope <= 0) throw new RangeError("The mixture has no heat capacity, so it has no equilibrium temperature.");
|
|
266
|
+
if (Number.isFinite(upper)) return upper - (at(upper) - target) / slope;
|
|
267
|
+
return lower + (target - bodies.reduce((sum, b) => {
|
|
268
|
+
let h = enthalpyJ(b.massKg, b.material, lower);
|
|
269
|
+
if (b.material.meltingPointC === lower) h += b.massKg * b.material.latentFusion;
|
|
270
|
+
if (b.material.boilingPointC === lower) h += b.massKg * b.material.latentVaporisation;
|
|
271
|
+
return sum + h;
|
|
272
|
+
}, 0)) / slope;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* One body's share of a partial transition, and the enthalpy it ended with.
|
|
276
|
+
*
|
|
277
|
+
* When the mixture settles inside a jump, the heat available has to be split
|
|
278
|
+
* across every body transitioning at that temperature. They share it in
|
|
279
|
+
* proportion to the latent heat each one needs, which is the only division that
|
|
280
|
+
* leaves them all at the same fraction: physically they are in contact at one
|
|
281
|
+
* temperature, so no body can get ahead of another.
|
|
282
|
+
*/
|
|
283
|
+
function shareOfJump(body, bodies, target, finalC) {
|
|
284
|
+
const base = enthalpyJ(body.massKg, body.material, finalC);
|
|
285
|
+
const latentOf = (b) => b.material.meltingPointC === finalC ? b.massKg * b.material.latentFusion : b.material.boilingPointC === finalC ? b.massKg * b.material.latentVaporisation : 0;
|
|
286
|
+
const jumpTotal = bodies.reduce((sum, b) => sum + latentOf(b), 0);
|
|
287
|
+
const mine = latentOf(body);
|
|
288
|
+
if (jumpTotal === 0 || mine === 0) return {
|
|
289
|
+
enthalpy: base,
|
|
290
|
+
phase: phaseAt(body.material, finalC),
|
|
291
|
+
fraction: null
|
|
292
|
+
};
|
|
293
|
+
const floor = bodies.reduce((sum, b) => sum + enthalpyJ(b.massKg, b.material, finalC), 0);
|
|
294
|
+
const fraction = Math.max(0, Math.min(1, (target - floor) / jumpTotal));
|
|
295
|
+
const phase = fraction >= 1 ? body.material.meltingPointC === finalC ? "liquid" : "gas" : phaseAt(body.material, finalC);
|
|
296
|
+
return {
|
|
297
|
+
enthalpy: base + fraction * mine,
|
|
298
|
+
phase,
|
|
299
|
+
fraction: fraction > 0 && fraction < 1 ? fraction : null
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* The temperature rise when a fraction of a moving body's kinetic energy turns
|
|
304
|
+
* into heat inside it: f·½mv² = m·c·Δθ.
|
|
305
|
+
*
|
|
306
|
+
* The mass cancels, which is the point and the thing students are surprised by:
|
|
307
|
+
* a bullet's temperature rise on impact depends on its SPEED and its material,
|
|
308
|
+
* not on how big it is. `fraction` is how much of the energy stays in the body
|
|
309
|
+
* rather than going into the target, the air, or sound.
|
|
310
|
+
*/
|
|
311
|
+
function temperatureRiseFromSpeedK(speedMs, specificHeat, fraction = 1) {
|
|
312
|
+
if (fraction < 0 || fraction > 1) throw new RangeError("The fraction retained must be between 0 and 1.");
|
|
313
|
+
const v = finite(speedMs, "Speed");
|
|
314
|
+
return fraction * .5 * v * v / positive(specificHeat, "Specific heat capacity");
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* The temperature rise when a fraction of a falling body's potential energy
|
|
318
|
+
* turns into heat inside it: f·mgh = m·c·Δθ.
|
|
319
|
+
*
|
|
320
|
+
* The mass cancels here too, so the answer depends only on the DROP. This is
|
|
321
|
+
* Joule's paddle-wheel experiment read backwards, and the classic worked
|
|
322
|
+
* example is the waterfall: the 4.2 kJ it takes to warm a kilogram of water by
|
|
323
|
+
* one degree is the same energy as dropping it 428 m.
|
|
324
|
+
*/
|
|
325
|
+
function temperatureRiseFromDropK(heightM, specificHeat, fraction = 1, gravity = STANDARD_GRAVITY) {
|
|
326
|
+
if (fraction < 0 || fraction > 1) throw new RangeError("The fraction retained must be between 0 and 1.");
|
|
327
|
+
return fraction * gravity * finite(heightM, "A height") / positive(specificHeat, "Specific heat capacity");
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* The mass melted when a fraction of a falling body's potential energy becomes
|
|
331
|
+
* heat in it: f·mgh = m'·L.
|
|
332
|
+
*
|
|
333
|
+
* Unlike the two above, this one keeps the mass, because the answer is a mass.
|
|
334
|
+
*/
|
|
335
|
+
function massMeltedFromDropKg(massKg, heightM, latentHeat, fraction = 1, gravity = STANDARD_GRAVITY) {
|
|
336
|
+
if (fraction < 0 || fraction > 1) throw new RangeError("The fraction retained must be between 0 and 1.");
|
|
337
|
+
return fraction * positive(massKg, "Mass") * gravity * finite(heightM, "A height") / positive(latentHeat, "Latent heat");
|
|
338
|
+
}
|
|
339
|
+
/** Calories to joules, through the thermochemical definition. */
|
|
340
|
+
const caloriesToJoules = (calories) => finite(calories, "An energy in calories") * JOULES_PER_CALORIE;
|
|
341
|
+
/** Joules to calories, through the thermochemical definition. */
|
|
342
|
+
const joulesToCalories = (joules) => finite(joules, "An energy in joules") / JOULES_PER_CALORIE;
|
|
343
|
+
|
|
344
|
+
//#endregion
|
|
345
|
+
export { MATERIALS, caloriesToJoules, enthalpyJ, heatToChangeStateJ, heatToWarmJ, joulesToCalories, massMeltedFromDropKg, mixtureEquilibrium, phaseAt, specificHeatFromJ, temperatureRiseFromDropK, temperatureRiseFromSpeedK, temperatureRiseK, waterEquivalentKg };
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { GasState, ProcessResult } from "./processes.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/thermo/cycles.d.ts
|
|
4
|
+
type CycleDirection = 'engine' | 'refrigerator' | 'neutral';
|
|
5
|
+
interface CycleSummary {
|
|
6
|
+
legs: ProcessResult[];
|
|
7
|
+
/** Net work done BY the gas over the cycle, J. Negative when work is done ON it. */
|
|
8
|
+
WnetJ: number;
|
|
9
|
+
/** Total heat absorbed on the legs that absorbed any, J (positive). */
|
|
10
|
+
QinJ: number;
|
|
11
|
+
/** Total heat rejected on the legs that rejected any, J (positive). */
|
|
12
|
+
QoutJ: number;
|
|
13
|
+
/**
|
|
14
|
+
* Clockwise on the p–V diagram is an engine, anticlockwise a refrigerator.
|
|
15
|
+
* Read from the sign of the net work rather than declared by the caller.
|
|
16
|
+
*/
|
|
17
|
+
direction: CycleDirection;
|
|
18
|
+
/**
|
|
19
|
+
* Thermal efficiency W_net/Q_in, or `null` for a cycle that is not an engine.
|
|
20
|
+
*
|
|
21
|
+
* Null rather than a negative number, because "efficiency" is not defined for
|
|
22
|
+
* a refrigerator and returning something for it would invite the comparison
|
|
23
|
+
* that the coefficient of performance exists to avoid.
|
|
24
|
+
*/
|
|
25
|
+
efficiency: number | null;
|
|
26
|
+
/** Q_cold/|W| for a refrigerator, or `null` for an engine. */
|
|
27
|
+
coefficientOfPerformance: number | null;
|
|
28
|
+
/** Q_hot/|W| for a heat pump: the same machine, sold for its warm end. */
|
|
29
|
+
heatPumpCOP: number | null;
|
|
30
|
+
/** ΣΔU round the cycle, J. Must be zero: reported so a lab can show it is. */
|
|
31
|
+
internalEnergyResidualJ: number;
|
|
32
|
+
/** ΣΔS round the cycle, J/K. Zero for a reversible cycle. */
|
|
33
|
+
entropyResidualJ: number;
|
|
34
|
+
/** How far the last leg ends from where the first began, as a fractional volume gap. */
|
|
35
|
+
closureError: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Totals, direction and figures of merit for any list of legs.
|
|
39
|
+
*
|
|
40
|
+
* Works on a cycle assembled from `runProcess`, on one built by hand, and on
|
|
41
|
+
* one that does not close, which is why the closure error is reported rather
|
|
42
|
+
* than enforced: a lab that lets a student build a cycle leg by leg needs to
|
|
43
|
+
* show them it has not closed yet, not refuse to draw it.
|
|
44
|
+
*/
|
|
45
|
+
declare function cycleSummary(legs: readonly ProcessResult[]): CycleSummary;
|
|
46
|
+
/**
|
|
47
|
+
* Carnot efficiency, 1 − T_c/T_h.
|
|
48
|
+
*
|
|
49
|
+
* The ceiling on every heat engine working between these two temperatures,
|
|
50
|
+
* whatever its working substance and however it is built. That universality is
|
|
51
|
+
* the content of the second law, and it is why this depends on nothing but the
|
|
52
|
+
* two temperatures.
|
|
53
|
+
*/
|
|
54
|
+
declare function carnotEfficiency(hotK: number, coldK: number): number;
|
|
55
|
+
/** Efficiency from the heats alone, 1 − Q_out/Q_in: the measurable version. */
|
|
56
|
+
declare function efficiencyFromHeat(QinJ: number, QoutJ: number): number;
|
|
57
|
+
/**
|
|
58
|
+
* Coefficient of performance of a refrigerator, T_c/(T_h − T_c).
|
|
59
|
+
*
|
|
60
|
+
* Not called an efficiency, and greater than 1 in any working fridge, because
|
|
61
|
+
* what you get out (heat removed from the cold space) is not the same kind of
|
|
62
|
+
* thing as what you put in (work). A COP of 5 moves five joules of heat per
|
|
63
|
+
* joule of electricity, and nothing is being created.
|
|
64
|
+
*/
|
|
65
|
+
declare function refrigeratorCOP(hotK: number, coldK: number): number;
|
|
66
|
+
/**
|
|
67
|
+
* Coefficient of performance of a heat pump, T_h/(T_h − T_c).
|
|
68
|
+
*
|
|
69
|
+
* Exactly one more than the refrigerator's, because the heat delivered to the
|
|
70
|
+
* warm end is the heat taken from the cold end PLUS the work. That is why a
|
|
71
|
+
* heat pump beats a resistive heater: the electricity arrives as heat either
|
|
72
|
+
* way, and the pump also brings the outside in.
|
|
73
|
+
*/
|
|
74
|
+
declare function heatPumpCOP(hotK: number, coldK: number): number;
|
|
75
|
+
/**
|
|
76
|
+
* Otto (petrol engine) efficiency, 1 − r^(1−γ), for a compression ratio r.
|
|
77
|
+
*
|
|
78
|
+
* Says compression ratio is the only thing that matters, which is true of the
|
|
79
|
+
* ideal cycle and is why the real limit is knock rather than thermodynamics.
|
|
80
|
+
*/
|
|
81
|
+
declare function ottoEfficiency(compressionRatio: number, gamma?: number): number;
|
|
82
|
+
/**
|
|
83
|
+
* Diesel efficiency for a compression ratio r and cut-off ratio rc:
|
|
84
|
+
*
|
|
85
|
+
* η = 1 − (1/r^(γ−1)) · (rc^γ − 1) / (γ(rc − 1))
|
|
86
|
+
*
|
|
87
|
+
* Always below an Otto cycle at the SAME compression ratio, which surprises
|
|
88
|
+
* people; the diesel wins in practice because it can use a compression ratio
|
|
89
|
+
* the petrol engine cannot.
|
|
90
|
+
*/
|
|
91
|
+
declare function dieselEfficiency(compressionRatio: number, cutoffRatio: number, gamma?: number): number;
|
|
92
|
+
interface CarnotResult {
|
|
93
|
+
/** The four legs in order: hot isothermal expansion, adiabatic expansion,
|
|
94
|
+
* cold isothermal compression, adiabatic compression back to the start. */
|
|
95
|
+
legs: ProcessResult[];
|
|
96
|
+
Th: number;
|
|
97
|
+
Tc: number;
|
|
98
|
+
/** Heat absorbed from the hot reservoir, J (>0). */
|
|
99
|
+
Qh: number;
|
|
100
|
+
/** Heat rejected to the cold reservoir, J (>0). */
|
|
101
|
+
Qc: number;
|
|
102
|
+
/** Net work done by the engine over the cycle, J ( = Qh − Qc = enclosed p–V area). */
|
|
103
|
+
Wnet: number;
|
|
104
|
+
/** Thermal efficiency = 1 − Tc/Th = Wnet/Qh. */
|
|
105
|
+
efficiency: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* A Carnot cycle starting at `(V1, Th)`: isothermal expansion V1→V2 at Th, then
|
|
109
|
+
* adiabatic expansion to Tc, isothermal compression at Tc, and adiabatic
|
|
110
|
+
* compression back to the start. V3 and V4 are fixed by the closure condition.
|
|
111
|
+
*/
|
|
112
|
+
declare function carnotCycle(n: number, Th: number, Tc: number, V1: number, V2: number, gamma?: number): CarnotResult;
|
|
113
|
+
/**
|
|
114
|
+
* An Otto cycle: adiabatic compression, isochoric heating (the spark),
|
|
115
|
+
* adiabatic expansion (the power stroke), isochoric cooling (the exhaust).
|
|
116
|
+
*
|
|
117
|
+
* `compressionRatio` is V_max/V_min, and `peakTemperatureK` is how hot the
|
|
118
|
+
* burning mixture gets, which is what sets the heat input.
|
|
119
|
+
*/
|
|
120
|
+
declare function ottoCycle(n: number, intakeK: number, peakTemperatureK: number, Vmax: number, compressionRatio: number, gamma?: number): ProcessResult[];
|
|
121
|
+
/**
|
|
122
|
+
* A Stirling cycle: isothermal expansion at Th, isochoric cooling, isothermal
|
|
123
|
+
* compression at Tc, isochoric heating.
|
|
124
|
+
*
|
|
125
|
+
* Reaches Carnot efficiency only with a perfect regenerator, because the heat
|
|
126
|
+
* dumped on the cooling leg is exactly the heat needed on the heating leg. With
|
|
127
|
+
* no regenerator, `cycleSummary` counts that heat as fresh input and the
|
|
128
|
+
* efficiency drops sharply, which is the honest answer and the reason the
|
|
129
|
+
* regenerator was the invention.
|
|
130
|
+
*/
|
|
131
|
+
declare function stirlingCycle(n: number, Th: number, Tc: number, Vmin: number, Vmax: number, gamma?: number): ProcessResult[];
|
|
132
|
+
/**
|
|
133
|
+
* The internal energy an ideal gas holds at a state, J, for reading a cycle's
|
|
134
|
+
* corners off a p–V diagram.
|
|
135
|
+
*
|
|
136
|
+
* Exists so a lab can label the corners of a cycle with U as well as p, V and
|
|
137
|
+
* T, which is what makes "ΔU round the loop is zero" visible rather than
|
|
138
|
+
* asserted.
|
|
139
|
+
*/
|
|
140
|
+
declare function stateInternalEnergyJ(state: GasState, gamma?: number): number;
|
|
141
|
+
//#endregion
|
|
142
|
+
export { CarnotResult, CycleDirection, CycleSummary, carnotCycle, carnotEfficiency, cycleSummary, dieselEfficiency, efficiencyFromHeat, heatPumpCOP, ottoCycle, ottoEfficiency, refrigeratorCOP, stateInternalEnergyJ, stirlingCycle };
|