mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
Round gas depth properly
The D in MOD, EAD, END, and EADD stands for "depth" and as such these should be mm in int rather than double. The intermediate fn2 and fhe2, however, as intermediate value should not be rounded to an integer. The upshot of this is a litle more numerical stability. It should lead to more stable values in TestProfile when run on architectures with different floating point precision. Signed-off-by: Robert C. Helling <helling@atdotde.de>
This commit is contained in:
parent
cbe6d89767
commit
9fd531dcc5
7 changed files with 31237 additions and 31232 deletions
16
core/dive.c
16
core/dive.c
|
@ -41,7 +41,7 @@ const char *divemode_text_ui[] = {
|
|||
// For writing/reading files.
|
||||
const char *divemode_text[] = {"OC", "CCR", "PSCR", "Freedive"};
|
||||
|
||||
static int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int salinity);
|
||||
static double calculate_depth_to_mbarf(int depth, pressure_t surface_pressure, int salinity);
|
||||
|
||||
/*
|
||||
* The legacy format for sample pressures has a single pressure
|
||||
|
@ -657,7 +657,7 @@ void update_setpoint_events(const struct dive *dive, struct divecomputer *dc)
|
|||
gasmix = get_gasmix_from_event(dive, ev);
|
||||
next = get_next_event(ev, "gaschange");
|
||||
}
|
||||
fill_pressures(&pressures, calculate_depth_to_mbar(dc->sample[i].depth.mm, dc->surface_pressure, 0), gasmix ,0, dc->divemode);
|
||||
fill_pressures(&pressures, lrint(calculate_depth_to_mbarf(dc->sample[i].depth.mm, dc->surface_pressure, 0)), gasmix ,0, dc->divemode);
|
||||
if (abs(dc->sample[i].setpoint.mbar - (int)(1000 * pressures.o2)) <= 50)
|
||||
dc->sample[i].setpoint.mbar = 0;
|
||||
}
|
||||
|
@ -3209,7 +3209,7 @@ static double salinity_to_specific_weight(int salinity)
|
|||
/* Pa = N/m^2 - so we determine the weight (in N) of the mass of 10m
|
||||
* of water (and use standard salt water at 1.03kg per liter if we don't know salinity)
|
||||
* and add that to the surface pressure (or to 1013 if that's unknown) */
|
||||
static int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int salinity)
|
||||
static double calculate_depth_to_mbarf(int depth, pressure_t surface_pressure, int salinity)
|
||||
{
|
||||
double specific_weight;
|
||||
int mbar = surface_pressure.mbar;
|
||||
|
@ -3221,13 +3221,17 @@ static int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int s
|
|||
if (salinity < 500)
|
||||
salinity += FRESHWATER_SALINITY;
|
||||
specific_weight = salinity_to_specific_weight(salinity);
|
||||
mbar += lrint(depth * specific_weight);
|
||||
return mbar;
|
||||
return mbar + depth * specific_weight;
|
||||
}
|
||||
|
||||
int depth_to_mbar(int depth, const struct dive *dive)
|
||||
{
|
||||
return calculate_depth_to_mbar(depth, dive->surface_pressure, dive->salinity);
|
||||
return lrint(calculate_depth_to_mbarf(depth, dive->surface_pressure, dive->salinity));
|
||||
}
|
||||
|
||||
double depth_to_mbarf(int depth, const struct dive *dive)
|
||||
{
|
||||
return calculate_depth_to_mbarf(depth, dive->surface_pressure, dive->salinity);
|
||||
}
|
||||
|
||||
double depth_to_bar(int depth, const struct dive *dive)
|
||||
|
|
|
@ -102,6 +102,7 @@ extern fraction_t best_he(depth_t depth, const struct dive *dive, bool o2narcoti
|
|||
|
||||
extern int get_surface_pressure_in_mbar(const struct dive *dive, bool non_null);
|
||||
extern int depth_to_mbar(int depth, const struct dive *dive);
|
||||
extern double depth_to_mbarf(int depth, const struct dive *dive);
|
||||
extern double depth_to_bar(int depth, const struct dive *dive);
|
||||
extern double depth_to_atm(int depth, const struct dive *dive);
|
||||
extern int rel_mbar_to_depth(int mbar, const struct dive *dive);
|
||||
|
|
|
@ -1236,15 +1236,15 @@ static void calculate_gas_information_new(const struct dive *dive, const struct
|
|||
enum divemode_t current_divemode = UNDEF_COMP_TYPE;
|
||||
|
||||
for (i = 1; i < pi->nr; i++) {
|
||||
int fn2, fhe;
|
||||
double fn2, fhe;
|
||||
struct plot_data *entry = pi->entry + i;
|
||||
|
||||
gasmix = get_gasmix(dive, dc, entry->sec, &evg, gasmix);
|
||||
amb_pressure = depth_to_bar(entry->depth, dive);
|
||||
current_divemode = get_current_divemode(dc, entry->sec, &evd, ¤t_divemode);
|
||||
fill_pressures(&entry->pressures, amb_pressure, gasmix, (current_divemode == OC) ? 0.0 : entry->o2pressure.mbar / 1000.0, current_divemode);
|
||||
fn2 = (int)(1000.0 * entry->pressures.n2 / amb_pressure);
|
||||
fhe = (int)(1000.0 * entry->pressures.he / amb_pressure);
|
||||
fn2 = 1000.0 * entry->pressures.n2 / amb_pressure;
|
||||
fhe = 1000.0 * entry->pressures.he / amb_pressure;
|
||||
if (dc->divemode == PSCR) { // OC pO2 is calulated for PSCR with or without external PO2 monitoring.
|
||||
struct gasmix gasmix2 = get_gasmix(dive, dc, entry->sec, &evg, gasmix);
|
||||
entry->scr_OC_pO2.mbar = (int) depth_to_mbar(entry->depth, dive) * get_o2(gasmix2) / 1000;
|
||||
|
@ -1255,14 +1255,14 @@ static void calculate_gas_information_new(const struct dive *dive, const struct
|
|||
* END takes O₂ + N₂ (air) into account ("Narcotic" for trimix dives)
|
||||
* EAD just uses N₂ ("Air" for nitrox dives) */
|
||||
pressure_t modpO2 = { .mbar = (int)(prefs.modpO2 * 1000) };
|
||||
entry->mod = (double)gas_mod(gasmix, modpO2, dive, 1).mm;
|
||||
entry->end = (entry->depth + 10000) * (1000 - fhe) / 1000.0 - 10000;
|
||||
entry->ead = (entry->depth + 10000) * fn2 / (double)N2_IN_AIR - 10000;
|
||||
entry->eadd = (entry->depth + 10000) *
|
||||
entry->mod = gas_mod(gasmix, modpO2, dive, 1).mm;
|
||||
entry->end = mbar_to_depth(lrint(depth_to_mbarf(entry->depth, dive) * (1000 - fhe) / 1000.0), dive);
|
||||
entry->ead = mbar_to_depth(lrint(depth_to_mbarf(entry->depth, dive) * fn2 / (double)N2_IN_AIR), dive);
|
||||
entry->eadd = mbar_to_depth(lrint(depth_to_mbarf(entry->depth, dive) *
|
||||
(entry->pressures.o2 / amb_pressure * O2_DENSITY +
|
||||
entry->pressures.n2 / amb_pressure * N2_DENSITY +
|
||||
entry->pressures.he / amb_pressure * HE_DENSITY) /
|
||||
(O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) * 1000 - 10000;
|
||||
(O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) * 1000), dive);
|
||||
entry->density = gas_density(gasmix, depth_to_mbar(entry->depth, dive));
|
||||
if (entry->mod < 0)
|
||||
entry->mod = 0;
|
||||
|
@ -1452,22 +1452,22 @@ static void plot_string(const struct dive *d, const struct plot_info *pi, int id
|
|||
if (prefs.pp_graphs.phe && entry->pressures.he > 0)
|
||||
put_format_loc(b, translate("gettextFromC", "pHe: %.2fbar\n"), entry->pressures.he);
|
||||
if (prefs.mod && entry->mod > 0) {
|
||||
mod = lrint(get_depth_units(lrint(entry->mod), NULL, &depth_unit));
|
||||
mod = lrint(get_depth_units(entry->mod, NULL, &depth_unit));
|
||||
put_format_loc(b, translate("gettextFromC", "MOD: %d%s\n"), mod, depth_unit);
|
||||
}
|
||||
eadd = lrint(get_depth_units(lrint(entry->eadd), NULL, &depth_unit));
|
||||
eadd = lrint(get_depth_units(entry->eadd, NULL, &depth_unit));
|
||||
|
||||
if (prefs.ead) {
|
||||
switch (pi->dive_type) {
|
||||
case NITROX:
|
||||
if (entry->ead > 0) {
|
||||
ead = lrint(get_depth_units(lrint(entry->ead), NULL, &depth_unit));
|
||||
ead = lrint(get_depth_units(entry->ead, NULL, &depth_unit));
|
||||
put_format_loc(b, translate("gettextFromC", "EAD: %d%s\nEADD: %d%s / %.1fg/ℓ\n"), ead, depth_unit, eadd, depth_unit, entry->density);
|
||||
break;
|
||||
}
|
||||
case TRIMIX:
|
||||
if (entry->end > 0) {
|
||||
end = lrint(get_depth_units(lrint(entry->end), NULL, &depth_unit));
|
||||
end = lrint(get_depth_units(entry->end, NULL, &depth_unit));
|
||||
put_format_loc(b, translate("gettextFromC", "END: %d%s\nEADD: %d%s / %.1fg/ℓ\n"), end, depth_unit, eadd, depth_unit, entry->density);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ struct plot_data {
|
|||
pressure_t o2sensor[3]; //for rebreathers with up to 3 PO2 sensors
|
||||
pressure_t o2setpoint;
|
||||
pressure_t scr_OC_pO2;
|
||||
double mod, ead, end, eadd;
|
||||
int mod, ead, end, eadd;
|
||||
velocity_t velocity;
|
||||
int speed;
|
||||
// stats over 9 minute window:
|
||||
|
|
|
@ -77,10 +77,10 @@ static void put_pd(struct membuffer *b, const struct plot_info *pi, int idx)
|
|||
put_int(b, entry->o2sensor[2].mbar);
|
||||
put_int(b, entry->o2setpoint.mbar);
|
||||
put_int(b, entry->scr_OC_pO2.mbar);
|
||||
put_double(b, entry->mod);
|
||||
put_double(b, entry->ead);
|
||||
put_double(b, entry->end);
|
||||
put_double(b, entry->eadd);
|
||||
put_int(b, entry->mod);
|
||||
put_int(b, entry->ead);
|
||||
put_int(b, entry->end);
|
||||
put_int(b, entry->eadd);
|
||||
switch (entry->velocity) {
|
||||
case STABLE:
|
||||
put_csv_string(b, "STABLE");
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue