formulab 0.37.1 → 0.39.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 (132) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/dist/automotive/evCharging.d.ts.map +1 -1
  3. package/dist/automotive/evCharging.js +3 -0
  4. package/dist/automotive/evCharging.js.map +1 -1
  5. package/dist/automotive/gearRatio.d.ts.map +1 -1
  6. package/dist/automotive/gearRatio.js +5 -0
  7. package/dist/automotive/gearRatio.js.map +1 -1
  8. package/dist/battery/batteryPackConfig.d.ts.map +1 -1
  9. package/dist/battery/batteryPackConfig.js +12 -0
  10. package/dist/battery/batteryPackConfig.js.map +1 -1
  11. package/dist/battery/bmsBalancing.d.ts.map +1 -1
  12. package/dist/battery/bmsBalancing.js +14 -0
  13. package/dist/battery/bmsBalancing.js.map +1 -1
  14. package/dist/battery/chargingProfile.d.ts.map +1 -1
  15. package/dist/battery/chargingProfile.js +14 -0
  16. package/dist/battery/chargingProfile.js.map +1 -1
  17. package/dist/battery/internalResistance.d.ts.map +1 -1
  18. package/dist/battery/internalResistance.js +3 -0
  19. package/dist/battery/internalResistance.js.map +1 -1
  20. package/dist/battery/selfDischarge.d.ts.map +1 -1
  21. package/dist/battery/selfDischarge.js +6 -0
  22. package/dist/battery/selfDischarge.js.map +1 -1
  23. package/dist/battery/stateOfHealth.d.ts.map +1 -1
  24. package/dist/battery/stateOfHealth.js +6 -0
  25. package/dist/battery/stateOfHealth.js.map +1 -1
  26. package/dist/battery/thermalRunaway.d.ts.map +1 -1
  27. package/dist/battery/thermalRunaway.js +8 -0
  28. package/dist/battery/thermalRunaway.js.map +1 -1
  29. package/dist/chemical/concentration.d.ts.map +1 -1
  30. package/dist/chemical/concentration.js +8 -0
  31. package/dist/chemical/concentration.js.map +1 -1
  32. package/dist/chemical/flowControl.d.ts +1 -0
  33. package/dist/chemical/flowControl.d.ts.map +1 -1
  34. package/dist/chemical/flowControl.js +18 -0
  35. package/dist/chemical/flowControl.js.map +1 -1
  36. package/dist/chemical/injectionCycle.d.ts +1 -0
  37. package/dist/chemical/injectionCycle.d.ts.map +1 -1
  38. package/dist/chemical/injectionCycle.js +8 -1
  39. package/dist/chemical/injectionCycle.js.map +1 -1
  40. package/dist/chemical/reactor.d.ts +1 -0
  41. package/dist/chemical/reactor.d.ts.map +1 -1
  42. package/dist/chemical/reactor.js +9 -0
  43. package/dist/chemical/reactor.js.map +1 -1
  44. package/dist/chemical/reliefValve.d.ts.map +1 -1
  45. package/dist/chemical/reliefValve.js +8 -0
  46. package/dist/chemical/reliefValve.js.map +1 -1
  47. package/dist/chemical/shelfLife.d.ts +1 -0
  48. package/dist/chemical/shelfLife.d.ts.map +1 -1
  49. package/dist/chemical/shelfLife.js +5 -0
  50. package/dist/chemical/shelfLife.js.map +1 -1
  51. package/dist/construction/formwork.d.ts.map +1 -1
  52. package/dist/construction/formwork.js +22 -16
  53. package/dist/construction/formwork.js.map +1 -1
  54. package/dist/energy/insulationRoi.d.ts +2 -2
  55. package/dist/energy/insulationRoi.d.ts.map +1 -1
  56. package/dist/energy/insulationRoi.js +8 -2
  57. package/dist/energy/insulationRoi.js.map +1 -1
  58. package/dist/energy/pfCorrection.d.ts.map +1 -1
  59. package/dist/energy/pfCorrection.js +8 -0
  60. package/dist/energy/pfCorrection.js.map +1 -1
  61. package/dist/energy/vfdSavings.d.ts.map +1 -1
  62. package/dist/energy/vfdSavings.js +15 -0
  63. package/dist/energy/vfdSavings.js.map +1 -1
  64. package/dist/energy/windOutput.d.ts.map +1 -1
  65. package/dist/energy/windOutput.js +8 -0
  66. package/dist/energy/windOutput.js.map +1 -1
  67. package/dist/environmental/esgSummary.d.ts.map +1 -1
  68. package/dist/environmental/esgSummary.js +5 -0
  69. package/dist/environmental/esgSummary.js.map +1 -1
  70. package/dist/logistics/containerFit.d.ts +1 -0
  71. package/dist/logistics/containerFit.d.ts.map +1 -1
  72. package/dist/logistics/containerFit.js +5 -0
  73. package/dist/logistics/containerFit.js.map +1 -1
  74. package/dist/logistics/pallet3d.d.ts +1 -0
  75. package/dist/logistics/pallet3d.d.ts.map +1 -1
  76. package/dist/logistics/pallet3d.js +7 -0
  77. package/dist/logistics/pallet3d.js.map +1 -1
  78. package/dist/logistics/palletStack.d.ts +1 -0
  79. package/dist/logistics/palletStack.d.ts.map +1 -1
  80. package/dist/logistics/palletStack.js +5 -0
  81. package/dist/logistics/palletStack.js.map +1 -1
  82. package/dist/logistics/safetyStock.d.ts +1 -0
  83. package/dist/logistics/safetyStock.d.ts.map +1 -1
  84. package/dist/logistics/safetyStock.js +10 -0
  85. package/dist/logistics/safetyStock.js.map +1 -1
  86. package/dist/machining/boltCircle.d.ts.map +1 -1
  87. package/dist/machining/boltCircle.js +6 -0
  88. package/dist/machining/boltCircle.js.map +1 -1
  89. package/dist/machining/cycleTimeEstimator.d.ts +1 -0
  90. package/dist/machining/cycleTimeEstimator.d.ts.map +1 -1
  91. package/dist/machining/cycleTimeEstimator.js +4 -0
  92. package/dist/machining/cycleTimeEstimator.js.map +1 -1
  93. package/dist/machining/radialChipThinning.d.ts.map +1 -1
  94. package/dist/machining/radialChipThinning.js +9 -0
  95. package/dist/machining/radialChipThinning.js.map +1 -1
  96. package/dist/machining/sineBarHeight.d.ts +1 -0
  97. package/dist/machining/sineBarHeight.d.ts.map +1 -1
  98. package/dist/machining/sineBarHeight.js +10 -0
  99. package/dist/machining/sineBarHeight.js.map +1 -1
  100. package/dist/machining/toolDeflection.d.ts +1 -0
  101. package/dist/machining/toolDeflection.d.ts.map +1 -1
  102. package/dist/machining/toolDeflection.js +3 -0
  103. package/dist/machining/toolDeflection.js.map +1 -1
  104. package/dist/machining/triangleSolver.d.ts.map +1 -1
  105. package/dist/machining/triangleSolver.js +12 -0
  106. package/dist/machining/triangleSolver.js.map +1 -1
  107. package/dist/metal/kFactorReverse.d.ts.map +1 -1
  108. package/dist/metal/kFactorReverse.js +8 -0
  109. package/dist/metal/kFactorReverse.js.map +1 -1
  110. package/dist/metal/pressTonnage.d.ts +3 -1
  111. package/dist/metal/pressTonnage.d.ts.map +1 -1
  112. package/dist/metal/pressTonnage.js +15 -1
  113. package/dist/metal/pressTonnage.js.map +1 -1
  114. package/dist/metal/vibration.d.ts +1 -0
  115. package/dist/metal/vibration.d.ts.map +1 -1
  116. package/dist/metal/vibration.js +13 -0
  117. package/dist/metal/vibration.js.map +1 -1
  118. package/dist/quality/weibull.d.ts +1 -0
  119. package/dist/quality/weibull.d.ts.map +1 -1
  120. package/dist/quality/weibull.js +16 -0
  121. package/dist/quality/weibull.js.map +1 -1
  122. package/dist/safety/illuminance.d.ts.map +1 -1
  123. package/dist/safety/illuminance.js +8 -0
  124. package/dist/safety/illuminance.js.map +1 -1
  125. package/dist/safety/index.d.ts +1 -1
  126. package/dist/safety/index.d.ts.map +1 -1
  127. package/dist/safety/noiseExposure.d.ts.map +1 -1
  128. package/dist/safety/noiseExposure.js +13 -9
  129. package/dist/safety/noiseExposure.js.map +1 -1
  130. package/dist/safety/types.d.ts +8 -0
  131. package/dist/safety/types.d.ts.map +1 -1
  132. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -5,6 +5,80 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.39.0] - 2026-09-15
9
+
10
+ ### Added
11
+
12
+ - **`safety/noiseExposure()`** now returns `contributions` — one entry per input exposure, in
13
+ input order, with its allowable time and its share of the dose. The shares add up to `dose`
14
+ by construction. An exposure below 80 dB is listed with `allowableTime: null` and a share of
15
+ 0, the same rule the dose already applied. Consumers that charted each exposure's share had
16
+ to repeat the OSHA formula to get it, and a repeat that missed the 80 dB cutoff drew bars
17
+ that no longer summed to the reported dose. New type: `NoiseExposureContribution`.
18
+
19
+ ### Fixed
20
+
21
+ - **Seventeen functions returned `NaN` or `Infinity` for degenerate inputs**, against the
22
+ documented "no silent NaN/Infinity" policy. They now throw `RangeError` naming the input,
23
+ only for the inputs that actually produced a non-finite value:
24
+ `flowControl()` (gas: molecularWeight ≤ 0, temperature at or below absolute zero),
25
+ `injectionCycle()` (density ≤ 0, injectionRate ≤ 0), `reactor()` (cylindrical height ≤ 0),
26
+ `shelfLife()` (q10 ≤ 0), `insulationRoi()` (surfaceCoefficient or boilerEfficiency ≤ 0),
27
+ `containerFit()` / `palletStack()` (a cargo or box dimension ≤ 0), `pallet3d()` (box weight ≤ 0),
28
+ `safetyStock()` (avgLeadTime < 0), `cycleTimeEstimator()` (rapid rate ≤ 0),
29
+ `sineBarHeight()` (bar length ≤ 0, or a block increment that rounds the stack past the bar),
30
+ `toolDeflection()` (Young's modulus ≤ 0), `vibration()` (custom E, density or G ≤ 0),
31
+ `pressTonnage()` (thickness ≤ 0, die opening ≤ 0, drawing with punch diameter ≤ 0) and
32
+ `weibull()` (fewer than 2 times, a time ≤ 0, all times identical, missionTime < 0).
33
+ The earlier audit changed only top-level fields; these sat in nested values or in functions
34
+ it had no fixture for. `ERRORS.md` rows for these functions now describe what the source does —
35
+ several claimed throws the code never made (`weibull()` "< 3 data points", `sineBarHeight()`
36
+ "angle out of range"), and three were listed as `safe`.
37
+ - Because inputs that used to return a value now throw, this is a contract change, not a patch.
38
+
39
+ ## [0.38.0] - 2026-09-09
40
+
41
+ ### Fixed
42
+
43
+ - **`construction/formwork()`** — the per-element contact area was rounded to two decimals
44
+ before being multiplied by the element quantity, which made that quantity the amplifier of
45
+ a display artefact. Half a square centimetre per element becomes six square metres over
46
+ twelve hundred of them, and `Math.ceil` then turns the drift into whole sheets of plywood
47
+ that would actually be ordered: a 0.3 x 0.25 x 4.15 m column at a quantity of 1200 reported
48
+ 1843 sheets over 5484 m2 against a true 1841 over 5478. Across a swept grid of plausible
49
+ inputs the sheet count differed in 81 of 1728 cases and the total area in 360. Every derived
50
+ figure now comes from the exact area and rounding happens once, on the way out; the reported
51
+ per-element area is unchanged.
52
+
53
+ - **Twenty-four functions returned `NaN` or `Infinity` in output fields** on degenerate input,
54
+ which `ERRORS.md` explicitly guarantees they will not. An execution-based audit — every
55
+ function called with each of its numeric inputs driven to zero and to minus one, every output
56
+ field checked for finiteness — found 44 such outputs. They now throw `RangeError` in line with
57
+ the documented error policy:
58
+
59
+ `batteryPackConfig`, `bmsBalancing`, `boltCircle`, `chargingProfile`, `concentration`,
60
+ `esgSummary`, `evCharging`, `flowControl`, `gearRatio`, `illuminance`, `internalResistance`,
61
+ `kFactorReverse` (and `kFactorReverseRange` through it), `pfCorrection`, `radialChipThinning`,
62
+ `reactor`, `reliefValve`, `safetyStock`, `selfDischarge`, `stateOfHealth`, `thermalRunaway`,
63
+ `triangleSolver`, `vfdSavings`, `windOutput`.
64
+
65
+ Two shapes recur. A function validated one parameter and not its neighbour — `gearRatio()`
66
+ checked the driving gear's tooth count while a driven gear of zero teeth spun infinitely fast.
67
+ Or nothing was validated at all and a divisor, a square root or a fractional exponent was left
68
+ to produce whatever it produced — `triangleSolver()` given a zero-length side divided by `2bc`
69
+ and returned all three angles as `NaN`, and `safetyStock()` at a service level of 0 or 1 took
70
+ the inverse normal CDF past its own asymptote.
71
+
72
+ Only inputs that actually produced a non-finite output are rejected. Finite results that are
73
+ physically odd are left alone, and existing zero-sentinel contracts are preserved — a formwork
74
+ reactor at `fillRatio: 0` still reports an empty vessel rather than throwing.
75
+
76
+ ### Changed
77
+
78
+ - **`ERRORS.md`** records the 2026-09-09 execution audit and why it found what a source reading
79
+ had cleared, and names `respiratorCalculate()`'s `Infinity` safety margin as an intentional
80
+ sentinel exempt from the no-`Infinity` rule.
81
+
8
82
  ## [0.37.1] - 2026-09-09
9
83
 
10
84
  ### Fixed
@@ -1 +1 @@
1
- {"version":3,"file":"evCharging.d.ts","sourceRoot":"","sources":["../../src/automotive/evCharging.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEhE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAsB/D"}
1
+ {"version":3,"file":"evCharging.d.ts","sourceRoot":"","sources":["../../src/automotive/evCharging.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEhE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CA0B/D"}
@@ -24,6 +24,9 @@ export function evCharging(input) {
24
24
  if (chargerPowerKw <= 0) {
25
25
  throw new RangeError('chargerPowerKw must be greater than 0');
26
26
  }
27
+ if (!(efficiency > 0)) {
28
+ throw new RangeError('efficiency must be greater than 0');
29
+ }
27
30
  const socDiff = (socEndPercent - socStartPercent) / 100;
28
31
  const energyNeeded = batteryCapacityKwh * socDiff;
29
32
  const energyFromGrid = energyNeeded / efficiency;
@@ -1 +1 @@
1
- {"version":3,"file":"evCharging.js","sourceRoot":"","sources":["../../src/automotive/evCharging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,MAAM,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAEjG,IAAI,aAAa,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,IAAI,UAAU,CAAC,oDAAoD,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAAC,uCAAuC,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,aAAa,GAAG,eAAe,CAAC,GAAG,GAAG,CAAC;IACxD,MAAM,YAAY,GAAG,kBAAkB,GAAG,OAAO,CAAC;IAClD,MAAM,cAAc,GAAG,YAAY,GAAG,UAAU,CAAC;IACjD,MAAM,iBAAiB,GAAG,cAAc,GAAG,cAAc,CAAC;IAC1D,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,EAAE,CAAC;IAEnD,OAAO;QACL,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QACtC,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QAC1C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAChD,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;KACrD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"evCharging.js","sourceRoot":"","sources":["../../src/automotive/evCharging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,MAAM,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAEjG,IAAI,aAAa,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,IAAI,UAAU,CAAC,oDAAoD,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAAC,uCAAuC,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,aAAa,GAAG,eAAe,CAAC,GAAG,GAAG,CAAC;IACxD,MAAM,YAAY,GAAG,kBAAkB,GAAG,OAAO,CAAC;IAClD,MAAM,cAAc,GAAG,YAAY,GAAG,UAAU,CAAC;IACjD,MAAM,iBAAiB,GAAG,cAAc,GAAG,cAAc,CAAC;IAC1D,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,EAAE,CAAC;IAEnD,OAAO;QACL,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QACtC,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QAC1C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAChD,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;KACrD,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"gearRatio.d.ts","sourceRoot":"","sources":["../../src/automotive/gearRatio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CAoBhE"}
1
+ {"version":3,"file":"gearRatio.d.ts","sourceRoot":"","sources":["../../src/automotive/gearRatio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CA0BhE"}
@@ -17,6 +17,11 @@ export function gearRatio(input) {
17
17
  if (drivingTeeth <= 0) {
18
18
  throw new RangeError('drivingTeeth must be greater than 0');
19
19
  }
20
+ // The output speed divides by the ratio, so a driven gear with no teeth spins infinitely
21
+ // fast rather than describing a gear pair.
22
+ if (!(drivenTeeth > 0)) {
23
+ throw new RangeError('drivenTeeth must be greater than 0');
24
+ }
20
25
  const ratio = drivenTeeth / drivingTeeth;
21
26
  const outputSpeed = inputSpeed / ratio;
22
27
  const outputTorque = inputTorque * ratio * efficiency;
@@ -1 +1 @@
1
- {"version":3,"file":"gearRatio.js","sourceRoot":"","sources":["../../src/automotive/gearRatio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAEjF,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,UAAU,CAAC,qCAAqC,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,GAAG,YAAY,CAAC;IACzC,MAAM,WAAW,GAAG,UAAU,GAAG,KAAK,CAAC;IACvC,MAAM,YAAY,GAAG,WAAW,GAAG,KAAK,GAAG,UAAU,CAAC;IACtD,MAAM,cAAc,GAAG,KAAK,GAAG,CAAC,CAAC;IACjC,MAAM,mBAAmB,GAAG,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,WAAW,CAAC;IAE/E,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5B,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACpC,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QACtC,cAAc;QACd,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;KACrD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"gearRatio.js","sourceRoot":"","sources":["../../src/automotive/gearRatio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAEjF,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,UAAU,CAAC,qCAAqC,CAAC,CAAC;IAC9D,CAAC;IAED,yFAAyF;IACzF,2CAA2C;IAC3C,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,UAAU,CAAC,oCAAoC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,GAAG,YAAY,CAAC;IACzC,MAAM,WAAW,GAAG,UAAU,GAAG,KAAK,CAAC;IACvC,MAAM,YAAY,GAAG,WAAW,GAAG,KAAK,GAAG,UAAU,CAAC;IACtD,MAAM,cAAc,GAAG,KAAK,GAAG,CAAC,CAAC;IACjC,MAAM,mBAAmB,GAAG,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,WAAW,CAAC;IAE/E,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5B,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACpC,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QACtC,cAAc;QACd,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;KACrD,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"batteryPackConfig.d.ts","sourceRoot":"","sources":["../../src/battery/batteryPackConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAElF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,uBAAuB,CAqBxF"}
1
+ {"version":3,"file":"batteryPackConfig.d.ts","sourceRoot":"","sources":["../../src/battery/batteryPackConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAElF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,uBAAuB,CAkCxF"}
@@ -8,6 +8,18 @@ import { roundTo } from '../utils.js';
8
8
  */
9
9
  export function batteryPackConfig(input) {
10
10
  const { cellVoltage, cellCapacityAh, targetVoltage, targetCapacityAh } = input;
11
+ if (!(cellVoltage > 0)) {
12
+ throw new RangeError('cellVoltage must be greater than 0');
13
+ }
14
+ if (!(cellCapacityAh > 0)) {
15
+ throw new RangeError('cellCapacityAh must be greater than 0');
16
+ }
17
+ if (!(targetVoltage > 0)) {
18
+ throw new RangeError('targetVoltage must be greater than 0');
19
+ }
20
+ if (!(targetCapacityAh > 0)) {
21
+ throw new RangeError('targetCapacityAh must be greater than 0');
22
+ }
11
23
  const seriesCells = Math.ceil(targetVoltage / cellVoltage);
12
24
  const parallelCells = Math.ceil(targetCapacityAh / cellCapacityAh);
13
25
  const totalCells = seriesCells * parallelCells;
@@ -1 +1 @@
1
- {"version":3,"file":"batteryPackConfig.js","sourceRoot":"","sources":["../../src/battery/batteryPackConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC;IAE/E,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,GAAG,cAAc,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;IAE/C,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,gBAAgB,GAAG,OAAO,CAAC,aAAa,GAAG,cAAc,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IACnE,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IAExD,OAAO;QACL,WAAW;QACX,aAAa;QACb,UAAU;QACV,aAAa;QACb,gBAAgB;QAChB,aAAa;QACb,cAAc;KACf,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"batteryPackConfig.js","sourceRoot":"","sources":["../../src/battery/batteryPackConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC;IAE/E,IAAI,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,UAAU,CAAC,oCAAoC,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,uCAAuC,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,UAAU,CAAC,sCAAsC,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,yCAAyC,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,GAAG,cAAc,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;IAE/C,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,gBAAgB,GAAG,OAAO,CAAC,aAAa,GAAG,cAAc,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IACnE,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IAExD,OAAO;QACL,WAAW;QACX,aAAa;QACb,UAAU;QACV,aAAa;QACb,gBAAgB;QAChB,aAAa;QACb,cAAc;KACf,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"bmsBalancing.d.ts","sourceRoot":"","sources":["../../src/battery/bmsBalancing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAExE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,kBAAkB,CA+CzE"}
1
+ {"version":3,"file":"bmsBalancing.d.ts","sourceRoot":"","sources":["../../src/battery/bmsBalancing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAExE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,kBAAkB,CA8DzE"}
@@ -9,6 +9,20 @@ import { roundTo } from '../utils.js';
9
9
  */
10
10
  export function bmsBalancing(input) {
11
11
  const { cellVoltages, balancingCurrentMA, cellCapacityAh } = input;
12
+ if (cellVoltages.length === 0) {
13
+ throw new RangeError('cellVoltages must not be empty');
14
+ }
15
+ // The balancing time divides by the pack average, so a cell at or below zero volts
16
+ // would drive it to infinity rather than describing a pack that can be balanced.
17
+ if (!cellVoltages.every((v) => v > 0)) {
18
+ throw new RangeError('every cell voltage must be greater than 0');
19
+ }
20
+ if (!(balancingCurrentMA > 0)) {
21
+ throw new RangeError('balancingCurrentMA must be greater than 0');
22
+ }
23
+ if (!(cellCapacityAh > 0)) {
24
+ throw new RangeError('cellCapacityAh must be greater than 0');
25
+ }
12
26
  const maxVoltage = Math.max(...cellVoltages);
13
27
  const minVoltage = Math.min(...cellVoltages);
14
28
  const voltageDelta = roundTo(maxVoltage - minVoltage, 4);
@@ -1 +1 @@
1
- {"version":3,"file":"bmsBalancing.js","sourceRoot":"","sources":["../../src/battery/bmsBalancing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAEnE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,OAAO,CAC5B,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,EACjE,CAAC,CACF,CAAC;IAEF,0BAA0B;IAC1B,MAAM,UAAU,GAAG,YAAY,IAAI,IAAI,CAAC;IAExC,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QACtD,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,OAAO,GAAG,cAAc,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK;QACzE,oEAAoE;QACpE,IAAI,gBAAgB,GAAG,CAAC,CAAC;QACzB,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,gEAAgE;YAChE,MAAM,SAAS,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,cAAc,GAAG,cAAc,GAAG,IAAI,CAAC;YACjF,gBAAgB,GAAG,OAAO,CAAC,SAAS,GAAG,kBAAkB,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5B,YAAY;YACZ,gBAAgB;SACjB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,mBAAmB,GAAG,OAAO,CACjC,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,EACrD,CAAC,CACF,CAAC;IACF,MAAM,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAE/D,OAAO;QACL,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAClC,YAAY;QACZ,cAAc;QACd,mBAAmB;QACnB,iBAAiB;QACjB,UAAU;QACV,WAAW;KACZ,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"bmsBalancing.js","sourceRoot":"","sources":["../../src/battery/bmsBalancing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAEnE,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,UAAU,CAAC,gCAAgC,CAAC,CAAC;IACzD,CAAC;IACD,mFAAmF;IACnF,iFAAiF;IACjF,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,UAAU,CAAC,2CAA2C,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,UAAU,CAAC,2CAA2C,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,uCAAuC,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,OAAO,CAC5B,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,EACjE,CAAC,CACF,CAAC;IAEF,0BAA0B;IAC1B,MAAM,UAAU,GAAG,YAAY,IAAI,IAAI,CAAC;IAExC,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QACtD,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,OAAO,GAAG,cAAc,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK;QACzE,oEAAoE;QACpE,IAAI,gBAAgB,GAAG,CAAC,CAAC;QACzB,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,gEAAgE;YAChE,MAAM,SAAS,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,cAAc,GAAG,cAAc,GAAG,IAAI,CAAC;YACjF,gBAAgB,GAAG,OAAO,CAAC,SAAS,GAAG,kBAAkB,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5B,YAAY;YACZ,gBAAgB;SACjB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,mBAAmB,GAAG,OAAO,CACjC,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,EACrD,CAAC,CACF,CAAC;IACF,MAAM,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAE/D,OAAO;QACL,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAClC,YAAY;QACZ,cAAc;QACd,mBAAmB;QACnB,iBAAiB;QACjB,UAAU;QACV,WAAW;KACZ,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"chargingProfile.d.ts","sourceRoot":"","sources":["../../src/battery/chargingProfile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE9E;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,qBAAqB,CAsClF"}
1
+ {"version":3,"file":"chargingProfile.d.ts","sourceRoot":"","sources":["../../src/battery/chargingProfile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE9E;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,qBAAqB,CAqDlF"}
@@ -9,6 +9,20 @@ import { roundTo } from '../utils.js';
9
9
  */
10
10
  export function chargingProfile(input) {
11
11
  const { capacityAh, chargingCurrentA, cutoffCurrentA, ccEndSocPercent = 80, } = input;
12
+ if (!(capacityAh > 0)) {
13
+ throw new RangeError('capacityAh must be greater than 0');
14
+ }
15
+ if (!(chargingCurrentA > 0)) {
16
+ throw new RangeError('chargingCurrentA must be greater than 0');
17
+ }
18
+ // The CV phase averages the charging and cutoff currents; a non-positive cutoff would
19
+ // make that average zero or negative and the phase time infinite.
20
+ if (!(cutoffCurrentA > 0)) {
21
+ throw new RangeError('cutoffCurrentA must be greater than 0');
22
+ }
23
+ if (!(ccEndSocPercent > 0) || ccEndSocPercent >= 100) {
24
+ throw new RangeError('ccEndSocPercent must be greater than 0 and less than 100');
25
+ }
12
26
  // CC phase delivers ccEndSocPercent of capacity
13
27
  const ccPhaseAh = roundTo(capacityAh * (ccEndSocPercent / 100), 2);
14
28
  const cvPhaseAh = roundTo(capacityAh - ccPhaseAh, 2);
@@ -1 +1 @@
1
- {"version":3,"file":"chargingProfile.js","sourceRoot":"","sources":["../../src/battery/chargingProfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,EACJ,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,GAAG,EAAE,GACrB,GAAG,KAAK,CAAC;IAEV,gDAAgD;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC;IAErD,+BAA+B;IAC/B,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAErD,kEAAkE;IAClE,MAAM,YAAY,GAAG,CAAC,gBAAgB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;IAC1D,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAErD,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAEjD,oCAAoC;IACpC,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IAExE,OAAO;QACL,YAAY;QACZ,cAAc;QACd,YAAY;QACZ,cAAc;QACd,UAAU;QACV,YAAY;QACZ,SAAS;QACT,SAAS;QACT,YAAY;KACb,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"chargingProfile.js","sourceRoot":"","sources":["../../src/battery/chargingProfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,EACJ,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,GAAG,EAAE,GACrB,GAAG,KAAK,CAAC;IAEV,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,UAAU,CAAC,mCAAmC,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAAC,yCAAyC,CAAC,CAAC;IAClE,CAAC;IACD,sFAAsF;IACtF,kEAAkE;IAClE,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,uCAAuC,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,IAAI,eAAe,IAAI,GAAG,EAAE,CAAC;QACrD,MAAM,IAAI,UAAU,CAAC,0DAA0D,CAAC,CAAC;IACnF,CAAC;IAED,gDAAgD;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC;IAErD,+BAA+B;IAC/B,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAErD,kEAAkE;IAClE,MAAM,YAAY,GAAG,CAAC,gBAAgB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;IAC1D,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAErD,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAEjD,oCAAoC;IACpC,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IAExE,OAAO;QACL,YAAY;QACZ,cAAc;QACd,YAAY;QACZ,cAAc;QACd,UAAU;QACV,YAAY;QACZ,SAAS;QACT,SAAS;QACT,YAAY;KACb,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"internalResistance.d.ts","sourceRoot":"","sources":["../../src/battery/internalResistance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEpF;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,wBAAwB,CAS3F"}
1
+ {"version":3,"file":"internalResistance.d.ts","sourceRoot":"","sources":["../../src/battery/internalResistance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEpF;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,wBAAwB,CAa3F"}
@@ -9,6 +9,9 @@ import { roundTo } from '../utils.js';
9
9
  */
10
10
  export function internalResistance(input) {
11
11
  const { openCircuitVoltage, loadVoltage, loadCurrentA } = input;
12
+ if (!(loadCurrentA > 0)) {
13
+ throw new RangeError('loadCurrentA must be greater than 0');
14
+ }
12
15
  const voltageDrop = roundTo(openCircuitVoltage - loadVoltage, 4);
13
16
  const resistanceOhm = roundTo(voltageDrop / loadCurrentA, 6);
14
17
  const resistanceMilliOhm = roundTo(resistanceOhm * 1000, 3);
@@ -1 +1 @@
1
- {"version":3,"file":"internalResistance.js","sourceRoot":"","sources":["../../src/battery/internalResistance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA8B;IAC/D,MAAM,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IAEhE,MAAM,WAAW,GAAG,OAAO,CAAC,kBAAkB,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,YAAY,GAAG,aAAa,EAAE,CAAC,CAAC,CAAC;IAE3E,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACxE,CAAC"}
1
+ {"version":3,"file":"internalResistance.js","sourceRoot":"","sources":["../../src/battery/internalResistance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA8B;IAC/D,MAAM,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IAEhE,IAAI,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAAC,qCAAqC,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,kBAAkB,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC;IACjE,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,GAAG,YAAY,GAAG,aAAa,EAAE,CAAC,CAAC,CAAC;IAE3E,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACxE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"selfDischarge.d.ts","sourceRoot":"","sources":["../../src/battery/selfDischarge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CAS5E"}
1
+ {"version":3,"file":"selfDischarge.d.ts","sourceRoot":"","sources":["../../src/battery/selfDischarge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CAgB5E"}
@@ -8,6 +8,12 @@ import { roundTo } from '../utils.js';
8
8
  */
9
9
  export function selfDischarge(input) {
10
10
  const { initialVoltage, finalVoltage, days, nominalVoltage } = input;
11
+ if (!(days > 0)) {
12
+ throw new RangeError('days must be greater than 0');
13
+ }
14
+ if (!(nominalVoltage > 0)) {
15
+ throw new RangeError('nominalVoltage must be greater than 0');
16
+ }
11
17
  const totalVoltageDrop = initialVoltage - finalVoltage;
12
18
  const voltageDropPerDay = roundTo(totalVoltageDrop / days, 6);
13
19
  const dailyRatePercent = roundTo((voltageDropPerDay / nominalVoltage) * 100, 4);
@@ -1 +1 @@
1
- {"version":3,"file":"selfDischarge.js","sourceRoot":"","sources":["../../src/battery/selfDischarge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAErE,MAAM,gBAAgB,GAAG,cAAc,GAAG,YAAY,CAAC;IACvD,MAAM,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,gBAAgB,GAAG,OAAO,CAAC,CAAC,iBAAiB,GAAG,cAAc,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAE7D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"selfDischarge.js","sourceRoot":"","sources":["../../src/battery/selfDischarge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAErE,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,UAAU,CAAC,6BAA6B,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,uCAAuC,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,gBAAgB,GAAG,cAAc,GAAG,YAAY,CAAC;IACvD,MAAM,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,gBAAgB,GAAG,OAAO,CAAC,CAAC,iBAAiB,GAAG,cAAc,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAE7D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;AACrE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stateOfHealth.d.ts","sourceRoot":"","sources":["../../src/battery/stateOfHealth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAa,MAAM,YAAY,CAAC;AAErF;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CAqB5E"}
1
+ {"version":3,"file":"stateOfHealth.d.ts","sourceRoot":"","sources":["../../src/battery/stateOfHealth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAa,MAAM,YAAY,CAAC;AAErF;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CA4B5E"}
@@ -9,6 +9,12 @@ import { roundTo } from '../utils.js';
9
9
  */
10
10
  export function stateOfHealth(input) {
11
11
  const { measuredCapacityAh, ratedCapacityAh } = input;
12
+ if (!(ratedCapacityAh > 0)) {
13
+ throw new RangeError('ratedCapacityAh must be greater than 0');
14
+ }
15
+ if (!(measuredCapacityAh >= 0)) {
16
+ throw new RangeError('measuredCapacityAh must not be negative');
17
+ }
12
18
  const sohPercent = roundTo((measuredCapacityAh / ratedCapacityAh) * 100, 2);
13
19
  const capacityLoss = roundTo(ratedCapacityAh - measuredCapacityAh, 2);
14
20
  const capacityLossPercent = roundTo(100 - sohPercent, 2);
@@ -1 +1 @@
1
- {"version":3,"file":"stateOfHealth.js","sourceRoot":"","sources":["../../src/battery/stateOfHealth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,kBAAkB,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IAEtD,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,kBAAkB,GAAG,eAAe,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IAC5E,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,GAAG,kBAAkB,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;IAEzD,IAAI,MAAiB,CAAC;IACtB,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QACrB,MAAM,GAAG,WAAW,CAAC;IACvB,CAAC;SAAM,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;SAAM,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,GAAG,UAAU,CAAC;IACtB,CAAC;SAAM,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,WAAW,CAAC;IACvB,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"stateOfHealth.js","sourceRoot":"","sources":["../../src/battery/stateOfHealth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,kBAAkB,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IAEtD,IAAI,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,UAAU,CAAC,wCAAwC,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,CAAC,kBAAkB,IAAI,CAAC,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,UAAU,CAAC,yCAAyC,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,kBAAkB,GAAG,eAAe,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IAC5E,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,GAAG,kBAAkB,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;IAEzD,IAAI,MAAiB,CAAC;IACtB,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QACrB,MAAM,GAAG,WAAW,CAAC;IACvB,CAAC;SAAM,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;SAAM,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,GAAG,UAAU,CAAC;IACtB,CAAC;SAAM,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,WAAW,CAAC;IACvB,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC;AACnE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"thermalRunaway.d.ts","sourceRoot":"","sources":["../../src/battery/thermalRunaway.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,CA0B/E"}
1
+ {"version":3,"file":"thermalRunaway.d.ts","sourceRoot":"","sources":["../../src/battery/thermalRunaway.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,CAmC/E"}
@@ -9,6 +9,14 @@ import { roundTo } from '../utils.js';
9
9
  */
10
10
  export function thermalRunaway(input) {
11
11
  const { ambientTempC, currentA, internalResistanceOhm, heatTransferCoeff, surfaceAreaM2, runawayTempC, } = input;
12
+ // The steady-state rise divides the generated heat by hA; a non-positive coefficient
13
+ // or area describes a cell that cannot shed heat at all, which is not a temperature.
14
+ if (!(heatTransferCoeff > 0)) {
15
+ throw new RangeError('heatTransferCoeff must be greater than 0');
16
+ }
17
+ if (!(surfaceAreaM2 > 0)) {
18
+ throw new RangeError('surfaceAreaM2 must be greater than 0');
19
+ }
12
20
  const heatGenerationW = roundTo(currentA * currentA * internalResistanceOhm, 4);
13
21
  const hA = heatTransferCoeff * surfaceAreaM2;
14
22
  const temperatureRiseC = roundTo(heatGenerationW / hA, 2);
@@ -1 +1 @@
1
- {"version":3,"file":"thermalRunaway.js","sourceRoot":"","sources":["../../src/battery/thermalRunaway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAA0B;IACvD,MAAM,EACJ,YAAY,EACZ,QAAQ,EACR,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,YAAY,GACb,GAAG,KAAK,CAAC;IAEV,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,GAAG,QAAQ,GAAG,qBAAqB,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,EAAE,GAAG,iBAAiB,GAAG,aAAa,CAAC;IAC7C,MAAM,gBAAgB,GAAG,OAAO,CAAC,eAAe,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1D,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IACrE,MAAM,gBAAgB,GAAG,OAAO,CAAC,EAAE,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,aAAa,GAAG,CAAC,CAAC;IAEjC,OAAO;QACL,gBAAgB;QAChB,gBAAgB;QAChB,eAAe;QACf,gBAAgB;QAChB,aAAa;QACb,MAAM;KACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"thermalRunaway.js","sourceRoot":"","sources":["../../src/battery/thermalRunaway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAA0B;IACvD,MAAM,EACJ,YAAY,EACZ,QAAQ,EACR,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,YAAY,GACb,GAAG,KAAK,CAAC;IAEV,qFAAqF;IACrF,qFAAqF;IACrF,IAAI,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,UAAU,CAAC,0CAA0C,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,UAAU,CAAC,sCAAsC,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,GAAG,QAAQ,GAAG,qBAAqB,EAAE,CAAC,CAAC,CAAC;IAChF,MAAM,EAAE,GAAG,iBAAiB,GAAG,aAAa,CAAC;IAC7C,MAAM,gBAAgB,GAAG,OAAO,CAAC,eAAe,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1D,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IACrE,MAAM,gBAAgB,GAAG,OAAO,CAAC,EAAE,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,aAAa,GAAG,CAAC,CAAC;IAEjC,OAAO;QACL,gBAAgB;QAChB,gBAAgB;QAChB,eAAe;QACf,gBAAgB;QAChB,aAAa;QACb,MAAM;KACP,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"concentration.d.ts","sourceRoot":"","sources":["../../src/chemical/concentration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CAqC5E"}
1
+ {"version":3,"file":"concentration.d.ts","sourceRoot":"","sources":["../../src/chemical/concentration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE1E;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CA8C5E"}
@@ -12,6 +12,14 @@
12
12
  */
13
13
  export function concentration(input) {
14
14
  const { fromUnit, value, molecularWeight, solutionDensity } = input;
15
+ // Every conversion below divides by one or both of these, so a non-positive value
16
+ // returns an infinite concentration rather than describing a solution.
17
+ if (!(molecularWeight > 0)) {
18
+ throw new RangeError('molecularWeight must be greater than 0');
19
+ }
20
+ if (!(solutionDensity > 0)) {
21
+ throw new RangeError('solutionDensity must be greater than 0');
22
+ }
15
23
  let molPerL;
16
24
  let wtPercent;
17
25
  let ppm;
@@ -1 +1 @@
1
- {"version":3,"file":"concentration.js","sourceRoot":"","sources":["../../src/chemical/concentration.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IAEpE,IAAI,OAAe,CAAC;IACpB,IAAI,SAAiB,CAAC;IACtB,IAAI,GAAW,CAAC;IAEhB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,GAAG,KAAK,CAAC;YAChB,sCAAsC;YACtC,SAAS,GAAG,CAAC,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC;YACjE,oBAAoB;YACpB,GAAG,GAAG,SAAS,GAAG,KAAK,CAAC;YACxB,MAAM;QAER,KAAK,WAAW;YACd,SAAS,GAAG,KAAK,CAAC;YAClB,oBAAoB;YACpB,GAAG,GAAG,SAAS,GAAG,KAAK,CAAC;YACxB,8CAA8C;YAC9C,OAAO,GAAG,CAAC,SAAS,GAAG,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,CAAC;YACzE,MAAM;QAER,KAAK,KAAK;YACR,GAAG,GAAG,KAAK,CAAC;YACZ,oBAAoB;YACpB,SAAS,GAAG,GAAG,GAAG,KAAK,CAAC;YACxB,wCAAwC;YACxC,OAAO,GAAG,CAAC,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;YAC7D,MAAM;QAER;YACE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAChD,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"concentration.js","sourceRoot":"","sources":["../../src/chemical/concentration.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IAEpE,kFAAkF;IAClF,uEAAuE;IACvE,IAAI,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,UAAU,CAAC,wCAAwC,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,UAAU,CAAC,wCAAwC,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,OAAe,CAAC;IACpB,IAAI,SAAiB,CAAC;IACtB,IAAI,GAAW,CAAC;IAEhB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,GAAG,KAAK,CAAC;YAChB,sCAAsC;YACtC,SAAS,GAAG,CAAC,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC;YACjE,oBAAoB;YACpB,GAAG,GAAG,SAAS,GAAG,KAAK,CAAC;YACxB,MAAM;QAER,KAAK,WAAW;YACd,SAAS,GAAG,KAAK,CAAC;YAClB,oBAAoB;YACpB,GAAG,GAAG,SAAS,GAAG,KAAK,CAAC;YACxB,8CAA8C;YAC9C,OAAO,GAAG,CAAC,SAAS,GAAG,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,CAAC;YACzE,MAAM;QAER,KAAK,KAAK;YACR,GAAG,GAAG,KAAK,CAAC;YACZ,oBAAoB;YACpB,SAAS,GAAG,GAAG,GAAG,KAAK,CAAC;YACxB,wCAAwC;YACxC,OAAO,GAAG,CAAC,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;YAC7D,MAAM;QAER;YACE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAChD,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AACrC,CAAC"}
@@ -9,6 +9,7 @@ import type { FlowControlInput, FlowControlResult } from './types.js';
9
9
  *
10
10
  * @reference ISA-75.01.01-2012 — Flow equations for sizing control valves
11
11
  * @reference IEC 60534-2-1 — Industrial-process control valves
12
+ * @throws RangeError if inletPressure or fluidDensity is not greater than 0; for gas/steam, if molecularWeight is given and not greater than 0, or temperature is not above -273.15 °C
12
13
  */
13
14
  export declare function flowControl(input: FlowControlInput): FlowControlResult;
14
15
  //# sourceMappingURL=flowControl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"flowControl.d.ts","sourceRoot":"","sources":["../../src/chemical/flowControl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAkEtE"}
1
+ {"version":3,"file":"flowControl.d.ts","sourceRoot":"","sources":["../../src/chemical/flowControl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEtE;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAoFtE"}
@@ -9,9 +9,27 @@ import { roundTo } from '../utils.js';
9
9
  *
10
10
  * @reference ISA-75.01.01-2012 — Flow equations for sizing control valves
11
11
  * @reference IEC 60534-2-1 — Industrial-process control valves
12
+ * @throws RangeError if inletPressure or fluidDensity is not greater than 0; for gas/steam, if molecularWeight is given and not greater than 0, or temperature is not above -273.15 °C
12
13
  */
13
14
  export function flowControl(input) {
14
15
  const { flowRate, inletPressure, outletPressure, fluidDensity, fluidType, temperature = 20, molecularWeight, specificHeatRatio = 1.4, } = input;
16
+ // The pressure ratio divides by the inlet pressure and the sizing coefficient takes the
17
+ // square root of the specific gravity, so neither may be zero or negative.
18
+ if (!(inletPressure > 0)) {
19
+ throw new RangeError('inletPressure must be greater than 0');
20
+ }
21
+ if (!(fluidDensity > 0)) {
22
+ throw new RangeError('fluidDensity must be greater than 0');
23
+ }
24
+ // Gas sizing takes the square root of MW × absolute temperature.
25
+ if (fluidType !== 'liquid') {
26
+ if (molecularWeight !== undefined && !(molecularWeight > 0)) {
27
+ throw new RangeError('molecularWeight must be greater than 0');
28
+ }
29
+ if (!(temperature > -273.15)) {
30
+ throw new RangeError('temperature must be above absolute zero (-273.15 °C)');
31
+ }
32
+ }
15
33
  const pressureDrop = inletPressure - outletPressure; // kPa
16
34
  // Reference density: water = 999 kg/m³
17
35
  const sg = fluidDensity / 999;
@@ -1 +1 @@
1
- {"version":3,"file":"flowControl.js","sourceRoot":"","sources":["../../src/chemical/flowControl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flowControl.js","sourceRoot":"","sources":["../../src/chemical/flowControl.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ import type { InjectionCycleInput, InjectionCycleResult } from './types.js';
14
14
  *
15
15
  * @param input - Injection cycle input with resin type and dimensions
16
16
  * @returns Cycle time breakdown and total
17
+ * @throws RangeError if the resin density is not greater than 0, or injectionRate is given and not greater than 0
17
18
  */
18
19
  export declare function injectionCycle(input: InjectionCycleInput): InjectionCycleResult;
19
20
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"injectionCycle.d.ts","sourceRoot":"","sources":["../../src/chemical/injectionCycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAkC,MAAM,YAAY,CAAC;AA8E5G;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,CAqG/E;AAED;;GAEG"}
1
+ {"version":3,"file":"injectionCycle.d.ts","sourceRoot":"","sources":["../../src/chemical/injectionCycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAkC,MAAM,YAAY,CAAC;AA8E5G;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,oBAAoB,CA2G/E;AAED;;GAEG"}
@@ -72,6 +72,7 @@ const RESIN_PROPERTIES = {
72
72
  *
73
73
  * @param input - Injection cycle input with resin type and dimensions
74
74
  * @returns Cycle time breakdown and total
75
+ * @throws RangeError if the resin density is not greater than 0, or injectionRate is given and not greater than 0
75
76
  */
76
77
  export function injectionCycle(input) {
77
78
  const { resin, wallThickness, shotWeight, injectionRate, moldOpenCloseTime = 3, ejectionTime = 0.5, } = input;
@@ -110,7 +111,13 @@ export function injectionCycle(input) {
110
111
  }
111
112
  }
112
113
  // Calculate fill time
113
- // Volume = shot weight / density (g / (g/cm^3) = cm^3)
114
+ // Volume = shot weight / density (g / (g/cm^3) = cm^3); fill time then divides by the rate.
115
+ if (!(props.density > 0)) {
116
+ throw new RangeError('density must be greater than 0');
117
+ }
118
+ if (injectionRate !== undefined && !(injectionRate > 0)) {
119
+ throw new RangeError('injectionRate must be greater than 0');
120
+ }
114
121
  const volume = shotWeight / props.density;
115
122
  // Default injection rate: estimate based on typical machine (~50-150 cm^3/s)
116
123
  const effectiveInjectionRate = injectionRate ?? 80;
@@ -1 +1 @@
1
- {"version":3,"file":"injectionCycle.js","sourceRoot":"","sources":["../../src/chemical/injectionCycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"injectionCycle.js","sourceRoot":"","sources":["../../src/chemical/injectionCycle.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ import type { ReactorInput, ReactorResult } from './types.js';
14
14
  *
15
15
  * @param input - Reactor dimensions and fill ratio
16
16
  * @returns Reactor volumes and surface area
17
+ * @throws RangeError if diameter is not greater than 0, or a cylindrical height is not greater than 0
17
18
  */
18
19
  export declare function reactor(input: ReactorInput): ReactorResult;
19
20
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"reactor.d.ts","sourceRoot":"","sources":["../../src/chemical/reactor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG9D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAmC1D;AAED;;GAEG"}
1
+ {"version":3,"file":"reactor.d.ts","sourceRoot":"","sources":["../../src/chemical/reactor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG9D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CA2C1D;AAED;;GAEG"}
@@ -14,15 +14,24 @@ import { roundTo } from '../utils.js';
14
14
  *
15
15
  * @param input - Reactor dimensions and fill ratio
16
16
  * @returns Reactor volumes and surface area
17
+ * @throws RangeError if diameter is not greater than 0, or a cylindrical height is not greater than 0
17
18
  */
18
19
  export function reactor(input) {
19
20
  const { shape, diameter, fillRatio } = input;
21
+ // A zero diameter gives zero volume over zero surface area, which is not a ratio.
22
+ if (!(diameter > 0)) {
23
+ throw new RangeError('diameter must be greater than 0');
24
+ }
20
25
  const radius = diameter / 2;
21
26
  let totalVolume;
22
27
  let surfaceArea;
23
28
  if (shape === 'cylindrical') {
24
29
  // Cylindrical reactor
25
30
  const h = input.height;
31
+ // A negative height can cancel the end caps and leave zero surface area to divide by.
32
+ if (!(h > 0)) {
33
+ throw new RangeError('height must be greater than 0');
34
+ }
26
35
  // V = PI * r^2 * h
27
36
  totalVolume = Math.PI * radius * radius * h;
28
37
  // Surface Area = 2 * PI * r^2 (ends) + 2 * PI * r * h (lateral)
@@ -1 +1 @@
1
- {"version":3,"file":"reactor.js","sourceRoot":"","sources":["../../src/chemical/reactor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,OAAO,CAAC,KAAmB;IACzC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAE7C,MAAM,MAAM,GAAG,QAAQ,GAAG,CAAC,CAAC;IAC5B,IAAI,WAAmB,CAAC;IACxB,IAAI,WAAmB,CAAC;IAExB,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;QAC5B,sBAAsB;QACtB,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;QACvB,mBAAmB;QACnB,WAAW,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC;QAC5C,gEAAgE;QAChE,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC;IACzE,CAAC;SAAM,CAAC;QACN,oBAAoB;QACpB,uBAAuB;QACvB,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;QAC3D,8BAA8B;QAC9B,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9C,CAAC;IAED,MAAM,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;IAC9C,MAAM,iBAAiB,GAAG,WAAW,GAAG,IAAI,CAAC,CAAC,gBAAgB;IAC9D,MAAM,mBAAmB,GAAG,aAAa,GAAG,IAAI,CAAC;IACjD,MAAM,oBAAoB,GAAG,WAAW,GAAG,WAAW,CAAC;IAEvD,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACpC,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QACxC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAChD,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACpD,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACpC,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;KACvD,CAAC;AACJ,CAAC;AAED;;GAEG"}
1
+ {"version":3,"file":"reactor.js","sourceRoot":"","sources":["../../src/chemical/reactor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,OAAO,CAAC,KAAmB;IACzC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAE7C,kFAAkF;IAClF,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,UAAU,CAAC,iCAAiC,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,GAAG,CAAC,CAAC;IAC5B,IAAI,WAAmB,CAAC;IACxB,IAAI,WAAmB,CAAC;IAExB,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;QAC5B,sBAAsB;QACtB,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;QACvB,sFAAsF;QACtF,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACb,MAAM,IAAI,UAAU,CAAC,+BAA+B,CAAC,CAAC;QACxD,CAAC;QACD,mBAAmB;QACnB,WAAW,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC;QAC5C,gEAAgE;QAChE,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC;IACzE,CAAC;SAAM,CAAC;QACN,oBAAoB;QACpB,uBAAuB;QACvB,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;QAC3D,8BAA8B;QAC9B,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9C,CAAC;IAED,MAAM,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;IAC9C,MAAM,iBAAiB,GAAG,WAAW,GAAG,IAAI,CAAC,CAAC,gBAAgB;IAC9D,MAAM,mBAAmB,GAAG,aAAa,GAAG,IAAI,CAAC;IACjD,MAAM,oBAAoB,GAAG,WAAW,GAAG,WAAW,CAAC;IAEvD,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACpC,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QACxC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAChD,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACpD,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACpC,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;KACvD,CAAC;AACJ,CAAC;AAED;;GAEG"}
@@ -1 +1 @@
1
- {"version":3,"file":"reliefValve.d.ts","sourceRoot":"","sources":["../../src/chemical/reliefValve.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAoBtE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CA+FtE"}
1
+ {"version":3,"file":"reliefValve.d.ts","sourceRoot":"","sources":["../../src/chemical/reliefValve.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAoBtE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAwGtE"}
@@ -37,6 +37,14 @@ const API_ORIFICES = [
37
37
  */
38
38
  export function reliefValve(input) {
39
39
  const { requiredCapacity, setPressure, backPressure, temperature, fluidType, molecularWeight = 29, specificGravity = 1.0, overpressure = 10, dischargeCoefficient, } = input;
40
+ // The gas/steam sizing equation divides by sqrt(M) after taking its square root, so a
41
+ // non-positive molecular weight gives an infinite or imaginary orifice area.
42
+ if (!(molecularWeight > 0)) {
43
+ throw new RangeError('molecularWeight must be greater than 0');
44
+ }
45
+ if (!(specificGravity > 0)) {
46
+ throw new RangeError('specificGravity must be greater than 0');
47
+ }
40
48
  // Atmospheric pressure
41
49
  const patm = 101.325; // kPa
42
50
  const P1 = setPressure + patm + (setPressure * overpressure / 100); // kPa absolute (relieving)
@@ -1 +1 @@
1
- {"version":3,"file":"reliefValve.js","sourceRoot":"","sources":["../../src/chemical/reliefValve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reliefValve.js","sourceRoot":"","sources":["../../src/chemical/reliefValve.ts"],"names":[],"mappings":"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"}