@driftengine/chemistry 3.61.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 (142) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +9 -0
  3. package/README.md +194 -0
  4. package/dist/conservation.d.ts +9 -0
  5. package/dist/conservation.js +38 -0
  6. package/dist/element/elements.d.ts +31 -0
  7. package/dist/element/elements.js +73 -0
  8. package/dist/element/matrix.d.ts +27 -0
  9. package/dist/element/matrix.js +80 -0
  10. package/dist/field/ambient.d.ts +49 -0
  11. package/dist/field/ambient.js +82 -0
  12. package/dist/field/atmosphere.d.ts +308 -0
  13. package/dist/field/atmosphere.js +1033 -0
  14. package/dist/ignition/criteria.d.ts +97 -0
  15. package/dist/ignition/criteria.js +135 -0
  16. package/dist/ignition/events.d.ts +56 -0
  17. package/dist/ignition/events.js +90 -0
  18. package/dist/index.d.ts +84 -0
  19. package/dist/index.js +66 -0
  20. package/dist/library/biological.d.ts +6 -0
  21. package/dist/library/biological.js +229 -0
  22. package/dist/library/common.d.ts +26 -0
  23. package/dist/library/common.js +208 -0
  24. package/dist/library/food.d.ts +9 -0
  25. package/dist/library/food.js +272 -0
  26. package/dist/library/fuel.d.ts +19 -0
  27. package/dist/library/fuel.js +290 -0
  28. package/dist/library/library.d.ts +45 -0
  29. package/dist/library/library.js +29 -0
  30. package/dist/library/metal.d.ts +6 -0
  31. package/dist/library/metal.js +181 -0
  32. package/dist/library/mineral.d.ts +4 -0
  33. package/dist/library/mineral.js +177 -0
  34. package/dist/library/organic.d.ts +12 -0
  35. package/dist/library/organic.js +489 -0
  36. package/dist/library/polymer.d.ts +4 -0
  37. package/dist/library/polymer.js +237 -0
  38. package/dist/parcel/conduction.d.ts +20 -0
  39. package/dist/parcel/conduction.js +160 -0
  40. package/dist/parcel/shells.d.ts +49 -0
  41. package/dist/parcel/shells.js +73 -0
  42. package/dist/parcel/store.d.ts +395 -0
  43. package/dist/parcel/store.js +1152 -0
  44. package/dist/parcel/tier.d.ts +48 -0
  45. package/dist/parcel/tier.js +51 -0
  46. package/dist/present/audio.d.ts +41 -0
  47. package/dist/present/audio.js +50 -0
  48. package/dist/present/blackbody.d.ts +55 -0
  49. package/dist/present/blackbody.js +112 -0
  50. package/dist/present/flame.d.ts +34 -0
  51. package/dist/present/flame.js +103 -0
  52. package/dist/present/index.d.ts +25 -0
  53. package/dist/present/index.js +22 -0
  54. package/dist/present/install.d.ts +87 -0
  55. package/dist/present/install.js +157 -0
  56. package/dist/present/smoke.d.ts +63 -0
  57. package/dist/present/smoke.js +85 -0
  58. package/dist/present/surface.d.ts +40 -0
  59. package/dist/present/surface.js +76 -0
  60. package/dist/reaction/localise.d.ts +16 -0
  61. package/dist/reaction/localise.js +95 -0
  62. package/dist/reaction/rates.d.ts +59 -0
  63. package/dist/reaction/rates.js +101 -0
  64. package/dist/reaction/reaction.d.ts +178 -0
  65. package/dist/reaction/reaction.js +104 -0
  66. package/dist/reaction/registry.d.ts +47 -0
  67. package/dist/reaction/registry.js +215 -0
  68. package/dist/reaction/solver.d.ts +51 -0
  69. package/dist/reaction/solver.js +277 -0
  70. package/dist/species/registry.d.ts +26 -0
  71. package/dist/species/registry.js +97 -0
  72. package/dist/species/species.d.ts +48 -0
  73. package/dist/species/species.js +20 -0
  74. package/dist/species/standard.d.ts +30 -0
  75. package/dist/species/standard.js +436 -0
  76. package/dist/species/thermal.d.ts +18 -0
  77. package/dist/species/thermal.js +72 -0
  78. package/dist/substance/boiling.d.ts +29 -0
  79. package/dist/substance/boiling.js +54 -0
  80. package/dist/substance/composition.d.ts +34 -0
  81. package/dist/substance/composition.js +53 -0
  82. package/dist/substance/registry.d.ts +86 -0
  83. package/dist/substance/registry.js +187 -0
  84. package/dist/substance/substance.d.ts +94 -0
  85. package/dist/substance/substance.js +48 -0
  86. package/dist/testing/drift.d.ts +15 -0
  87. package/dist/testing/drift.js +29 -0
  88. package/dist/transport/contacts.d.ts +22 -0
  89. package/dist/transport/contacts.js +50 -0
  90. package/dist/transport/radiation.d.ts +101 -0
  91. package/dist/transport/radiation.js +199 -0
  92. package/dist/transport/world.d.ts +92 -0
  93. package/dist/transport/world.js +381 -0
  94. package/dist/world/fingerprint.d.ts +31 -0
  95. package/dist/world/fingerprint.js +70 -0
  96. package/package.json +100 -0
  97. package/src/conservation.ts +44 -0
  98. package/src/element/elements.ts +80 -0
  99. package/src/element/matrix.ts +89 -0
  100. package/src/field/ambient.ts +111 -0
  101. package/src/field/atmosphere.ts +1159 -0
  102. package/src/ignition/criteria.ts +177 -0
  103. package/src/ignition/events.ts +100 -0
  104. package/src/index.ts +213 -0
  105. package/src/library/biological.ts +252 -0
  106. package/src/library/common.ts +224 -0
  107. package/src/library/food.ts +302 -0
  108. package/src/library/fuel.ts +299 -0
  109. package/src/library/library.ts +62 -0
  110. package/src/library/metal.ts +186 -0
  111. package/src/library/mineral.ts +194 -0
  112. package/src/library/organic.ts +545 -0
  113. package/src/library/polymer.ts +243 -0
  114. package/src/parcel/conduction.ts +188 -0
  115. package/src/parcel/shells.ts +100 -0
  116. package/src/parcel/store.ts +1270 -0
  117. package/src/parcel/tier.ts +60 -0
  118. package/src/present/audio.ts +54 -0
  119. package/src/present/blackbody.ts +118 -0
  120. package/src/present/flame.ts +111 -0
  121. package/src/present/index.ts +25 -0
  122. package/src/present/install.ts +209 -0
  123. package/src/present/smoke.ts +139 -0
  124. package/src/present/surface.ts +107 -0
  125. package/src/reaction/localise.ts +126 -0
  126. package/src/reaction/rates.ts +153 -0
  127. package/src/reaction/reaction.ts +235 -0
  128. package/src/reaction/registry.ts +257 -0
  129. package/src/reaction/solver.ts +326 -0
  130. package/src/species/registry.ts +117 -0
  131. package/src/species/species.ts +53 -0
  132. package/src/species/standard.ts +449 -0
  133. package/src/species/thermal.ts +74 -0
  134. package/src/substance/boiling.ts +64 -0
  135. package/src/substance/composition.ts +81 -0
  136. package/src/substance/registry.ts +223 -0
  137. package/src/substance/substance.ts +148 -0
  138. package/src/testing/drift.ts +28 -0
  139. package/src/transport/contacts.ts +56 -0
  140. package/src/transport/radiation.ts +238 -0
  141. package/src/transport/world.ts +437 -0
  142. package/src/world/fingerprint.ts +106 -0
@@ -0,0 +1,186 @@
1
+ /**
2
+ * `@driftengine/chemistry/library/metal` — five metals, and the one number that decides most of it.
3
+ *
4
+ * **It is the emissivity, not the conductivity.** Polished copper's is 0.05 against oak's 0.90, and
5
+ * a radiative term is linear in it, so eighteen times less of the same fire arrives at the same
6
+ * distance. That is why a metal poker's handle stays cool beside a fire that chars a wooden one, and
7
+ * it is one field.
8
+ *
9
+ * **Three published heats of combustion fall out and none is stored**: magnesium 24.7 MJ/kg,
10
+ * aluminium 31.0, iron 7.4. What the table holds is the formation enthalpy of each oxide.
11
+ */
12
+ import { KIND_CORROSION, type Reaction } from '../reaction/reaction.ts';
13
+ import { SHAPE_CYLINDER, SHAPE_SLAB } from '../parcel/shells.ts';
14
+ import { massFractions } from '../substance/composition.ts';
15
+ import type { SubstanceThermal } from '../substance/substance.ts';
16
+ import type { SubstanceLibrary } from './library.ts';
17
+ import { COMMON_REACTIONS } from './common.ts';
18
+
19
+ export const RUST_IRON = 'rust-iron';
20
+ export const OXIDISE_ALUMINIUM = 'oxidise-aluminium';
21
+ export const OXIDISE_COPPER = 'oxidise-copper';
22
+ export const BURN_MAGNESIUM = 'burn-magnesium';
23
+
24
+ const REACTIONS: readonly Reaction[] = [
25
+ ...COMMON_REACTIONS,
26
+ {
27
+ /*
28
+ * The slowest reaction in the model by orders of magnitude, back-derived from the measured
29
+ * atmospheric corrosion rate — roughly a percent of a kilogram bar in a year.
30
+ *
31
+ * **The humidity gate `§8.7` asks for is absent.** `ReactionGates` is temperature only, so
32
+ * nothing here reproduces the 60% relative humidity below which atmospheric rusting effectively
33
+ * stops, and a bar in a desert corrodes as fast as one in a bog. Fixing it means a gate on a
34
+ * species fraction, which is a change to `reaction/` rather than to this file.
35
+ */
36
+ id: RUST_IRON,
37
+ reactants: [
38
+ { species: 'Fe', moles: 4 },
39
+ { species: 'O2', moles: 3 },
40
+ ],
41
+ products: [{ species: 'Fe2O3', moles: 2 }],
42
+ kinetics: { type: 'arrhenius', A: 5.6e-4, activationEnergy: 35000 },
43
+ kind: KIND_CORROSION,
44
+ },
45
+ {
46
+ /*
47
+ * **Gated at the melting point, which is the honest proxy for passivation.** Aluminium releases
48
+ * 31 MJ/kg and does not burn, because its oxide is coherent and seals the surface — and the
49
+ * temperature at which that layer stops being coherent is the temperature at which the metal
50
+ * under it is no longer solid. `§8.7` wanted an oxide-thickness gate; this is a gate that gets
51
+ * the same two answers right, said out loud rather than left off.
52
+ */
53
+ id: OXIDISE_ALUMINIUM,
54
+ reactants: [
55
+ { species: 'Al', moles: 4 },
56
+ { species: 'O2', moles: 3 },
57
+ ],
58
+ products: [{ species: 'Al2O3', moles: 2 }],
59
+ kinetics: { type: 'arrhenius', A: 1e6, activationEnergy: 120000 },
60
+ kind: KIND_CORROSION,
61
+ gates: { minTemperature: 933.15, width: 10 },
62
+ },
63
+ {
64
+ /* Slower than iron and green rather than red, which is a `§17` decision and not one here. */
65
+ id: OXIDISE_COPPER,
66
+ reactants: [
67
+ { species: 'Cu', moles: 2 },
68
+ { species: 'O2', moles: 1 },
69
+ ],
70
+ products: [{ species: 'CuO', moles: 2 }],
71
+ kinetics: { type: 'arrhenius', A: 1e-4, activationEnergy: 45000 },
72
+ kind: KIND_CORROSION,
73
+ },
74
+ {
75
+ /*
76
+ * The one metal a fire can actually light. It ignites at 973 K, fifty kelvin above its own
77
+ * melting point and eight hundred below its boiling one — so it burns as a liquid, which is why
78
+ * a magnesium fire runs.
79
+ */
80
+ id: BURN_MAGNESIUM,
81
+ reactants: [
82
+ { species: 'Mg', moles: 2 },
83
+ { species: 'O2', moles: 1 },
84
+ ],
85
+ products: [{ species: 'MgO', moles: 2 }],
86
+ kinetics: { type: 'arrhenius', A: 1e8, activationEnergy: 100000 },
87
+ kind: KIND_CORROSION,
88
+ gates: { minTemperature: 973.15, width: 10 },
89
+ },
90
+ ];
91
+
92
+ export const METAL: SubstanceLibrary = {
93
+ id: 'metal',
94
+ species: [],
95
+ reactions: REACTIONS,
96
+ substances: (species): readonly SubstanceThermal[] => [
97
+ {
98
+ id: 'iron',
99
+ composition: massFractions(species, { Fe: 1 }),
100
+ density: 7870,
101
+ conductivity: { k0: 80.4, k1: -0.03 },
102
+ shells: 3,
103
+ shape: SHAPE_CYLINDER,
104
+ /* Oxidised rather than polished, which is what iron actually is after a week outdoors. */
105
+ emissivity: 0.65,
106
+ reactions: [RUST_IRON],
107
+ appearance: {
108
+ albedo: [0.28, 0.22, 0.18],
109
+ charAlbedo: [0.28, 0.22, 0.18],
110
+ sootYield: 0,
111
+ },
112
+ },
113
+ {
114
+ /* A little carbon and a little silicon, which is what makes it steel and not iron. */
115
+ id: 'steel',
116
+ composition: massFractions(species, { Fe: 0.98, 'C(graphite)': 0.008, SiO2: 0.012 }),
117
+ density: 7850,
118
+ conductivity: { k0: 45, k1: -0.02 },
119
+ shells: 3,
120
+ shape: SHAPE_SLAB,
121
+ emissivity: 0.28,
122
+ reactions: [RUST_IRON],
123
+ appearance: {
124
+ albedo: [0.56, 0.57, 0.58],
125
+ charAlbedo: [0.56, 0.57, 0.58],
126
+ sootYield: 0,
127
+ },
128
+ },
129
+ {
130
+ id: 'aluminium',
131
+ composition: massFractions(species, { Al: 1 }),
132
+ density: 2700,
133
+ conductivity: { k0: 237, k1: -0.04 },
134
+ shells: 3,
135
+ shape: SHAPE_SLAB,
136
+ emissivity: 0.09,
137
+ reactions: [OXIDISE_ALUMINIUM],
138
+ appearance: {
139
+ albedo: [0.91, 0.92, 0.92],
140
+ charAlbedo: [0.91, 0.92, 0.92],
141
+ sootYield: 0,
142
+ },
143
+ },
144
+ {
145
+ id: 'copper',
146
+ composition: massFractions(species, { Cu: 1 }),
147
+ density: 8960,
148
+ conductivity: { k0: 401, k1: -0.07 },
149
+ shells: 3,
150
+ shape: SHAPE_CYLINDER,
151
+ emissivity: 0.05,
152
+ reactions: [OXIDISE_COPPER],
153
+ appearance: {
154
+ albedo: [0.95, 0.64, 0.54],
155
+ charAlbedo: [0.2, 0.34, 0.28],
156
+ sootYield: 0,
157
+ },
158
+ },
159
+ {
160
+ id: 'magnesium',
161
+ composition: massFractions(species, { Mg: 1 }),
162
+ density: 1740,
163
+ conductivity: { k0: 156, k1: -0.02 },
164
+ shells: 3,
165
+ shape: SHAPE_CYLINDER,
166
+ emissivity: 0.13,
167
+ reactions: [BURN_MAGNESIUM],
168
+ /*
169
+ * A metal that genuinely catches, and the two temperatures are far apart from everything else
170
+ * in the library. Its flame is also the one water makes worse, which falls out of the
171
+ * enthalpy: 24.7 MJ/kg is enough to take the oxygen back out of steam.
172
+ */
173
+ ignition: {
174
+ pilotedSurfaceK: 973,
175
+ autoSurfaceK: 1023,
176
+ criticalMassFlux: 0.02,
177
+ limitingOxygen: 0.05,
178
+ },
179
+ appearance: {
180
+ albedo: [0.78, 0.78, 0.76],
181
+ charAlbedo: [0.9, 0.9, 0.88],
182
+ sootYield: 0,
183
+ },
184
+ },
185
+ ],
186
+ };
@@ -0,0 +1,194 @@
1
+ /**
2
+ * `@driftengine/chemistry/library/mineral` — stone, board, sand and glass.
3
+ *
4
+ * **Two reactions, and both matter for the same reason: they are endothermic and they release gas.**
5
+ * Gypsum gives up two waters at 120 °C, which is why plasterboard is a fire barrier. Limestone gives
6
+ * up carbon dioxide at 825 °C, which is why stone spalls in a fire and why a concrete wall in a
7
+ * serious one loses its surface explosively.
8
+ *
9
+ * Both enthalpies are Hess's law over the standard table and neither is written down: +179.2 kJ/mol
10
+ * for calcination against a published +178.3, and +104.4 for gypsum against a published +104.
11
+ */
12
+ import { KIND_CALCINATION, type Reaction } from '../reaction/reaction.ts';
13
+ import { SHAPE_SLAB } from '../parcel/shells.ts';
14
+ import { massFractions } from '../substance/composition.ts';
15
+ import { wetComposition } from '../substance/substance.ts';
16
+ import type { SubstanceThermal } from '../substance/substance.ts';
17
+ import type { SubstanceLibrary } from './library.ts';
18
+ import { BOIL_WATER, COMMON_REACTIONS } from './common.ts';
19
+
20
+ export const CALCINE_LIMESTONE = 'calcine-limestone';
21
+ export const DEHYDRATE_GYPSUM = 'dehydrate-gypsum';
22
+
23
+ const REACTIONS: readonly Reaction[] = [
24
+ ...COMMON_REACTIONS,
25
+ {
26
+ /* Onset near 825 °C at one atmosphere. Endothermic and gas-releasing, so a limestone block in a
27
+ fire is both a heat sink and, eventually, a thing that comes apart. */
28
+ id: CALCINE_LIMESTONE,
29
+ reactants: [{ species: 'CaCO3', moles: 1 }],
30
+ products: [
31
+ { species: 'CaO', moles: 1 },
32
+ { species: 'CO2', moles: 1 },
33
+ ],
34
+ kinetics: { type: 'arrhenius', A: 1e8, activationEnergy: 190000 },
35
+ kind: KIND_CALCINATION,
36
+ gates: { minTemperature: 1098.15, width: 20 },
37
+ },
38
+ {
39
+ /*
40
+ * **The same idea four hundred degrees lower, and it is what a fire-rated wall is.** A kilogram
41
+ * of board holds 607 kJ of latent heat in two waters of crystallisation, and it will not let the
42
+ * far side past the boiling point until every one of them has gone.
43
+ */
44
+ id: DEHYDRATE_GYPSUM,
45
+ reactants: [{ species: 'gypsum', moles: 1 }],
46
+ products: [
47
+ { species: 'anhydrite', moles: 1 },
48
+ { species: 'H2O(g)', moles: 2 },
49
+ ],
50
+ kinetics: { type: 'arrhenius', A: 1e6, activationEnergy: 80000 },
51
+ kind: KIND_CALCINATION,
52
+ gates: { minTemperature: 393.15, width: 20 },
53
+ },
54
+ ];
55
+
56
+ export const MINERAL: SubstanceLibrary = {
57
+ id: 'mineral',
58
+ species: [],
59
+ reactions: REACTIONS,
60
+ substances: (species): readonly SubstanceThermal[] => [
61
+ {
62
+ id: 'limestone',
63
+ composition: massFractions(species, { CaCO3: 1 }),
64
+ density: 2700,
65
+ conductivity: { k0: 2.2, k1: -0.0005 },
66
+ shells: 4,
67
+ shape: SHAPE_SLAB,
68
+ emissivity: 0.93,
69
+ reactions: [CALCINE_LIMESTONE],
70
+ appearance: {
71
+ albedo: [0.68, 0.66, 0.6],
72
+ charAlbedo: [0.68, 0.66, 0.6],
73
+ sootYield: 0,
74
+ },
75
+ },
76
+ {
77
+ /* Light, because it is foamed, and thermally poor — which together with the dehydration is the
78
+ whole of its fire rating. */
79
+ id: 'gypsum-board',
80
+ composition: wetComposition(
81
+ species,
82
+ massFractions(species, {
83
+ gypsum: 0.95,
84
+ SiO2: 0.05,
85
+ }),
86
+ 0.01,
87
+ ),
88
+ density: 700,
89
+ conductivity: { k0: 0.25, k1: 0.0002 },
90
+ shells: 4,
91
+ shape: SHAPE_SLAB,
92
+ porosity: 0.3,
93
+ emissivity: 0.9,
94
+ reactions: [BOIL_WATER, DEHYDRATE_GYPSUM],
95
+ appearance: {
96
+ albedo: [0.82, 0.81, 0.78],
97
+ charAlbedo: [0.82, 0.81, 0.78],
98
+ sootYield: 0,
99
+ },
100
+ },
101
+ {
102
+ id: 'sand',
103
+ composition: massFractions(species, { SiO2: 1 }),
104
+ density: 1600,
105
+ conductivity: { k0: 0.3, k1: 0.0003 },
106
+ shells: 3,
107
+ shape: SHAPE_SLAB,
108
+ porosity: 0.4,
109
+ emissivity: 0.9,
110
+ /* No reactions, which is why throwing it on a fire works: it is a blanket and a heat sink. */
111
+ appearance: {
112
+ albedo: [0.6, 0.52, 0.36],
113
+ charAlbedo: [0.6, 0.52, 0.36],
114
+ sootYield: 0,
115
+ },
116
+ },
117
+ {
118
+ /* Fifteen percent water, and it is the water that makes wet clay near a fire crack. */
119
+ id: 'clay',
120
+ composition: wetComposition(
121
+ species,
122
+ massFractions(species, {
123
+ SiO2: 0.55,
124
+ Al2O3: 0.4,
125
+ Fe2O3: 0.05,
126
+ }),
127
+ 0.15,
128
+ ),
129
+ density: 1700,
130
+ conductivity: { k0: 1.0, k1: 0.0002 },
131
+ shells: 4,
132
+ shape: SHAPE_SLAB,
133
+ porosity: 0.25,
134
+ emissivity: 0.91,
135
+ reactions: [BOIL_WATER],
136
+ appearance: {
137
+ albedo: [0.48, 0.34, 0.24],
138
+ charAlbedo: [0.48, 0.34, 0.24],
139
+ sootYield: 0,
140
+ },
141
+ },
142
+ {
143
+ /*
144
+ * **Spalls for two reasons at once and gets both by being declared.** Free water flashing to
145
+ * steam inside a matrix that cannot vent it, and then the limestone in the aggregate calcining
146
+ * and releasing carbon dioxide in the same place.
147
+ */
148
+ id: 'concrete',
149
+ composition: wetComposition(
150
+ species,
151
+ massFractions(species, {
152
+ SiO2: 0.62,
153
+ CaCO3: 0.2,
154
+ Al2O3: 0.1,
155
+ CaO: 0.05,
156
+ Fe2O3: 0.03,
157
+ }),
158
+ 0.04,
159
+ ),
160
+ density: 2300,
161
+ conductivity: { k0: 1.7, k1: -0.0003 },
162
+ shells: 4,
163
+ shape: SHAPE_SLAB,
164
+ porosity: 0.12,
165
+ emissivity: 0.92,
166
+ reactions: [BOIL_WATER, CALCINE_LIMESTONE],
167
+ appearance: {
168
+ albedo: [0.52, 0.52, 0.5],
169
+ charAlbedo: [0.52, 0.52, 0.5],
170
+ sootYield: 0,
171
+ },
172
+ },
173
+ {
174
+ /*
175
+ * **Nothing at all, and that is the point of it.** Glass in a fire gets hot, conducts,
176
+ * radiates and eventually softens — and softening is mechanical, which `§26` refuses in
177
+ * writing because this package owns no solver. A chemistry invented so the entry would not
178
+ * look empty would be worse than the empty entry.
179
+ */
180
+ id: 'glass',
181
+ composition: massFractions(species, { SiO2: 0.8, CaO: 0.13, Al2O3: 0.07 }),
182
+ density: 2500,
183
+ conductivity: { k0: 1.0, k1: 0.0005 },
184
+ shells: 3,
185
+ shape: SHAPE_SLAB,
186
+ emissivity: 0.94,
187
+ appearance: {
188
+ albedo: [0.1, 0.12, 0.11],
189
+ charAlbedo: [0.1, 0.12, 0.11],
190
+ sootYield: 0,
191
+ },
192
+ },
193
+ ],
194
+ };