summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar willem ferguson <willemferguson@zoology.up.ac.za>2014-11-03 22:11:00 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2014-11-03 14:13:55 -0800
commit40bdd607c0258270e6289bdb725d3366bcad1e62 (patch)
treef367a8fb9697b7501a5a3012d72629360a677680
parentdfc7ee0b296dd834b794d2f5be20924d6578a96a (diff)
downloadsubsurface-40bdd607c0258270e6289bdb725d3366bcad1e62.tar.gz
Calculate nitrogen and helium gas pressures for CCR after import from CSV
Currently the gas pressures stored in structures of pressure are calculated using the gasmix composition of the currently selected cylinder. But with CCR dives the default cylinder is the oxygen cylinder (here, index 0). However, the gas pressures need to be calculated using gasmix data from cylinder 1 (the diluent cylinder). This patch allows setting the appropriate cylinder for calculating the values in the structures of pressure. It also allows for correctly calculating gas pressures for any open circuit cylinders (e.g. bailout) that a CCR diver may use. This is performed as follows: 1) In dive.h create an enum variable {oxygen, diluent, bailout} 2) Within the definition of cylinder_t, add a member: cylinder_use_type This stores an enum variable, one of the above. 3) In file.c where the Poseidon CSV data are read in, assign the appropriate enum values to each of the cylinders. 4) Within the definition of structure dive, add two members: int oxygen_cylinder_index int diluent_cylinder_index This will keep the indices of the two main CCR cylinders. 5) In dive.c create a function get_cylinder_use(). This scans the cylinders for that dive, looking for a cylinder that has a particular cylinder_use_type and returns that cylinder index. 6) In dive.c create a function fixup_cylinder_use() that stores the indices of the oxygen and diluent cylinders in the variables dive->oxygen_cylinder_index and dive->diluent_cylinder_index, making use of the function in 4) above. 7) In profile.c, modify function calculate_gas_information_new() to use the above functions for CCR dives to find the oxygen and diluent cylinders and to calculate partail gas pressures based on the diluent cylinder gas mix. This results in the correct calculation of gas partial pressures in the case of CCR dives, displaying the correct partial pressure graphs in the dive profile widget. Signed-off-by: willem ferguson <willemferguson@zoology.up.ac.za> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--dive.c23
-rw-r--r--dive.h5
-rw-r--r--file.c2
-rw-r--r--profile.c4
4 files changed, 34 insertions, 0 deletions
diff --git a/dive.c b/dive.c
index 73c7bd2e7..9ec535d86 100644
--- a/dive.c
+++ b/dive.c
@@ -1038,6 +1038,12 @@ unsigned int dc_airtemp(struct divecomputer *dc)
return (sum + nr / 2) / nr;
}
+static void fixup_cylinder_use(struct dive *dive) // for CCR dives, store the indices
+{ // of the oxygen and diluent cylinders
+ dive->oxygen_cylinder_index = get_cylinder_use(dive, oxygen);
+ dive->diluent_cylinder_index = get_cylinder_use(dive, diluent);
+}
+
static void fixup_airtemp(struct dive *dive)
{
if (!dive->airtemp.mkelvin)
@@ -1228,6 +1234,7 @@ struct dive *fixup_dive(struct dive *dive)
fixup_duration(dive);
fixup_watertemp(dive);
fixup_airtemp(dive);
+ fixup_cylinder_use(dive); // store indices for CCR oxygen and diluent cylinders
for (i = 0; i < MAX_CYLINDERS; i++) {
cylinder_t *cyl = dive->cylinder + i;
add_cylinder_description(&cyl->type);
@@ -1506,6 +1513,22 @@ static void merge_weightsystem_info(weightsystem_t *res, weightsystem_t *a, weig
*res = *a;
}
+/* get_cylinder_use(): Find the index of the first cylinder with a particular CCR use type.
+ * The index returned corresponds to that of the first cylinder with a cylinder_use that
+ * equals the appropriate enum value [oxygen, diluent, bailout] given by cylinder_use_type.
+ * A negative number returned indicates that a match could not be found.
+ * Call parameters: dive = the dive being processed
+ * cylinder_use_type = an enum, one of {oxygen, diluent, bailout} */
+extern int get_cylinder_use(struct dive *dive, enum cylinderuse cylinder_use_type)
+{
+ int cylinder_index;
+ for (cylinder_index = 0; cylinder_index < MAX_CYLINDERS; cylinder_index++) {
+ if (dive->cylinder[cylinder_index].cylinder_use == cylinder_use_type)
+ return cylinder_index; // return the index of the cylinder with that cylinder use type
+ }
+ return -1; // negative number means cylinder_use_type not found in list of cylinders
+}
+
int gasmix_distance(const struct gasmix *a, const struct gasmix *b)
{
int a_o2 = get_o2(a), b_o2 = get_o2(b);
diff --git a/dive.h b/dive.h
index 6809d8384..6ca091e9d 100644
--- a/dive.h
+++ b/dive.h
@@ -48,6 +48,7 @@ extern "C" {
#endif
enum dive_comp_type {OC, CCR}; // Flags (Open-circuit and Closed-circuit-rebreather) for setting dive computer type
+enum cylinderuse {oxygen, diluent, bailout}; // The different uses for cylinders in CCR dives
struct gasmix {
fraction_t o2;
@@ -70,6 +71,7 @@ typedef struct
bool manually_added;
volume_t gas_used;
volume_t deco_gas_used;
+ enum cylinderuse cylinder_use;
} cylinder_t;
typedef struct
@@ -319,8 +321,11 @@ struct dive {
struct divecomputer dc;
int id; // unique ID for this dive
struct picture *picture_list;
+ int oxygen_cylinder_index, diluent_cylinder_index; // CCR dive cylinder indices
};
+extern int get_cylinder_use(struct dive *dive, enum cylinderuse cylinder_use_type);
+
/* when selectively copying dive information, which parts should be copied? */
struct dive_components {
unsigned int location : 1;
diff --git a/file.c b/file.c
index bab7909d7..60b79f228 100644
--- a/file.c
+++ b/file.c
@@ -474,12 +474,14 @@ int parse_txt_file(const char *filename, const char *csv)
dive->dc.dctype = CCR;
dive->dc.no_o2sensors = 2;
+ dive->cylinder[cur_cylinder_index].cylinder_use = oxygen;
dive->cylinder[cur_cylinder_index].type.size.mliter = 3000;
dive->cylinder[cur_cylinder_index].type.workingpressure.mbar = 200000;
dive->cylinder[cur_cylinder_index].type.description = strdup("3l Mk6");
dive->cylinder[cur_cylinder_index].gasmix.o2.permille = 1000;
cur_cylinder_index++;
+ dive->cylinder[cur_cylinder_index].cylinder_use = diluent;
dive->cylinder[cur_cylinder_index].type.size.mliter = 3000;
dive->cylinder[cur_cylinder_index].type.workingpressure.mbar = 200000;
dive->cylinder[cur_cylinder_index].type.description = strdup("3l Mk6");
diff --git a/profile.c b/profile.c
index 4be3a5b67..454dc1bcd 100644
--- a/profile.c
+++ b/profile.c
@@ -901,6 +901,10 @@ static void calculate_gas_information_new(struct dive *dive, struct plot_info *p
fo2 = get_o2(&dive->cylinder[cylinderindex].gasmix);
fhe = get_he(&dive->cylinder[cylinderindex].gasmix);
+ // For CCR dives use the diluent gas composition for calculating partial gas pressures:
+ if ((dive->dc.dctype == CCR) && (cylinderindex == dive->oxygen_cylinder_index))
+ cylinderindex = dive->diluent_cylinder_index;
+
fill_pressures(&entry->pressures, amb_pressure, &dive->cylinder[cylinderindex].gasmix, entry->pressures.o2);
/* Calculate MOD, EAD, END and EADD based on partial pressures calculated before