@classytic/stage 0.3.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/dist/_virtual/_rolldown/runtime.mjs +18 -0
- 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/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 +3 -1
- package/dist/core/index.mjs +3 -1
- 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 +21 -39
- package/dist/finance/bizsim.mjs +276 -97
- package/dist/finance/index.d.mts +20 -43
- package/dist/finance/index.mjs +19 -77
- 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 +6 -6
- package/dist/index.mjs +1 -1
- 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 +4 -9
- package/dist/math/calculus.mjs +216 -7
- 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 +8 -22
- package/dist/math/index.mjs +8 -37
- package/dist/math/latex.mjs +2 -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/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/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/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 +74 -2
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { R, gammaMonatomic, molarHeatCapacities } from "./gas.mjs";
|
|
2
|
+
import { runProcess } from "./processes.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/thermo/cycles.ts
|
|
5
|
+
/**
|
|
6
|
+
* Cycles, engines, refrigerators, and the second law.
|
|
7
|
+
*
|
|
8
|
+
* THE MODEL. A cycle is a list of processes that returns the gas to where it
|
|
9
|
+
* started. Because internal energy and entropy are STATE functions, going all
|
|
10
|
+
* the way round must leave both unchanged, and so the net work equals the net
|
|
11
|
+
* heat:
|
|
12
|
+
*
|
|
13
|
+
* ΣΔU = 0 ⟹ W_net = Q_in − Q_out
|
|
14
|
+
* efficiency η = W_net / Q_in = 1 − Q_out/Q_in
|
|
15
|
+
*
|
|
16
|
+
* For a reversible cycle between two reservoirs that becomes Carnot's result,
|
|
17
|
+
* η = 1 − T_c/T_h, which is the second law with a number attached: the only way
|
|
18
|
+
* to reach η = 1 is a cold reservoir at absolute zero.
|
|
19
|
+
*
|
|
20
|
+
* THE GENERAL CASE FIRST. `cycleSummary` takes any list of legs and works out
|
|
21
|
+
* the totals, the direction, and the efficiency or coefficient of performance.
|
|
22
|
+
* The named cycles below are compositions of `runProcess` that feed it. The
|
|
23
|
+
* closed forms are kept as CHECKS on the general machinery rather than as the
|
|
24
|
+
* way answers are produced, which is the same discipline the field integrals
|
|
25
|
+
* follow: a formula that is only ever compared against is a formula that cannot
|
|
26
|
+
* quietly become the source of truth.
|
|
27
|
+
*
|
|
28
|
+
* DIRECTION IS NOT A SETTING. Whether a cycle is an engine or a refrigerator is
|
|
29
|
+
* read off the sign of the net work, not passed in. Traverse the same four legs
|
|
30
|
+
* the other way round and the same code reports a refrigerator, because that is
|
|
31
|
+
* what it has become.
|
|
32
|
+
*
|
|
33
|
+
* UNITS: SI throughout, as `processes.ts`.
|
|
34
|
+
*/
|
|
35
|
+
const positive = (value, what) => {
|
|
36
|
+
if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${what} must be positive.`);
|
|
37
|
+
return value;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Reservoir temperatures, with the ordering checked.
|
|
41
|
+
*
|
|
42
|
+
* A "hot" reservoir colder than the "cold" one is not a sign error to be
|
|
43
|
+
* absorbed silently: it produces an efficiency above 1, which looks like a
|
|
44
|
+
* result rather than like a mistake.
|
|
45
|
+
*/
|
|
46
|
+
const reservoirs = (hotK, coldK) => {
|
|
47
|
+
positive(hotK, "The hot reservoir temperature");
|
|
48
|
+
positive(coldK, "The cold reservoir temperature");
|
|
49
|
+
if (coldK > hotK) throw new RangeError(`The cold reservoir (${coldK} K) is hotter than the hot one (${hotK} K), so these are the wrong way round.`);
|
|
50
|
+
return [hotK, coldK];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Totals, direction and figures of merit for any list of legs.
|
|
54
|
+
*
|
|
55
|
+
* Works on a cycle assembled from `runProcess`, on one built by hand, and on
|
|
56
|
+
* one that does not close, which is why the closure error is reported rather
|
|
57
|
+
* than enforced: a lab that lets a student build a cycle leg by leg needs to
|
|
58
|
+
* show them it has not closed yet, not refuse to draw it.
|
|
59
|
+
*/
|
|
60
|
+
function cycleSummary(legs) {
|
|
61
|
+
if (legs.length === 0) throw new RangeError("A cycle needs at least one leg.");
|
|
62
|
+
const WnetJ = legs.reduce((sum, l) => sum + l.W, 0);
|
|
63
|
+
const QinJ = legs.reduce((sum, l) => sum + Math.max(0, l.Q), 0);
|
|
64
|
+
const QoutJ = legs.reduce((sum, l) => sum - Math.min(0, l.Q), 0);
|
|
65
|
+
const first = legs[0].start;
|
|
66
|
+
const last = legs[legs.length - 1].end;
|
|
67
|
+
const closureError = Math.abs(last.V - first.V) / Math.abs(first.V) + Math.abs(last.P - first.P) / Math.abs(first.P);
|
|
68
|
+
const scale = Math.max(QinJ, QoutJ, 1e-30);
|
|
69
|
+
const direction = WnetJ > 1e-9 * scale ? "engine" : WnetJ < -1e-9 * scale ? "refrigerator" : "neutral";
|
|
70
|
+
return {
|
|
71
|
+
legs: [...legs],
|
|
72
|
+
WnetJ,
|
|
73
|
+
QinJ,
|
|
74
|
+
QoutJ,
|
|
75
|
+
direction,
|
|
76
|
+
efficiency: direction === "engine" && QinJ > 0 ? WnetJ / QinJ : null,
|
|
77
|
+
coefficientOfPerformance: direction === "refrigerator" ? QinJ / Math.abs(WnetJ) : null,
|
|
78
|
+
heatPumpCOP: direction === "refrigerator" ? QoutJ / Math.abs(WnetJ) : null,
|
|
79
|
+
internalEnergyResidualJ: legs.reduce((sum, l) => sum + l.dU, 0),
|
|
80
|
+
entropyResidualJ: legs.reduce((sum, l) => sum + l.dS, 0),
|
|
81
|
+
closureError
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Carnot efficiency, 1 − T_c/T_h.
|
|
86
|
+
*
|
|
87
|
+
* The ceiling on every heat engine working between these two temperatures,
|
|
88
|
+
* whatever its working substance and however it is built. That universality is
|
|
89
|
+
* the content of the second law, and it is why this depends on nothing but the
|
|
90
|
+
* two temperatures.
|
|
91
|
+
*/
|
|
92
|
+
function carnotEfficiency(hotK, coldK) {
|
|
93
|
+
const [Th, Tc] = reservoirs(hotK, coldK);
|
|
94
|
+
return 1 - Tc / Th;
|
|
95
|
+
}
|
|
96
|
+
/** Efficiency from the heats alone, 1 − Q_out/Q_in: the measurable version. */
|
|
97
|
+
function efficiencyFromHeat(QinJ, QoutJ) {
|
|
98
|
+
const qin = positive(QinJ, "The heat absorbed");
|
|
99
|
+
const qout = positive(QoutJ, "The heat rejected");
|
|
100
|
+
if (qout > qin) throw new RangeError("More heat rejected than absorbed, so this engine is producing negative work.");
|
|
101
|
+
return 1 - qout / qin;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Coefficient of performance of a refrigerator, T_c/(T_h − T_c).
|
|
105
|
+
*
|
|
106
|
+
* Not called an efficiency, and greater than 1 in any working fridge, because
|
|
107
|
+
* what you get out (heat removed from the cold space) is not the same kind of
|
|
108
|
+
* thing as what you put in (work). A COP of 5 moves five joules of heat per
|
|
109
|
+
* joule of electricity, and nothing is being created.
|
|
110
|
+
*/
|
|
111
|
+
function refrigeratorCOP(hotK, coldK) {
|
|
112
|
+
const [Th, Tc] = reservoirs(hotK, coldK);
|
|
113
|
+
if (Th === Tc) throw new RangeError("With no temperature difference the coefficient of performance is unbounded.");
|
|
114
|
+
return Tc / (Th - Tc);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Coefficient of performance of a heat pump, T_h/(T_h − T_c).
|
|
118
|
+
*
|
|
119
|
+
* Exactly one more than the refrigerator's, because the heat delivered to the
|
|
120
|
+
* warm end is the heat taken from the cold end PLUS the work. That is why a
|
|
121
|
+
* heat pump beats a resistive heater: the electricity arrives as heat either
|
|
122
|
+
* way, and the pump also brings the outside in.
|
|
123
|
+
*/
|
|
124
|
+
function heatPumpCOP(hotK, coldK) {
|
|
125
|
+
return refrigeratorCOP(hotK, coldK) + 1;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Otto (petrol engine) efficiency, 1 − r^(1−γ), for a compression ratio r.
|
|
129
|
+
*
|
|
130
|
+
* Says compression ratio is the only thing that matters, which is true of the
|
|
131
|
+
* ideal cycle and is why the real limit is knock rather than thermodynamics.
|
|
132
|
+
*/
|
|
133
|
+
function ottoEfficiency(compressionRatio, gamma = 7 / 5) {
|
|
134
|
+
const r = positive(compressionRatio, "The compression ratio");
|
|
135
|
+
if (r <= 1) throw new RangeError("A compression ratio must exceed 1.");
|
|
136
|
+
return 1 - r ** (1 - gamma);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Diesel efficiency for a compression ratio r and cut-off ratio rc:
|
|
140
|
+
*
|
|
141
|
+
* η = 1 − (1/r^(γ−1)) · (rc^γ − 1) / (γ(rc − 1))
|
|
142
|
+
*
|
|
143
|
+
* Always below an Otto cycle at the SAME compression ratio, which surprises
|
|
144
|
+
* people; the diesel wins in practice because it can use a compression ratio
|
|
145
|
+
* the petrol engine cannot.
|
|
146
|
+
*/
|
|
147
|
+
function dieselEfficiency(compressionRatio, cutoffRatio, gamma = 7 / 5) {
|
|
148
|
+
const r = positive(compressionRatio, "The compression ratio");
|
|
149
|
+
const rc = positive(cutoffRatio, "The cut-off ratio");
|
|
150
|
+
if (r <= 1) throw new RangeError("A compression ratio must exceed 1.");
|
|
151
|
+
if (rc <= 1) throw new RangeError("A cut-off ratio must exceed 1.");
|
|
152
|
+
return 1 - 1 / r ** (gamma - 1) * ((rc ** gamma - 1) / (gamma * (rc - 1)));
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* A Carnot cycle starting at `(V1, Th)`: isothermal expansion V1→V2 at Th, then
|
|
156
|
+
* adiabatic expansion to Tc, isothermal compression at Tc, and adiabatic
|
|
157
|
+
* compression back to the start. V3 and V4 are fixed by the closure condition.
|
|
158
|
+
*/
|
|
159
|
+
function carnotCycle(n, Th, Tc, V1, V2, gamma = gammaMonatomic) {
|
|
160
|
+
reservoirs(Th, Tc);
|
|
161
|
+
const ratio = (Th / Tc) ** (1 / (gamma - 1));
|
|
162
|
+
const V3 = V2 * ratio;
|
|
163
|
+
const V4 = V1 * ratio;
|
|
164
|
+
const legHot = runProcess({
|
|
165
|
+
P: n * R * Th / V1,
|
|
166
|
+
V: V1,
|
|
167
|
+
n,
|
|
168
|
+
T: Th
|
|
169
|
+
}, "isothermal", { V: V2 }, gamma);
|
|
170
|
+
const legExp = runProcess(legHot.end, "adiabatic", { V: V3 }, gamma);
|
|
171
|
+
const legCold = runProcess(legExp.end, "isothermal", { V: V4 }, gamma);
|
|
172
|
+
const legComp = runProcess(legCold.end, "adiabatic", { V: V1 }, gamma);
|
|
173
|
+
const Qh = legHot.Q;
|
|
174
|
+
const Qc = -legCold.Q;
|
|
175
|
+
return {
|
|
176
|
+
legs: [
|
|
177
|
+
legHot,
|
|
178
|
+
legExp,
|
|
179
|
+
legCold,
|
|
180
|
+
legComp
|
|
181
|
+
],
|
|
182
|
+
Th,
|
|
183
|
+
Tc,
|
|
184
|
+
Qh,
|
|
185
|
+
Qc,
|
|
186
|
+
Wnet: Qh - Qc,
|
|
187
|
+
efficiency: 1 - Tc / Th
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* An Otto cycle: adiabatic compression, isochoric heating (the spark),
|
|
192
|
+
* adiabatic expansion (the power stroke), isochoric cooling (the exhaust).
|
|
193
|
+
*
|
|
194
|
+
* `compressionRatio` is V_max/V_min, and `peakTemperatureK` is how hot the
|
|
195
|
+
* burning mixture gets, which is what sets the heat input.
|
|
196
|
+
*/
|
|
197
|
+
function ottoCycle(n, intakeK, peakTemperatureK, Vmax, compressionRatio, gamma = 7 / 5) {
|
|
198
|
+
const r = positive(compressionRatio, "The compression ratio");
|
|
199
|
+
if (r <= 1) throw new RangeError("A compression ratio must exceed 1.");
|
|
200
|
+
const Vmin = Vmax / r;
|
|
201
|
+
const compress = runProcess({
|
|
202
|
+
P: n * R * intakeK / Vmax,
|
|
203
|
+
V: Vmax,
|
|
204
|
+
n,
|
|
205
|
+
T: intakeK
|
|
206
|
+
}, "adiabatic", { V: Vmin }, gamma);
|
|
207
|
+
const spark = runProcess(compress.end, "isochoric", { T: peakTemperatureK }, gamma);
|
|
208
|
+
const power = runProcess(spark.end, "adiabatic", { V: Vmax }, gamma);
|
|
209
|
+
return [
|
|
210
|
+
compress,
|
|
211
|
+
spark,
|
|
212
|
+
power,
|
|
213
|
+
runProcess(power.end, "isochoric", { T: intakeK }, gamma)
|
|
214
|
+
];
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* A Stirling cycle: isothermal expansion at Th, isochoric cooling, isothermal
|
|
218
|
+
* compression at Tc, isochoric heating.
|
|
219
|
+
*
|
|
220
|
+
* Reaches Carnot efficiency only with a perfect regenerator, because the heat
|
|
221
|
+
* dumped on the cooling leg is exactly the heat needed on the heating leg. With
|
|
222
|
+
* no regenerator, `cycleSummary` counts that heat as fresh input and the
|
|
223
|
+
* efficiency drops sharply, which is the honest answer and the reason the
|
|
224
|
+
* regenerator was the invention.
|
|
225
|
+
*/
|
|
226
|
+
function stirlingCycle(n, Th, Tc, Vmin, Vmax, gamma = gammaMonatomic) {
|
|
227
|
+
reservoirs(Th, Tc);
|
|
228
|
+
const expand = runProcess({
|
|
229
|
+
P: n * R * Th / Vmin,
|
|
230
|
+
V: Vmin,
|
|
231
|
+
n,
|
|
232
|
+
T: Th
|
|
233
|
+
}, "isothermal", { V: Vmax }, gamma);
|
|
234
|
+
const cool = runProcess(expand.end, "isochoric", { T: Tc }, gamma);
|
|
235
|
+
const compress = runProcess(cool.end, "isothermal", { V: Vmin }, gamma);
|
|
236
|
+
return [
|
|
237
|
+
expand,
|
|
238
|
+
cool,
|
|
239
|
+
compress,
|
|
240
|
+
runProcess(compress.end, "isochoric", { T: Th }, gamma)
|
|
241
|
+
];
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The internal energy an ideal gas holds at a state, J, for reading a cycle's
|
|
245
|
+
* corners off a p–V diagram.
|
|
246
|
+
*
|
|
247
|
+
* Exists so a lab can label the corners of a cycle with U as well as p, V and
|
|
248
|
+
* T, which is what makes "ΔU round the loop is zero" visible rather than
|
|
249
|
+
* asserted.
|
|
250
|
+
*/
|
|
251
|
+
function stateInternalEnergyJ(state, gamma = gammaMonatomic) {
|
|
252
|
+
return state.n * molarHeatCapacities(gamma).cv * state.T;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
//#endregion
|
|
256
|
+
export { carnotCycle, carnotEfficiency, cycleSummary, dieselEfficiency, efficiencyFromHeat, heatPumpCOP, ottoCycle, ottoEfficiency, refrigeratorCOP, stateInternalEnergyJ, stirlingCycle };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { MixtureBody } from "./calorimetry.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/thermo/entropy.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Entropy change on warming or cooling a body, J/K: ΔS = m·c·ln(T₂/T₁).
|
|
6
|
+
*
|
|
7
|
+
* The logarithm is the whole difference from q = m·c·ΔT, and it is there
|
|
8
|
+
* because each joule is divided by the temperature it arrives at, which is
|
|
9
|
+
* rising as it goes. A body warmed through 10 K near absolute zero gains far
|
|
10
|
+
* more entropy than the same body warmed through 10 K on a hot day.
|
|
11
|
+
*/
|
|
12
|
+
declare function entropyChangeWarmingJPerK(massKg: number, specificHeat: number, fromK: number, toK: number): number;
|
|
13
|
+
/** Entropy change on a phase change at constant temperature, J/K: ΔS = m·L/T. */
|
|
14
|
+
declare function entropyChangePhaseJPerK(massKg: number, latentHeat: number, atK: number): number;
|
|
15
|
+
/**
|
|
16
|
+
* Entropy change of a reservoir that gains heat Q at temperature T, J/K.
|
|
17
|
+
*
|
|
18
|
+
* `heatJ` is signed: a reservoir that GIVES heat up loses entropy. A reservoir
|
|
19
|
+
* is by definition large enough that its temperature does not move, which is
|
|
20
|
+
* what makes this a division rather than a logarithm.
|
|
21
|
+
*/
|
|
22
|
+
declare function entropyChangeReservoirJPerK(heatJ: number, atK: number): number;
|
|
23
|
+
/**
|
|
24
|
+
* Entropy change of an ideal gas expanding isothermally, J/K: ΔS = nR·ln(V₂/V₁).
|
|
25
|
+
*
|
|
26
|
+
* The same number whether the expansion was reversible and did work, or was a
|
|
27
|
+
* free expansion into a vacuum and did none. Entropy does not care how it got
|
|
28
|
+
* there; only the surroundings' share differs.
|
|
29
|
+
*/
|
|
30
|
+
declare function entropyChangeIsothermalGasJPerK(moles: number, fromV: number, toV: number): number;
|
|
31
|
+
interface EntropyBalance {
|
|
32
|
+
/** Entropy lost by whatever gave the heat up, J/K (negative). */
|
|
33
|
+
sourceJPerK: number;
|
|
34
|
+
/** Entropy gained by whatever received it, J/K (positive). */
|
|
35
|
+
sinkJPerK: number;
|
|
36
|
+
/** The sum, J/K. Positive for a spontaneous transfer. */
|
|
37
|
+
totalJPerK: number;
|
|
38
|
+
/**
|
|
39
|
+
* True when the total is positive, so the transfer can happen on its own.
|
|
40
|
+
*
|
|
41
|
+
* The second law reduced to a boolean, and it is worth the field: the whole
|
|
42
|
+
* content of Clausius's statement is that this is false for heat running
|
|
43
|
+
* uphill, and a lab can now let a student drag the temperatures around and
|
|
44
|
+
* watch it flip.
|
|
45
|
+
*/
|
|
46
|
+
spontaneous: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The entropy books for a quantity of heat moving between two reservoirs.
|
|
50
|
+
*
|
|
51
|
+
* Both halves and the sum, because the sum is the point: the hot body loses
|
|
52
|
+
* Q/T_h and the cold body gains Q/T_c, and since T_c is the smaller divisor the
|
|
53
|
+
* gain always beats the loss. Heat flowing the other way makes the total
|
|
54
|
+
* negative, which is the second law stated as an arithmetic fact rather than as
|
|
55
|
+
* a prohibition.
|
|
56
|
+
*/
|
|
57
|
+
declare function heatTransferEntropy(heatJ: number, fromK: number, toK: number): EntropyBalance;
|
|
58
|
+
interface MixtureEntropyResult {
|
|
59
|
+
/** The equilibrium temperature the mixture reaches, °C. */
|
|
60
|
+
finalTemperatureC: number;
|
|
61
|
+
/** Each body's entropy change, J/K. */
|
|
62
|
+
bodies: {
|
|
63
|
+
label: string;
|
|
64
|
+
entropyChangeJPerK: number;
|
|
65
|
+
}[];
|
|
66
|
+
/** The total, J/K. Positive for any real mixing. */
|
|
67
|
+
totalJPerK: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The entropy generated by letting bodies at different temperatures reach
|
|
71
|
+
* equilibrium.
|
|
72
|
+
*
|
|
73
|
+
* Built on `mixtureEquilibrium`, so the final temperature is the real one
|
|
74
|
+
* including any partial melting, and each body's contribution is integrated
|
|
75
|
+
* along a reversible path to it. The total is always positive when the bodies
|
|
76
|
+
* started at different temperatures, and zero only when they were already in
|
|
77
|
+
* equilibrium, which is the cleanest numerical demonstration of the second law
|
|
78
|
+
* available at this level: nothing was wasted, no engine was involved, and
|
|
79
|
+
* entropy went up anyway.
|
|
80
|
+
*
|
|
81
|
+
* SCOPE: the per-body integral uses the specific heat of the phase each body
|
|
82
|
+
* ENDS in, so a body that changes phase on the way gets an approximate answer.
|
|
83
|
+
* Phase changes carry their own m·L/T term, which this does not yet split out.
|
|
84
|
+
*/
|
|
85
|
+
declare function mixtureEntropyChange(bodies: readonly MixtureBody[]): MixtureEntropyResult;
|
|
86
|
+
//#endregion
|
|
87
|
+
export { EntropyBalance, MixtureEntropyResult, entropyChangeIsothermalGasJPerK, entropyChangePhaseJPerK, entropyChangeReservoirJPerK, entropyChangeWarmingJPerK, heatTransferEntropy, mixtureEntropyChange };
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { ZERO_CELSIUS_K } from "../core/constants.mjs";
|
|
2
|
+
import { mixtureEquilibrium } from "./calorimetry.mjs";
|
|
3
|
+
import { R } from "./gas.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/thermo/entropy.ts
|
|
6
|
+
/**
|
|
7
|
+
* Entropy, and the second law as an inequality you can evaluate.
|
|
8
|
+
*
|
|
9
|
+
* THE MODEL. Entropy change along a REVERSIBLE path is
|
|
10
|
+
*
|
|
11
|
+
* ΔS = ∫ dQ / T
|
|
12
|
+
*
|
|
13
|
+
* and because S is a state function, that integral can be taken along any
|
|
14
|
+
* reversible path between the same two states even when the real process was
|
|
15
|
+
* nothing like it. That is the move that makes irreversible changes
|
|
16
|
+
* computable: a free expansion does no work and transfers no heat, so ∫dQ/T
|
|
17
|
+
* along what actually happened is zero, yet the entropy rises, and the way to
|
|
18
|
+
* get the right answer is to integrate along a reversible isothermal expansion
|
|
19
|
+
* between the same endpoints instead.
|
|
20
|
+
*
|
|
21
|
+
* The three cases that cover the syllabus:
|
|
22
|
+
*
|
|
23
|
+
* warming a body ΔS = m·c·ln(T₂/T₁) (T varies, so it integrates)
|
|
24
|
+
* changing phase ΔS = m·L / T (T fixed, so it does not)
|
|
25
|
+
* a reservoir ΔS = Q / T (too big to change temperature)
|
|
26
|
+
*
|
|
27
|
+
* WHAT IS WORTH SHOWING. Every function here returns a signed number, and the
|
|
28
|
+
* interesting results are the TOTALS: heat flowing from hot to cold gives a
|
|
29
|
+
* positive total, the reverse gives a negative one, and the second law is
|
|
30
|
+
* exactly the observation that only the first is ever seen. That is a
|
|
31
|
+
* calculation a student can do, not a slogan, which is why the paired functions
|
|
32
|
+
* below report both halves and the sum rather than just the answer.
|
|
33
|
+
*
|
|
34
|
+
* UNITS: SI. Entropy in J/K, temperatures in KELVIN throughout, since these are
|
|
35
|
+
* all ratios or divisions and an offset scale would be meaningless.
|
|
36
|
+
*/
|
|
37
|
+
const positive = (value, what) => {
|
|
38
|
+
if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${what} must be positive.`);
|
|
39
|
+
return value;
|
|
40
|
+
};
|
|
41
|
+
const kelvin = (value, what = "Temperature") => {
|
|
42
|
+
if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${what} must be a positive number of kelvin (got ${value}).`);
|
|
43
|
+
return value;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Entropy change on warming or cooling a body, J/K: ΔS = m·c·ln(T₂/T₁).
|
|
47
|
+
*
|
|
48
|
+
* The logarithm is the whole difference from q = m·c·ΔT, and it is there
|
|
49
|
+
* because each joule is divided by the temperature it arrives at, which is
|
|
50
|
+
* rising as it goes. A body warmed through 10 K near absolute zero gains far
|
|
51
|
+
* more entropy than the same body warmed through 10 K on a hot day.
|
|
52
|
+
*/
|
|
53
|
+
function entropyChangeWarmingJPerK(massKg, specificHeat, fromK, toK) {
|
|
54
|
+
return positive(massKg, "Mass") * positive(specificHeat, "Specific heat capacity") * Math.log(kelvin(toK, "The final temperature") / kelvin(fromK, "The initial temperature"));
|
|
55
|
+
}
|
|
56
|
+
/** Entropy change on a phase change at constant temperature, J/K: ΔS = m·L/T. */
|
|
57
|
+
function entropyChangePhaseJPerK(massKg, latentHeat, atK) {
|
|
58
|
+
return positive(massKg, "Mass") * positive(latentHeat, "Latent heat") / kelvin(atK, "The transition temperature");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Entropy change of a reservoir that gains heat Q at temperature T, J/K.
|
|
62
|
+
*
|
|
63
|
+
* `heatJ` is signed: a reservoir that GIVES heat up loses entropy. A reservoir
|
|
64
|
+
* is by definition large enough that its temperature does not move, which is
|
|
65
|
+
* what makes this a division rather than a logarithm.
|
|
66
|
+
*/
|
|
67
|
+
function entropyChangeReservoirJPerK(heatJ, atK) {
|
|
68
|
+
if (!Number.isFinite(heatJ)) throw new RangeError("Heat must be a finite number.");
|
|
69
|
+
return heatJ / kelvin(atK, "The reservoir temperature");
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Entropy change of an ideal gas expanding isothermally, J/K: ΔS = nR·ln(V₂/V₁).
|
|
73
|
+
*
|
|
74
|
+
* The same number whether the expansion was reversible and did work, or was a
|
|
75
|
+
* free expansion into a vacuum and did none. Entropy does not care how it got
|
|
76
|
+
* there; only the surroundings' share differs.
|
|
77
|
+
*/
|
|
78
|
+
function entropyChangeIsothermalGasJPerK(moles, fromV, toV) {
|
|
79
|
+
return positive(moles, "Amount") * R * Math.log(positive(toV, "The final volume") / positive(fromV, "The initial volume"));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The entropy books for a quantity of heat moving between two reservoirs.
|
|
83
|
+
*
|
|
84
|
+
* Both halves and the sum, because the sum is the point: the hot body loses
|
|
85
|
+
* Q/T_h and the cold body gains Q/T_c, and since T_c is the smaller divisor the
|
|
86
|
+
* gain always beats the loss. Heat flowing the other way makes the total
|
|
87
|
+
* negative, which is the second law stated as an arithmetic fact rather than as
|
|
88
|
+
* a prohibition.
|
|
89
|
+
*/
|
|
90
|
+
function heatTransferEntropy(heatJ, fromK, toK) {
|
|
91
|
+
const Q = positive(heatJ, "The heat transferred");
|
|
92
|
+
const sourceJPerK = -Q / kelvin(fromK, "The source temperature");
|
|
93
|
+
const sinkJPerK = Q / kelvin(toK, "The destination temperature");
|
|
94
|
+
const totalJPerK = sourceJPerK + sinkJPerK;
|
|
95
|
+
return {
|
|
96
|
+
sourceJPerK,
|
|
97
|
+
sinkJPerK,
|
|
98
|
+
totalJPerK,
|
|
99
|
+
spontaneous: totalJPerK > 0
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The entropy generated by letting bodies at different temperatures reach
|
|
104
|
+
* equilibrium.
|
|
105
|
+
*
|
|
106
|
+
* Built on `mixtureEquilibrium`, so the final temperature is the real one
|
|
107
|
+
* including any partial melting, and each body's contribution is integrated
|
|
108
|
+
* along a reversible path to it. The total is always positive when the bodies
|
|
109
|
+
* started at different temperatures, and zero only when they were already in
|
|
110
|
+
* equilibrium, which is the cleanest numerical demonstration of the second law
|
|
111
|
+
* available at this level: nothing was wasted, no engine was involved, and
|
|
112
|
+
* entropy went up anyway.
|
|
113
|
+
*
|
|
114
|
+
* SCOPE: the per-body integral uses the specific heat of the phase each body
|
|
115
|
+
* ENDS in, so a body that changes phase on the way gets an approximate answer.
|
|
116
|
+
* Phase changes carry their own m·L/T term, which this does not yet split out.
|
|
117
|
+
*/
|
|
118
|
+
function mixtureEntropyChange(bodies) {
|
|
119
|
+
const equilibrium = mixtureEquilibrium(bodies);
|
|
120
|
+
const finalK = equilibrium.finalTemperatureC + ZERO_CELSIUS_K;
|
|
121
|
+
const perBody = bodies.map((b, i) => {
|
|
122
|
+
const result = equilibrium.bodies[i];
|
|
123
|
+
const startK = b.temperatureC + ZERO_CELSIUS_K;
|
|
124
|
+
const phase = result.endPhase;
|
|
125
|
+
const c = phase === "solid" ? b.material.cSolid : phase === "liquid" ? b.material.cLiquid : b.material.cGas;
|
|
126
|
+
const entropyChangeJPerK = startK === finalK ? 0 : entropyChangeWarmingJPerK(b.massKg, c, startK, finalK);
|
|
127
|
+
return {
|
|
128
|
+
label: b.label,
|
|
129
|
+
entropyChangeJPerK
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
finalTemperatureC: equilibrium.finalTemperatureC,
|
|
134
|
+
bodies: perBody,
|
|
135
|
+
totalJPerK: perBody.reduce((sum, b) => sum + b.entropyChangeJPerK, 0)
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
140
|
+
export { entropyChangeIsothermalGasJPerK, entropyChangePhaseJPerK, entropyChangeReservoirJPerK, entropyChangeWarmingJPerK, heatTransferEntropy, mixtureEntropyChange };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
//#region src/thermo/expansion.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Thermal expansion: how much bigger things get when they are warmed, and what
|
|
4
|
+
* happens when they are not allowed to.
|
|
5
|
+
*
|
|
6
|
+
* THE MODEL. To first order every dimension grows in proportion to its own
|
|
7
|
+
* length and to the temperature rise:
|
|
8
|
+
*
|
|
9
|
+
* length ΔL = L₀·α·Δθ
|
|
10
|
+
* area ΔA = A₀·β·Δθ with β ≈ 2α
|
|
11
|
+
* volume ΔV = V₀·γ·Δθ with γ ≈ 3α
|
|
12
|
+
*
|
|
13
|
+
* WHY β = 2α AND γ = 3α ARE NOT SEPARATE MEASUREMENTS. A square of side L has
|
|
14
|
+
* area L², and (1+αΔθ)² = 1 + 2αΔθ + (αΔθ)², so the area coefficient is twice
|
|
15
|
+
* the linear one plus a term in α² that is about 10⁻⁸ for a metal over a 100 K
|
|
16
|
+
* rise. The functions below use the EXACT powers rather than the doubled and
|
|
17
|
+
* tripled approximations, and `areaCoefficient` / `volumeCoefficient` return
|
|
18
|
+
* the textbook 2α and 3α, so a lab can show the two agreeing and then show
|
|
19
|
+
* where they part company.
|
|
20
|
+
*
|
|
21
|
+
* THE THING STUDENTS GET WRONG. A hole in a plate gets BIGGER, not smaller.
|
|
22
|
+
* Every function here takes a dimension and scales it, with no notion of
|
|
23
|
+
* "solid" or "hole", precisely because the material does not have one: the
|
|
24
|
+
* plate expands as if the hole were filled with more plate.
|
|
25
|
+
*
|
|
26
|
+
* UNITS: SI. Lengths in m, areas in m², volumes in m³, coefficients per kelvin,
|
|
27
|
+
* temperature changes in K (identical to changes in °C).
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Linear expansivity α, per kelvin, for materials that appear in the standard
|
|
31
|
+
* questions.
|
|
32
|
+
*
|
|
33
|
+
* Invar is in the table because it is the control: an alloy chosen to have
|
|
34
|
+
* almost no expansion, which is what makes the others' numbers mean something.
|
|
35
|
+
* The glass pair matters for the same reason, since the whole point of Pyrex is
|
|
36
|
+
* that a third of the expansion is a third of the thermal shock.
|
|
37
|
+
*/
|
|
38
|
+
declare const LINEAR_EXPANSIVITY: Record<string, number>;
|
|
39
|
+
/** Length after a temperature change: L = L₀(1 + αΔθ). */
|
|
40
|
+
declare function expandedLengthM(length0: number, alpha: number, deltaT: number): number;
|
|
41
|
+
/** The change in length itself, m: ΔL = L₀·α·Δθ. */
|
|
42
|
+
declare function lengthChangeM(length0: number, alpha: number, deltaT: number): number;
|
|
43
|
+
/**
|
|
44
|
+
* Area after a temperature change, using the exact square rather than 2α.
|
|
45
|
+
*
|
|
46
|
+
* A = A₀(1 + αΔθ)², which is where β = 2α comes from and where it stops being
|
|
47
|
+
* quite right.
|
|
48
|
+
*/
|
|
49
|
+
declare function expandedAreaM2(area0: number, alpha: number, deltaT: number): number;
|
|
50
|
+
/** Volume after a temperature change, using the exact cube rather than 3α. */
|
|
51
|
+
declare function expandedVolumeM3(volume0: number, alpha: number, deltaT: number): number;
|
|
52
|
+
/** The area expansivity β = 2α, as the textbook approximation. */
|
|
53
|
+
declare const areaCoefficient: (alpha: number) => number;
|
|
54
|
+
/** The volume expansivity γ = 3α, as the textbook approximation. */
|
|
55
|
+
declare const volumeCoefficient: (alpha: number) => number;
|
|
56
|
+
/**
|
|
57
|
+
* Density after a temperature change, kg/m³: ρ = ρ₀/(1 + γΔθ).
|
|
58
|
+
*
|
|
59
|
+
* The mass does not change and the volume does, so the density falls. This is
|
|
60
|
+
* the engine behind convection: warmed fluid is less dense, so it rises, and
|
|
61
|
+
* the buoyancy that drives every convection current is this division.
|
|
62
|
+
*/
|
|
63
|
+
declare function densityAfterExpansionKgM3(density0: number, volumeExpansivity: number, deltaT: number): number;
|
|
64
|
+
/**
|
|
65
|
+
* The real expansivity of a liquid from the apparent one:
|
|
66
|
+
*
|
|
67
|
+
* γ_real = γ_apparent + γ_container
|
|
68
|
+
*
|
|
69
|
+
* Measuring a liquid's expansion means watching it rise in a vessel that is
|
|
70
|
+
* also expanding, so what you see is the DIFFERENCE. Forgetting the container's
|
|
71
|
+
* share is the standard error in this experiment, and it is systematic rather
|
|
72
|
+
* than random, so no amount of repetition finds it.
|
|
73
|
+
*/
|
|
74
|
+
declare function realExpansivity(apparent: number, containerVolumeExpansivity: number): number;
|
|
75
|
+
/**
|
|
76
|
+
* Thermal stress in a bar held rigidly while its temperature changes, Pa:
|
|
77
|
+
*
|
|
78
|
+
* σ = E·α·Δθ
|
|
79
|
+
*
|
|
80
|
+
* Note what is NOT in it: the length. A rail a kilometre long and a bolt a
|
|
81
|
+
* centimetre long, both clamped, reach the same stress for the same temperature
|
|
82
|
+
* rise, because the strain that would have been αΔθ is the same fraction
|
|
83
|
+
* either way. That is why expansion gaps are about the same size whatever the
|
|
84
|
+
* span, and why a long bridge needs more of them rather than bigger ones.
|
|
85
|
+
*/
|
|
86
|
+
declare function thermalStressPa(youngsModulus: number, alpha: number, deltaT: number): number;
|
|
87
|
+
interface BimetallicBend {
|
|
88
|
+
/** Radius of curvature the strip bends to, m. Infinite when it stays straight. */
|
|
89
|
+
radiusM: number;
|
|
90
|
+
/** Angle subtended by the strip, radians. */
|
|
91
|
+
angleRad: number;
|
|
92
|
+
/** Sideways deflection of the free end of a clamped strip, m. */
|
|
93
|
+
deflectionM: number;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* A bimetallic strip's bend, for two bonded strips of EQUAL thickness and
|
|
97
|
+
* equal Young's modulus:
|
|
98
|
+
*
|
|
99
|
+
* 1/ρ = 3·(α₂ − α₁)·Δθ / (2·t)
|
|
100
|
+
*
|
|
101
|
+
* with t the TOTAL thickness of the pair. The strip bends because the two
|
|
102
|
+
* metals want different lengths and are not allowed to have them, so it curves
|
|
103
|
+
* with the faster-expanding metal on the OUTSIDE of the curve.
|
|
104
|
+
*
|
|
105
|
+
* The sign follows through: a negative Δθ bends it the other way, which is what
|
|
106
|
+
* makes the strip a switch rather than merely a warning light.
|
|
107
|
+
*
|
|
108
|
+
* SCOPE: the equal-thickness, equal-modulus case of Timoshenko's result, which
|
|
109
|
+
* is how these strips are actually made and what every textbook quotes. A pair
|
|
110
|
+
* with different moduli bends less than this predicts.
|
|
111
|
+
*/
|
|
112
|
+
declare function bimetallicBend(totalThicknessM: number, alphaHigh: number, alphaLow: number, deltaT: number, lengthM: number): BimetallicBend;
|
|
113
|
+
/**
|
|
114
|
+
* The density of liquid water, kg/m³, between 0 °C and 100 °C.
|
|
115
|
+
*
|
|
116
|
+
* Water is the exception this whole file otherwise assumes away: its density
|
|
117
|
+
* PEAKS near 4 °C, so between 0 and 4 it contracts on warming and its expansion
|
|
118
|
+
* coefficient is negative. That anomaly is why ice floats, why a lake freezes
|
|
119
|
+
* from the top down, and why fish survive winter, so it is worth having as real
|
|
120
|
+
* data rather than as a note saying water is unusual.
|
|
121
|
+
*
|
|
122
|
+
* Uses the Thiesen-Scheel-Diesselhorst form, which fits measurement to about
|
|
123
|
+
* one part in 10⁵ across the range. A polynomial, not a physical model: it
|
|
124
|
+
* knows the shape of the curve and nothing about why.
|
|
125
|
+
*/
|
|
126
|
+
declare function waterDensityKgM3(celsius: number): number;
|
|
127
|
+
/** The temperature at which water is densest, °C: the anomaly's turning point. */
|
|
128
|
+
declare const WATER_DENSITY_PEAK_C = 3.9863;
|
|
129
|
+
//#endregion
|
|
130
|
+
export { BimetallicBend, LINEAR_EXPANSIVITY, WATER_DENSITY_PEAK_C, areaCoefficient, bimetallicBend, densityAfterExpansionKgM3, expandedAreaM2, expandedLengthM, expandedVolumeM3, lengthChangeM, realExpansivity, thermalStressPa, volumeCoefficient, waterDensityKgM3 };
|