BioSTEAMDevelopmentGroup / biosteam

The Biorefinery Simulation and Techno-Economic Analysis Modules; Life Cycle Assessment; Chemical Process Simulation Under Uncertainty
Other
180 stars 35 forks source link

Kinetic model does not take 't' into account #162

Closed adilsal33m closed 1 year ago

adilsal33m commented 1 year ago

Describe the bug Kinetic model does not consider time in its calculation even though it accepts it as a parameter. See the snippet below from the Fermentation class: def kinetic_model(z, t, *kinetic_constants): # pragma: no cover """ Return change of yeast, ethanol, and substrate concentration in kg/m3.

    Parameters
    ----------
    z : Iterable with (X, E, S) [-]:
        * X: Yeast concentration (kg/m3)
        * P: Ethanol concentration (kg/m3)
        * S: Substrate concentration (kg/m3)

    t : float
        Time point

    *kinetic_constants
        * mu_m1: Maximum specific growth rate (1/hr)
        * mu_m2: Maximum specific ethanol production rate (g-product/g-cell-hr)
        * Ks1: Sugar saturation constant for growth (g/L)
        * Ks2: Sugar saturation constant for product (g/L)
        * Pm1: Maximum product concentration at zero growth [mu_m1=0] (g/L)
        * Pm2: Maximum product concentration [mu_m2=0] (g/L)
        * Xm: Maximum cell concentration [mu_m1=0] (g/L)
        * Y_PS: Ethanol yield based on sugar consumed
        * a: Toxic power

    """
    mu_m1, mu_m2, Ks1, Ks2, Pm1, Pm2, Xm, Y_PS, a = kinetic_constants

    # Current yeast, ethanol, and glucose concentration (kg/m3)
    X, P, S = z

    # Compute coefficients
    if P > Pm1: P = Pm1
    mu_X = mu_m1 * (S/(Ks1 + S)) * (1 - P/Pm1)**a*((1-X/Xm))
    mu_P = mu_m2 * (S/(Ks2 + S)) * (1 - P/Pm2)
    mu_S = mu_P / 0.45

    # Compute derivatives
    dXdt = mu_X * X
    dPdt = (mu_P * X)
    dSdt =  - mu_S * X
    return (dXdt, dPdt, dSdt)

To Reproduce val = (532,0,4000)

print(f'For t=0 {F1.kinetic_model(val,0,F1.kinetic_constants)}') print(f'For t=10 {F1.kinetic_model(val,10,F1.kinetic_constants)}') print(f'For t=100 {F1.kinetic_model(val,100,*F1.kinetic_constants)}')

Expected behavior Rate of change of yeast, ethanol and substrate at a specific time.

Actual behavior Output: For t=0 (-608.4927738283994, 536.9427976846265, -1193.2062170769477) For t=10 (-608.4927738283994, 536.9427976846265, -1193.2062170769477) For t=100 (-608.4927738283994, 536.9427976846265, -1193.2062170769477)

Version biosteam-2.37.4 Python: 3.10.11

Additional context It is entirely possible I am using the function incorrectly and the 't' parameter is added for future use.

yoelcortes commented 1 year ago

@adilsal33m, yeah, bugs/cells don't care what time is it, but scipy's ode integrator does need the odes (the kinetic model) to accept t as a parameter. What you are running is the ODEs, calc_efficiency does the integration until time tau. When you simulate the Fermentation object with iskinetic=True, calc_efficiency is run.