summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Robert C. Helling <helling@atdotde.de>2017-08-25 23:21:27 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2017-08-29 06:49:44 -0700
commit456e2cec89bf53904851cce2bad7f344c64c6f98 (patch)
tree12c8dacfd0da586d6e5cd8ef5875a8c82ff023b7
parent515b7b5fea13762f8003963eca4c2a241c52dfb7 (diff)
downloadsubsurface-456e2cec89bf53904851cce2bad7f344c64c6f98.tar.gz
Cache all Buehlmann factors
not just the last one. Signed-off-by: Robert C. Helling <helling@atdotde.de>
-rw-r--r--core/deco.c50
-rw-r--r--core/planner.c1
-rw-r--r--core/qthelper.cpp18
-rw-r--r--core/qthelper.h3
-rw-r--r--core/qthelperfromc.h4
5 files changed, 43 insertions, 33 deletions
diff --git a/core/deco.c b/core/deco.c
index 33a049f7c..469679684 100644
--- a/core/deco.c
+++ b/core/deco.c
@@ -321,46 +321,34 @@ double tissue_tolerance_calc(const struct dive *dive, double pressure)
/*
* Return buelman factor for a particular period and tissue index.
*
- * We cache the last factor, since we commonly call this with the
+ * We cache the factor, since we commonly call this with the
* same values... We have a special "fixed cache" for the one second
* case, although I wonder if that's even worth it considering the
* more general-purpose cache.
*/
-struct factor_cache {
- int last_period;
- double last_factor;
-};
-
-double n2_factor(int period_in_seconds, int ci)
-{
- static struct factor_cache cache[16];
-
- if (period_in_seconds == 1)
- return buehlmann_N2_factor_expositon_one_second[ci];
-
- if (period_in_seconds != cache[ci].last_period) {
- cache[ci].last_period = period_in_seconds;
- // ln(2)/60 = 1.155245301e-02
- cache[ci].last_factor = 1 - exp(-period_in_seconds * 1.155245301e-02 / buehlmann_N2_t_halflife[ci]);
- }
- return cache[ci].last_factor;
-}
-double he_factor(int period_in_seconds, int ci)
+double factor(int period_in_seconds, int ci, enum inertgas gas)
{
- static struct factor_cache cache[16];
-
- if (period_in_seconds == 1)
- return buehlmann_He_factor_expositon_one_second[ci];
+ double factor;
+ if (period_in_seconds == 1) {
+ if (gas == N2)
+ return buehlmann_N2_factor_expositon_one_second[ci];
+ else
+ return buehlmann_He_factor_expositon_one_second[ci];
+ }
- if (period_in_seconds != cache[ci].last_period) {
- cache[ci].last_period = period_in_seconds;
+ factor = cache_value(ci, period_in_seconds, gas);
+ if (!factor) {
// ln(2)/60 = 1.155245301e-02
- cache[ci].last_factor = 1 - exp(-period_in_seconds * 1.155245301e-02 / buehlmann_He_t_halflife[ci]);
+ if (gas == N2)
+ factor = 1 - exp(-period_in_seconds * 1.155245301e-02 / buehlmann_N2_t_halflife[ci]);
+ else
+ factor = 1 - exp(-period_in_seconds * 1.155245301e-02 / buehlmann_He_t_halflife[ci]);
+ cache_insert(ci, period_in_seconds, gas, factor);
}
- return cache[ci].last_factor;
+ return factor;
}
double calc_surface_phase(double surface_pressure, double he_pressure, double n2_pressure, double he_time_constant, double n2_time_constant)
@@ -515,8 +503,8 @@ void add_segment(double pressure, const struct gasmix *gasmix, int period_in_sec
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 n2_f = n2_factor(period_in_seconds, ci);
- double he_f = he_factor(period_in_seconds, 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;
diff --git a/core/planner.c b/core/planner.c
index 9bf0436a0..61022d914 100644
--- a/core/planner.c
+++ b/core/planner.c
@@ -627,7 +627,6 @@ int wait_until(struct dive *dive, int clock, int min, int leap, int stepsize, in
{
// Round min + leap up to the next multiple of stepsize
int upper = min + leap + stepsize - 1 - (min + leap - 1) % stepsize;
- printf("clock: %d min: %d leap: %d, depth %d\n", clock / 60, min / 60, leap, depth);
// Is the upper boundary too small?
if (!trial_ascent(upper - clock, depth, target_depth, avg_depth, bottom_time, gasmix, po2, surface_pressure, dive))
return wait_until(dive, clock, upper, leap, stepsize, depth, target_depth, avg_depth, bottom_time, gasmix, po2, surface_pressure);
diff --git a/core/qthelper.cpp b/core/qthelper.cpp
index b9698e6b8..e6a4e056a 100644
--- a/core/qthelper.cpp
+++ b/core/qthelper.cpp
@@ -1710,3 +1710,21 @@ char *intdup(int index)
tmpbuf[20] = 0;
return strdup(tmpbuf);
}
+
+QHash<int, double> factor_cache;
+
+extern "C" double cache_value(int tissue, int timestep, enum inertgas inertgas)
+{
+ int key = (timestep << 5) + (tissue << 1);
+ if (inertgas == HE)
+ ++key;
+ return factor_cache.value(key);
+}
+
+extern "C" void cache_insert(int tissue, int timestep, enum inertgas inertgas, double value)
+{
+ int key = (timestep << 5) + (tissue << 1);
+ if (inertgas == HE)
+ ++key;
+ factor_cache.insert(key, value);
+}
diff --git a/core/qthelper.h b/core/qthelper.h
index ff91b771a..ac91fbc1e 100644
--- a/core/qthelper.h
+++ b/core/qthelper.h
@@ -49,5 +49,8 @@ QString getUUID();
QStringList imageExtensionFilters();
char *intdup(int index);
extern "C" int parse_seabear_header(const char *filename, char **params, int pnr);
+enum inertgas {N2, HE};
+extern "C" double cache_value(int tissue, int timestep, enum inertgas gas);
+extern "C" void cache_insert(int tissue, int timestep, enum inertgas gas, double value);
#endif // QTHELPER_H
diff --git a/core/qthelperfromc.h b/core/qthelperfromc.h
index 3ea18e7cf..dc09e224b 100644
--- a/core/qthelperfromc.h
+++ b/core/qthelperfromc.h
@@ -22,6 +22,8 @@ const char *subsurface_user_agent();
enum deco_mode decoMode();
int parse_seabear_header(const char *filename, char **params, int pnr);
extern const char *get_current_date();
-
+enum inertgas {N2, HE};
+double cache_value(int tissue, int timestep, enum inertgas gas);
+void cache_insert(int tissue, int timestep, enum inertgas gas, double value);
#endif // QTHELPERFROMC_H