@sh.add_function(
dsp, inputs_kwargs=True, inputs_defaults=True,
outputs=['co2_params_initial_guess', 'initial_friction_params']
)
def define_initial_co2_emission_model_params_guess(
co2_params, engine_type, engine_thermostat_temperature,
engine_thermostat_temperature_window,
engine_n_cylinders=dfl.values.engine_n_cylinders,
is_cycle_hot=dfl.values.is_cycle_hot):
"""
Selects initial guess and bounds of co2 emission model params.
:param co2_params:
CO2 emission model params (a2, b2, a, b, c, l, l2, t, trg).
:type co2_params: dict
:param engine_type:
Engine type (positive turbo, positive natural aspiration, compression).
:type engine_type: str
:param engine_thermostat_temperature:
Engine normalization temperature [°C].
:type engine_thermostat_temperature: float
:param engine_thermostat_temperature_window:
Thermostat engine temperature limits [°C].
:type engine_thermostat_temperature_window: (float, float)
:param engine_n_cylinders:
Number of engine cylinders [-].
:type engine_n_cylinders: int
:param is_cycle_hot:
Is an hot cycle?
:type is_cycle_hot: bool, optional
:return:
Initial guess of co2 emission model params and of friction params.
:rtype: lmfit.Parameters, list[float]
"""
import lmfit
import collections
bounds = {} # Parameters bounds.
par = dfl.functions.define_initial_co2_emission_model_params_guess
default = collections.OrderedDict(
copy.deepcopy(par.CO2_PARAMS[engine_type])
)
default['trg'] = {
'value': engine_thermostat_temperature,
'min': engine_thermostat_temperature_window[0],
'max': engine_thermostat_temperature_window[1],
'vary': False
}
keys, n = ('l', 'l2'), engine_n_cylinders / default.pop('n_cylinders', 4)
for d in sh.selector(keys, default, allow_miss=True).values():
for k in {'value', 'min', 'max'}.intersection(d):
d[k] *= n
if is_cycle_hot:
default['t1'].update({'value': 0.0, 'vary': False})
default['dt'].update({'value': 0.0, 'vary': False})
p = lmfit.Parameters()
eps = dfl.EPS
for k, kw in default.items():
kw['name'] = k
kw['value'] = co2_params.get(k, kw.get('value', None))
if k in bounds:
b = bounds[k]
kw['min'] = b.get('min', kw.get('min', None))
kw['max'] = b.get('max', kw.get('max', None))
kw['vary'] = b.get('vary', kw.get('vary', True))
elif 'vary' not in kw:
kw['vary'] = k not in co2_params
if kw['value'] is not None:
if 'min' in kw and kw['value'] < kw['min']:
kw['min'] = kw['value'] - eps
if 'max' in kw and kw['value'] > kw['max']:
kw['max'] = kw['value'] + eps
if 'min' in kw and 'max' in kw and kw['min'] == kw['max']:
kw['vary'] = False
# noinspection PyTypeChecker
kw['max'] = kw['min'] = None
kw['min'] = kw.get('min', None)
kw['max'] = kw.get('max', None)
p.add(**kw)
friction_params = _select_initial_friction_params(p)
if not _missing_co2_params(co2_params):
p = sh.NONE
return p, friction_params