mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-12 13:16:16 +00:00
Some unification between Buehlmann and VPM-B
This patch makes deco_allowed_depth() work both for Buehlmann as well as VPM-B (as long as the VPM-B internal variable total_gradient[] is valid). As a bonus, in VPM-B mode, in the planner, the ceilings are VPM-B ceilings and not Buehlmann GF. Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
2455a5dec7
commit
a8ce8c3ef1
5 changed files with 54 additions and 51 deletions
86
deco.c
86
deco.c
|
@ -19,6 +19,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "dive.h"
|
#include "dive.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <planner.h>
|
||||||
|
|
||||||
//! Option structure for Buehlmann decompression.
|
//! Option structure for Buehlmann decompression.
|
||||||
struct buehlmann_config {
|
struct buehlmann_config {
|
||||||
|
@ -125,43 +126,55 @@ static double tissue_tolerance_calc(const struct dive *dive)
|
||||||
double lowest_ceiling = 0.0;
|
double lowest_ceiling = 0.0;
|
||||||
double tissue_lowest_ceiling[16];
|
double tissue_lowest_ceiling[16];
|
||||||
|
|
||||||
for (ci = 0; ci < 16; ci++) {
|
if (prefs.deco_mode != VPMB || !in_planner) {
|
||||||
tissue_inertgas_saturation[ci] = tissue_n2_sat[ci] + tissue_he_sat[ci];
|
for (ci = 0; ci < 16; 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];
|
tissue_inertgas_saturation[ci] = tissue_n2_sat[ci] + tissue_he_sat[ci];
|
||||||
buehlmann_inertgas_b[ci] = ((buehlmann_N2_b[ci] * tissue_n2_sat[ci]) + (buehlmann_He_b[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[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];
|
||||||
|
buehlmann_inertgas_b[ci] = ((buehlmann_N2_b[ci] * tissue_n2_sat[ci]) + (buehlmann_He_b[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci];
|
||||||
|
|
||||||
|
|
||||||
/* tolerated = (tissue_inertgas_saturation - buehlmann_inertgas_a) * buehlmann_inertgas_b; */
|
/* tolerated = (tissue_inertgas_saturation - buehlmann_inertgas_a) * buehlmann_inertgas_b; */
|
||||||
|
|
||||||
tissue_lowest_ceiling[ci] = (buehlmann_inertgas_b[ci] * tissue_inertgas_saturation[ci] - gf_low * buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci]) /
|
tissue_lowest_ceiling[ci] = (buehlmann_inertgas_b[ci] * tissue_inertgas_saturation[ci] - gf_low * buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci]) /
|
||||||
((1.0 - buehlmann_inertgas_b[ci]) * gf_low + buehlmann_inertgas_b[ci]);
|
((1.0 - buehlmann_inertgas_b[ci]) * gf_low + buehlmann_inertgas_b[ci]);
|
||||||
if (tissue_lowest_ceiling[ci] > lowest_ceiling)
|
if (tissue_lowest_ceiling[ci] > lowest_ceiling)
|
||||||
lowest_ceiling = tissue_lowest_ceiling[ci];
|
lowest_ceiling = tissue_lowest_ceiling[ci];
|
||||||
if (!buehlmann_config.gf_low_at_maxdepth) {
|
if (!buehlmann_config.gf_low_at_maxdepth) {
|
||||||
if (lowest_ceiling > gf_low_pressure_this_dive)
|
if (lowest_ceiling > gf_low_pressure_this_dive)
|
||||||
gf_low_pressure_this_dive = lowest_ceiling;
|
gf_low_pressure_this_dive = lowest_ceiling;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
for (ci = 0; ci < 16; ci++) {
|
||||||
for (ci = 0; ci <16; ci++) {
|
double tolerated;
|
||||||
double tolerated;
|
|
||||||
|
|
||||||
if ((surface / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - surface) * gf_high + surface <
|
if ((surface / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - surface) * gf_high + surface <
|
||||||
(gf_low_pressure_this_dive / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - gf_low_pressure_this_dive) * gf_low + gf_low_pressure_this_dive)
|
(gf_low_pressure_this_dive / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - gf_low_pressure_this_dive) * gf_low + gf_low_pressure_this_dive)
|
||||||
tolerated = (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high * gf_low_pressure_this_dive - gf_low * surface) -
|
tolerated = (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high * gf_low_pressure_this_dive - gf_low * surface) -
|
||||||
(1.0 - buehlmann_inertgas_b[ci]) * (gf_high - gf_low) * gf_low_pressure_this_dive * surface +
|
(1.0 - buehlmann_inertgas_b[ci]) * (gf_high - gf_low) * gf_low_pressure_this_dive * surface +
|
||||||
buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface) * tissue_inertgas_saturation[ci]) /
|
buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface) * tissue_inertgas_saturation[ci]) /
|
||||||
(-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high - gf_low) +
|
(-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high - gf_low) +
|
||||||
(1.0 - buehlmann_inertgas_b[ci]) * (gf_low * gf_low_pressure_this_dive - gf_high * surface) +
|
(1.0 - buehlmann_inertgas_b[ci]) * (gf_low * gf_low_pressure_this_dive - gf_high * surface) +
|
||||||
buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface));
|
buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface));
|
||||||
else
|
else
|
||||||
tolerated = ret_tolerance_limit_ambient_pressure;
|
tolerated = ret_tolerance_limit_ambient_pressure;
|
||||||
|
|
||||||
|
|
||||||
tolerated_by_tissue[ci] = tolerated;
|
tolerated_by_tissue[ci] = tolerated;
|
||||||
|
|
||||||
if (tolerated >= ret_tolerance_limit_ambient_pressure) {
|
if (tolerated >= ret_tolerance_limit_ambient_pressure) {
|
||||||
ci_pointing_to_guiding_tissue = ci;
|
ci_pointing_to_guiding_tissue = ci;
|
||||||
ret_tolerance_limit_ambient_pressure = tolerated;
|
ret_tolerance_limit_ambient_pressure = tolerated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// VPM-B ceiling
|
||||||
|
for (ci = 0; ci < 16; ci++) {
|
||||||
|
double tolerated = tissue_n2_sat[ci] + tissue_he_sat[ci] + vpmb_config.other_gases_pressure - total_gradient[ci];
|
||||||
|
if (tolerated >= ret_tolerance_limit_ambient_pressure) {
|
||||||
|
ci_pointing_to_guiding_tissue = ci;
|
||||||
|
ret_tolerance_limit_ambient_pressure = tolerated;
|
||||||
|
}
|
||||||
|
tolerated_by_tissue[ci] = tolerated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret_tolerance_limit_ambient_pressure;
|
return ret_tolerance_limit_ambient_pressure;
|
||||||
|
@ -210,21 +223,6 @@ double he_factor(int period_in_seconds, int ci)
|
||||||
return cache[ci].last_factor;
|
return cache[ci].last_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_vpmb_ok(double pressure)
|
|
||||||
{
|
|
||||||
int ci;
|
|
||||||
double gradient;
|
|
||||||
double gas_tension;
|
|
||||||
|
|
||||||
for (ci = 0; ci < 16; ++ci) {
|
|
||||||
gas_tension = tissue_n2_sat[ci] + tissue_he_sat[ci] + vpmb_config.other_gases_pressure;
|
|
||||||
gradient = gas_tension - pressure;
|
|
||||||
if (gradient > total_gradient[ci])
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vpmb_start_gradient()
|
void vpmb_start_gradient()
|
||||||
{
|
{
|
||||||
int ci;
|
int ci;
|
||||||
|
|
1
dive.h
1
dive.h
|
@ -801,7 +801,6 @@ extern double restore_deco_state(char *data);
|
||||||
extern void nuclear_regeneration(double time);
|
extern void nuclear_regeneration(double time);
|
||||||
extern void vpmb_start_gradient();
|
extern void vpmb_start_gradient();
|
||||||
extern void vpmb_next_gradient(double deco_time);
|
extern void vpmb_next_gradient(double deco_time);
|
||||||
extern bool is_vpmb_ok(double pressure);
|
|
||||||
|
|
||||||
/* this should be converted to use our types */
|
/* this should be converted to use our types */
|
||||||
struct divedatapoint {
|
struct divedatapoint {
|
||||||
|
|
14
planner.c
14
planner.c
|
@ -33,6 +33,14 @@ int decostoplevels_imperial[] = { 0, 3048, 6096, 9144, 12192, 15240, 18288, 2133
|
||||||
double plangflow, plangfhigh;
|
double plangflow, plangfhigh;
|
||||||
bool plan_verbatim, plan_display_runtime, plan_display_duration, plan_display_transitions;
|
bool plan_verbatim, plan_display_runtime, plan_display_duration, plan_display_transitions;
|
||||||
|
|
||||||
|
/* This is a bit round about: Currently, we only support VPM-B in the planner,
|
||||||
|
* so, when we compute ceilings we have to know if we are in planning mode since
|
||||||
|
* the maximally allowed gradient in the tissues is determined by the critical volume algorithm for
|
||||||
|
* which we currently have no version for logged dives. But the information about the application state
|
||||||
|
* is only available in the C++/Qt part. So this global variable is a way to leak this info. */
|
||||||
|
|
||||||
|
bool in_planner = false;
|
||||||
|
|
||||||
const char *disclaimer;
|
const char *disclaimer;
|
||||||
|
|
||||||
#if DEBUG_PLAN
|
#if DEBUG_PLAN
|
||||||
|
@ -879,15 +887,11 @@ bool trial_ascent(int trial_depth, int stoplevel, int avg_depth, int bottom_time
|
||||||
tissue_tolerance = add_segment(depth_to_mbar(trial_depth, &displayed_dive) / 1000.0,
|
tissue_tolerance = add_segment(depth_to_mbar(trial_depth, &displayed_dive) / 1000.0,
|
||||||
gasmix,
|
gasmix,
|
||||||
TIMESTEP, po2, &displayed_dive, prefs.decosac);
|
TIMESTEP, po2, &displayed_dive, prefs.decosac);
|
||||||
if (prefs.deco_mode != VPMB && deco_allowed_depth(tissue_tolerance, surface_pressure, &displayed_dive, 1) > trial_depth - deltad) {
|
if (deco_allowed_depth(tissue_tolerance, surface_pressure, &displayed_dive, 1) > trial_depth - deltad) {
|
||||||
/* We should have stopped */
|
/* We should have stopped */
|
||||||
clear_to_ascend = false;
|
clear_to_ascend = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (prefs.deco_mode == VPMB && (!is_vpmb_ok(depth_to_mbar(trial_depth, &displayed_dive) / 1000.0))){
|
|
||||||
clear_to_ascend = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
trial_depth -= deltad;
|
trial_depth -= deltad;
|
||||||
}
|
}
|
||||||
restore_deco_state(trial_cache);
|
restore_deco_state(trial_cache);
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern struct dive *planned_dive;
|
||||||
extern char *cache_data;
|
extern char *cache_data;
|
||||||
extern const char *disclaimer;
|
extern const char *disclaimer;
|
||||||
extern double plangflow, plangfhigh;
|
extern double plangflow, plangfhigh;
|
||||||
|
extern bool in_planner;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1716,6 +1716,8 @@ void MainWindow::setApplicationState(const QByteArray& state) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
currentApplicationState = state;
|
currentApplicationState = state;
|
||||||
|
in_planner = (state == "PlanDive" || state == "EditPlannedDive");
|
||||||
|
|
||||||
#define SET_CURRENT_INDEX( X ) \
|
#define SET_CURRENT_INDEX( X ) \
|
||||||
if (applicationState[state].X) { \
|
if (applicationState[state].X) { \
|
||||||
ui.X->setCurrentWidget( applicationState[state].X); \
|
ui.X->setCurrentWidget( applicationState[state].X); \
|
||||||
|
|
Loading…
Add table
Reference in a new issue