Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/recalculate all tissues with max gf #37

Merged
merged 5 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,18 @@ jobs:
- name: Enforce formatting
run: cargo fmt --check

build:
clippy:
name: Clippy check
env:
RUSTFLAGS: "-Dwarnings"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Clippy
run: cargo clippy

build_and_test:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dive-deco"
version = "4.2.1"
version = "4.3.0"
edition = "2021"
license = "MIT"
description = "A dive decompression models library (Buehlmann ZH-L 16C)"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Current config options:
- `ceiling_type` (enum `CeilingType`)
- `Actual` (default) - both NDL time and ceiling are determined by the current tissues saturation, it counts down to a condition where calculated ceiling is below the surface
- `Adaptive` - takes into account off-gassing on ascent, determines if real deco obligation assuming direct ascent with set ascent rate
- `recalc_all_tissues_m_values` - recalculate all tissues considering gradient factors (default: true). If set to false, only leading tissue is recalculated with max gf

```rust
// fluid-interface-like built config
Expand Down
1 change: 1 addition & 0 deletions examples/config_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ fn main() {
deco_ascent_rate: 9.,
ceiling_type: CeilingType::Actual,
round_ceiling: false,
recalc_all_tissues_m_values: true,
};
let model_2 = BuehlmannModel::new(config_instance);
println!("{:?}", model_2.config());
Expand Down
7 changes: 7 additions & 0 deletions src/buehlmann/buehlmann_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct BuehlmannConfig {
pub deco_ascent_rate: AscentRatePerMinute,
pub ceiling_type: CeilingType,
pub round_ceiling: bool,
pub recalc_all_tissues_m_values: bool,
}

impl BuehlmannConfig {
Expand Down Expand Up @@ -48,6 +49,11 @@ impl BuehlmannConfig {
self.round_ceiling = round_ceiling;
self
}

pub fn with_all_m_values_recalculated(mut self, recalc_all_tissues_m_values: bool) -> Self {
self.recalc_all_tissues_m_values = recalc_all_tissues_m_values;
self
}
}

impl Default for BuehlmannConfig {
Expand All @@ -58,6 +64,7 @@ impl Default for BuehlmannConfig {
deco_ascent_rate: 10.,
ceiling_type: CeilingType::Actual,
round_ceiling: false,
recalc_all_tissues_m_values: true,
}
}
}
Expand Down
39 changes: 29 additions & 10 deletions src/buehlmann/buehlmann_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,19 +305,38 @@ impl BuehlmannModel {
}

fn recalculate_compartments(&mut self, record: &RecordData) {
let (gf_low, gf_high) = self.config.gf;
for compartment in self.compartments.iter_mut() {
compartment.recalculate(record, self.config.gf.1, self.config.surface_pressure);
compartment.recalculate(record, gf_high, self.config.surface_pressure);
}

// recalc
if gf_high != gf_low {
let max_gf = self.max_gf(self.config.gf, record.depth);
match self.config.recalc_all_tissues_m_values {
true => self.recalculate_all_tisues_with_gf(record, max_gf),
false => self.recalculate_leading_compartment_with_gf(record, max_gf),
}
}
self.recalculate_leading_compartment_with_gf(record);
}

fn recalculate_leading_compartment_with_gf(&mut self, record: &RecordData) {
let BuehlmannConfig {
gf,
surface_pressure,
..
} = self.config;
let max_gf = self.max_gf(gf, record.depth);
fn recalculate_all_tisues_with_gf(&mut self, record: &RecordData, max_gf: GradientFactor) {
let recalc_record = RecordData {
depth: record.depth,
time: 0,
gas: record.gas,
};
for compartment in self.compartments.iter_mut() {
compartment.recalculate(&recalc_record, max_gf, self.config.surface_pressure);
}
}

fn recalculate_leading_compartment_with_gf(
&mut self,
record: &RecordData,
max_gf: GradientFactor,
) {
let surface_pressure = self.config.surface_pressure;
let leading = self.leading_comp_mut();

// recalculate leading tissue with max gf
Expand Down Expand Up @@ -451,7 +470,7 @@ mod tests {

model.record(40., 30 * 60, &air);
model.record(21., 5 * 60, &air);
model.record(14., 0 * 60, &air);
model.record(14., 0, &air);
assert_eq!(model.max_gf(gf, 14.), 40);
}

Expand Down
3 changes: 1 addition & 2 deletions src/buehlmann/compartment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,8 @@ impl Compartment {
self.max_gf_adjusted_zhl_params(weighted_zhl_params, max_gf);
let p_surf = (surface_pressure as f64) / 1000.;
let p_amb = p_surf + (depth / 10.);
let m_value = a_coeff_adjusted + (p_amb / b_coeff_adjusted);

m_value
a_coeff_adjusted + (p_amb / b_coeff_adjusted)
}

// tissue inert gasses pressure after record
Expand Down
6 changes: 3 additions & 3 deletions src/common/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ pub enum InertGas {
Nitrogen,
}

impl ToString for Gas {
fn to_string(&self) -> String {
format!("{}/{}", self.o2_pp * 100., self.he_pp * 100.)
impl std::fmt::Display for Gas {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}/{}", self.o2_pp * 100., self.he_pp * 100.)
}
}

Expand Down
6 changes: 3 additions & 3 deletions tests/buehlmann_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,21 @@ fn test_multi_gas_ndl() {
let air = Gas::new(0.21, 0.);
let ean_28 = Gas::new(0.28, 0.);

model.record(30., 0 * 60, &air);
model.record(30., 0, &air);
assert_eq!(model.ndl(), 16);

model.record(30., 10 * 60, &air);
assert_eq!(model.ndl(), 6);

model.record(30., 0 * 60, &ean_28);
model.record(30., 0, &ean_28);
assert_eq!(model.ndl(), 10);
}

#[test]
fn test_ndl_with_gf() {
let mut model = fixtures::model_gf((70, 70));
let air = Gas::new(0.21, 0.);
model.record(20., 0 * 60, &air);
model.record(20., 0, &air);
assert_eq!(model.ndl(), 21);
}

Expand Down