Source code for co2mpas.core.model.physical.final_drive

# -*- coding: utf-8 -*-
#
# Copyright 2015-2019 European Commission (JRC);
# Licensed under the EUPL (the 'Licence');
# You may not use this work except in compliance with the Licence.
# You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
"""
Functions and `dsp` model to model the final drive.
"""

import logging
import collections
import numpy as np
import schedula as sh
from co2mpas.defaults import dfl

log = logging.getLogger(__name__)

dsp = sh.BlueDispatcher(
    name='Final drive', description='Models the final drive.'
)
dsp.add_data('final_drive_ratio', dfl.values.final_drive_ratio)


[docs]@sh.add_function(dsp, inputs_kwargs=True, outputs=['final_drive_ratios']) def calculate_final_drive_ratios(final_drive_ratio, n_gears=1): """ Defines final drive ratios for each gear [-]. :param final_drive_ratio: Final drive ratio [-]. :type final_drive_ratio: float :param n_gears: Number of gears [-]. :type n_gears: int, optional :return: Final drive ratios [-]. :rtype: dict """ d = collections.defaultdict(lambda: final_drive_ratio) d.update(dict.fromkeys(range(0, int(n_gears + 1)), final_drive_ratio)) return d
# noinspection PyUnusedLocal,PyMissingOrEmptyDocstring
[docs]def is_not_manual_or_automatic(gear_box_type, *args): return gear_box_type not in ('manual', 'automatic')
dsp.add_function( function=sh.add_args(calculate_final_drive_ratios), inputs=['gear_box_type', 'final_drive_ratio'], outputs=['final_drive_ratios'], input_domain=is_not_manual_or_automatic )
[docs]@sh.add_function(dsp, outputs=['final_drive_ratio_vector']) def calculate_final_drive_ratio_vector(final_drive_ratios, gears): """ Calculates the final drive ratio vector [-]. :param final_drive_ratios: Final drive ratios [-]. :type final_drive_ratios: dict[int, float | int] :param gears: Gear vector [-]. :type gears: numpy.array :return: Final drive ratio vector [-]. :rtype: numpy.array """ fdr0 = final_drive_ratios[min(final_drive_ratios)] d = collections.defaultdict(lambda: fdr0) d.update(final_drive_ratios) return np.vectorize(lambda k: d[k])(gears)
[docs]@sh.add_function(dsp, outputs=['final_drive_speeds_in']) def calculate_final_drive_speeds_in( final_drive_speeds_out, final_drive_ratio_vector): """ Calculates final drive speed [RPM]. :param final_drive_speeds_out: Rotating speed of the wheel [RPM]. :type final_drive_speeds_out: numpy.array | float :param final_drive_ratio_vector: Final drive ratio vector [-]. :type final_drive_ratio_vector: numpy.array | float :return: Final drive speed in [RPM]. :rtype: numpy.array | float """ return final_drive_speeds_out * final_drive_ratio_vector
dsp.add_data('n_wheel_drive', dfl.values.n_wheel_drive)
[docs]@sh.add_function(dsp, outputs=['final_drive_efficiency']) def default_final_drive_efficiency(n_wheel_drive): """ Returns the default final drive efficiency [-]. :param n_wheel_drive: Number of wheel drive [-]. :type n_wheel_drive: int :return: Final drive efficiency [-]. :rtype: float """ from asteval import Interpreter as Interp formula = dfl.functions.default_final_drive_efficiency.formula return Interp(dict(n_wheel_drive=n_wheel_drive)).eval(formula)
[docs]@sh.add_function(dsp, outputs=['final_drive_powers_in']) def calculate_final_drive_powers_in( final_drive_powers_out, final_drive_efficiency): """ Calculate final drive power in [kW]. :param final_drive_powers_out: Final drive power out [kW]. :type final_drive_powers_out: numpy.array | float :param final_drive_efficiency: Final drive efficiency [-]. :type final_drive_efficiency: float :return: Final drive power in [kW]. :rtype: numpy.array | float """ eff, p = final_drive_efficiency, final_drive_powers_out return np.where(p > 0, eff, 1 / eff) * p
[docs]@sh.add_function(dsp, outputs=['final_drive_torques_in']) def calculate_final_drive_torques_in( final_drive_powers_in, final_drive_speeds_in): """ Calculate final drive power in [kW]. :param final_drive_powers_in: Final drive power in [kW]. :type final_drive_powers_in: numpy.array | float :param final_drive_speeds_in: Final drive speed in [RPM]. :type final_drive_speeds_in: numpy.array | float :return: Final drive torque in [N*m]. :rtype: numpy.array | float """ from .wheels import calculate_wheel_torques as func return func(final_drive_powers_in, final_drive_speeds_in)
dsp.add_function( function=sh.bypass, inputs=['final_drive_efficiency'], outputs=['final_drive_mean_efficiency'] ) # noinspection PyUnusedLocal
[docs]def domain_final_drive_torque_losses_v1(n_dyno_axes, n_wheel_drive, *args): """ Check the validity of number of wheel drive respect to the dyno axes assuming 2 wheels per axes. :param n_dyno_axes: Number of dyno axes [-]. :type n_dyno_axes: int :param n_wheel_drive: Number of wheel drive [-]. :type n_wheel_drive: int :return: True and log a waring if `n_wheel_drive` does not respect the domain. :rtype: bool """ if n_dyno_axes < n_wheel_drive / 2: msg = 'WARNING: n_dyno_axes(%d) < n_wheel_drive(%d) / 2!' log.warning(msg, n_dyno_axes, n_wheel_drive) return True