diff options
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; |