Skip to content

ecnet.blends

equations

Helper equations for functions in .predict.py

celsius_to_rankine(temp)

Converts temperature in celsius to temperature in rankine

Parameters:

Name Type Description Default
temp float

supplied temperature, in celsius

required

Returns:

Type Description
float

float: temperature in rankine

Source code in ecnet/blends/equations.py
def celsius_to_rankine(temp: float) -> float:
    """
    Converts temperature in celsius to temperature in rankine

    Args:
        temp (float): supplied temperature, in celsius

    Returns:
        float: temperature in rankine
    """

    return (9 / 5) * temp + 491.67

exponential_blend_err(values, result, errors, proportions, a, b)

Calculates the error of a blend whose equation is defined as $$ f = aA^b $$

$$ f = aA^b \rightarrow err_f^2 = (abA^{b-1}err_A)^2 = (fberr_A / A)^2 \rightarrow \sum $$

Parameters:

Name Type Description Default
values List[float]

predicted values

required
result float

resulting blend property value

required
errors List[float]

errors for predicted values in values

required
proportions List[float]

contribution of each value to blend; sum = 1

required
a float

scalar coefficient preceeding variable A

required
b float

exponential coefficient which A is raised to

required

Returns:

Type Description
float

float: weighed exponential error

Source code in ecnet/blends/equations.py
def exponential_blend_err(values: List[float], result: float, errors: List[float],
                          proportions: List[float], a: float, b: float) -> float:
    """
    Calculates the error of a blend whose equation is defined as $$ f = aA^b $$

    $$ f = aA^b \\rightarrow err_f^2 = (abA^{b-1}err_A)^2 = (fberr_A / A)^2
    \\rightarrow \\sum $$

    Args:
        values (list[float]): predicted values
        result (float): resulting blend property value
        errors (list[float]): errors for predicted values in `values`
        proportions (list[float]): contribution of each value to blend; sum = 1
        a (float): scalar coefficient preceeding variable A
        b (float): exponential coefficient which A is raised to

    Returns:
        float: weighed exponential error
    """

    total_error = 0.0
    for idx, err in enumerate(errors):
        total_error += (((result * b * err) / values[idx]) * proportions[idx])**2
    return sqrt(total_error)

kv_error(values, errors, proportions)

Calculates the error of a KV blend whose equation is in the form $$ f=aln(bA) $$

$$ f = aln(bA) \rightarrow err_f^2 = (a * err_A / A)^2 \rightarrow \sum $$ for KV, $$a = 1.0, b = 2000$$

Parameters:

Name Type Description Default
values List[float]

predicted values

required
errors List[float]

errors for predicted values in values

required
proportions List[float]

contribution of each value to blend; sum = 1

required

Returns:

Type Description
float

float: weighted inverse logarithmic error for KV blend

Source code in ecnet/blends/equations.py
def kv_error(values: List[float], errors: List[float], proportions: List[float]) -> float:
    """
    Calculates the error of a KV blend whose equation is in the form $$ f=aln(bA) $$

    $$ f = aln(bA) \\rightarrow err_f^2 = (a * err_A / A)^2 \\rightarrow \\sum $$
    for KV, $$a = 1.0, b = 2000$$

    Args:
        values (list[float]): predicted values
        errors (list[float]): errors for predicted values in `values`
        proportions (list[float]): contribution of each value to blend; sum = 1

    Returns:
        float: weighted inverse logarithmic error for KV blend
    """

    total_error = 0.0
    for idx, err in enumerate(errors):
        total_error += (proportions[idx] * err / values[idx])**2
    return sqrt(total_error)

linear_blend_ave(values, proportions)

Calculates the linear combination of multiple values given discrete proportions for each value

Parameters:

Name Type Description Default
values List[float]

list of values to form linear average

required
proportions List[float]

proportions of each value in values; should sum to 1; len(proportions) == len(values)

required

Returns:

Type Description
float

float: weighted linear average

Source code in ecnet/blends/equations.py
def linear_blend_ave(values: List[float], proportions: List[float]) -> float:
    """
    Calculates the linear combination of multiple values given discrete
    proportions for each value

    Args:
        values (list[float]): list of values to form linear average
        proportions (list[float]): proportions of each value in `values`; should sum
            to 1; len(proportions) == len(values)

    Returns:
        float: weighted linear average
    """

    weighted_ave = 0
    for idx, proportion in enumerate(proportions):
        weighted_ave += (proportion * values[idx])
    return weighted_ave

linear_blend_err(errors, proportions)

Calculates the linear combination of multiple errors given discrete proportions for each value

$$ f = aA \rightarrow error^2 = a^2 * error_A^2 \rightarrow error^2 \rightarrow \sum $$

Parameters:

Name Type Description Default
errors List[float]

list of error values

required
proportions List[float]

proportions of each value in values; should sum to 1; len(proportions) == len(errors)

required

Returns:

Type Description
float

float: weighted linear error

Source code in ecnet/blends/equations.py
def linear_blend_err(errors: List[float], proportions: List[float]) -> float:
    """
    Calculates the linear combination of multiple errors given discrete
    proportions for each value

    $$ f = aA \\rightarrow error^2 = a^2 * error_A^2 \\rightarrow error^2 \\rightarrow \\sum $$

    Args:
        errors (list[float]): list of error values
        proportions (list[float]): proportions of each value in `values`; should sum
            to 1; len(proportions) == len(errors)

    Returns:
        float: weighted linear error
    """

    total_error = 0.0
    for idx, err in enumerate(errors):
        total_error += (err * proportions[idx])**2
    return sqrt(total_error)

rankine_to_celsius(temp)

Converts temperature in rankine to temperature in celsius

Parameters:

Name Type Description Default
temp float

temperature in rankine

required

Returns:

Type Description
float

float: temperature in celsius

Source code in ecnet/blends/equations.py
def rankine_to_celsius(temp: float) -> float:
    """
    Converts temperature in rankine to temperature in celsius

    Args:
        temp (float): temperature in rankine

    Returns:
        float: temperature in celsius
    """

    return (temp - 491.67) * (1 / (9 / 5))

predict

Functions for predicting blend properties

cetane_number(values, vol_fractions)

Calculates blended CN from individual CNs, volume fractions of each individual CN in blend; blend assumed proportionally linear: NREL/SR-540-36805

Parameters:

Name Type Description Default
values List[float]

CN values

required
vol_fractions List[float]

list of volume fractions, sum(vol_fractions) == 1.0

required

Returns:

Type Description
float

float: blended CN

Source code in ecnet/blends/predict.py
def cetane_number(values: List[float], vol_fractions: List[float]) -> float:
    """
    Calculates blended CN from individual CNs, volume fractions of each individual CN in blend;
    blend assumed proportionally linear: NREL/SR-540-36805

    Args:
        values (list[float]): CN values
        vol_fractions (list[float]): list of volume fractions, sum(vol_fractions) == 1.0

    Returns:
        float: blended CN
    """

    return linear_blend_ave(values, vol_fractions)

cloud_point(values, vol_fractions)

Calculates blended CP from individual CPs, volume fractions of each individual CP in blend; from paper "Predictions of pour, cloud and cold filter plugging point for future diesel fuels with application to diesel blending models" by Semwal et al.

$$ CP_{b}^{13.45} = \sum_{i}^{N} V_{i} CP_{i}^{13.45} $$

Where $$V_i$$ is the ith components weight percent, $$CP_i$$ is the ith component's CP, in Rankine, and $$CP_b$$ is the blend's CP, in Rankine

Parameters:

Name Type Description Default
values List[float]

CP values, in Celsius

required
vol_fractions List[float]

list of volume fractions, sum(vol_fractions) == 1.0

required

Returns:

Type Description
float

float: blended CP, in Celsius

Source code in ecnet/blends/predict.py
def cloud_point(values: List[float], vol_fractions: List[float]) -> float:
    """
    Calculates blended CP from individual CPs, volume fractions of each individual CP in blend;
    from paper "Predictions of pour, cloud and cold filter plugging point for future diesel
    fuels with application to diesel blending models" by Semwal et al.

    $$
    CP_{b}^{13.45} = \\sum_{i}^{N} V_{i} CP_{i}^{13.45}
    $$

    Where $$V_i$$ is the ith components weight percent, $$CP_i$$ is the ith component's CP, in
    Rankine, and $$CP_b$$ is the blend's CP, in Rankine

    Args:
        values (list[float]): CP values, in Celsius
        vol_fractions (list[float]): list of volume fractions, sum(vol_fractions) == 1.0

    Returns:
        float: blended CP, in Celsius
    """

    cp_sum = 0.0
    for idx, val in enumerate(values):
        cp_sum += (vol_fractions[idx] * celsius_to_rankine(val)**13.45)
    return rankine_to_celsius(cp_sum**(1 / 13.45))

kinematic_viscosity(values, vol_fractions)

Calculates blended KV from individual KVs, volume fractions of each individual KV in blend; equation 8 from paper "Estimation of the kinematic viscosities of bio-oil/alcohol blends: Kinematic viscosity-temperature formula and mixing rules" by Ding et al.

$$ 1 / ln(2000 * kv_{blend}) = \sum_{i}^{N} \frac{V_i}{ln(2000 * kv_i)} $$

Where $$V_i$$ is the volume fraction of the ith component, $$kv_i$$ is the kinematic viscosity of the ith component, and $$kv_{blend}$$ is the kinematic viscosity of the blend

Parameters:

Name Type Description Default
values List[float]

KV values, in cSt

required
vol_fractions List[float]

list of volume fractions, sum(vol_fractions) == 1.0

required
Source code in ecnet/blends/predict.py
def kinematic_viscosity(values: List[float], vol_fractions: List[float]) -> float:
    """
    Calculates blended KV from individual KVs, volume fractions of each individual KV in blend;
    equation 8 from paper "Estimation of the kinematic viscosities of bio-oil/alcohol blends:
    Kinematic viscosity-temperature formula and mixing rules" by Ding et al.

    $$
    1 / ln(2000 * kv_{blend}) = \\sum_{i}^{N} \\frac{V_i}{ln(2000 * kv_i)}
    $$

    Where $$V_i$$ is the volume fraction of the ith component, $$kv_i$$ is the kinematic viscosity
    of the ith component, and $$kv_{blend}$$ is the kinematic viscosity of the blend

    Args:
        values (list[float]): KV values, in cSt
        vol_fractions (list[float]): list of volume fractions, sum(vol_fractions) == 1.0
    """

    kv_sum = 0.0
    for idx, val in enumerate(values):
        kv_sum += (vol_fractions[idx] / log(2000 * val))
    return exp(1 / kv_sum) / 2000

lower_heating_value(values, vol_fractions)

Calculates blended LHV from individual LHVs, volume fractions of each individual LHV in blend; blend assumed proportionally linear: https://doi.org/10.1016/j.ejpe.2015.11.002

Parameters:

Name Type Description Default
values List[float]

LHV values

required
vol_fractions List[float]

list of volume fractions, sum(vol_fractions) == 1.0

required

Returns:

Type Description
float

float: blended LHV

Source code in ecnet/blends/predict.py
def lower_heating_value(values: List[float], vol_fractions: List[float]) -> float:
    """
    Calculates blended LHV from individual LHVs, volume fractions of each individual LHV in blend;
    blend assumed proportionally linear: https://doi.org/10.1016/j.ejpe.2015.11.002

    Args:
        values (list[float]): LHV values
        vol_fractions (list[float]): list of volume fractions, sum(vol_fractions) == 1.0

    Returns:
        float: blended LHV
    """

    return linear_blend_ave(values, vol_fractions)

yield_sooting_index(values, vol_fractions)

Calculates blended YSI from individual YSIs, volume fractions of each individual YSI in blend; blend assumed proportionally linear: https://doi.org/10.1016/j.fuel.2020.119522

Parameters:

Name Type Description Default
values List[float]

YSI values

required
vol_fractions List[float]

list of volume fractions, sum(vol_fractions) == 1.0

required

Returns:

Type Description
float

float: blended YSI

Source code in ecnet/blends/predict.py
def yield_sooting_index(values: List[float], vol_fractions: List[float]) -> float:
    """
    Calculates blended YSI from individual YSIs, volume fractions of each individual YSI in blend;
    blend assumed proportionally linear: https://doi.org/10.1016/j.fuel.2020.119522

    Args:
        values (list[float]): YSI values
        vol_fractions (list[float]): list of volume fractions, sum(vol_fractions) == 1.0

    Returns:
        float: blended YSI
    """

    return linear_blend_ave(values, vol_fractions)