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
		Add a link
		
	
		Reference in a new issue