mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Parser: remove global state
The parser had global state in the form of a linear regression and the "plot_depth" variable. Collect that in the deco_state struct and pass it down the call-chain. Move out the code to update the regression data to not bother other callers of tissue_tolerance_calc(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at> Signed-off-by: Robert C. Helling <helling@atdotde.de>
This commit is contained in:
parent
852239e6de
commit
ddff68ddae
3 changed files with 60 additions and 54 deletions
70
core/deco.c
70
core/deco.c
|
@ -37,8 +37,6 @@
|
|||
// was introduced in v4.6.3 this can be set to a value of 1.0 which means no correction.
|
||||
#define subsurface_conservatism_factor 1.0
|
||||
|
||||
extern int plot_depth;
|
||||
|
||||
//! Option structure for Buehlmann decompression.
|
||||
struct buehlmann_config {
|
||||
double satmult; //! safety at inert gas accumulation as percentage of effect (more than 100).
|
||||
|
@ -157,10 +155,6 @@ static const double vpmb_conservatism_lvls[] = { 1.0, 1.05, 1.12, 1.22, 1.35 };
|
|||
|
||||
#define TISSUE_ARRAY_SZ sizeof(ds->tissue_n2_sat)
|
||||
|
||||
static int sum1;
|
||||
static long sumx, sumxx;
|
||||
static double sumy, sumxy;
|
||||
|
||||
static double get_crit_radius_He()
|
||||
{
|
||||
if (vpmb_config.conservatism <= 4)
|
||||
|
@ -223,7 +217,6 @@ static double vpmb_tolerated_ambient_pressure(struct deco_state *ds, double refe
|
|||
return ds->tissue_n2_sat[ci] + ds->tissue_he_sat[ci] + vpmb_config.other_gases_pressure - total_gradient;
|
||||
}
|
||||
|
||||
|
||||
double tissue_tolerance_calc(struct deco_state *ds, const struct dive *dive, double pressure)
|
||||
{
|
||||
int ci = -1;
|
||||
|
@ -292,23 +285,6 @@ double tissue_tolerance_calc(struct deco_state *ds, const struct dive *dive, dou
|
|||
}
|
||||
// We are doing ok if the gradient was computed within ten centimeters of the ceiling.
|
||||
} while (fabs(ret_tolerance_limit_ambient_pressure - reference_pressure) > 0.01);
|
||||
|
||||
if (plot_depth) {
|
||||
++sum1;
|
||||
sumx += plot_depth;
|
||||
sumxx += (long)plot_depth * plot_depth;
|
||||
double n2_gradient, he_gradient, total_gradient;
|
||||
n2_gradient = update_gradient(ds, depth_to_bar(plot_depth, &displayed_dive), ds->bottom_n2_gradient[ds->ci_pointing_to_guiding_tissue]);
|
||||
he_gradient = update_gradient(ds, depth_to_bar(plot_depth, &displayed_dive), ds->bottom_he_gradient[ds->ci_pointing_to_guiding_tissue]);
|
||||
total_gradient = ((n2_gradient * ds->tissue_n2_sat[ds->ci_pointing_to_guiding_tissue]) + (he_gradient * ds->tissue_he_sat[ds->ci_pointing_to_guiding_tissue]))
|
||||
/ (ds->tissue_n2_sat[ds->ci_pointing_to_guiding_tissue] + ds->tissue_he_sat[ds->ci_pointing_to_guiding_tissue]);
|
||||
|
||||
double buehlmann_gradient = (1.0 / ds->buehlmann_inertgas_b[ds->ci_pointing_to_guiding_tissue] - 1.0) * depth_to_bar(plot_depth, &displayed_dive) + ds->buehlmann_inertgas_a[ds->ci_pointing_to_guiding_tissue];
|
||||
double gf = (total_gradient - vpmb_config.other_gases_pressure) / buehlmann_gradient;
|
||||
sumxy += gf * plot_depth;
|
||||
sumy += gf;
|
||||
plot_depth = 0;
|
||||
}
|
||||
}
|
||||
return ret_tolerance_limit_ambient_pressure;
|
||||
}
|
||||
|
@ -639,30 +615,50 @@ double get_gf(struct deco_state *ds, double ambpressure_bar, const struct dive *
|
|||
return gf;
|
||||
}
|
||||
|
||||
double regressiona()
|
||||
double regressiona(const struct deco_state *ds)
|
||||
{
|
||||
if (sum1 > 1) {
|
||||
double avxy = sumxy / sum1;
|
||||
double avx = (double)sumx / sum1;
|
||||
double avy = sumy / sum1;
|
||||
double avxx = (double) sumxx / sum1;
|
||||
if (ds->sum1 > 1) {
|
||||
double avxy = ds->sumxy / ds->sum1;
|
||||
double avx = (double)ds->sumx / ds->sum1;
|
||||
double avy = ds->sumy / ds->sum1;
|
||||
double avxx = (double) ds->sumxx / ds->sum1;
|
||||
return (avxy - avx * avy) / (avxx - avx*avx);
|
||||
}
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double regressionb()
|
||||
double regressionb(const struct deco_state *ds)
|
||||
{
|
||||
if (sum1)
|
||||
return sumy / sum1 - sumx * regressiona() / sum1;
|
||||
if (ds->sum1)
|
||||
return ds->sumy / ds->sum1 - ds->sumx * regressiona(ds) / ds->sum1;
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void reset_regression()
|
||||
void reset_regression(struct deco_state *ds)
|
||||
{
|
||||
sum1 = 0;
|
||||
sumxx = sumx = 0L;
|
||||
sumy = sumxy = 0.0;
|
||||
ds->sum1 = 0;
|
||||
ds->sumxx = ds->sumx = 0L;
|
||||
ds->sumy = ds->sumxy = 0.0;
|
||||
}
|
||||
|
||||
void update_regression(struct deco_state *ds, const struct dive *dive)
|
||||
{
|
||||
if (!ds->plot_depth)
|
||||
return;
|
||||
ds->sum1 += 1;
|
||||
ds->sumx += ds->plot_depth;
|
||||
ds->sumxx += (long)ds->plot_depth * ds->plot_depth;
|
||||
double n2_gradient, he_gradient, total_gradient;
|
||||
n2_gradient = update_gradient(ds, depth_to_bar(ds->plot_depth, dive), ds->bottom_n2_gradient[ds->ci_pointing_to_guiding_tissue]);
|
||||
he_gradient = update_gradient(ds, depth_to_bar(ds->plot_depth, dive), ds->bottom_he_gradient[ds->ci_pointing_to_guiding_tissue]);
|
||||
total_gradient = ((n2_gradient * ds->tissue_n2_sat[ds->ci_pointing_to_guiding_tissue]) + (he_gradient * ds->tissue_he_sat[ds->ci_pointing_to_guiding_tissue]))
|
||||
/ (ds->tissue_n2_sat[ds->ci_pointing_to_guiding_tissue] + ds->tissue_he_sat[ds->ci_pointing_to_guiding_tissue]);
|
||||
|
||||
double buehlmann_gradient = (1.0 / ds->buehlmann_inertgas_b[ds->ci_pointing_to_guiding_tissue] - 1.0) * depth_to_bar(ds->plot_depth, dive) + ds->buehlmann_inertgas_a[ds->ci_pointing_to_guiding_tissue];
|
||||
double gf = (total_gradient - vpmb_config.other_gases_pressure) / buehlmann_gradient;
|
||||
ds->sumxy += gf * ds->plot_depth;
|
||||
ds->sumy += gf;
|
||||
ds->plot_depth = 0;
|
||||
}
|
||||
|
|
11
core/deco.h
11
core/deco.h
|
@ -41,6 +41,10 @@ struct deco_state {
|
|||
double gf_low_pressure_this_dive;
|
||||
int deco_time;
|
||||
bool icd_warning;
|
||||
int sum1;
|
||||
long sumx, sumxx;
|
||||
double sumy, sumxy;
|
||||
int plot_depth;
|
||||
};
|
||||
|
||||
extern const double buehlmann_N2_t_halflife[];
|
||||
|
@ -63,9 +67,10 @@ extern void vpmb_start_gradient(struct deco_state *ds);
|
|||
extern void clear_vpmb_state(struct deco_state *ds);
|
||||
extern void add_segment(struct deco_state *ds, double pressure, struct gasmix gasmix, int period_in_seconds, int setpoint, enum divemode_t divemode, int sac);
|
||||
|
||||
extern double regressiona();
|
||||
extern double regressionb();
|
||||
extern void reset_regression();
|
||||
extern double regressiona(const struct deco_state *ds);
|
||||
extern double regressionb(const struct deco_state *ds);
|
||||
extern void reset_regression(struct deco_state *ds);
|
||||
extern void update_regression(struct deco_state *ds, const struct dive *dive);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ static int decostoplevels_imperial[] = { 0, 3048, 6096, 9144, 12192, 15240, 1828
|
|||
325120, 345440, 365760, 386080 };
|
||||
|
||||
char *disclaimer;
|
||||
int plot_depth = 0;
|
||||
#if DEBUG_PLAN
|
||||
void dump_plan(struct diveplan *diveplan)
|
||||
{
|
||||
|
@ -557,23 +556,28 @@ static bool trial_ascent(struct deco_state *ds, int wait_time, int trial_depth,
|
|||
add_segment(ds, depth_to_bar(trial_depth, dive),
|
||||
gasmix,
|
||||
wait_time, po2, divemode, prefs.decosac);
|
||||
if (decoMode() == VPMB && (deco_allowed_depth(tissue_tolerance_calc(ds, dive,depth_to_bar(stoplevel, dive)),
|
||||
surface_pressure, dive, 1)
|
||||
> stoplevel)) {
|
||||
restore_deco_state(trial_cache, ds, false);
|
||||
free(trial_cache);
|
||||
return false;
|
||||
if (decoMode() == VPMB) {
|
||||
double tolerance_limit = tissue_tolerance_calc(ds, dive, depth_to_bar(stoplevel, dive));
|
||||
update_regression(ds, dive);
|
||||
if (deco_allowed_depth(tolerance_limit, surface_pressure, dive, 1) > stoplevel) {
|
||||
restore_deco_state(trial_cache, ds, false);
|
||||
free(trial_cache);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
while (trial_depth > stoplevel) {
|
||||
double tolerance_limit;
|
||||
int deltad = ascent_velocity(trial_depth, avg_depth, bottom_time) * TIMESTEP;
|
||||
if (deltad > trial_depth) /* don't test against depth above surface */
|
||||
deltad = trial_depth;
|
||||
add_segment(ds, depth_to_bar(trial_depth, dive),
|
||||
gasmix,
|
||||
TIMESTEP, po2, divemode, prefs.decosac);
|
||||
if (deco_allowed_depth(tissue_tolerance_calc(ds, dive, depth_to_bar(trial_depth, dive)),
|
||||
surface_pressure, dive, 1) > trial_depth - deltad) {
|
||||
tolerance_limit = tissue_tolerance_calc(ds, dive, depth_to_bar(trial_depth, dive));
|
||||
if (decoMode() == VPMB)
|
||||
update_regression(ds, dive);
|
||||
if (deco_allowed_depth(tolerance_limit, surface_pressure, dive, 1) > trial_depth - deltad) {
|
||||
/* We should have stopped */
|
||||
clear_to_ascend = false;
|
||||
break;
|
||||
|
@ -878,7 +882,8 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
first_stop_depth = 0;
|
||||
stopidx = bottom_stopidx;
|
||||
ds->first_ceiling_pressure.mbar = depth_to_mbar(
|
||||
deco_allowed_depth(tissue_tolerance_calc(ds, dive, depth_to_bar(depth, dive)), diveplan->surface_pressure / 1000.0, dive, 1),
|
||||
deco_allowed_depth(tissue_tolerance_calc(ds, dive, depth_to_bar(depth, dive)),
|
||||
diveplan->surface_pressure / 1000.0, dive, 1),
|
||||
dive);
|
||||
if (ds->max_bottom_ceiling_pressure.mbar > ds->first_ceiling_pressure.mbar)
|
||||
ds->first_ceiling_pressure.mbar = ds->max_bottom_ceiling_pressure.mbar;
|
||||
|
@ -894,7 +899,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
report_error(translate("gettextFromC", "Can't find gas %s"), gasname(gas));
|
||||
current_cylinder = 0;
|
||||
}
|
||||
reset_regression();
|
||||
reset_regression(ds);
|
||||
while (1) {
|
||||
/* We will break out when we hit the surface */
|
||||
do {
|
||||
|
@ -918,7 +923,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
depth -= deltad;
|
||||
/* Print VPM-Gradient as gradient factor, this has to be done from within deco.c */
|
||||
if (decodive)
|
||||
plot_depth = depth;
|
||||
ds->plot_depth = depth;
|
||||
} while (depth > 0 && depth > stoplevels[stopidx]);
|
||||
|
||||
if (depth <= 0)
|
||||
|
@ -1089,8 +1094,8 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
|
||||
plan_add_segment(diveplan, clock - previous_point_time, 0, current_cylinder, po2, false, divemode);
|
||||
if (decoMode() == VPMB) {
|
||||
diveplan->eff_gfhigh = lrint(100.0 * regressionb());
|
||||
diveplan->eff_gflow = lrint(100.0 * (regressiona() * first_stop_depth + regressionb()));
|
||||
diveplan->eff_gfhigh = lrint(100.0 * regressionb(ds));
|
||||
diveplan->eff_gflow = lrint(100.0 * (regressiona(ds) * first_stop_depth + regressionb(ds)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_CYLINDERS; i++)
|
||||
|
|
Loading…
Add table
Reference in a new issue