From 0238b47ee57c3ddaeeaf151cf2d982b7eeb83e3c Mon Sep 17 00:00:00 2001 From: Jiri Pokorny Date: Sat, 18 Jan 2025 00:15:01 +0100 Subject: [PATCH] Hidden tissues in context. --- .../scuba-physics/src/lib/AlgorithmContext.ts | 15 +++++++++--- .../src/lib/BuhlmannAlgorithm.ts | 9 ++++--- .../lib/BuhlmannAlgortihm.repetitive.spec.ts | 24 +++++++++---------- .../src/lib/CalculatedProfile.ts | 8 +++++++ .../src/lib/performanceTests.spec.ts | 8 +++---- 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/projects/scuba-physics/src/lib/AlgorithmContext.ts b/projects/scuba-physics/src/lib/AlgorithmContext.ts index dac099d8..fb53da77 100644 --- a/projects/scuba-physics/src/lib/AlgorithmContext.ts +++ b/projects/scuba-physics/src/lib/AlgorithmContext.ts @@ -1,4 +1,4 @@ -import { Tissues } from './Tissues'; +import { LoadSegment, Tissues } from './Tissues'; import { Ceiling } from './CalculatedProfile'; import { BestGasOptions, Gas, Gases, OCGasSource } from './Gases'; import { GradientFactors, SubSurfaceGradientFactors } from './GradientFactors'; @@ -23,13 +23,13 @@ export interface ContextMemento { } export class AlgorithmContext { - public tissues: Tissues; public ceilings: Ceiling[] = []; public tissueOverPressures: TissueOverPressures[] = []; public tissuesHistory: LoadedTissue[][] = []; /** in seconds */ public runTime = 0; + private tissues: Tissues; private _oxygenStarted = 0; private _currentGas: Gas; private gradients: GradientFactors; @@ -95,6 +95,11 @@ export class AlgorithmContext { return this.runTime - this._oxygenStarted; } + public get finalTissues(): LoadedTissue[] { + //TODO replace with tissuesHistory.last + return this.tissues.finalState(); + } + /** * Current gas is oxygen - For Air breaks. * Correct is to compare ppO2 is high (>= 1.6), @@ -150,11 +155,15 @@ export class AlgorithmContext { this.tissueOverPressures.push(currentOverPressures); } + public loadTissues(segment: LoadSegment, gas: Gas): number { + return this.tissues.load(segment, gas); + } + public createMemento(): ContextMemento { return { runTime: this.runTime, oxygenStarted: this._oxygenStarted, - tissues: this.tissues.finalState(), + tissues: this.finalTissues, ceilings: this.ceilings.length, tissueOverPressures: this.tissueOverPressures.length, segments: this.segments.length, diff --git a/projects/scuba-physics/src/lib/BuhlmannAlgorithm.ts b/projects/scuba-physics/src/lib/BuhlmannAlgorithm.ts index 5f8a85dc..d062258c 100644 --- a/projects/scuba-physics/src/lib/BuhlmannAlgorithm.ts +++ b/projects/scuba-physics/src/lib/BuhlmannAlgorithm.ts @@ -172,8 +172,7 @@ export class BuhlmannAlgorithm { } const merged = context.segments.mergeFlat(segments.length); - const finalTissues = context.tissues.finalState(); - return CalculatedProfile.fromProfile(merged, context.ceilings, context.tissueOverPressures, finalTissues); + return CalculatedProfile.fromProfile(merged, context.ceilings, context.tissueOverPressures, context.finalTissues); } /** @@ -217,7 +216,7 @@ export class BuhlmannAlgorithm { this.swim(context, restingSegment); // we don't have here the saturation from the dive, so we can return only the surface changes return { - finalTissues: context.tissues.finalState(), + finalTissues: context.finalTissues, tissueOverPressures: context.tissueOverPressures }; } @@ -360,7 +359,7 @@ export class BuhlmannAlgorithm { private swimPart(context: AlgorithmContext, segment: Segment) { const loadSegment = this.toLoadSegment(context.depthConverter, segment); - context.tissues.load(loadSegment, segment.gas); + context.loadTissues(loadSegment, segment.gas); context.runTime += segment.duration; // following methods slow down calculation 2x - consider speedup by extracting them context.addCeiling(); @@ -394,7 +393,7 @@ export class BuhlmannAlgorithm { let change = 1; while (context.ceiling() <= 0 && change > 0) { - change = context.tissues.load(hoverLoad, last.gas); + change = context.loadTissues(hoverLoad, last.gas); context.runTime += Time.oneMinute; } diff --git a/projects/scuba-physics/src/lib/BuhlmannAlgortihm.repetitive.spec.ts b/projects/scuba-physics/src/lib/BuhlmannAlgortihm.repetitive.spec.ts index d7c18c7d..d55db623 100644 --- a/projects/scuba-physics/src/lib/BuhlmannAlgortihm.repetitive.spec.ts +++ b/projects/scuba-physics/src/lib/BuhlmannAlgortihm.repetitive.spec.ts @@ -57,15 +57,15 @@ describe('Buhlmann Algorithm - Repetitive dives', () => { describe('Surface interval', () => { it('Isn\'t applied for 0 seconds surface interval duration', () => { const diveResult = diveOnTrimix(); - const restedTissues = applySurfaceInterval(diveResult.tissues, 0, 0); - const r1 = toTissueResult(diveResult.tissues); + const restedTissues = applySurfaceInterval(diveResult.lastTissues, 0, 0); + const r1 = toTissueResult(diveResult.lastTissues); const r2 = toTissueResult(restedTissues); expect(r1).toEqual(r2); }); it('Reset tissues to stable for infinite surface interval', () => { const diveResult = diveOnTrimix(); - const restedTissues = applySurfaceInterval(diveResult.tissues, 0, Number.POSITIVE_INFINITY); + const restedTissues = applySurfaceInterval(diveResult.lastTissues, 0, Number.POSITIVE_INFINITY); const r1 = toTissueResult(restedTissues); const r2 = toTissueResult(stableTissues); expect(r1).toEqual(r2); @@ -99,8 +99,8 @@ describe('Buhlmann Algorithm - Repetitive dives', () => { it('Adapts helium loading', () => { const diveResult = diveOnTrimix(); - const r1 = toTissueResult(diveResult.tissues); - const result2 = applySurfaceInterval(diveResult.tissues, 0, Time.oneMinute * 10); + const r1 = toTissueResult(diveResult.lastTissues); + const result2 = applySurfaceInterval(diveResult.lastTissues, 0, Time.oneMinute * 10); const r2 = toTissueResult(result2); expect(_(r1).every((item, index) => item.pHe > r2[index].pHe && item.pHe !== 0 && r2[index].pHe !== 0 @@ -109,7 +109,7 @@ describe('Buhlmann Algorithm - Repetitive dives', () => { it('Tissue come back to original state after 1.5 days surface interval', () => { const diveResult = diveOnTrimix(); - const restedTissues = applySurfaceInterval(diveResult.tissues, 0, Time.oneHour * 36); + const restedTissues = applySurfaceInterval(diveResult.lastTissues, 0, Time.oneHour * 36); const roundto = 2; // rounding to less than 1 % of error const r1 = toTissueResult(restedTissues, roundto); const r2 = toTissueResult(stableTissues, roundto); @@ -129,11 +129,11 @@ describe('Buhlmann Algorithm - Repetitive dives', () => { describe('Following dive', () => { it('Deco calculation ends with different tissues loading', () => { const firstDive = diveOnTrimix(); - const restingParameters = new RestingParameters(firstDive.tissues, Time.oneMinute * 5); + const restingParameters = new RestingParameters(firstDive.lastTissues, Time.oneMinute * 5); const secondDive = diveOnTrimix(restingParameters); - const firstTissues = toTissueResult(firstDive.tissues); - const secondTissues = toTissueResult(secondDive.tissues); + const firstTissues = toTissueResult(firstDive.lastTissues); + const secondTissues = toTissueResult(secondDive.lastTissues); // there is difference in both he and N2, some tissues have higher loading, some lower. expect(firstTissues).not.toEqual(secondTissues); @@ -142,15 +142,15 @@ describe('Buhlmann Algorithm - Repetitive dives', () => { it('Deco calculation generates reproducible results', () => { const firstDive = diveOnTrimix(); const secondDive = diveOnTrimix(); - const firstTissues = toTissueResult(firstDive.tissues); - const secondTissues = toTissueResult(secondDive.tissues); + const firstTissues = toTissueResult(firstDive.lastTissues); + const secondTissues = toTissueResult(secondDive.lastTissues); expect(firstTissues).toEqual(secondTissues); }); it('Nodeco limit are lower', () => { const firstDive = diveOnTrimix(); const firstDiveNdl = noDecoLimits(); - const restingParameters = new RestingParameters(firstDive.tissues, Time.oneMinute * 10); + const restingParameters = new RestingParameters(firstDive.lastTissues, Time.oneMinute * 10); const secondDiveNdl = noDecoLimits(restingParameters); expect(_(firstDiveNdl).every((item, index) => item > secondDiveNdl[index] )) .toBeTruthy(); diff --git a/projects/scuba-physics/src/lib/CalculatedProfile.ts b/projects/scuba-physics/src/lib/CalculatedProfile.ts index 055626d2..7e75df41 100644 --- a/projects/scuba-physics/src/lib/CalculatedProfile.ts +++ b/projects/scuba-physics/src/lib/CalculatedProfile.ts @@ -196,6 +196,14 @@ export class CalculatedProfile { return this.ceil; } + public get lastTissues(): LoadedTissue[] { + if(this.tiss.length < 1) { + return []; + } + return this.tiss; + // return this.tiss[this.tiss.length - 1]; + } + /** * Not null tissues state at end of the dive or empty in case of error. * Items are ordered as Compartments by their half time Buhlmann m-values table. diff --git a/projects/scuba-physics/src/lib/performanceTests.spec.ts b/projects/scuba-physics/src/lib/performanceTests.spec.ts index 5a51258e..ebde7406 100644 --- a/projects/scuba-physics/src/lib/performanceTests.spec.ts +++ b/projects/scuba-physics/src/lib/performanceTests.spec.ts @@ -42,7 +42,7 @@ describe('Performance', () => { expect(averageDuration).toBeLessThan(limit); }; - it('Decompression is calculated within 100 ms', () => { + it('Decompression is calculated within 150 ms', () => { const options = OptionExtensions.createOptions(0.4, 0.85, 1.4, 1.6, Salinity.salt); options.safetyStop = SafetyStop.always; options.salinity = Salinity.salt; @@ -64,7 +64,7 @@ describe('Performance', () => { const algorithm = new BuhlmannAlgorithm(); const parameters = AlgorithmParams.forMultilevelDive(segments, gases, options); - assertDuration(`Decompression calculation duration`, 100, + assertDuration(`Decompression calculation duration`, 150, () => algorithm.decompression(parameters)); }); @@ -78,7 +78,7 @@ describe('Performance', () => { () => algorithm.noDecoLimit(simpleDive)); }); - it('Consumption Max bottom time is calculated within 550 ms', () => { + it('Consumption Max bottom time is calculated within 1000 ms', () => { const consumptionOptions: ConsumptionOptions = { diver: new Diver(20), primaryTankReserve: Consumption.defaultPrimaryReserve, @@ -99,7 +99,7 @@ describe('Performance', () => { segments.add(5, tank.gas, Time.oneMinute); segments.addFlat(tank.gas, Time.oneMinute * 10); - assertDuration(`Consumption Max bottom time duration`, 550, + assertDuration(`Consumption Max bottom time duration`, 1000, () => consumption.calculateMaxBottomTime(segments, tanks, consumptionOptions, options)); }); });