[PATCH] Unify ceiling calculation between Buehlmann and VPM-B

Robert Helling helling at lmu.de
Sat Aug 15 07:19:12 PDT 2015


On 15 Aug 2015, at 13:49, Dirk Hohndel <dirk at hohndel.org> wrote:

Hi Dirk,

> Please remind me, what is missing to be able to show VPM-B ceilings for
> logged dives? I remember there was something about the way VPM-B makes
> assumptions about remainder of the dive…

OK, here is VPM-B in a nutshell (not totally accurate but you get the idea): It uses the same tissue loadings as Buehlmann to start with. Then, for a given loading, one needs to know how far to ascent, i.e. what is the minimal ambient pressure. While for Buehlmann that is a linear function of the depth (something like

max. allowed overpressure = const1 * ambient pressure + const2 )

the max allowed overpressure (“gradient” in the model’s parlance) is constant over the ascent. But it varies from dive to dive and is determined by the requirement (here is where I am simplifying a bit) that the gradient times the total deco time (plus a but for the remaining desaturation at the surface) should be below a given value. The idea is that the rate at which bubbles are produced is proportional to the gradient, so the total number is the gradient times the deco time.

So, one guesses a gradient, computes a deco schedule and thus the total deco time. Then the gradient gets adopted iteratively until the criterion is met (not even clear to be if the gradient is increased — as then the deco is shortened — or decreased as then the first factor in the product gets smaller).

So that is the theory. And for a planned dive, with my patch, we simply plot the ceiling based on the gradient that was computed as described in the previous paragraph. To do so, we need do know this gradient to which we converged to (one per tissue actually), total_gradient[ci]. When not in planner anymore, this value is not stored (we could do that but I doubt that makes much sense and is not available for real dives anyway), so we cannot plot the ceiling outside the planner.

For a real dive, the above product gradient * deco time could of course be replaced by the integral of the gradient over the deco time. But different from Buehlmann, where at each point during the dive we can check if we violate a ceiling, for VPMB the criterion for a good deco is really this integral (representing the total volume of gas in bubbles). We can of course print this number (or this number as a percentage of the allowed value). But this is not a thing we can plot as a function of time.

What I proposed to plot instead as a function of time is the rate of bubbling (i.e. the gradient) in units of the rate accruing to VPM-B to meet the criterion assuming the total deco time of the dive.

Does this explain the problem?
> 
> Yet another case where I wish that there was a diff that handled
> indentation changes better. It's really hard to see what was actually done
> here. :-)
> 

Indeed. I added an if clause and the old code is in the “true” path and there is a new “false” path.

> Sure, that's a way to do that. We have way too many global variables that
> hold some state like that :-(
> 
> You could just as easily have a helper function that queries the state and
> is callable from C. That way we only have to keep the actual state once
> and can simply access it from the C routines as well.

I tried not to violate the “C++ calls C but not the other way around” rule (and, honestly, I did not know how to do it actually.

I am about to leave for my vacation (just taking a break from packing bags). I will have internet there but I don’t know when I have time again. Right now, I don’t have time to do the helper function, but I can promise to look into this once I have time again.

> 
>> @@ -879,15 +887,11 @@ bool trial_ascent(int trial_depth, int stoplevel, int avg_depth, int bottom_time
>> 		tissue_tolerance = add_segment(depth_to_mbar(trial_depth, &displayed_dive) / 1000.0,
>> 					       gasmix,
>> 					       TIMESTEP, po2, &displayed_dive, prefs.decosac);
>> -		if (prefs.deco_mode != VPMB && deco_allowed_depth(tissue_tolerance, surface_pressure, &displayed_dive, 1) > trial_depth - deltad) {
>> +		if (deco_allowed_depth(tissue_tolerance, surface_pressure, &displayed_dive, 1) > trial_depth - deltad) {
>> 			/* We should have stopped */
>> 			clear_to_ascend = false;
>> 			break;
>> 		}
>> -		if (prefs.deco_mode == VPMB && (!is_vpmb_ok(depth_to_mbar(trial_depth, &displayed_dive) / 1000.0))){
>> -			clear_to_ascend = false;
>> -			break;
>> -		}
> 
> Can you explain this part, please? So with the changes made above
> deco_allowed_depth() now works in both VPM-B and Buehlmann mode?
> I'm guessing that's the side effect of adjusting tissue_tolerance_calc()
> but it would be nice to have that explicitly explained in the commit
> message.

Indeed, that was the intention of the whole patch. But, as explained above, only if the data in total_gradient[] is valid (which is the case only in the planner). Therefore, outside the planner it always uses the Buehlmann ceiling.

Again, I am not on my coding computer, so cannot just send patch with updated commit message.

Would you mind adding

“This patch makes deco_alled_depthO() work both for Buehlmann as well as VPM-B (as long as the VPM-B internal variable total_gradient[] is valid).”

to the commit message if you decide to take the patch?

> 
> OK, admittedly that should keep things in sync. Still, it seems rather
> awkward to me.

I felt the same. As I said, in a few days, I should be abel to update the to using a helper function (in C++ to be called from C).

Best
Robert

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 203 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.subsurface-divelog.org/pipermail/subsurface/attachments/20150815/7861e29b/attachment.sig>


More information about the subsurface mailing list