-
Notifications
You must be signed in to change notification settings - Fork 0
Model 03 Schreiner Equation
Applies when the ambient pressure changes at a constant linear rate — i.e. descent at a fixed m/min, ascent at a fixed m/min. This is the workhorse of DecoJS: every segment between waypoints except pure level-offs gets dispatched through Schreiner.
Origin: Schreiner & Kelley 1971 (see References). The closed-form solution of the Haldane ODE with a time-varying alveolar source.
// js/decoModel.js:125-130
export function schreinerEquation(initialPressure, initialAlveolarPressure, rate, time, halfTime) {
const k = getRateConstant(halfTime);
const term1 = initialAlveolarPressure + rate * (time - 1/k);
const term2 = (initialAlveolarPressure - initialPressure - rate/k) * Math.exp(-k * time);
return term1 - term2;
}Note:
Examples (air,
| Depth rate (m/min) | Direction |
|
|
|---|---|---|---|
| +20 | Descent | +2.0 | +1.5804 |
| +10 | Descent | +1.0 | +0.7902 |
| −10 | Ascent | −1.0 | −0.7902 |
| −9 | Ascent | −0.9 | −0.7112 |
On EAN32 (
Useful as a mental model — rewrite as:
The first two terms together ($P_{alv,0} + R(t - 1/k)$) describe a tissue that perfectly tracks the alveolar pressure but lags by
Ascent from 30 m to 21 m at 10 m/min, TC5 (variant C:
Segment time:
Rate constant:
Alveolar N₂ at 30 m (start):
Initial tissue (saturated at 30 m):
Rate:
Plugging in:
Tissue barely moved — TC5 is slow relative to a 0.9-min segment. Compare to TC1 (
simulateDepthChange() runs Schreiner across all 16 compartments for a single linear segment:
// js/decoModel.js:860 (signature)
export function simulateDepthChange(tissuePressures, startDepth, endDepth, time, n2Fraction)calculateTissueLoading() iterates across an entire waypoint array:
// js/decoModel.js:1178 (signature)
export function calculateTissueLoading(profile, surfaceInterval = 60, options = {})It samples at 10-second resolution (CALC_INTERVAL = 10 s) — for each interval it decides descent/level/ascent and dispatches to Haldane or Schreiner accordingly, threading tissue state forward. Gas switches are respected via the gasId field on waypoints.
When
Exactly the Haldane equation. DecoJS still dispatches to haldaneEquation() separately on level segments for code clarity — the arithmetic is equivalent either way, but numerical stability is better when you don't pass
- Model-02-Haldane-Equation — the constant-depth specialization.
- Algo-01-Ascent-Simulation — the loop that drives Schreiner through a dive.
- References — Schreiner & Kelley 1971, plus Baker's "Clearing Up The Confusion About 'Deep Stops'" which derives the same form in modern notation.