summaryrefslogtreecommitdiffstats
path: root/core/gas.c
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2019-06-04 13:52:48 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2019-06-19 13:11:10 -0700
commit619d3fb1fd4b7ab532537b7eca78f668d2ce381b (patch)
tree7a4575845be7b5a196a1450c370b660a18ef9e13 /core/gas.c
parent83522747581500ef39005bc76b1048db1cd3bd29 (diff)
downloadsubsurface-619d3fb1fd4b7ab532537b7eca78f668d2ce381b.tar.gz
Cleanup: move gas-functions to own translation unit
But only functions that operate only on gases. Functions concerning cylinders or dives remain in dive.c or are moved to equipment.c Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core/gas.c')
-rw-r--r--core/gas.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/core/gas.c b/core/gas.c
new file mode 100644
index 000000000..9f67d0b92
--- /dev/null
+++ b/core/gas.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "gas.h"
+#include "pref.h"
+#include <stdio.h>
+#include <string.h>
+
+/* Perform isobaric counterdiffusion calculations for gas changes in trimix dives.
+ * Here we use the rule-of-fifths where, during a change involving trimix gas, the increase in nitrogen
+ * should not exceed one fifth of the decrease in helium.
+ * Parameters: 1) pointers to two gas mixes, the gas being switched from and the gas being switched to.
+ * 2) a pointer to an icd_data structure.
+ * Output: i) The icd_data stucture is filled with the delta_N2 and delta_He numbers (as permille).
+ * ii) Function returns a boolean indicating an exceeding of the rule-of-fifths. False = no icd problem.
+ */
+bool isobaric_counterdiffusion(struct gasmix oldgasmix, struct gasmix newgasmix, struct icd_data *results)
+{
+ if (!prefs.show_icd)
+ return false;
+ results->dN2 = get_he(oldgasmix) + get_o2(oldgasmix) - get_he(newgasmix) - get_o2(newgasmix);
+ results->dHe = get_he(newgasmix) - get_he(oldgasmix);
+ return get_he(oldgasmix) > 0 && results->dN2 > 0 && results->dHe < 0 && get_he(oldgasmix) && results->dN2 > 0 && 5 * results->dN2 > -results->dHe;
+}
+
+static bool gasmix_is_invalid(struct gasmix mix)
+{
+ return mix.o2.permille < 0;
+}
+
+int same_gasmix(struct gasmix a, struct gasmix b)
+{
+ if (gasmix_is_invalid(a) || gasmix_is_invalid(b))
+ return 0;
+ if (gasmix_is_air(a) && gasmix_is_air(b))
+ return 1;
+ return a.o2.permille == b.o2.permille && a.he.permille == b.he.permille;
+}
+
+void sanitize_gasmix(struct gasmix *mix)
+{
+ unsigned int o2, he;
+
+ o2 = mix->o2.permille;
+ he = mix->he.permille;
+
+ /* Regular air: leave empty */
+ if (!he) {
+ if (!o2)
+ return;
+ /* 20.8% to 21% O2 is just air */
+ if (gasmix_is_air(*mix)) {
+ mix->o2.permille = 0;
+ return;
+ }
+ }
+
+ /* Sane mix? */
+ if (o2 <= 1000 && he <= 1000 && o2 + he <= 1000)
+ return;
+ fprintf(stderr, "Odd gasmix: %u O2 %u He\n", o2, he);
+ memset(mix, 0, sizeof(*mix));
+}
+
+int gasmix_distance(struct gasmix a, struct gasmix b)
+{
+ int a_o2 = get_o2(a), b_o2 = get_o2(b);
+ int a_he = get_he(a), b_he = get_he(b);
+ int delta_o2 = a_o2 - b_o2, delta_he = a_he - b_he;
+
+ delta_he = delta_he * delta_he;
+ delta_o2 = delta_o2 * delta_o2;
+ return delta_he + delta_o2;
+}
+
+bool gasmix_is_air(struct gasmix gasmix)
+{
+ int o2 = gasmix.o2.permille;
+ int he = gasmix.he.permille;
+ return (he == 0) && (o2 == 0 || ((o2 >= O2_IN_AIR - 1) && (o2 <= O2_IN_AIR + 1)));
+}