Estimate Thermodynamic Parameters from Data

Main.VLEWilson History

Show minor edits - Show changes to markup

June 21, 2020, at 04:48 AM by 136.36.211.159 -
Deleted lines 364-382:

(:html:)

 <div id="disqus_thread"></div>
    <script type="text/javascript">
        /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
        var disqus_shortname = 'apmonitor'; // required: replace example with your forum shortname

        /* * * DON'T EDIT BELOW THIS LINE * * */
        (function() {
            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
            dsq.src = 'https://' + disqus_shortname + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    </script>
    <noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
    <a href="https://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>

(:htmlend:)

February 17, 2020, at 12:42 PM by 99.203.12.127 -
Changed line 11 from:

Using data from an ebulliometer, determine parameters for the Wilson activity coefficient model using the measured data for an ethanol-cyclohexane mixture at ambient pressure. Use the results to determine whether there is:

to:

Using data from an ebulliometer, determine parameters for a Vapor Liquid Equilibrium chart using the Wilson activity coefficient model with measured data for an ethanol-cyclohexane mixture at ambient pressure. Use the results to determine whether there is:

April 12, 2019, at 05:06 PM by 10.35.117.63 -
Changed lines 60-334 from:
to:

from gekko import GEKKO import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy.optimize import fsolve from scipy.optimize import curve_fit from scipy.interpolate import interp1d

  1. from numpy import *

R = 1.9858775 # cal/mol K

def vaporP(T: float, component: list):

    '''
    :param T: temp [K]
    :param component: [vapor pressure parameters]
    :return: Vapor Pressure [Pa]
    '''
    A = component[0]
    B = component[1]
    C = component[2]
    D = component[3]
    E = component[4]
    return np.exp(A + B/T + C*np.log(T) + D*T**E)

def liquidMolarVolume(T: float, component: list):

    '''
    :param T: temp in [K}
    :param component: component liquid molar volume
    : constants in list or array
    :return: liquid molar volume []
    '''
    A = component[0]
    B = component[1]
    C = component[2]
    D = component[3]
    return 1 / A * B ** (1 + (1 - T / C) ** D)

def Lij(aij: float, T: float, Vlvali: float, Vlvalj: float):

    # Vl1 = liquidMolarVolume(T, Vlvali)
    # Vl2 = liquidMolarVolume(T, Vlvalj)
    Vl1 = Vlvali
    Vl2 = Vlvalj

    return Vl2 / Vl1 * np.exp(-aij / (R * T))

def Gamma(a12: float, a21: float, x1: float, Temp: float, Component: int):

    '''
    :param Component:
    :param a12:
    :param a21:
    :param x1:
    :param Temp:
    :return:
    '''
    # Liquid molar volume
    Vethanol = 5.8492e-2
    VCyclochexane = 0.10882

    x2 = 1.0 - x1
    L12 = Lij(a12, Temp, Vethanol, VCyclochexane)
    L21 = Lij(a21, Temp,  VCyclochexane, Vethanol)
    L11 = 1.0
    L22 = 1.0

    if Component == 1:
        A = x1 + x2 * L12
        B = x1 * L11 / (x1 * L11 + x2 * L12)            +x2 * L21 / (x1 * L21 + x2 * L22)

    elif Component == 2:

        A = x2  + x1 * L21
        B = x2 * L22 / (x2 * L22 + x1 * L21)            +x1 * L12 / (x2 * L12 + x1 * L11)

    return np.exp(1.0 - np.log(A) - B)
  1. yi * P = xi * Îģi * Pisat
  2. Component 1: Ethanol
  3. Component 2: Cyclohexane

def massTOMoleF(x: list):

    #Converts RI to mole fraction of Ethanol
    MW_Ethanol = 46.06844
    MW_cyclohexane = 84.15948
    xeth = 49.261*x**2 - 152.51*x + 117.32
    xcyc = 1-xeth
    moleth = xeth / MW_Ethanol
    molcyc = xcyc/ MW_cyclohexane
    return moleth/ (moleth + molcyc)
  1. Read in actual data
  2. filename = 'RealData.csv'

filename = 'http://apmonitor.com/me575/uploads/Main/vle_data.txt' data = pd.read_csv(filename)

temp_data = data['Temp_D'].values + 273.15 # K IndexMeasuredY = data['Distills_RI'] IndexMeasuredX = data['Bottoms_RI'] x1_data = massTOMoleF(IndexMeasuredX) x1_data[0] = 0 x1_data[1] = 1 y1_data = massTOMoleF(IndexMeasuredY) y1_data[0] = 0 y1_data[1] = 1

  1. Ethanol & Cyclohexane Properties ---------
  2. Psat paramater values

PsatC2H5OH = [73.304, -7122.3, -7.1424, 2.8853e-6, 2.0] PsatC6H12 = [51.087, -5226.4, -4.2278, 9.7554e-18, 6.0]

  1. thermo Liquid Molar Volume paramaters

Vl_C2H5OH = [1.6288, 0.27469, 514.0, 0.23178] Vl_C6H12 = [0.88998, 0.27376, 553.8, 0.28571]

  1. Build Model ------------------------------

m = GEKKO()

  1. Define Variables & Parameters

a12_ = m.FV(value = 2026.3) a12_.STATUS = 1 a21_ = m.FV(value = 390.4) a21_.STATUS = 1 Temp = m.Var(333) x1 = m.Param(value = np.array(x1_data)) y1 = m.CV(value = np.array(y1_data)) y1.FSTATUS = 1 # min fstatus * (meas-pred)^2 y2 = m.Intermediate(1.0 - y1) P = 85900 # Pa in Provo, UT

  1. Calc Vapor pressures of ethanol & cyclohexane at
  2. different temps using thermo parameters
  3. Psat = exp(A + B / T + C * log(T) + D * T ** E)

PsatEthanol = m.Intermediate(

        m.exp(
                PsatC2H5OH[0] +
                PsatC2H5OH[1] / Temp +
                PsatC2H5OH[2] * m.log(Temp) +
                PsatC2H5OH[3] * Temp ** PsatC2H5OH[4]
        )

)

PsatCyclohexane = m.Intermediate(

        m.exp(
                PsatC6H12[0] +
                PsatC6H12[1] / Temp +
                PsatC6H12[2] * m.log(Temp) +
                PsatC6H12[3] * Temp ** PsatC6H12[4]
        )

)

  1. Calculate Liquid Molar volumes of components 1 and 2:
  2. ethanol & cyclohexane, respectively

LMV_C2H5OH = 5.8492e-2 LMV_C6H12 = 0.10882

  1. Construct parameters for Wilson Model

L12 = m.Intermediate(LMV_C6H12 / LMV_C2H5OH * m.exp(-a12_ / (R * Temp))) L21 = m.Intermediate(LMV_C2H5OH / LMV_C6H12 * m.exp(-a21_ / (R * Temp))) L11 = 1.0 L22 = 1.0

x2 = m.Intermediate(1.0 - x1)

A1 = m.Intermediate(x1 + x2 * L12) B1 = m.Intermediate(x1 * L11 / (x1 * L11 + x2 * L12) + x2 * L21 / (x1 * L21 + x2 * L22))

A2 = m.Intermediate(x2 + x1 * L21) B2 = m.Intermediate(x2 * L22 / (x2 * L22 + x1 * L21) + x1 * L12 / (x2 * L12 + x1 * L11))

  1. Find Gammas for each component

G_C2H5OH = m.Intermediate(m.exp(1.0 - m.log(A1) - B1)) G_C6H12 = m.Intermediate(m.exp(1.0 - m.log(A2) - B2))

m.Equation(y2 == (G_C6H12 * PsatCyclohexane / P) * x2) m.Equation(y1 == (G_C2H5OH * PsatEthanol / P) * x1)

  1. Options

m.options.IMODE = 2 m.options.EV_TYPE = 2 # Objective type, SSE m.options.NODES = 3 # Collocation nodes m.options.SOLVER = 3 # IPOPT

m.solve()

regressed_a12 = a12_.value[-1] regressed_a21 = a21_.value[-1]

a12_Hysys = 2026.3 a21_Hysys = 390.4

x1_linspace = np.linspace(0, 1.0, 100) y1_predicted = [] T_predicted = []

print("Activity Coefficient Parameters") print('Model a12 a21') print('Gekko: ' + str(round(regressed_a12,2)) + str(round(regressed_a21,2))) print('Hysys: ' + str(round(a12_Hysys,2)) + str(round(a21_Hysys,2)))

def getValues(y1_and_Temp: list, a12: float, a21: float, P: float, x1: float):

    y1 = y1_and_Temp[0]
    T = y1_and_Temp[1]

    y2 = 1 - y1
    x2 = 1 - x1

    A = y1*P - x1*Gamma(a12,a21,x1,T,1)         * vaporP(T,PsatC2H5OH)
    B = y2*P - x2*Gamma(a12,a21,x1,T,2)         * vaporP(T,PsatC6H12)

    return [A,B]

TempInterp = interp1d(x1_data, temp_data) for i in range(len(x1_linspace)):

    answers = fsolve(getValues, [x1_linspace[i],                     TempInterp(x1_linspace[i])],                     args = (regressed_a12,                              regressed_a21,                              P, x1_linspace[i]))
    y1_predicted.append(answers[0])
    T_predicted.append(answers[1])

GammaPred = Gamma(regressed_a12, regressed_a21, x1_data, temp_data, 1) GammaPredHysys = Gamma(a12_Hysys, a21_Hysys, x1_data, temp_data, 2)

VP_Ethanol = vaporP(temp_data, PsatC2H5OH)

y1Predicted = (GammaPred * VP_Ethanol / P) * x1_data y1PredictedHysys = (GammaPredHysys * VP_Ethanol / P) * x1_data

plt.figure(1) plt.plot(x1_data,y1_data,"bx",label = "Measured Data") plt.plot(x1_linspace,x1_linspace,"-", color="#8bd8bd", label="Reference",markersize=7) plt.plot(x1_linspace,y1_predicted,"--", color="#243665",label = "Model",markersize=7) plt.plot(x1_data, y1Predicted, "o",

         color="#ec8b5e",label="Predicted",markersize=5)

plt.legend(loc = "best") plt.xlabel("x") plt.ylabel("y") plt.grid()

plt.figure(2) plt.plot(x1_data, temp_data, "go") plt.plot(y1_data, temp_data, "bo") plt.plot(x1_linspace, T_predicted, "r--",) plt.plot(y1_predicted, T_predicted, "k--",) plt.legend(["$x_1$ Measured", "$y_1$ Measured", "$x_1$ Predicted", "$y_1$ Predicted"]) plt.xlabel("$x, y$") plt.ylabel("$Temp$") plt.grid()

plt.show()

April 12, 2019, at 05:04 PM by 10.35.117.63 -
Added lines 42-43:

APM Python

Added lines 47-62:

Python GEKKO

(:toggle hide gekko button show="Show GEKKO (Python) Code":) (:div id=gekko:)

(:source lang=python:)

(:sourceend:) (:divend:)

March 01, 2017, at 11:19 PM by 10.5.113.121 -
Changed line 70 from:
to:
March 01, 2017, at 11:19 PM by 10.5.113.121 -
Changed lines 69-70 from:
to:
March 01, 2017, at 11:14 PM by 10.5.113.121 -
Added lines 55-71:

Nonlinear Confidence Interval

(:html:) <iframe width="560" height="315" src="https://www.youtube.com/embed/rL7Mvl2-XIM" frameborder="0" allowfullscreen></iframe> (:htmlend:)

Nonlinear confidence intervals can be visualized as a function of 2 parameters. In this case, both parameters are simultaneously varied to find the confidence region. The confidence interval is determined with an F-test that specifies an upper limit to the deviation from the optimal solution

with p=2 (number of parameters), n=number of measurements, theta=[parameter 1, parameter 2] (parameters), theta* as the optimal parameters, SSE as the sum of squared errors, and the F statistic that has 3 arguments (alpha=confidence level, degrees of freedom 1, and degrees of freedom 2). For many problems, this creates a multi-dimensional nonlinear confidence region. In the case of 2 parameters, the nonlinear confidence region is a 2-dimensional space. Below is an example that shows the confidence region for the dye fading experiment confidence region for forward and reverse activation energies.

The optimal parameter values are in the 95% confidence region. This plot demonstrates that the 2D confidence region is not necessarily symmetric.

Changed lines 5-9 from:

Case Study on Thermodynamic Parameter Estimation

to:

Thermodynamic Parameter Estimation

(:html:) <iframe width="560" height="315" src="https://www.youtube.com/embed/ZJXgcrJ7Elw" frameborder="0" allowfullscreen></iframe> (:htmlend:)

March 25, 2013, at 04:32 PM by 69.169.188.188 -
Changed line 38 from:
to:
March 25, 2013, at 04:31 PM by 69.169.188.188 -
Added lines 37-38:
January 11, 2013, at 02:21 PM by 69.169.188.188 -
Added lines 46-64:

(:htmlend:)


(:html:)

 <div id="disqus_thread"></div>
    <script type="text/javascript">
        /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
        var disqus_shortname = 'apmonitor'; // required: replace example with your forum shortname

        /* * * DON'T EDIT BELOW THIS LINE * * */
        (function() {
            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
            dsq.src = 'https://' + disqus_shortname + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    </script>
    <noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
    <a href="https://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
December 27, 2012, at 04:09 AM by 69.169.188.188 -
Changed line 7 from:

Using data from an ebulliometer, determine parameters for the Wilson activity coefficient model using the measured data for an ethanol-cyclohexane mixture at ambient pressure. Use the results to determine whether there is:

to:

Using data from an ebulliometer, determine parameters for the Wilson activity coefficient model using the measured data for an ethanol-cyclohexane mixture at ambient pressure. Use the results to determine whether there is:

December 27, 2012, at 03:57 AM by 69.169.188.188 -
Changed lines 22-24 from:
to:
December 27, 2012, at 03:56 AM by 69.169.188.188 -
Added lines 35-36:
December 27, 2012, at 03:52 AM by 69.169.188.188 -
Added lines 25-26:
December 27, 2012, at 03:51 AM by 69.169.188.188 -
Changed lines 18-19 from:

where y1is the vapor mole fraction, P is the pressure, x1 is the liquid mole fraction, gamma1 is the activity coefficient that is different than 1.0 for non-ideal mixtures, and Psat1 is the pure component vapor pressure. The same equation also applies to component 2 in the mixture with the corresponding equation with subscript 2.

to:

where y1is the vapor mole fraction, P is the pressure, x1 is the liquid mole fraction, gamma1 is the activity coefficient that is different than 1.0 for non-ideal mixtures, and P1sat is the pure component vapor pressure. The same equation also applies to component 2 in the mixture with the corresponding equation with subscript 2.

Changed lines 26-27 from:

There are correlations for Psat1 for many common pure components from BYU's DIPPR database. In this case Psat1 is a function of temperature according to

to:

There are correlations for Psat1 and density (rho) for many common pure components from BYU's DIPPR database. In this case P1sat is a function of temperature according to

Added lines 29-32:

and density rho or molar volume v is also a function of temperature according to

December 27, 2012, at 03:47 AM by 69.169.188.188 -
Added lines 1-40:

(:title Estimate Thermodynamic Parameters from Data:) (:keywords VLE, wilson equation, nonlinear, optimization, engineering optimization, dynamic estimation, interior point, active set, differential, algebraic, modeling language, university course:) (:description Case study on data reconciliation for thermodynamic properties using optimization techniques in engineering:)

Case Study on Thermodynamic Parameter Estimation

Using data from an ebulliometer, determine parameters for the Wilson activity coefficient model using the measured data for an ethanol-cyclohexane mixture at ambient pressure. Use the results to determine whether there is:

  • An azeotrope in the system and, if so, at what composition
  • The values of the activity coefficients at the infinitely dilute compositions
    • gamma1 at x1=0
    • gamma2 at x1=1

The liquid and vapor compositions of this binary mixture are related by the following thermodynamic relationships

where y1is the vapor mole fraction, P is the pressure, x1 is the liquid mole fraction, gamma1 is the activity coefficient that is different than 1.0 for non-ideal mixtures, and Psat1 is the pure component vapor pressure. The same equation also applies to component 2 in the mixture with the corresponding equation with subscript 2.

The Wilson equation is used to predict the activity coefficients gamma2 and gamma2 over the range of liquid compositions.

There are correlations for Psat1 for many common pure components from BYU's DIPPR database. In this case Psat1 is a function of temperature according to

The number of degrees of freedom in a multi-component and multi-phase system is given by DOF = 2 + #Components - #Phases. In this case, there are two phases (liquid and vapor) and two components (ethanol and cyclohexane). This leads to two degrees of freedom that must be specified. In this case, we can chose to fix two of the four measured values for this system with either x1, y1, P, or T. It is recommended to fix the values of x1 and P as shown in the tutorial below.

Background on Parameter Estimation

A common application of optimization is to estimate parameters from experimental data. One of the most common forms of parameter estimation is the least squares objective with (model-measurement)^2 summed over all of the data points. The optimization problem is subject to the model equations that relate the model parameters or exogenous inputs to the predicted measurements. The model predictions are connected by common parameters that are adjusted to minimize the sum of squared errors.

Tutorial on Parameter Estimation

(:html:) <iframe width="560" height="315" src="https://www.youtube.com/embed/ss4jDiLTQ1A" frameborder="0" allowfullscreen></iframe> (:htmlend:)