David Doolette has written a blog post “GRADIENT FACTORS IN A POST-DEEP STOPS WORLD” on the GUE blog that has caught some attention on the inter webs. He summarises the state of affairs about the current sentiment against too excessive deep stops, a trend that got momentum in the wake of the NEDU study.

It’s a nice summary but for those who followed the debates about this there are not too many news except in the last paragraph where he describes his personal take away: He says that newer results indicate that the increase in allowed over-pressures with depth (in the Bühlmann model expressed by the fact that the b-parameters are smaller than one and thus the M-value grows faster than the ambient pressure) is doubtful and that in fact the algorithms used by the Navy have the allowed over-pressure independent of depth, i.e. an effective b=1 for all compartments.

As with standard dive computers you are not at liberty to change the a and b parameters of your deco model. Rather the tuneable parameters are usually the gradient factors. So he proposes to set

\(GFlow = b GFhigh\)

citing 0.83 being an average b parameter amongst tissues and thus justifying his personal choice of gradient factors to be 70/85 saying “Although the algebra is not exact, this roughly counteracts the slope of the “b” values.”

This caught my attention as many divers lack a good motivation for some specific setting of their gradient factors (besides quoting that “they always felt good with these settings” and thus ignoring that this is as best subjective anecdotal evidence for a statement the would need a much higher number of tests under controlled circumstances to have any significance.

We could add this as a feature to Subsurface where you could turn on “Doolette’s rule” and then your GFlow would automatically be set as 0.83 of your GFhigh (we could even use the actual b value for the compartment and make the GFlow depend on the compartment). Of course, since we have access to the source code, we could directly set the all the b’s to 1 by hand and get rid of the gradient factors in that mode entirely. That might involve also modifying the a’s (as the now depth independent M-value) which made me worry that I might be pulling numbers out of thin air which when implemented might cause other divers to actually use them in their diving while being without any empirical testing, something I wouldn’t like to be responsible for.

So, rather being the theoretical diver, I fired off mathematica to better understand the “non-exact algebra” and to see if it could be improved. Turns out “non-exact” is somewhat of a euphemism.

Allowed over pressure: Green is 100/100 plain vanilla Bühlmann, blue 70/85 as of Doolette, orange is actually b=1 depth independent and red is ambient pressure. All numbers are bar.

Of course, how bad this approximation is depends on the depth at which GFlow applies (i.e. the first stop depth) but from the plot it is clear that a constant M-value corresponds to smaller and smaller GFlow (as a fraction between the red and green line).

Required GFlow/GFhigh for constant M-value as a function of ambient pressure (in bar) at first stop

As you can see, for somewhat greater fist stop depths (corresponding to deeper and/or longer dives), to keep a depth independent M-value one needs such a small GFlow that I would consider this to be very well in deep stop territory, opposed to what the blog post started out with.

If you want to play around with the numbers yourself, here is the mathematica notebook.

Intro to Bühlmann/GF by H&W

In my posts here at the theoretical diver, I usually assume that besides some mathematics and physics literacy (which allows me to use formulas) my readers already know about the workings at least of the Bühlmann model and its generalisation using gradient factors.

Of course, that assumption is not always justified and for some time I wanted to write a foundational post on these topics (maybe with some personal twist, let’s see) but I never got around doing that. There is my old text (in German) but that covers only the very basics and in particular it is very short on gradient factors.

Some consolation was that there are a number of such descriptions available on the inter-webs. But now, on the occasion of the Boot trade show, there is a new one written by Ralph Lembcke und Matthias Heinrichs of Heinrichs Weikamp, the manufacturer of OSTC dive computers (and friends of the blog), Matthias and Ralph are now the principal developers of the OSTC firmware. It has a broader audience (and is in German as well) in mind and thus does a good job using diagrams instead of formulas. I like it a lot and give a strong reading recommendation (even though I might phrase the justification for using smaller GFlow differently, and there is of course my private pet peeve of not thinking of tissue half times as part of the model)!

Update September 2020: Now also available in English.

NDL and Gradient Factors

There is an interesting discussion over at ScubaBoard how the non-decompression limit (NDL) is affected by the settings for gradient factors (GFlow and GFhigh), in particular which of the two is relevant. My initial reaction was: It’s clearly GFlow, as that sets the depth of the first stop and the criterion for NDL is that the (theoretical) first stop is at a depth of 0.

Others argued that it must be GFhigh as that applies, by definition, at the surface.

And indeed, in this limit (of the first stop is at the surface) the idea of gradient factors degenerates: In that limit, the rate of change of effective gradient factor as a function of depth diverges. So, like in the last post, there is an interesting point that involves taking limits.

What I had in mind is the implementation in Subsurface: As you can see, as long as there has not been a stop yet (because the ceiling is still above the surface), the effective gradient factor is GFlow. So, in a no decompression dive, you would think, you never see anything else.

But to show that in the recreational mode in the planner turned out so be quite hard: I had to play a lot with the parameters to find a dive where GFlow has any influence on the total dive time of a recreational dive (defined as a dive without mandatory stops and without running out of gas). Eventually I found one: For an air dive to 20m (with an ascent rate of 20m/min for the last segment, see below why this is important), you get a maximal run time of 49min with GF settings 20/100 while you can stay for 50min with GF settings of 100/100. But changing GFhigh has much stronger influence:

What did I miss? In the end, it’s the fine-print of the definition of “first stop depth” that I already talked about in an earlier post: The problem is that for real world dives there is no clear distinction between ascent and stop. So you need to come up with some definition which depth one wants to use to actually anchor GFlow. Subsurface uses the lowest ceiling encountered during the dive so far. But in particular for dives with very little (or none at all) deco obligation that is not exactly what others might consider the first stop depth. The difference is that the diver first need to get to that depth of the ceiling before the ceiling actually becomes a stop depth. And during that ascent, there is already off-gassing going on which can eliminate the ceiling during the time it takes the diver to get there.

As an example, you could have a first ceiling (which as I explained above is determined by GFlow) at say 1m of depth. But then, in this last meter of water, the effective gradient factor has to vary from GFlow to GFhigh. Given that we are talking about dives that are only marginally deco dives, it is likely that this first ceiling comes form a very fast tissue so it is likely that much of it goes away during the short time of ascent to that depth. Then, to find the NDL, the remaining question is if there is ceiling left below the surface. But then the GFlow is already anchored at 1m so for the surface it’s really GFhigh (and GFlow is no longer relevant as there is no ceiling left at 1m where it applies).

So the challenge to find a dive where GFlow makes any difference at all for the NDL was to produce a dive where there is something left of the initial ceiling at the time when the diver gets there in the marginal case of staying a little bit shorter not occurring any stops at all. So the dive must not be too deep (otherwise the ascent takes too long and there is a lot of on the way off-gassing). That’s why I had to increase the ascent rate.

So the upshot is: It is almost entirely GFhigh that sets the difference between a non-stop dive and a decompression stop dive. But if you stay a little bit longer the depth of your first stop (and also the duration) depends a lot on GFlow.

I should not end without pointing out that once more this discussion is quite academic: Gradient factors were invented for dives that have significant deco obligation to force deeper stops. Here, we are in the limit of recreational no-stop diving. So we are really not in the realm of gradient factors. And this manifests itself in the degeneracy of the model in the case of the ceiling being exactly at the surface that determines the NDL. But it was interesting anyway.

VPM-B Gradients as Gradient factors

In a comment, Rick suggested that given that in the end, VPM-B computes depth dependent maximal gradients, one could compare those to the depth dependent gradients computed from the Buehlmann model and expressed as gradient factors (i.e. as percentage of the gradient of a plain vanilla Buehlmann gradient). Here is what I found when I did this.


For concreteness, I computed deco schedules with Subsurface for a dive to 120m leaving the bottom at runtime 20min with TMX18/50 (yes, I know this is far too much pO2, but for deco that does not matter), EAN50 and EAN100. For some reason, my ascent speeds are set to 9m/min up to 75% average depth, then 6m/min up to 6m and 1m/min for the final ascent. With Bühlmann with GF 30/80, I obtain a plan that reaches the surface at a runtime of 188min while for VPM-B+1 it takes only 141min.

Actually, I patched subsurface a little bit (see this branch on github) that, during deco, it prints out the allowed gradient for all tissues at all deco stops. This output I ran thru a mathematica notebook  to produce these plots:


On the x-axis, we have depth in meters while on the y-axis, we have the current gradient factor. The different colored dots are the different tissues (red being those with the shortest halft-time) with the thick dot indicating the leading tissue, i.e. the tissue that is causing the current stop.

The first diagram is Bühlmann while the second is VPM-B.

A few remarks are in order: First, why is Bühlmann not a single line from GF 30 to GF 40? This is because of the way I compute things: The exact Bühlmann a and b coefficients depend on the gas mixture currently in the tissue. In addition, what is actually computed is the maximal ambient pressure at the ceiling (which is the current depth only for the leading tissue) for that tissue and the gradient I plot is the difference between that and the current ambient pressure. So this is not exactly the right thing for tissues that are not leading. But still we see, it is a nice band of values and they all nicely move between 30% and 80%.

For the VPM-B plot, on the other hand, we see that the variation within a tissue is much less but the gradient factor varies a lot more between tissues. After all, the actual variation in gradient factor with depth comes about mainly because the leading tissue is changing and much less from the cubic curve that implements the Boyle compensation.

The other thing that is striking is the scale: At the last deco stop, the effective gradient factor is 124% for the leading tissue (while for some slower ones it is as high 180% (which never matters as that tissue never leads). In fact, a Bühlmann plan with GF 20/125 leads to a very similar profile.

Here are the actual profiles: First, Bühlmann GF 30/80





120m 7min 7min (18/50)
120m 13min 20min
51m 9min 29min
51m 2min 31min
48m 1min 32min
48m 1min 32min
45m 1min 33min
45m 2min 34min
42m 1min 35min
42m 2min 36min
39m 1min 37min
39m 4min 40min
36m 1min 41min
36m 3min 43min
33m 1min 44min
33m 4min 47min
30m 1min 48min
30m 6min 53min
27m 1min 54min
27m 6min 59min
24m 1min 60min
24m 10min 69min
21m 1min 70min
21m 5min 74min EAN50
18m 1min 75min
18m 7min 81min
15m 1min 82min
15m 8min 89min
12m 1min 90min
12m 13min 102min
9m 1min 103min
9m 20min 122min
6m 1min 123min
6m 20min 142min EAN100
3m 3min 145min
3m 40min 185min
0m 3min 188min

Then VPM-B+1: 





120m 7min 7min (18/50)
120m 13min 20min
63m 7min 27min
63m 1min 28min
57m 1min 29min
57m 1min 30min
54m 1min 31min
54m 1min 31min
51m 1min 32min
51m 2min 33min
48m 1min 34min
48m 1min 34min
45m 1min 35min
45m 2min 36min
42m 1min 37min
42m 2min 38min
39m 1min 39min
39m 3min 41min
36m 1min 42min
36m 3min 44min
33m 1min 45min
33m 3min 47min
30m 1min 48min
30m 4min 51min
27m 1min 52min
27m 5min 56min
24m 1min 57min
24m 7min 63min
21m 1min 64min
21m 4min 67min EAN50
18m 1min 68min
18m 5min 72min
15m 1min 73min
15m 6min 78min
12m 1min 79min
12m 8min 86min
9m 1min 87min
9m 12min 98min
6m 1min 99min
6m 15min 113min EAN100
3m 3min 116min
3m 22min 138min
0m 3min 141min

Finally Bühlmann 20/125:





120m 7min 7min (18/50)
120m 13min 20min
54m 8min 28min
54m 1min 29min
51m 1min 30min
51m 2min 31min
48m 1min 32min
48m 1min 32min
45m 1min 33min
45m 2min 34min
42m 1min 35min
42m 2min 36min
39m 1min 37min
39m 2min 38min
36m 1min 39min
36m 3min 41min
33m 1min 42min
33m 3min 44min
30m 1min 45min
30m 5min 49min
27m 1min 50min
27m 5min 54min
24m 1min 55min
24m 6min 60min
21m 1min 61min
21m 4min 64min EAN50
18m 1min 65min
18m 4min 68min
15m 1min 69min
15m 7min 75min
12m 1min 76min
12m 8min 83min
9m 1min 84min
9m 13min 96min
6m 1min 97min
6m 12min 108min EAN100
3m 3min 111min
3m 21min 132min
0m 3min 135min

Why is Bühlmann not like Bühlmann

I often see complaints that two different dive planning programs or dive computers do not give identical deco schedules even though both claim to implement the same decompression model. Like both being Bühlmann with gradient factors. Once you implement a model, it should deterministically give you a plan for the ascend.

And yes, in an ideal world that would be true. But in ours, the model does not exist. Even though some description of how one is supposed to compute stops is written down, there are still a lot of undefined details that are up to the implementation to decide (often enough not consciously since the ill-definedness might be rather subtle). And I am not talking about random fudge factors that programmers add to their implementations to make the schedules more conservative and to reduce the DCS risk to divers following the program or computer’s advice (like always increasing the depth by a constant amount or some percentage or letting time run faster upon tissue loading and slower during off-gassing, OSTC I am looking at you!). IN particular, for dive computers with proprietary software the customer will never know which tweaks were implemented (or even advertised as features like taking temperature or heart rate into account or breathing rate or punishing ceiling violations). I am not saying these are bad ideas, it just makes schedules hard to compare

Here, I want to discuss more subtle issues, issues that arise since models are only defined in prose and that is up to interpretation. Like the original Bühlmann model being described in his book and gradient factors essentially defined in a figure on the last page of Erik Baker’s paper. In this respect, VPM-B is different: There exist texts but I find those confusing to say the least (which was also my motivation for some previous posts) and those are silent about things like repetitive diving or how to apply the model to real logged dives rather than in planning. The actual definition of VPM-B is, however, in the original FORTRAN program. And that has deterministic output. So that is clearly defined. On the other hand, the program does not tell you about the reasoning behind it so provides no basis for extrapolation (to things like logged dives).

  • When is it time to leave a stop? All models I know provide you with a current minimal ambient pressure given the tissue loadings and the current ambient pressure. So, should you leave your stop once that minimal ambient pressure is less or equal than the ambient pressure of your next potential stop? This might be the naive guess. But one could also take into account not the current ambient pressure but that of the stop. And for gradient factors (see below), one has to take the gradient factor into account not at the current depth but at the depth of the next stop (or ceiling). I have seen implementations that got the maths of this wrong. But there is another thing that one could take into account: There is further off-gassing during the ascend to the next stop. So, the criterium should not be if the next stop is below the ceiling once i leave the previous stop but once I reach the next. To me, this is the only sensible criterium, so Subsurface does this for Bühlmann where it is not specified. But in order to be 100% compatible with the original implementation of VPM-B, using that model, we take the criterium to be the ceiling at the time of leaving the previous stop. The difference is minimal but can make stops one minute shorter or longer (and due to on-gassing on the deeper stops also influence the length of the shallower stops).
  • The next difference is in what actually constitutes stop times: Everybody wants there stops to have integer minute lengths. But what exactly is the length of a stop (which is then subject to integer rounding), starting at the time you leave the previous stop or only at the time you arrive at the next? For 9m/min ascent rate and 3m intervals, this difference is 20s. This is only a rounding effect, so the immediate difference is only one minute per stop. But again, due to on-gassing of slow tissues on deeper stops this difference can multiply at the shallower stops.
  • Looking at the graphics that is supposed to define gradient factors, Gradient factor definition one understands that the GFlow is supposed to be applied at the first stop depth. So far, so good. But what is that exactly? Is the the ceiling at the end of the bottom time? Or the deepest ceiling ever encountered during the dive? Or should we take into account the off-gassing during the ascend and take it to be the first time we actually hit the ceiling (since the first ceiling we see at the end of the bottom time might have moved up during the ascent? The last option is probably what was implied by Baker. And that might well apply to a planned dive. But not so much for a real dive: Image a carful diver that always does his stops one meter too deep (at the price of potentially longer stops). He never reaches the “first stop” in a strict sense because he always stays shy of reaching that stop and waits for it to clear before the further ascent (one could summarize his behavior also in terms of a very very slow ascent rate). So, in  a strict sense, for this diver, GFlow never applies (or only at the surface). Of course, this does not really make sense and thus, to avoid this paradox, in Subsurface we use the deepest ceiling encountered during the dive as the anchor depth for GFlow (also since for logged dives there is no clear distinction between the bottom part of the dive and the ascent).
  • Finally, there are some other smaller ill-defined bits, like in how to average things when diving with different gases (as initially N2 and He are treated separately), how to take care of the notorious water vapor (and which partial pressure assume for it).

So in summery, even if two implementations follow the letters of the definition of a decompression model, they might come up with different deco plans. For all practical purposes, those differences should be small (like a few percent of total decompression time) and thus be hidden in the much larger systematic error of all these very simple models (after all, we do not have good information about all the things that are going on in a diver’s body) but they can be big enough to make people worry since they think decompression is an exact science or even that computer programs should be deterministic. Yes, programs can be deterministic, but it is well possible that a model described only in prose has several different implementations.


PS: Something completely different: I set up a Facebook page for this blog. Subscribe it if you want to be notified whenever a new post appears!