diff options
author | Robert C. Helling <helling@atdotde.de> | 2017-11-22 20:42:33 +0100 |
---|---|---|
committer | Robert C. Helling <helling@atdotde.de> | 2017-11-25 20:13:01 +0100 |
commit | 8e21a65653514d9340ef45c9b9c53dfe5d280350 (patch) | |
tree | 2ada40567e25bc45035698748f368127b1cca199 /core/deco.c | |
parent | a9ceecc2e3646432d6688d04b592c48f9c63ae65 (diff) | |
download | subsurface-8e21a65653514d9340ef45c9b9c53dfe5d280350.tar.gz |
Localize global planner state
For UI responsiveness, we need to be able to run the planner in the background. This needs the
planner state to be localized (and we need to pass a pointer around).
In order to not let too many lines overrun (and to save typing in the future)
I have renamed instances of struct deco_state to ds. Yes this should have gone
to a separate commit but I accidentally commit --amend'ed it.
Computing of planner variations is temporarily disabled.
Unlock the planner when returning early
So we don't deadlock in add dive and recreational mode (which
use the planner without actually planning).
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Diffstat (limited to 'core/deco.c')
-rw-r--r-- | core/deco.c | 206 |
1 files changed, 101 insertions, 105 deletions
diff --git a/core/deco.c b/core/deco.c index 7a7325297..c104205d8 100644 --- a/core/deco.c +++ b/core/deco.c @@ -151,11 +151,7 @@ const double vpmb_conservatism_lvls[] = { 1.0, 1.05, 1.12, 1.22, 1.35 }; #define DECO_STOPS_MULTIPLIER_MM 3000.0 #define NITROGEN_FRACTION 0.79 -struct deco_state global_deco_state; - -struct deco_state *deco_state = &global_deco_state; - -#define TISSUE_ARRAY_SZ sizeof(deco_state->tissue_n2_sat) +#define TISSUE_ARRAY_SZ sizeof(ds->tissue_n2_sat) int sumx, sum1; long sumxx; @@ -194,9 +190,9 @@ double solve_cubic2(double B, double C) // This is a simplified formula avoiding radii. It uses the fact that Boyle's law says // pV = (G + P_amb) / G^3 is constant to solve for the new gradient G. -double update_gradient(double next_stop_pressure, double first_gradient) +double update_gradient(struct deco_state *ds, double next_stop_pressure, double first_gradient) { - double B = cube(first_gradient) / (deco_state->first_ceiling_pressure.mbar / 1000.0 + first_gradient); + double B = cube(first_gradient) / (ds->first_ceiling_pressure.mbar / 1000.0 + first_gradient); double C = next_stop_pressure * B; double new_gradient = solve_cubic2(B, C); @@ -206,25 +202,25 @@ double update_gradient(double next_stop_pressure, double first_gradient) return new_gradient; } -double vpmb_tolerated_ambient_pressure(double reference_pressure, int ci) +double vpmb_tolerated_ambient_pressure(struct deco_state *ds, double reference_pressure, int ci) { double n2_gradient, he_gradient, total_gradient; - if (reference_pressure >= deco_state->first_ceiling_pressure.mbar / 1000.0 || !deco_state->first_ceiling_pressure.mbar) { - n2_gradient = deco_state->bottom_n2_gradient[ci]; - he_gradient = deco_state->bottom_he_gradient[ci]; + if (reference_pressure >= ds->first_ceiling_pressure.mbar / 1000.0 || !ds->first_ceiling_pressure.mbar) { + n2_gradient = ds->bottom_n2_gradient[ci]; + he_gradient = ds->bottom_he_gradient[ci]; } else { - n2_gradient = update_gradient(reference_pressure, deco_state->bottom_n2_gradient[ci]); - he_gradient = update_gradient(reference_pressure, deco_state->bottom_he_gradient[ci]); + n2_gradient = update_gradient(ds, reference_pressure, ds->bottom_n2_gradient[ci]); + he_gradient = update_gradient(ds, reference_pressure, ds->bottom_he_gradient[ci]); } - total_gradient = ((n2_gradient * deco_state->tissue_n2_sat[ci]) + (he_gradient * deco_state->tissue_he_sat[ci])) / (deco_state->tissue_n2_sat[ci] + deco_state->tissue_he_sat[ci]); + total_gradient = ((n2_gradient * ds->tissue_n2_sat[ci]) + (he_gradient * ds->tissue_he_sat[ci])) / (ds->tissue_n2_sat[ci] + ds->tissue_he_sat[ci]); - return deco_state->tissue_n2_sat[ci] + deco_state->tissue_he_sat[ci] + vpmb_config.other_gases_pressure - total_gradient; + return ds->tissue_n2_sat[ci] + ds->tissue_he_sat[ci] + vpmb_config.other_gases_pressure - total_gradient; } -double tissue_tolerance_calc(const struct dive *dive, double pressure) +double tissue_tolerance_calc(struct deco_state *ds, const struct dive *dive, double pressure) { int ci = -1; double ret_tolerance_limit_ambient_pressure = 0.0; @@ -235,8 +231,8 @@ double tissue_tolerance_calc(const struct dive *dive, double pressure) double tissue_lowest_ceiling[16]; for (ci = 0; ci < 16; ci++) { - deco_state->buehlmann_inertgas_a[ci] = ((buehlmann_N2_a[ci] * deco_state->tissue_n2_sat[ci]) + (buehlmann_He_a[ci] * deco_state->tissue_he_sat[ci])) / deco_state->tissue_inertgas_saturation[ci]; - deco_state->buehlmann_inertgas_b[ci] = ((buehlmann_N2_b[ci] * deco_state->tissue_n2_sat[ci]) + (buehlmann_He_b[ci] * deco_state->tissue_he_sat[ci])) / deco_state->tissue_inertgas_saturation[ci]; + ds->buehlmann_inertgas_a[ci] = ((buehlmann_N2_a[ci] * ds->tissue_n2_sat[ci]) + (buehlmann_He_a[ci] * ds->tissue_he_sat[ci])) / ds->tissue_inertgas_saturation[ci]; + ds->buehlmann_inertgas_b[ci] = ((buehlmann_N2_b[ci] * ds->tissue_n2_sat[ci]) + (buehlmann_He_b[ci] * ds->tissue_he_sat[ci])) / ds->tissue_inertgas_saturation[ci]; } if (decoMode() != VPMB) { @@ -244,32 +240,32 @@ double tissue_tolerance_calc(const struct dive *dive, double pressure) /* tolerated = (tissue_inertgas_saturation - buehlmann_inertgas_a) * buehlmann_inertgas_b; */ - tissue_lowest_ceiling[ci] = (deco_state->buehlmann_inertgas_b[ci] * deco_state->tissue_inertgas_saturation[ci] - gf_low * deco_state->buehlmann_inertgas_a[ci] * deco_state->buehlmann_inertgas_b[ci]) / - ((1.0 - deco_state->buehlmann_inertgas_b[ci]) * gf_low + deco_state->buehlmann_inertgas_b[ci]); + tissue_lowest_ceiling[ci] = (ds->buehlmann_inertgas_b[ci] * ds->tissue_inertgas_saturation[ci] - gf_low * ds->buehlmann_inertgas_a[ci] * ds->buehlmann_inertgas_b[ci]) / + ((1.0 - ds->buehlmann_inertgas_b[ci]) * gf_low + ds->buehlmann_inertgas_b[ci]); if (tissue_lowest_ceiling[ci] > lowest_ceiling) lowest_ceiling = tissue_lowest_ceiling[ci]; - if (lowest_ceiling > deco_state->gf_low_pressure_this_dive) - deco_state->gf_low_pressure_this_dive = lowest_ceiling; + if (lowest_ceiling > ds->gf_low_pressure_this_dive) + ds->gf_low_pressure_this_dive = lowest_ceiling; } for (ci = 0; ci < 16; ci++) { double tolerated; - if ((surface / deco_state->buehlmann_inertgas_b[ci] + deco_state->buehlmann_inertgas_a[ci] - surface) * gf_high + surface < - (deco_state->gf_low_pressure_this_dive / deco_state->buehlmann_inertgas_b[ci] + deco_state->buehlmann_inertgas_a[ci] - deco_state->gf_low_pressure_this_dive) * gf_low + deco_state->gf_low_pressure_this_dive) - tolerated = (-deco_state->buehlmann_inertgas_a[ci] * deco_state->buehlmann_inertgas_b[ci] * (gf_high * deco_state->gf_low_pressure_this_dive - gf_low * surface) - - (1.0 - deco_state->buehlmann_inertgas_b[ci]) * (gf_high - gf_low) * deco_state->gf_low_pressure_this_dive * surface + - deco_state->buehlmann_inertgas_b[ci] * (deco_state->gf_low_pressure_this_dive - surface) * deco_state->tissue_inertgas_saturation[ci]) / - (-deco_state->buehlmann_inertgas_a[ci] * deco_state->buehlmann_inertgas_b[ci] * (gf_high - gf_low) + - (1.0 - deco_state->buehlmann_inertgas_b[ci]) * (gf_low * deco_state->gf_low_pressure_this_dive - gf_high * surface) + - deco_state->buehlmann_inertgas_b[ci] * (deco_state->gf_low_pressure_this_dive - surface)); + if ((surface / ds->buehlmann_inertgas_b[ci] + ds->buehlmann_inertgas_a[ci] - surface) * gf_high + surface < + (ds->gf_low_pressure_this_dive / ds->buehlmann_inertgas_b[ci] + ds->buehlmann_inertgas_a[ci] - ds->gf_low_pressure_this_dive) * gf_low + ds->gf_low_pressure_this_dive) + tolerated = (-ds->buehlmann_inertgas_a[ci] * ds->buehlmann_inertgas_b[ci] * (gf_high * ds->gf_low_pressure_this_dive - gf_low * surface) - + (1.0 - ds->buehlmann_inertgas_b[ci]) * (gf_high - gf_low) * ds->gf_low_pressure_this_dive * surface + + ds->buehlmann_inertgas_b[ci] * (ds->gf_low_pressure_this_dive - surface) * ds->tissue_inertgas_saturation[ci]) / + (-ds->buehlmann_inertgas_a[ci] * ds->buehlmann_inertgas_b[ci] * (gf_high - gf_low) + + (1.0 - ds->buehlmann_inertgas_b[ci]) * (gf_low * ds->gf_low_pressure_this_dive - gf_high * surface) + + ds->buehlmann_inertgas_b[ci] * (ds->gf_low_pressure_this_dive - surface)); else tolerated = ret_tolerance_limit_ambient_pressure; - deco_state->tolerated_by_tissue[ci] = tolerated; + ds->tolerated_by_tissue[ci] = tolerated; if (tolerated >= ret_tolerance_limit_ambient_pressure) { - deco_state->ci_pointing_to_guiding_tissue = ci; + ds->ci_pointing_to_guiding_tissue = ci; ret_tolerance_limit_ambient_pressure = tolerated; } } @@ -283,12 +279,12 @@ double tissue_tolerance_calc(const struct dive *dive, double pressure) reference_pressure = ret_tolerance_limit_ambient_pressure; ret_tolerance_limit_ambient_pressure = 0.0; for (ci = 0; ci < 16; ci++) { - double tolerated = vpmb_tolerated_ambient_pressure(reference_pressure, ci); + double tolerated = vpmb_tolerated_ambient_pressure(ds, reference_pressure, ci); if (tolerated >= ret_tolerance_limit_ambient_pressure) { - deco_state->ci_pointing_to_guiding_tissue = ci; + ds->ci_pointing_to_guiding_tissue = ci; ret_tolerance_limit_ambient_pressure = tolerated; } - deco_state->tolerated_by_tissue[ci] = tolerated; + ds->tolerated_by_tissue[ci] = tolerated; } // 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); @@ -298,12 +294,12 @@ double tissue_tolerance_calc(const struct dive *dive, double pressure) sumx += plot_depth; sumxx += plot_depth * plot_depth; double n2_gradient, he_gradient, total_gradient; - n2_gradient = update_gradient(depth_to_bar(plot_depth, &displayed_dive), deco_state->bottom_n2_gradient[deco_state->ci_pointing_to_guiding_tissue]); - he_gradient = update_gradient(depth_to_bar(plot_depth, &displayed_dive), deco_state->bottom_he_gradient[deco_state->ci_pointing_to_guiding_tissue]); - total_gradient = ((n2_gradient * deco_state->tissue_n2_sat[deco_state->ci_pointing_to_guiding_tissue]) + (he_gradient * deco_state->tissue_he_sat[deco_state->ci_pointing_to_guiding_tissue])) - / (deco_state->tissue_n2_sat[deco_state->ci_pointing_to_guiding_tissue] + deco_state->tissue_he_sat[deco_state->ci_pointing_to_guiding_tissue]); + 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 / deco_state->buehlmann_inertgas_b[deco_state->ci_pointing_to_guiding_tissue] - 1.0) * depth_to_bar(plot_depth, &displayed_dive) + deco_state->buehlmann_inertgas_a[deco_state->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; @@ -362,17 +358,17 @@ double calc_surface_phase(double surface_pressure, double he_pressure, double n2 return 0; } -void vpmb_start_gradient() +void vpmb_start_gradient(struct deco_state *ds) { int ci; for (ci = 0; ci < 16; ++ci) { - deco_state->initial_n2_gradient[ci] = deco_state->bottom_n2_gradient[ci] = 2.0 * (vpmb_config.surface_tension_gamma / vpmb_config.skin_compression_gammaC) * ((vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma) / deco_state->n2_regen_radius[ci]); - deco_state->initial_he_gradient[ci] = deco_state->bottom_he_gradient[ci] = 2.0 * (vpmb_config.surface_tension_gamma / vpmb_config.skin_compression_gammaC) * ((vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma) / deco_state->he_regen_radius[ci]); + ds->initial_n2_gradient[ci] = ds->bottom_n2_gradient[ci] = 2.0 * (vpmb_config.surface_tension_gamma / vpmb_config.skin_compression_gammaC) * ((vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma) / ds->n2_regen_radius[ci]); + ds->initial_he_gradient[ci] = ds->bottom_he_gradient[ci] = 2.0 * (vpmb_config.surface_tension_gamma / vpmb_config.skin_compression_gammaC) * ((vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma) / ds->he_regen_radius[ci]); } } -void vpmb_next_gradient(double deco_time, double surface_pressure) +void vpmb_next_gradient(struct deco_state *ds, double deco_time, double surface_pressure) { int ci; double n2_b, n2_c; @@ -381,18 +377,18 @@ void vpmb_next_gradient(double deco_time, double surface_pressure) deco_time /= 60.0; for (ci = 0; ci < 16; ++ci) { - desat_time = deco_time + calc_surface_phase(surface_pressure, deco_state->tissue_he_sat[ci], deco_state->tissue_n2_sat[ci], log(2.0) / buehlmann_He_t_halflife[ci], log(2.0) / buehlmann_N2_t_halflife[ci]); + desat_time = deco_time + calc_surface_phase(surface_pressure, ds->tissue_he_sat[ci], ds->tissue_n2_sat[ci], log(2.0) / buehlmann_He_t_halflife[ci], log(2.0) / buehlmann_N2_t_halflife[ci]); - n2_b = deco_state->initial_n2_gradient[ci] + (vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * desat_time); - he_b = deco_state->initial_he_gradient[ci] + (vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * desat_time); + n2_b = ds->initial_n2_gradient[ci] + (vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * desat_time); + he_b = ds->initial_he_gradient[ci] + (vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * desat_time); - n2_c = vpmb_config.surface_tension_gamma * vpmb_config.surface_tension_gamma * vpmb_config.crit_volume_lambda * deco_state->max_n2_crushing_pressure[ci]; + n2_c = vpmb_config.surface_tension_gamma * vpmb_config.surface_tension_gamma * vpmb_config.crit_volume_lambda * ds->max_n2_crushing_pressure[ci]; n2_c = n2_c / (vpmb_config.skin_compression_gammaC * vpmb_config.skin_compression_gammaC * desat_time); - he_c = vpmb_config.surface_tension_gamma * vpmb_config.surface_tension_gamma * vpmb_config.crit_volume_lambda * deco_state->max_he_crushing_pressure[ci]; + he_c = vpmb_config.surface_tension_gamma * vpmb_config.surface_tension_gamma * vpmb_config.crit_volume_lambda * ds->max_he_crushing_pressure[ci]; he_c = he_c / (vpmb_config.skin_compression_gammaC * vpmb_config.skin_compression_gammaC * desat_time); - deco_state->bottom_n2_gradient[ci] = 0.5 * ( n2_b + sqrt(n2_b * n2_b - 4.0 * n2_c)); - deco_state->bottom_he_gradient[ci] = 0.5 * ( he_b + sqrt(he_b * he_b - 4.0 * he_c)); + ds->bottom_n2_gradient[ci] = 0.5 * ( n2_b + sqrt(n2_b * n2_b - 4.0 * n2_c)); + ds->bottom_he_gradient[ci] = 0.5 * ( he_b + sqrt(he_b * he_b - 4.0 * he_c)); } } @@ -418,18 +414,18 @@ double solve_cubic(double A, double B, double C) } -void nuclear_regeneration(double time) +void nuclear_regeneration(struct deco_state *ds, double time) { time /= 60.0; int ci; double crushing_radius_N2, crushing_radius_He; for (ci = 0; ci < 16; ++ci) { //rm - crushing_radius_N2 = 1.0 / (deco_state->max_n2_crushing_pressure[ci] / (2.0 * (vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma)) + 1.0 / get_crit_radius_N2()); - crushing_radius_He = 1.0 / (deco_state->max_he_crushing_pressure[ci] / (2.0 * (vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma)) + 1.0 / get_crit_radius_He()); + crushing_radius_N2 = 1.0 / (ds->max_n2_crushing_pressure[ci] / (2.0 * (vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma)) + 1.0 / get_crit_radius_N2()); + crushing_radius_He = 1.0 / (ds->max_he_crushing_pressure[ci] / (2.0 * (vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma)) + 1.0 / get_crit_radius_He()); //rs - deco_state->n2_regen_radius[ci] = crushing_radius_N2 + (get_crit_radius_N2() - crushing_radius_N2) * (1.0 - exp (-time / vpmb_config.regeneration_time)); - deco_state->he_regen_radius[ci] = crushing_radius_He + (get_crit_radius_He() - crushing_radius_He) * (1.0 - exp (-time / vpmb_config.regeneration_time)); + ds->n2_regen_radius[ci] = crushing_radius_N2 + (get_crit_radius_N2() - crushing_radius_N2) * (1.0 - exp (-time / vpmb_config.regeneration_time)); + ds->he_regen_radius[ci] = crushing_radius_He + (get_crit_radius_He() - crushing_radius_He) * (1.0 - exp (-time / vpmb_config.regeneration_time)); } } @@ -450,7 +446,7 @@ double calc_inner_pressure(double crit_radius, double onset_tension, double curr } // Calculates the crushing pressure in the given moment. Updates crushing_onset_tension and critical radius if needed -void calc_crushing_pressure(double pressure) +void calc_crushing_pressure(struct deco_state *ds, double pressure) { int ci; double gradient; @@ -459,31 +455,31 @@ void calc_crushing_pressure(double pressure) double n2_inner_pressure, he_inner_pressure; for (ci = 0; ci < 16; ++ci) { - gas_tension = deco_state->tissue_n2_sat[ci] + deco_state->tissue_he_sat[ci] + vpmb_config.other_gases_pressure; + gas_tension = ds->tissue_n2_sat[ci] + ds->tissue_he_sat[ci] + vpmb_config.other_gases_pressure; gradient = pressure - gas_tension; if (gradient <= vpmb_config.gradient_of_imperm) { // permeable situation n2_crushing_pressure = he_crushing_pressure = gradient; - deco_state->crushing_onset_tension[ci] = gas_tension; + ds->crushing_onset_tension[ci] = gas_tension; } else { // impermeable - if (deco_state->max_ambient_pressure >= pressure) + if (ds->max_ambient_pressure >= pressure) return; - n2_inner_pressure = calc_inner_pressure(get_crit_radius_N2(), deco_state->crushing_onset_tension[ci], pressure); - he_inner_pressure = calc_inner_pressure(get_crit_radius_He(), deco_state->crushing_onset_tension[ci], pressure); + n2_inner_pressure = calc_inner_pressure(get_crit_radius_N2(), ds->crushing_onset_tension[ci], pressure); + he_inner_pressure = calc_inner_pressure(get_crit_radius_He(), ds->crushing_onset_tension[ci], pressure); n2_crushing_pressure = pressure - n2_inner_pressure; he_crushing_pressure = pressure - he_inner_pressure; } - deco_state->max_n2_crushing_pressure[ci] = MAX(deco_state->max_n2_crushing_pressure[ci], n2_crushing_pressure); - deco_state->max_he_crushing_pressure[ci] = MAX(deco_state->max_he_crushing_pressure[ci], he_crushing_pressure); + ds->max_n2_crushing_pressure[ci] = MAX(ds->max_n2_crushing_pressure[ci], n2_crushing_pressure); + ds->max_he_crushing_pressure[ci] = MAX(ds->max_he_crushing_pressure[ci], he_crushing_pressure); } - deco_state->max_ambient_pressure = MAX(pressure, deco_state->max_ambient_pressure); + ds->max_ambient_pressure = MAX(pressure, ds->max_ambient_pressure); } /* add period_in_seconds at the given pressure and gas to the deco calculation */ -void add_segment(double pressure, const struct gasmix *gasmix, int period_in_seconds, int ccpo2, const struct dive *dive, int sac) +void add_segment(struct deco_state *ds, double pressure, const struct gasmix *gasmix, int period_in_seconds, int ccpo2, const struct dive *dive, int sac) { (void) sac; int ci; @@ -493,64 +489,64 @@ void add_segment(double pressure, const struct gasmix *gasmix, int period_in_sec gasmix, (double) ccpo2 / 1000.0, dive->dc.divemode); for (ci = 0; ci < 16; ci++) { - double pn2_oversat = pressures.n2 - deco_state->tissue_n2_sat[ci]; - double phe_oversat = pressures.he - deco_state->tissue_he_sat[ci]; + double pn2_oversat = pressures.n2 - ds->tissue_n2_sat[ci]; + double phe_oversat = pressures.he - ds->tissue_he_sat[ci]; double n2_f = factor(period_in_seconds, ci, N2); double he_f = factor(period_in_seconds, ci, HE); double n2_satmult = pn2_oversat > 0 ? buehlmann_config.satmult : buehlmann_config.desatmult; double he_satmult = phe_oversat > 0 ? buehlmann_config.satmult : buehlmann_config.desatmult; - deco_state->tissue_n2_sat[ci] += n2_satmult * pn2_oversat * n2_f; - deco_state->tissue_he_sat[ci] += he_satmult * phe_oversat * he_f; - deco_state->tissue_inertgas_saturation[ci] = deco_state->tissue_n2_sat[ci] + deco_state->tissue_he_sat[ci]; + ds->tissue_n2_sat[ci] += n2_satmult * pn2_oversat * n2_f; + ds->tissue_he_sat[ci] += he_satmult * phe_oversat * he_f; + ds->tissue_inertgas_saturation[ci] = ds->tissue_n2_sat[ci] + ds->tissue_he_sat[ci]; } if(decoMode() == VPMB) - calc_crushing_pressure(pressure); + calc_crushing_pressure(ds, pressure); return; } -void dump_tissues() +void dump_tissues(struct deco_state *ds) { int ci; printf("N2 tissues:"); for (ci = 0; ci < 16; ci++) - printf(" %6.3e", deco_state->tissue_n2_sat[ci]); + printf(" %6.3e", ds->tissue_n2_sat[ci]); printf("\nHe tissues:"); for (ci = 0; ci < 16; ci++) - printf(" %6.3e", deco_state->tissue_he_sat[ci]); + printf(" %6.3e", ds->tissue_he_sat[ci]); printf("\n"); } -void clear_vpmb_state() { +void clear_vpmb_state(struct deco_state *ds) { int ci; for (ci = 0; ci < 16; ci++) { - deco_state->max_n2_crushing_pressure[ci] = 0.0; - deco_state->max_he_crushing_pressure[ci] = 0.0; + ds->max_n2_crushing_pressure[ci] = 0.0; + ds->max_he_crushing_pressure[ci] = 0.0; } - deco_state->max_ambient_pressure = 0; - deco_state->first_ceiling_pressure.mbar = 0; - deco_state->max_bottom_ceiling_pressure.mbar = 0; + ds->max_ambient_pressure = 0; + ds->first_ceiling_pressure.mbar = 0; + ds->max_bottom_ceiling_pressure.mbar = 0; } -void clear_deco(double surface_pressure) +void clear_deco(struct deco_state *ds, double surface_pressure) { int ci; - clear_vpmb_state(); + clear_vpmb_state(ds); for (ci = 0; ci < 16; ci++) { - deco_state->tissue_n2_sat[ci] = (surface_pressure - ((in_planner() && (decoMode() == VPMB)) ? WV_PRESSURE_SCHREINER : WV_PRESSURE)) * N2_IN_AIR / 1000; - deco_state->tissue_he_sat[ci] = 0.0; - deco_state->max_n2_crushing_pressure[ci] = 0.0; - deco_state->max_he_crushing_pressure[ci] = 0.0; - deco_state->n2_regen_radius[ci] = get_crit_radius_N2(); - deco_state->he_regen_radius[ci] = get_crit_radius_He(); + ds->tissue_n2_sat[ci] = (surface_pressure - ((in_planner() && (decoMode() == VPMB)) ? WV_PRESSURE_SCHREINER : WV_PRESSURE)) * N2_IN_AIR / 1000; + ds->tissue_he_sat[ci] = 0.0; + ds->max_n2_crushing_pressure[ci] = 0.0; + ds->max_he_crushing_pressure[ci] = 0.0; + ds->n2_regen_radius[ci] = get_crit_radius_N2(); + ds->he_regen_radius[ci] = get_crit_radius_He(); } - deco_state->gf_low_pressure_this_dive = surface_pressure; - deco_state->gf_low_pressure_this_dive += buehlmann_config.gf_low_position_min; - deco_state->max_ambient_pressure = 0.0; + ds->gf_low_pressure_this_dive = surface_pressure; + ds->gf_low_pressure_this_dive += buehlmann_config.gf_low_position_min; + ds->max_ambient_pressure = 0.0; } -void cache_deco_state(struct deco_state **cached_datap) +void cache_deco_state(struct deco_state *src, struct deco_state **cached_datap) { struct deco_state *data = *cached_datap; @@ -558,23 +554,23 @@ void cache_deco_state(struct deco_state **cached_datap) data = malloc(sizeof(struct deco_state)); *cached_datap = data; } - *data = *deco_state; + *data = *src; } -void restore_deco_state(struct deco_state *data, bool keep_vpmb_state) +void restore_deco_state(struct deco_state *data, struct deco_state *target, bool keep_vpmb_state) { if (keep_vpmb_state) { int ci; for (ci = 0; ci < 16; ci++) { - data->bottom_n2_gradient[ci] = deco_state->bottom_n2_gradient[ci]; - data->bottom_he_gradient[ci] = deco_state->bottom_he_gradient[ci]; - data->initial_n2_gradient[ci] = deco_state->initial_n2_gradient[ci]; - data->initial_he_gradient[ci] = deco_state->initial_he_gradient[ci]; + data->bottom_n2_gradient[ci] = target->bottom_n2_gradient[ci]; + data->bottom_he_gradient[ci] = target->bottom_he_gradient[ci]; + data->initial_n2_gradient[ci] = target->initial_n2_gradient[ci]; + data->initial_he_gradient[ci] = target->initial_he_gradient[ci]; } - data->first_ceiling_pressure = deco_state->first_ceiling_pressure; - data->max_bottom_ceiling_pressure = deco_state->max_bottom_ceiling_pressure; + data->first_ceiling_pressure = target->first_ceiling_pressure; + data->max_bottom_ceiling_pressure = target->max_bottom_ceiling_pressure; } - *deco_state = *data; + *target = *data; } @@ -615,15 +611,15 @@ void set_vpmb_conservatism(short conservatism) vpmb_config.conservatism = conservatism; } -double get_gf(double ambpressure_bar, const struct dive *dive) +double get_gf(struct deco_state *ds, double ambpressure_bar, const struct dive *dive) { double surface_pressure_bar = get_surface_pressure_in_mbar(dive, true) / 1000.0; double gf_low = buehlmann_config.gf_low; double gf_high = buehlmann_config.gf_high; double gf; - if (deco_state->gf_low_pressure_this_dive > surface_pressure_bar) + if (ds->gf_low_pressure_this_dive > surface_pressure_bar) gf = MAX((double)gf_low, (ambpressure_bar - surface_pressure_bar) / - (deco_state->gf_low_pressure_this_dive - surface_pressure_bar) * (gf_low - gf_high) + gf_high); + (ds->gf_low_pressure_this_dive - surface_pressure_bar) * (gf_low - gf_high) + gf_high); else gf = gf_low; return gf; |