Source code for decotengu.alt.naive

#
# DecoTengu - dive decompression library.
#
# Copyright (C) 2013-2018 by Artur Wroblewski <wrobell@riseup.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

"""
Naive Algorithms
----------------
There are various algorithms, which can be used for decompression
calculations. The ``decotengu.alt.naive`` module implements some of them,
i.e. calculation of decompression stop length using 1 minute intervals.

The algorithms are quite inefficient, usually :math:`O(n)` while algorithm
of complexity :math:`O(log(n))` could be used. They are implemented in
DecoTengu for comparison purposes only.

Decompression Stop Stepper
~~~~~~~~~~~~~~~~~~~~~~~~~~
The decompression stop stepper is simple algorithm to calculate length of
a decompression stop.

Decompression stop length is calculated by increasing length of the stop
by one minute until it is possible to ascend to next stop or to the
surface.

The algorithm is implemented by :py:class:`decotengu.alt.naive.DecoStopStepper`
class.

The complexity of the algorithm is :math:`O(n)`, where :math:`n` is length
of decompression stop in minutes.
"""

#- ascent jump - go to next depth, then calculate tissue saturation for
#  time, which would take to get from previous to next depth (can be used
#  when trying to avoid Schreiner equation)

import logging

from ..engine import Phase, Step, ConfigError
from .. import const

logger = logging.getLogger(__name__)

class AscentJumper(object):
    """
    Ascent by jumping (teleporting).

    Simulate ascent by jumping to shallower depth and stay there for
    appropriate amount of time. The depth jump and time are determined by
    ascent rate, i.e. for 10m/min the depth jump is 10m and time is 1 minute.

    Such ascent simulation allows to avoid Schreiner equation, but is less
    accurate. The longer depth jump, the less accuracy. Do not use for
    ascents faster than 10m/min.

    :var engine: DecoTengu decompression engine.
    """
    def __init__(self, engine):
        """
        Create ascent jumper object.

        :param engine: DecoTengu decompression engine.
        """
        self.engine = engine


    def __call__(self, start, abs_p, gas):
        """
        Ascent from start dive step to destination depth (its absolute
        pressure) using specified gas mix.

        .. seealso:: `decotengu.Engine._free_ascent`
        """
        logger.debug('executing ascent jumper')
        engine = self.engine
        ascent_rate = engine.ascent_rate
        model = engine.model
        if ascent_rate > 10:
            raise ConfigError(
                'Ascent jumper requires ascent rate lower than 10m/min'
            )

        t = engine._pressure_to_time(start.abs_p - abs_p, ascent_rate)
        end_time = int(start.time + t)
        logger.debug(
            'ascent from {0.abs_p}bar ({0.time}min) to {1}bar ({2}min))'
            .format(start, abs_p, end_time)
        )

        step = start
        minute = const.MINUTE
        dp = engine._time_to_pressure(minute, ascent_rate)
        for i in range(start.time, end_time, minute):
            abs_p = step.abs_p - dp # jump
            data = model.load(abs_p, minute, gas, 0, step.data)
            step = Step(Phase.DECO_STOP, abs_p, step.time + minute, gas, data)
            yield step



[docs]class DecoStopStepper(object): """ Execute decompression stop using 1min intervals. The algorithm is quite inefficient, but is used by some of the diving computers and software, so this class is created for comparison purposes. :var engine: DecoTengu decompression engine. .. seealso:: :py:meth:`decotengu.Engine._deco_stop` """ def __init__(self, engine): """ Create deco stop stepper object. :param engine: DecoTengu decompression engine. """ self.engine = engine
[docs] def __call__(self, start, time, gas, gf): """ Execute dive decompression stop using 1min intervals. .. seealso:: :py:meth:`decotengu.Engine._deco_stop` """ engine = self.engine abs_p = start.abs_p if __debug__: depth = engine._to_depth(abs_p) assert depth % 3 == 0 logger.debug('deco stepper: deco stop at {}m'.format(depth)) minute = const.MINUTE data = engine._tissue_pressure_const(abs_p, minute, gas, start.data) deco_time = minute while not engine._can_ascend(abs_p, time, data, gf): data = engine._tissue_pressure_const(abs_p, minute, gas, data) deco_time += minute if __debug__: logger.debug('deco stepper: time {}min'.format(deco_time)) step = start._replace( phase=Phase.DECO_STOP, time=start.time + deco_time, data=data ) return step
# vim: sw=4:et:ai