@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.
Files changed (431) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +18 -0
  2. package/dist/atomic/aufbau.d.mts +144 -0
  3. package/dist/atomic/aufbau.mjs +384 -0
  4. package/dist/atomic/elements.d.mts +67 -0
  5. package/dist/atomic/elements.mjs +785 -0
  6. package/dist/atomic/emission.d.mts +112 -0
  7. package/dist/atomic/emission.mjs +179 -0
  8. package/dist/atomic/index.d.mts +8 -0
  9. package/dist/atomic/index.mjs +9 -0
  10. package/dist/atomic/periodic.d.mts +82 -0
  11. package/dist/atomic/periodic.mjs +231 -0
  12. package/dist/atomic/properties.d.mts +100 -0
  13. package/dist/atomic/properties.mjs +574 -0
  14. package/dist/atomic/shells.d.mts +137 -0
  15. package/dist/atomic/shells.mjs +170 -0
  16. package/dist/atomic/trends.d.mts +148 -0
  17. package/dist/atomic/trends.mjs +225 -0
  18. package/dist/chem/chromatography.d.mts +66 -0
  19. package/dist/chem/chromatography.mjs +63 -0
  20. package/dist/chem/complex.d.mts +114 -0
  21. package/dist/chem/complex.mjs +234 -0
  22. package/dist/chem/cycle.d.mts +75 -0
  23. package/dist/chem/cycle.mjs +145 -0
  24. package/dist/chem/equation.d.mts +86 -0
  25. package/dist/chem/equation.mjs +168 -0
  26. package/dist/chem/formula.d.mts +90 -0
  27. package/dist/chem/formula.mjs +201 -0
  28. package/dist/chem/functional-groups.d.mts +31 -0
  29. package/dist/chem/functional-groups.mjs +187 -0
  30. package/dist/chem/hazard.d.mts +94 -0
  31. package/dist/chem/hazard.mjs +329 -0
  32. package/dist/chem/index.d.mts +34 -33
  33. package/dist/chem/index.mjs +34 -28
  34. package/dist/chem/ionic.d.mts +98 -0
  35. package/dist/chem/ionic.mjs +156 -0
  36. package/dist/chem/layout.d.mts +46 -0
  37. package/dist/chem/layout.mjs +342 -0
  38. package/dist/chem/lewis.d.mts +79 -0
  39. package/dist/chem/lewis.mjs +163 -0
  40. package/dist/chem/molecular-orbital.d.mts +114 -0
  41. package/dist/chem/molecular-orbital.mjs +201 -0
  42. package/dist/chem/molecule.d.mts +154 -0
  43. package/dist/chem/molecule.mjs +282 -0
  44. package/dist/chem/nmr.d.mts +153 -0
  45. package/dist/chem/nmr.mjs +165 -0
  46. package/dist/chem/polymer.d.mts +65 -0
  47. package/dist/chem/polymer.mjs +179 -0
  48. package/dist/chem/redox.d.mts +138 -0
  49. package/dist/chem/redox.mjs +328 -0
  50. package/dist/chem/relations.d.mts +183 -0
  51. package/dist/chem/relations.mjs +299 -0
  52. package/dist/chem/skeleton.d.mts +51 -0
  53. package/dist/chem/skeleton.mjs +186 -0
  54. package/dist/chem/solution.d.mts +116 -0
  55. package/dist/chem/solution.mjs +186 -0
  56. package/dist/chem/species.d.mts +47 -0
  57. package/dist/chem/species.mjs +128 -0
  58. package/dist/chem/stereo.d.mts +108 -0
  59. package/dist/chem/stereo.mjs +286 -0
  60. package/dist/chem/stoichiometry.d.mts +95 -0
  61. package/dist/chem/stoichiometry.mjs +145 -0
  62. package/dist/chem/synthesis.d.mts +113 -0
  63. package/dist/chem/synthesis.mjs +281 -0
  64. package/dist/chem/vsepr.d.mts +80 -0
  65. package/dist/chem/vsepr.mjs +247 -0
  66. package/dist/circuit/ac.d.mts +163 -0
  67. package/dist/circuit/ac.mjs +452 -0
  68. package/dist/circuit/dc.d.mts +92 -0
  69. package/dist/circuit/dc.mjs +333 -0
  70. package/dist/circuit/index.d.mts +5 -92
  71. package/dist/circuit/index.mjs +5 -332
  72. package/dist/circuit/network.d.mts +99 -0
  73. package/dist/circuit/network.mjs +440 -0
  74. package/dist/circuit/topology.d.mts +102 -0
  75. package/dist/circuit/topology.mjs +143 -0
  76. package/dist/colour/absorption.d.mts +79 -0
  77. package/dist/colour/absorption.mjs +137 -0
  78. package/dist/colour/index.d.mts +6 -0
  79. package/dist/colour/index.mjs +7 -0
  80. package/dist/colour/name.d.mts +14 -0
  81. package/dist/colour/name.mjs +76 -0
  82. package/dist/colour/observer.d.mts +31 -0
  83. package/dist/colour/observer.mjs +46 -0
  84. package/dist/colour/spectrum.d.mts +61 -0
  85. package/dist/colour/spectrum.mjs +108 -0
  86. package/dist/colour/srgb.d.mts +49 -0
  87. package/dist/colour/srgb.mjs +108 -0
  88. package/dist/core/constants.d.mts +138 -0
  89. package/dist/core/constants.mjs +139 -0
  90. package/dist/core/index.d.mts +3 -1
  91. package/dist/core/index.mjs +3 -1
  92. package/dist/core/vec3.d.mts +94 -0
  93. package/dist/core/vec3.mjs +123 -0
  94. package/dist/core/worked.d.mts +35 -0
  95. package/dist/core/worked.mjs +44 -0
  96. package/dist/electro/cell.d.mts +102 -0
  97. package/dist/electro/cell.mjs +170 -0
  98. package/dist/electro/conductivity.d.mts +157 -0
  99. package/dist/electro/conductivity.mjs +156 -0
  100. package/dist/electro/couples.d.mts +114 -0
  101. package/dist/electro/couples.mjs +334 -0
  102. package/dist/electro/electrolysis.d.mts +96 -0
  103. package/dist/electro/electrolysis.mjs +274 -0
  104. package/dist/electro/faraday.d.mts +150 -0
  105. package/dist/electro/faraday.mjs +118 -0
  106. package/dist/electro/index.d.mts +6 -0
  107. package/dist/electro/index.mjs +7 -0
  108. package/dist/finance/accounting/adjustments.d.mts +17 -0
  109. package/dist/finance/accounting/adjustments.mjs +202 -0
  110. package/dist/finance/accounting/analysis.d.mts +8 -0
  111. package/dist/finance/accounting/analysis.mjs +205 -0
  112. package/dist/finance/accounting/clubs.d.mts +21 -0
  113. package/dist/finance/accounting/clubs.mjs +217 -0
  114. package/dist/finance/accounting/company-statements.d.mts +7 -0
  115. package/dist/finance/accounting/company-statements.mjs +150 -0
  116. package/dist/finance/accounting/harness.d.mts +7 -0
  117. package/dist/finance/accounting/harness.mjs +45 -0
  118. package/dist/finance/accounting/index.d.mts +18 -0
  119. package/dist/finance/accounting/index.mjs +18 -0
  120. package/dist/finance/accounting/journalize.d.mts +16 -0
  121. package/dist/finance/accounting/journalize.mjs +128 -0
  122. package/dist/finance/accounting/manufacturing.d.mts +8 -0
  123. package/dist/finance/accounting/manufacturing.mjs +236 -0
  124. package/dist/finance/accounting/partnership.d.mts +7 -0
  125. package/dist/finance/accounting/partnership.mjs +152 -0
  126. package/dist/finance/accounting/period-case.d.mts +6 -0
  127. package/dist/finance/accounting/period-case.mjs +71 -0
  128. package/dist/finance/accounting/post.d.mts +9 -0
  129. package/dist/finance/accounting/post.mjs +84 -0
  130. package/dist/finance/accounting/precision.d.mts +9 -0
  131. package/dist/finance/accounting/precision.mjs +15 -0
  132. package/dist/finance/accounting/rules.d.mts +21 -0
  133. package/dist/finance/accounting/rules.mjs +37 -0
  134. package/dist/finance/accounting/solve.d.mts +28 -0
  135. package/dist/finance/accounting/solve.mjs +92 -0
  136. package/dist/finance/accounting/statements.d.mts +7 -0
  137. package/dist/finance/accounting/statements.mjs +142 -0
  138. package/dist/finance/accounting/types.d.mts +649 -0
  139. package/dist/finance/accounting/validate.d.mts +7 -0
  140. package/dist/finance/accounting/validate.mjs +67 -0
  141. package/dist/finance/accounting/verification.d.mts +24 -0
  142. package/dist/finance/accounting/verification.mjs +386 -0
  143. package/dist/finance/bizsim.d.mts +21 -39
  144. package/dist/finance/bizsim.mjs +276 -97
  145. package/dist/finance/index.d.mts +20 -43
  146. package/dist/finance/index.mjs +19 -77
  147. package/dist/finance/investment-math.d.mts +7 -0
  148. package/dist/finance/investment-math.mjs +18 -0
  149. package/dist/finance/management-accounting/budgeting.d.mts +7 -0
  150. package/dist/finance/management-accounting/budgeting.mjs +189 -0
  151. package/dist/finance/management-accounting/cash-budget.d.mts +7 -0
  152. package/dist/finance/management-accounting/cash-budget.mjs +154 -0
  153. package/dist/finance/management-accounting/costing.d.mts +8 -0
  154. package/dist/finance/management-accounting/costing.mjs +175 -0
  155. package/dist/finance/management-accounting/decisions.d.mts +8 -0
  156. package/dist/finance/management-accounting/decisions.mjs +164 -0
  157. package/dist/finance/management-accounting/index.d.mts +13 -0
  158. package/dist/finance/management-accounting/index.mjs +13 -0
  159. package/dist/finance/management-accounting/integrated-budget.d.mts +8 -0
  160. package/dist/finance/management-accounting/integrated-budget.mjs +67 -0
  161. package/dist/finance/management-accounting/inventory-costing.d.mts +7 -0
  162. package/dist/finance/management-accounting/inventory-costing.mjs +173 -0
  163. package/dist/finance/management-accounting/investment-appraisal.d.mts +7 -0
  164. package/dist/finance/management-accounting/investment-appraisal.mjs +148 -0
  165. package/dist/finance/management-accounting/management-case.d.mts +8 -0
  166. package/dist/finance/management-accounting/management-case.mjs +91 -0
  167. package/dist/finance/management-accounting/master-budget.d.mts +7 -0
  168. package/dist/finance/management-accounting/master-budget.mjs +137 -0
  169. package/dist/finance/management-accounting/production-costing.d.mts +8 -0
  170. package/dist/finance/management-accounting/production-costing.mjs +214 -0
  171. package/dist/finance/management-accounting/types.d.mts +644 -0
  172. package/dist/finance/management-accounting/variances.d.mts +7 -0
  173. package/dist/finance/management-accounting/variances.mjs +150 -0
  174. package/dist/index.d.mts +6 -6
  175. package/dist/index.mjs +1 -1
  176. package/dist/math/analysis.d.mts +61 -0
  177. package/dist/math/analysis.mjs +187 -0
  178. package/dist/math/answer-check.d.mts +50 -0
  179. package/dist/math/answer-check.mjs +106 -0
  180. package/dist/math/calculus.d.mts +4 -9
  181. package/dist/math/calculus.mjs +216 -7
  182. package/dist/math/complex.d.mts +93 -0
  183. package/dist/math/complex.mjs +239 -0
  184. package/dist/math/expr.d.mts +23 -0
  185. package/dist/math/expr.mjs +36 -0
  186. package/dist/math/index.d.mts +8 -22
  187. package/dist/math/index.mjs +8 -37
  188. package/dist/math/latex.mjs +2 -1
  189. package/dist/math/parse.mjs +1 -1
  190. package/dist/math/poly.d.mts +55 -0
  191. package/dist/math/poly.mjs +273 -0
  192. package/dist/math/rearrange.d.mts +14 -0
  193. package/dist/math/rearrange.mjs +125 -0
  194. package/dist/math/solve.d.mts +21 -0
  195. package/dist/math/solve.mjs +75 -0
  196. package/dist/networking/addressing.d.mts +26 -0
  197. package/dist/networking/addressing.mjs +33 -0
  198. package/dist/networking/cloud/access.d.mts +36 -0
  199. package/dist/networking/cloud/access.mjs +95 -0
  200. package/dist/networking/cloud/containers.d.mts +43 -0
  201. package/dist/networking/cloud/containers.mjs +54 -0
  202. package/dist/networking/cloud/edge.d.mts +17 -0
  203. package/dist/networking/cloud/edge.mjs +31 -0
  204. package/dist/networking/cloud/failure-domains.d.mts +19 -0
  205. package/dist/networking/cloud/failure-domains.mjs +22 -0
  206. package/dist/networking/cloud/geo-routing.d.mts +22 -0
  207. package/dist/networking/cloud/geo-routing.mjs +64 -0
  208. package/dist/networking/cloud/index.d.mts +18 -0
  209. package/dist/networking/cloud/index.mjs +19 -0
  210. package/dist/networking/cloud/inference-reliability.d.mts +30 -0
  211. package/dist/networking/cloud/inference-reliability.mjs +76 -0
  212. package/dist/networking/cloud/inference.d.mts +118 -0
  213. package/dist/networking/cloud/inference.mjs +179 -0
  214. package/dist/networking/cloud/infrastructure.d.mts +45 -0
  215. package/dist/networking/cloud/infrastructure.mjs +96 -0
  216. package/dist/networking/cloud/observability.d.mts +24 -0
  217. package/dist/networking/cloud/observability.mjs +34 -0
  218. package/dist/networking/cloud/orchestration.d.mts +32 -0
  219. package/dist/networking/cloud/orchestration.mjs +38 -0
  220. package/dist/networking/cloud/recovery.d.mts +21 -0
  221. package/dist/networking/cloud/recovery.mjs +27 -0
  222. package/dist/networking/cloud/releases.d.mts +42 -0
  223. package/dist/networking/cloud/releases.mjs +135 -0
  224. package/dist/networking/cloud/scaling.d.mts +25 -0
  225. package/dist/networking/cloud/scaling.mjs +65 -0
  226. package/dist/networking/cloud/secrets.d.mts +39 -0
  227. package/dist/networking/cloud/secrets.mjs +68 -0
  228. package/dist/networking/cloud/server-deployment.d.mts +29 -0
  229. package/dist/networking/cloud/server-deployment.mjs +72 -0
  230. package/dist/networking/cloud/storage.d.mts +16 -0
  231. package/dist/networking/cloud/storage.mjs +58 -0
  232. package/dist/networking/cloud/vpc.d.mts +18 -0
  233. package/dist/networking/cloud/vpc.mjs +100 -0
  234. package/dist/networking/delivery.d.mts +34 -0
  235. package/dist/networking/delivery.mjs +52 -0
  236. package/dist/networking/index.d.mts +47 -0
  237. package/dist/networking/index.mjs +47 -0
  238. package/dist/networking/ipv6.d.mts +28 -0
  239. package/dist/networking/ipv6.mjs +17 -0
  240. package/dist/networking/journeys.d.mts +83 -0
  241. package/dist/networking/journeys.mjs +161 -0
  242. package/dist/networking/models/airtime.d.mts +87 -0
  243. package/dist/networking/models/airtime.mjs +130 -0
  244. package/dist/networking/models/cellular.d.mts +157 -0
  245. package/dist/networking/models/cellular.mjs +252 -0
  246. package/dist/networking/models/encapsulation.d.mts +98 -0
  247. package/dist/networking/models/encapsulation.mjs +132 -0
  248. package/dist/networking/models/handover.d.mts +116 -0
  249. package/dist/networking/models/handover.mjs +209 -0
  250. package/dist/networking/models/handshake.d.mts +90 -0
  251. package/dist/networking/models/handshake.mjs +122 -0
  252. package/dist/networking/models/index.d.mts +14 -0
  253. package/dist/networking/models/index.mjs +15 -0
  254. package/dist/networking/models/media.d.mts +82 -0
  255. package/dist/networking/models/media.mjs +188 -0
  256. package/dist/networking/models/satellite.d.mts +86 -0
  257. package/dist/networking/models/satellite.mjs +121 -0
  258. package/dist/networking/models/spectrum.d.mts +83 -0
  259. package/dist/networking/models/spectrum.mjs +235 -0
  260. package/dist/networking/models/switch.d.mts +80 -0
  261. package/dist/networking/models/switch.mjs +155 -0
  262. package/dist/networking/models/vlan.d.mts +62 -0
  263. package/dist/networking/models/vlan.mjs +100 -0
  264. package/dist/networking/models/vpn.d.mts +66 -0
  265. package/dist/networking/models/vpn.mjs +125 -0
  266. package/dist/networking/models/wifi-privacy.d.mts +82 -0
  267. package/dist/networking/models/wifi-privacy.mjs +130 -0
  268. package/dist/networking/models/wifi.d.mts +240 -0
  269. package/dist/networking/models/wifi.mjs +562 -0
  270. package/dist/networking/nat-traversal.d.mts +24 -0
  271. package/dist/networking/nat-traversal.mjs +38 -0
  272. package/dist/networking/protocols.d.mts +17 -0
  273. package/dist/networking/protocols.mjs +57 -0
  274. package/dist/networking/queue.d.mts +12 -0
  275. package/dist/networking/queue.mjs +18 -0
  276. package/dist/networking/route-learning.d.mts +23 -0
  277. package/dist/networking/route-learning.mjs +43 -0
  278. package/dist/networking/routing.d.mts +11 -0
  279. package/dist/networking/routing.mjs +25 -0
  280. package/dist/networking/signals.d.mts +26 -0
  281. package/dist/networking/signals.mjs +35 -0
  282. package/dist/networking/subnet.d.mts +49 -0
  283. package/dist/networking/subnet.mjs +89 -0
  284. package/dist/networking/tcp-reliability.d.mts +24 -0
  285. package/dist/networking/tcp-reliability.mjs +38 -0
  286. package/dist/networking/topology/contract.d.mts +123 -0
  287. package/dist/networking/topology/index.d.mts +4 -0
  288. package/dist/networking/topology/index.mjs +4 -0
  289. package/dist/networking/topology/presets.d.mts +7 -0
  290. package/dist/networking/topology/presets.mjs +302 -0
  291. package/dist/networking/topology/simulation.d.mts +8 -0
  292. package/dist/networking/topology/simulation.mjs +179 -0
  293. package/dist/networking/wireless.d.mts +11 -0
  294. package/dist/networking/wireless.mjs +17 -0
  295. package/dist/optics/imaging.d.mts +218 -0
  296. package/dist/optics/imaging.mjs +276 -0
  297. package/dist/optics/index.d.mts +7 -0
  298. package/dist/optics/index.mjs +8 -0
  299. package/dist/optics/laws.d.mts +70 -0
  300. package/dist/optics/laws.mjs +195 -0
  301. package/dist/optics/prism.d.mts +148 -0
  302. package/dist/optics/prism.mjs +197 -0
  303. package/dist/optics/refraction.d.mts +201 -0
  304. package/dist/optics/refraction.mjs +270 -0
  305. package/dist/optics/wave-optics.d.mts +171 -0
  306. package/dist/optics/wave-optics.mjs +259 -0
  307. package/dist/physics/ac/index.d.mts +183 -0
  308. package/dist/physics/ac/index.mjs +203 -0
  309. package/dist/physics/dynamics/forces.d.mts +98 -0
  310. package/dist/physics/dynamics/forces.mjs +153 -0
  311. package/dist/physics/dynamics/friction.d.mts +76 -0
  312. package/dist/physics/dynamics/friction.mjs +119 -0
  313. package/dist/physics/dynamics/system.d.mts +68 -0
  314. package/dist/physics/dynamics/system.mjs +125 -0
  315. package/dist/physics/electrostatics/index.d.mts +169 -0
  316. package/dist/physics/electrostatics/index.mjs +249 -0
  317. package/dist/physics/energy/centre-of-mass.d.mts +115 -0
  318. package/dist/physics/energy/centre-of-mass.mjs +180 -0
  319. package/dist/physics/energy/conservation.d.mts +81 -0
  320. package/dist/physics/energy/conservation.mjs +129 -0
  321. package/dist/physics/energy/power.d.mts +90 -0
  322. package/dist/physics/energy/power.mjs +167 -0
  323. package/dist/physics/energy/spring.d.mts +73 -0
  324. package/dist/physics/energy/spring.mjs +129 -0
  325. package/dist/physics/energy/store.d.mts +63 -0
  326. package/dist/physics/energy/store.mjs +108 -0
  327. package/dist/physics/energy/theorem.d.mts +65 -0
  328. package/dist/physics/energy/theorem.mjs +113 -0
  329. package/dist/physics/energy/work.d.mts +114 -0
  330. package/dist/physics/energy/work.mjs +219 -0
  331. package/dist/physics/gravitation/body.d.mts +85 -0
  332. package/dist/physics/gravitation/body.mjs +168 -0
  333. package/dist/physics/gravitation/kepler.d.mts +127 -0
  334. package/dist/physics/gravitation/kepler.mjs +216 -0
  335. package/dist/physics/gravitation/law.d.mts +117 -0
  336. package/dist/physics/gravitation/law.mjs +175 -0
  337. package/dist/physics/gravitation/orbit.d.mts +119 -0
  338. package/dist/physics/gravitation/orbit.mjs +202 -0
  339. package/dist/physics/gravitation/potential.d.mts +114 -0
  340. package/dist/physics/gravitation/potential.mjs +202 -0
  341. package/dist/physics/gravitation/variation.d.mts +97 -0
  342. package/dist/physics/gravitation/variation.mjs +175 -0
  343. package/dist/physics/index.d.mts +35 -0
  344. package/dist/physics/index.mjs +36 -0
  345. package/dist/physics/integral-sweep.d.mts +63 -0
  346. package/dist/physics/integral-sweep.mjs +126 -0
  347. package/dist/physics/kinematics/equations.d.mts +47 -0
  348. package/dist/physics/kinematics/equations.mjs +126 -0
  349. package/dist/physics/kinematics/free-fall.d.mts +53 -0
  350. package/dist/physics/kinematics/free-fall.mjs +71 -0
  351. package/dist/physics/kinematics/given.d.mts +16 -0
  352. package/dist/physics/kinematics/given.mjs +55 -0
  353. package/dist/physics/kinematics/roots.d.mts +41 -0
  354. package/dist/physics/kinematics/roots.mjs +72 -0
  355. package/dist/physics/kinematics/solve.d.mts +52 -0
  356. package/dist/physics/kinematics/solve.mjs +172 -0
  357. package/dist/physics/magnetism/biot-savart.d.mts +161 -0
  358. package/dist/physics/magnetism/biot-savart.mjs +353 -0
  359. package/dist/physics/magnetism/flux.d.mts +94 -0
  360. package/dist/physics/magnetism/flux.mjs +313 -0
  361. package/dist/physics/magnetism/geomagnetism.d.mts +151 -0
  362. package/dist/physics/magnetism/geomagnetism.mjs +184 -0
  363. package/dist/physics/magnetism/index.d.mts +12 -0
  364. package/dist/physics/magnetism/index.mjs +74 -0
  365. package/dist/physics/magnetism/lorentz.d.mts +28 -0
  366. package/dist/physics/magnetism/lorentz.mjs +88 -0
  367. package/dist/physics/magnetism/magnetic-force.d.mts +102 -0
  368. package/dist/physics/magnetism/magnetic-force.mjs +169 -0
  369. package/dist/physics/momentum/collide.d.mts +77 -0
  370. package/dist/physics/momentum/collide.mjs +115 -0
  371. package/dist/physics/momentum/impulse.d.mts +89 -0
  372. package/dist/physics/momentum/impulse.mjs +159 -0
  373. package/dist/physics/momentum/planar.d.mts +60 -0
  374. package/dist/physics/momentum/planar.mjs +110 -0
  375. package/dist/physics/projectile.d.mts +107 -0
  376. package/dist/physics/projectile.mjs +185 -0
  377. package/dist/physics/rotation/angular.d.mts +85 -0
  378. package/dist/physics/rotation/angular.mjs +130 -0
  379. package/dist/physics/rotation/circular.d.mts +79 -0
  380. package/dist/physics/rotation/circular.mjs +131 -0
  381. package/dist/physics/rotation/inertia.d.mts +164 -0
  382. package/dist/physics/rotation/inertia.mjs +332 -0
  383. package/dist/physics/rotation/torque.d.mts +65 -0
  384. package/dist/physics/rotation/torque.mjs +134 -0
  385. package/dist/physics/vectors.d.mts +64 -0
  386. package/dist/physics/vectors.mjs +114 -0
  387. package/dist/quantity/index.d.mts +119 -0
  388. package/dist/quantity/index.mjs +417 -0
  389. package/dist/relation/derive.d.mts +74 -0
  390. package/dist/relation/derive.mjs +73 -0
  391. package/dist/relation/index.d.mts +56 -0
  392. package/dist/relation/index.mjs +234 -0
  393. package/dist/scene/evaluators.mjs +1 -1
  394. package/dist/sim/thermal.mjs +45 -20
  395. package/dist/thermo/calorimetry.d.mts +207 -0
  396. package/dist/thermo/calorimetry.mjs +345 -0
  397. package/dist/thermo/cycles.d.mts +142 -0
  398. package/dist/thermo/cycles.mjs +256 -0
  399. package/dist/thermo/entropy.d.mts +87 -0
  400. package/dist/thermo/entropy.mjs +140 -0
  401. package/dist/thermo/expansion.d.mts +130 -0
  402. package/dist/thermo/expansion.mjs +178 -0
  403. package/dist/thermo/gas.d.mts +197 -0
  404. package/dist/thermo/gas.mjs +279 -0
  405. package/dist/thermo/heat-transfer.d.mts +164 -0
  406. package/dist/thermo/heat-transfer.mjs +217 -0
  407. package/dist/thermo/index.d.mts +9 -82
  408. package/dist/thermo/index.mjs +9 -132
  409. package/dist/thermo/processes.d.mts +95 -0
  410. package/dist/thermo/processes.mjs +154 -0
  411. package/dist/thermo/temperature.d.mts +174 -0
  412. package/dist/thermo/temperature.mjs +236 -0
  413. package/dist/waves/damping.d.mts +224 -0
  414. package/dist/waves/damping.mjs +317 -0
  415. package/dist/waves/doppler.d.mts +72 -0
  416. package/dist/waves/doppler.mjs +125 -0
  417. package/dist/waves/index.d.mts +10 -0
  418. package/dist/waves/index.mjs +10 -0
  419. package/dist/waves/pendulum.d.mts +130 -0
  420. package/dist/waves/pendulum.mjs +211 -0
  421. package/dist/waves/pitch.d.mts +125 -0
  422. package/dist/waves/pitch.mjs +158 -0
  423. package/dist/waves/shm.d.mts +170 -0
  424. package/dist/waves/shm.mjs +279 -0
  425. package/dist/waves/springs.d.mts +103 -0
  426. package/dist/waves/springs.mjs +176 -0
  427. package/dist/waves/superposition.d.mts +124 -0
  428. package/dist/waves/superposition.mjs +196 -0
  429. package/dist/waves/wave.d.mts +154 -0
  430. package/dist/waves/wave.mjs +178 -0
  431. 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 };