Hi, here are two more patches, the first should actually be amended to what I have sent yesterday (about the in_planner() helper function).
The second makes the ceilings in the profile happy with VPM with Boyle compensation (they were missing the Boyle compensation). A lesson I learned: I claimed earlier, one could use deco_allowed_depth also for VPM-B. Turns out, with Boyle compensation, that has to be called explicitly before the add_segment() call that produces the tissue tolerance. Best Robert
From 14b229d24409b5b5ff4e68bf884a978678db7dbd Mon Sep 17 00:00:00 2001 From: "Robert C. Helling" <[email protected]> Date: Wed, 19 Aug 2015 23:12:30 +0200 Subject: [PATCH 1/2] Leftovers from introduction of in_planner() helper function I have no idea how these could have been left behind Signed-off-by: Robert C. Helling <[email protected]> --- deco.c | 4 +++- planner.h | 1 - qthelper.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/deco.c b/deco.c index 3c7b9c1..12e59a9 100644 --- a/deco.c +++ b/deco.c @@ -21,6 +21,8 @@ #include <assert.h> #include <planner.h> +extern bool in_planner(); + //! Option structure for Buehlmann decompression. struct buehlmann_config { double satmult; //! safety at inert gas accumulation as percentage of effect (more than 100). @@ -167,7 +169,7 @@ static double tissue_tolerance_calc(const struct dive *dive) double lowest_ceiling = 0.0; double tissue_lowest_ceiling[16]; - if (prefs.deco_mode != VPMB || !in_planner) { + if (prefs.deco_mode != VPMB || !in_planner()) { for (ci = 0; ci < 16; ci++) { tissue_inertgas_saturation[ci] = tissue_n2_sat[ci] + tissue_he_sat[ci]; buehlmann_inertgas_a[ci] = ((buehlmann_N2_a[ci] * tissue_n2_sat[ci]) + (buehlmann_He_a[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci]; diff --git a/planner.h b/planner.h index 20aff89..a675989 100644 --- a/planner.h +++ b/planner.h @@ -25,7 +25,6 @@ extern struct dive *planned_dive; extern char *cache_data; extern const char *disclaimer; extern double plangflow, plangfhigh; -extern bool in_planner; #ifdef __cplusplus } diff --git a/qthelper.h b/qthelper.h index 4a5ade7..674f036 100644 --- a/qthelper.h +++ b/qthelper.h @@ -36,5 +36,6 @@ fraction_t string_to_fraction(const char *str); int getCloudURL(QString &filename); void loadPreferences(); bool parseGpsText(const QString &gps_text, double *latitude, double *longitude); +extern "C" bool in_planner(); #endif // QTHELPER_H -- 1.9.5 (Apple Git-50.3)
From 539fb36c29d636e94e634cba0e2719144bdfd348 Mon Sep 17 00:00:00 2001 From: "Robert C. Helling" <[email protected]> Date: Wed, 19 Aug 2015 23:14:00 +0200 Subject: [PATCH 2/2] Use boyle_compensation in profile otherwise VPM-B planned profiles seem to violate the ceiling. This needs the first_stop_pressure to be available also in the profile, so I made it global in planner.c Important lesson: If you want to use deco_allowed_depth on a tissue_tolerance that comes from a VPM-B planned dive, you have to call boyles_law() before add_segment()! Signed-off-by: Robert C. Helling <[email protected]> --- deco.c | 15 ++++++++++----- dive.h | 2 +- planner.c | 10 ++++++---- profile.c | 1 + 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/deco.c b/deco.c index 12e59a9..8a19a71 100644 --- a/deco.c +++ b/deco.c @@ -23,6 +23,8 @@ extern bool in_planner(); +extern int first_stop_pressure; + //! Option structure for Buehlmann decompression. struct buehlmann_config { double satmult; //! safety at inert gas accumulation as percentage of effect (more than 100). @@ -344,24 +346,27 @@ double solve_cubic(double A, double B, double C) } -double update_gradient(double first_stop_pressure, double next_stop_pressure, double first_gradient) +double update_gradient(double next_stop_pressure, double first_gradient) { double first_radius = 2.0 * vpmb_config.surface_tension_gamma / first_gradient; double A = next_stop_pressure; double B = -2.0 * vpmb_config.surface_tension_gamma; - double C = (first_stop_pressure + 2.0 * vpmb_config.surface_tension_gamma / first_radius) * cube(first_radius); + double C = (first_stop_pressure / 1000.0 + 2.0 * vpmb_config.surface_tension_gamma / first_radius) * cube(first_radius); double next_radius = solve_cubic(A, B, C); return 2.0 * vpmb_config.surface_tension_gamma / next_radius; } -void boyles_law(double first_stop_pressure, double next_stop_pressure) +void boyles_law(double next_stop_pressure) { int ci; + + if (!first_stop_pressure) + return; for (ci = 0; ci < 16; ++ci) { - allowable_n2_gradient[ci] = update_gradient(first_stop_pressure, next_stop_pressure, bottom_n2_gradient[ci]); - allowable_he_gradient[ci] = update_gradient(first_stop_pressure, next_stop_pressure, bottom_he_gradient[ci]); + allowable_n2_gradient[ci] = update_gradient(next_stop_pressure, bottom_n2_gradient[ci]); + allowable_he_gradient[ci] = update_gradient(next_stop_pressure, bottom_he_gradient[ci]); total_gradient[ci] = ((allowable_n2_gradient[ci] * tissue_n2_sat[ci]) + (allowable_he_gradient[ci] * tissue_he_sat[ci])) / (tissue_n2_sat[ci] + tissue_he_sat[ci]); } diff --git a/dive.h b/dive.h index ee3f637..0125b76 100644 --- a/dive.h +++ b/dive.h @@ -801,7 +801,7 @@ extern double restore_deco_state(char *data); extern void nuclear_regeneration(double time); extern void vpmb_start_gradient(); extern void vpmb_next_gradient(double deco_time, double surface_pressure); -extern void boyles_law(double first_stop_pressure, double next_stop_pressure); +extern void boyles_law(double next_stop_pressure); /* this should be converted to use our types */ struct divedatapoint { diff --git a/planner.c b/planner.c index 5ce75cd..50dd778 100644 --- a/planner.c +++ b/planner.c @@ -33,6 +33,8 @@ int decostoplevels_imperial[] = { 0, 3048, 6096, 9144, 12192, 15240, 18288, 2133 double plangflow, plangfhigh; bool plan_verbatim, plan_display_runtime, plan_display_duration, plan_display_transitions; +int first_stop_pressure; + const char *disclaimer; #if DEBUG_PLAN @@ -921,7 +923,6 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool int bottom_depth; int bottom_gi; int bottom_stopidx; - int first_stop_pressure; bool is_final_plan = true; int deco_time; int previous_deco_time; @@ -996,6 +997,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool return(false); } tissue_tolerance = tissue_at_end(&displayed_dive, cached_datap); + displayed_dive.surface_pressure.mbar = diveplan->surface_pressure; #if DEBUG_PLAN & 4 printf("gas %s\n", gasname(&gas)); @@ -1160,12 +1162,12 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool // Boyles Law compensation if (first_stop_pressure == 0) first_stop_pressure = depth_to_mbar(depth, &displayed_dive); - boyles_law(first_stop_pressure / 1000.0, depth_to_mbar(stoplevels[stopidx], &displayed_dive) / 1000.0); + boyles_law(depth_to_mbar(stoplevels[stopidx], &displayed_dive) / 1000.0); // Boyles Law compensation if (first_stop_pressure == 0) first_stop_pressure = depth_to_mbar(depth, &displayed_dive); - boyles_law(first_stop_pressure / 1000.0, depth_to_mbar(stoplevels[stopidx], &displayed_dive) / 1000.0); + boyles_law(depth_to_mbar(stoplevels[stopidx], &displayed_dive) / 1000.0); /* Check we need to change cylinder. * We might not if the cylinder was chosen by the user @@ -1220,7 +1222,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool // Boyles Law compensation if (first_stop_pressure == 0) first_stop_pressure = depth_to_mbar(depth, &displayed_dive); - boyles_law(first_stop_pressure / 1000.0, depth_to_mbar(stoplevels[stopidx], &displayed_dive) / 1000.0); + boyles_law(depth_to_mbar(stoplevels[stopidx], &displayed_dive) / 1000.0); } /* Are we waiting to switch gas? diff --git a/profile.c b/profile.c index 51f322c..6716854 100644 --- a/profile.c +++ b/profile.c @@ -853,6 +853,7 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru time_stepsize = t1 - t0; for (j = t0 + time_stepsize; j <= t1; j += time_stepsize) { int depth = interpolate(entry[-1].depth, entry[0].depth, j - t0, t1 - t0); + boyles_law(depth_to_mbar(entry->depth, &displayed_dive) / 1000.0); double min_pressure = add_segment(depth_to_mbar(depth, dive) / 1000.0, &dive->cylinder[entry->cylinderindex].gasmix, time_stepsize, entry->o2pressure.mbar, dive, entry->sac); tissue_tolerance = min_pressure; -- 1.9.5 (Apple Git-50.3)
signature.asc
Description: Message signed with OpenPGP using GPGMail
_______________________________________________ subsurface mailing list [email protected] http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
