Ejemplo n.º 1
0
 def __init__(self, s1, s2, T):
     self.s1 = s1
     self.s2 = s2
     self.p1_s = get_psat(s1, T)
     self.p2_s = get_psat(s2, T)
     self.q1 = get_volume(self.s1, T)
     self.q2 = get_volume(self.s2, T)
Ejemplo n.º 2
0
def main(x1, y1, P, G_e, T, s1, s2):
    style.use('classic')

    w = Wohls(s1, s2, T)
    A = get_parameter(x1, G_e, s1, s2, T)
    acc = get_accuracy(G_e, w.Ge(x1, A))

    x = np.linspace(0, 1, 50)

    fig4 = plt.figure(facecolor='white')
    plt.title(r"$G^E-x$")
    plt.xlim(0, 1)
    plt.xlabel(r'$x_1$')
    plt.ylabel(r'$G^E\ (J/mol)$')
    plt.scatter(x1, G_e)
    plt.plot(x, w.Ge(x, A), label=r"$Wohls\ model$", color='red')
    plt.axhline(0, color='black')

    q1 = get_volume(s1, T)
    q2 = get_volume(s2, T)
    z = x * q1 / (x * q1 + (1 - x) * q2)

    p1_s = get_psat(s1, T)
    p2_s = get_psat(s2, T)

    P_Wohls = x * p1_s * w.gamma1(z, A) + (1 - x) * p2_s * w.gamma2(z, A)
    y_Wohls = x * p1_s * w.gamma1(z, A) / P_Wohls

    P_raoult = x * p1_s + (1 - x) * p2_s

    fig5 = plt.figure(facecolor='white')
    plt.title(r"$P-x$")
    plt.xlim(0, 1)
    plt.ylim(0, 1.2 * max(P))
    plt.xlabel(r'$x_1$')
    plt.ylabel(r'$P\ (kPa)$')
    plt.scatter(x1, P)
    plt.plot(x, P_Wohls, label=r"$Wohls\ model$", color='red')
    plt.plot(x, P_raoult, color='black', label=r"$Raoult's\ Law$")
    plt.legend(loc='best', fontsize=10)

    fig6 = plt.figure(facecolor='white')
    plt.gca().set_aspect('equal', adjustable='box')
    plt.title(r"$y-x$")
    plt.xlim(0, 1)
    plt.ylim(0, 1)
    plt.xlabel(r'$x_1$')
    plt.ylabel(r'$y_1$')
    plt.scatter(x1, y1)
    plt.plot(x, y_Wohls, label=r"$Wohls\ model$", color='red')
    plt.plot(x, x, color='black')
    plt.legend(loc='best', fontsize=10)

    return A, acc, fig4, fig5, fig6
Ejemplo n.º 3
0
            st.write('%d)' % (i + 1), 'T = ', T[i], 'K')
            st.write(isothermal_vledata[i])
        if len(T) == 1:
            choice = 1
        else:
            choice = st.number_input('Choose a dataset', value=1, min_value=1, max_value=len(T))

        if st.button('Go!'):
            st.write('Analysing dataset %d ...' % choice)
            P = isothermal_vledata[choice - 1]['P [kPa]']
            x1 = isothermal_vledata[choice - 1]['x1 [mol/mol]']
            y1 = isothermal_vledata[choice - 1]['y1 [mol/mol]']
            T = T[choice - 1]
            st.write(r'$T = %0.2f K$' % T)

            p1sat = get_psat(compounds[i1], T)
            p2sat = get_psat(compounds[i2], T)

            if p1sat > p2sat:
                st.write('The more volatile component is %s' % menu_options[i1])
            else:
                st.write('The more volatile component is %s' % menu_options[i2])

            p1_s = max(p1sat, p2sat)
            p2_s = min(p1sat, p2sat)

            st.write(r'$p_1^s = %0.3f kPa$' % p1_s)
            st.write(r'$p_2^s = %0.3f kPa$' % p2_s)

            x = np.linspace(0, 1, 50)
            P_raoult = x * p1_s + (1 - x) * p2_s
Ejemplo n.º 4
0
def main():
    st.title("Correlations")
    st.write(
        """ The *Margules* model, *Redlich-Kister Expansion* truncated to two terms and the *Van Laar* predictive model are implemented here. """
        r"In case $\alpha$ fits the data with an accuracy of 80% or above, the $\alpha_{GM}$ value is displayed."
    )

    compounds = [
        'Acetonitrile', 'Acetone', '1,2-Ethanediol', 'Ethanol',
        'Diethyl ether', 'Ethyl acetate', 'Benzene', '1-Butanol', 'Chloroform',
        'Cyclohexane', 'Acetic acid butyl ester', 'Acetic acid', 'Hexane',
        '2-Propanol', '1-Hexene', 'Methanol', 'Tetrahydrofuran', 'Water',
        'm-Xylene', 'p-Xylene', 'N-Methyl-2-pyrrolidone', '1,3-Butadiene',
        'Hexadecane'
    ]

    menu_options = compounds.copy()

    for i, compound in enumerate(compounds):
        if ' ' in compound:
            compounds[i] = compound.replace(' ', '%20')

    compound1 = st.selectbox('Select compound 1',
                             menu_options,
                             key='compound1')
    compound2 = st.selectbox('Select compound 2',
                             menu_options,
                             key='compound2')

    i1 = menu_options.index(compound1)
    i2 = menu_options.index(compound2)

    st.info("You have chosen %s and %s" % (compound1, compound2))

    @st.cache(suppress_st_warning=True)
    def link_generator(i1, i2):
        url = 'http://www.ddbst.com/en/EED/VLE/VLE%20' + compounds[
            i1] + '%3B' + compounds[i2] + '.php'
        if requests.get(url).status_code == 404:
            url = 'http://www.ddbst.com/en/EED/VLE/VLE%20' + compounds[
                i2] + '%3B' + compounds[i1] + '.php'
        return url

    try:
        if compound1 == compound2:
            st.warning('Choose different compounds')
        else:
            url = link_generator(i1, i2)

        if requests.get(url).status_code == 404:
            st.error(
                "VLE data for this pair of compounds doesn't exist at DDBST.")

        dataframes = pd.read_html(url)

        isothermal_vledata = []
        T = []
        for i, data in enumerate(dataframes):
            col = data.columns
            if col.dtype == object:
                if len(col) == 3 and 'P' in col[0] and 'x1' in col[
                        1] and 'y1' in col[2]:
                    T.append(float(dataframes[i - 1][1]))
                    isothermal_vledata.append(dataframes[i])

        if isothermal_vledata == []:
            st.error('There is no isothermal data available at DDBST')
        else:
            for i in range(len(T)):
                st.write('%d)' % (i + 1), 'T = ', T[i], 'K')
                st.write(isothermal_vledata[i])
            if len(T) == 1:
                choice = 1
            else:
                choice = st.number_input('Choose a dataset',
                                         value=1,
                                         min_value=1,
                                         max_value=len(T))

            st.info('Analysing dataset %d ...' % choice)
            P = isothermal_vledata[choice - 1]['P [kPa]']
            x1 = isothermal_vledata[choice - 1]['x1 [mol/mol]']
            y1 = isothermal_vledata[choice - 1]['y1 [mol/mol]']
            T = T[choice - 1]
            st.write(r'$T = %0.2f K$' % T)

            p1sat = get_psat(compounds[i1], T)
            p2sat = get_psat(compounds[i2], T)

            if p1sat > p2sat:
                st.info('The more volatile component is %s' % menu_options[i1])
            else:
                st.info('The more volatile component is %s' % menu_options[i2])

            p1_s = max(p1sat, p2sat)
            p2_s = min(p1sat, p2sat)

            st.write(r'$p_1^s = %0.3f kPa$' % p1_s)
            st.write(r'$p_2^s = %0.3f kPa$' % p2_s)

            x = np.linspace(0, 1, 50)
            P_raoult = x * p1_s + (1 - x) * p2_s
            y_raoult = x * p1_s / P_raoult

            n_points = len(x1) - 1

            try:
                if x1[0] == 0 and x1[n_points] != 1:
                    x1, y1, P = x1[1:], y1[1:], P[1:]
                if x1[0] != 0 and x1[n_points] == 1:
                    x1, y1, P = x1[:n_points], y1[:n_points], P[:n_points]
                if x1[0] == 0 and x1[n_points] == 1:
                    x1, y1, P = x1[1:n_points], y1[1:n_points], P[1:n_points]
            except KeyError:
                pass

            gamma1 = np.divide(P * y1, x1 * p1_s)
            gamma2 = np.divide(P * (1 - y1), ((1 - x1) * p2_s))
            G_e = constants.R * T * (xlogy(x1, gamma1) + xlogy(1 - x1, gamma2))

            alpha_gm = models.alphagm.get_alpha_gm(x1, y1)
            if alpha_gm == 0:
                pass
            else:
                st.success(
                    r"The geometric mean of $\alpha$ is $\alpha_{GM}=%0.3f$" %
                    alpha_gm)
                st.text("Try using this value in the McCabe-Thiele Plotter!")

            model = st.selectbox(
                "Choose a model",
                ["Select", "Margules", "Redlich Kister", "Van Laar"])

            if model == "Select":
                st.info("Select a model")
            else:
                MODELS = {
                    "Margules": models.margules,
                    "Redlich Kister": models.redlichkister,
                    "Van Laar": models.vanlaar
                }
                latest_iteration = st.empty()
                bar = st.progress(0)

                for i in range(100):
                    latest_iteration.text(f'{i + 1}%')
                    bar.progress(i + 1)
                    time.sleep(0.1)

                A, acc, fig4, fig5, fig6 = MODELS[model].main(
                    x1, y1, P, G_e, x, p1_s, p2_s, T, P_raoult)

                if model == "Margules":
                    st.write(r"$G^E = %0.3fx_1x_2$" % A)
                if model == "Redlich Kister":
                    st.write(r"$G^E = x_1x_2(%0.3f + (%0.3f)(x_1-x_2))$" %
                             (A[0], A[1]))
                if model == "Van Laar":
                    st.write(
                        r"$\frac{x_1x_2}{G^E} = \frac{x_1}{%0.3f} + \frac{x_2}{%0.3f}$"
                        % (A[1], A[0]))
                st.write(r"$R^2$ score = %0.3f" % acc)
                st.write(fig4, fig5, fig6)

    except:
        pass

    st.sidebar.title("Note")
    st.sidebar.info(""" The saturation pressures are obtained from 
        [DDBST's database](http://ddbonline.ddbst.com/AntoineCalculation/AntoineCalculationCGI.exe?component=Ethanol)."""
                    )
    st.sidebar.info(
        "These models can only be used for binary isothermal vapor-liquid equilibrium data."
    )
Ejemplo n.º 5
0
        st.info('Analysing dataset %d ...' % choice)
        T = isobaric_vledata[choice - 1]['T [K]']
        x1 = np.array(isobaric_vledata[choice - 1]['x1 [mol/mol]'])
        y1 = np.array(isobaric_vledata[choice - 1]['y1 [mol/mol]'])
        P = P[choice - 1]
        st.write(r'$P = %0.3f kPa$' % P)

        n_points = len(x1) - 1

        T1 = T[n_points]
        T2 = T[0]

        if T1 > T2:
            st.info('The more volatile component is %s' % menu_options[i2])
            p1_s = np.array(get_psat(compounds[i2], T))
            p2_s = np.array(get_psat(compounds[i1], T))
        else:
            st.info('The more volatile component is %s' % menu_options[i1])
            p1_s = np.array(get_psat(compounds[i1], T))
            p2_s = np.array(get_psat(compounds[i2], T))

        x = np.linspace(0, 1, 50)

        try:
            if x1[0] == 0 and x1[n_points] != 1:
                x1, y1, T = x1[1:], y1[1:], T[1:]
            if x1[0] != 0 and x1[n_points] == 1:
                x1, y1, T = x1[:n_points], y1[:n_points], T[:n_points]
            if x1[0] == 0 and x1[n_points] == 1:
                x1, y1, T = x1[1:n_points], y1[1:n_points], T[1:n_points]
Ejemplo n.º 6
0
def main():
    st.title('Binary VLE Data')
    st.markdown(
        "Vapor-liquid equlibrium data of 30 important components from "
        "[Dortmund Data Bank](http://www.ddbst.com/en/EED/VLE/VLEindex.php) can be accessed from here. "
    )

    style.use("classic")

    compounds = [
        'Acetonitrile', 'Acetone', '1,2-Ethanediol', 'Ethanol',
        'Diethyl ether', 'Ethyl acetate', 'Benzene', '1-Butanol', 'Chloroform',
        'Cyclohexane', 'Acetic acid butyl ester', 'Acetic acid', 'Hexane',
        '2-Propanol', '1-Hexene', 'Methanol', 'Tetrahydrofuran', 'Water',
        'm-Xylene', 'p-Xylene', 'N-Methyl-2-pyrrolidone', '1,3-Butadiene',
        'Hexadecane'
    ]

    menu_options = compounds.copy()

    for i, compound in enumerate(compounds):
        if ' ' in compound:
            compounds[i] = compound.replace(' ', '%20')

    compound1 = st.selectbox('Select compound 1',
                             menu_options,
                             key='compound1')
    compound2 = st.selectbox('Select compound 2',
                             menu_options,
                             key='compound2')

    i1 = menu_options.index(compound1)
    i2 = menu_options.index(compound2)

    st.info("You have chosen %s and %s" % (compound1, compound2))

    @st.cache(suppress_st_warning=True)
    def link_generator(i1, i2):
        url = 'http://www.ddbst.com/en/EED/VLE/VLE%20' + compounds[
            i1] + '%3B' + compounds[i2] + '.php'
        if requests.get(url).status_code == 404:
            url = 'http://www.ddbst.com/en/EED/VLE/VLE%20' + compounds[
                i2] + '%3B' + compounds[i1] + '.php'
        return url

    try:
        if compound1 == compound2:
            st.warning('Choose different compounds')
        else:
            url = link_generator(i1, i2)

        if requests.get(url).status_code == 404:
            st.error(
                "VLE data for this pair of compounds doesn't exist at DDBST.")

        dataframes = pd.read_html(url)

        vledata = []
        S = []
        for i, data in enumerate(dataframes):
            col = data.columns
            if col.dtype == object:
                if (len(col) == 3 and 'P' in col[0] and 'x1' in col[1]
                        and 'y1' in col[2]) or (len(col) == 3 and 'T' in col[0]
                                                and 'x1' in col[1]
                                                and 'y1' in col[2]):
                    S.append(float(dataframes[i - 1][1]))
                    vledata.append(dataframes[i])

        if vledata == []:
            st.error('Complete VLE data is not available at DDBST')
        else:
            for i in range(len(S)):
                if vledata[i].columns[0] == 'P [kPa]':
                    st.write('%d)' % (i + 1), 'T = ', S[i], 'K')
                if vledata[i].columns[0] == 'T [K]':
                    st.write('%d)' % (i + 1), 'P = ', S[i], 'kPa')
                st.write(vledata[i])
            if len(S) == 1:
                choice = 1
            else:
                choice = st.number_input('Choose a dataset',
                                         value=1,
                                         min_value=1,
                                         max_value=len(S))

            st.info('Analysing dataset %d ...' % choice)

            try:
                P = vledata[choice - 1]['P [kPa]']
                x1 = vledata[choice - 1]['x1 [mol/mol]']
                y1 = vledata[choice - 1]['y1 [mol/mol]']
                T = S[choice - 1]

                st.write(r'$T = %0.2f K$' % T)

                p1sat = get_psat(compounds[i1], T)
                p2sat = get_psat(compounds[i2], T)

                if p1sat > p2sat:
                    st.info('The more volatile component is %s' %
                            menu_options[i1])
                else:
                    st.info('The more volatile component is %s' %
                            menu_options[i2])

                p1_s = max(p1sat, p2sat)
                p2_s = min(p1sat, p2sat)

                fig1, fig2 = isothermalPlots(x1, y1, P, p1_s, p2_s)
                st.write(fig1, fig2)
            except:
                pass
            try:
                T = vledata[choice - 1]['T [K]']
                x1 = vledata[choice - 1]['x1 [mol/mol]']
                y1 = vledata[choice - 1]['y1 [mol/mol]']
                P = S[choice - 1]

                st.write(r'$P = %0.2f kPa$' % P)

                p1sat = get_psat(compounds[i1], T[0])
                p2sat = get_psat(compounds[i2], T[0])

                if p1sat > p2sat:
                    st.info('The more volatile component is %s' %
                            menu_options[i1])
                    s1, s2 = compounds[i1], compounds[i2]
                else:
                    st.info('The more volatile component is %s' %
                            menu_options[i2])
                    s1, s2 = compounds[i2], compounds[i1]

                p1_s = get_psat(s1, T)
                p2_s = get_psat(s2, T)

                fig1, fig2 = isobaricPlots(x1, y1, T)
                st.write(fig1, fig2)
            except:
                pass
    except:
        ''
    st.sidebar.title("Note")
    st.sidebar.info(""" The saturation pressures are obtained from 
            [DDBST's database](http://ddbonline.ddbst.com/AntoineCalculation/AntoineCalculationCGI.exe?component=Ethanol)."""
                    )
Ejemplo n.º 7
0
def main():
    st.title('Isothermal Binary VLE Data')
    st.markdown("Vapor-liquid equlibrium data of 30 important components from "
                "[Dortmund Data Bank](http://www.ddbst.com/en/EED/VLE/VLEindex.php) can be accessed from here. "
                "Find out which pair of components have isothermal data available and see the $y-x$, $P-x$ and $G^E-x$ graphs.")


    compounds = ['Acetonitrile', 'Acetone', '1,2-Ethanediol', 'Ethanol',
                 'Diethyl ether', 'Ethyl acetate', 'Benzene', '1-Butanol',
                 'Chloroform', 'Cyclohexane', 'Acetic acid butyl ester', 'Acetic acid',
                 'Hexane', '2-Propanol', '1-Hexene', 'Methanol',
                 'Tetrahydrofuran', 'Water', 'm-Xylene', 'p-Xylene',
                 'N-Methyl-2-pyrrolidone', '1,3-Butadiene', 'Hexadecane']

    menu_options = compounds.copy()

    for i, compound in enumerate(compounds):
        if ' ' in compound:
            compounds[i] = compound.replace(' ', '%20')

    compound1 = st.selectbox('Select compound 1', menu_options, key='compound1')
    compound2 = st.selectbox('Select compound 2', menu_options, key='compound2')

    i1 = menu_options.index(compound1)
    i2 = menu_options.index(compound2)

    st.info("You have chosen %s and %s" % (compound1, compound2))

    @st.cache(suppress_st_warning=True)
    def link_generator(i1, i2):
        url = 'http://www.ddbst.com/en/EED/VLE/VLE%20' + compounds[i1] + '%3B' + compounds[i2] + '.php'
        if requests.get(url).status_code == 404:
            url = 'http://www.ddbst.com/en/EED/VLE/VLE%20' + compounds[i2] + '%3B' + compounds[i1] + '.php'
        return url

    try:
        if compound1 == compound2:
            st.warning('Choose different compounds')
        else:
            url = link_generator(i1, i2)

        if requests.get(url).status_code == 404:
            st.error("VLE data for this pair of compounds doesn't exist at DDBST.")

        dataframes = pd.read_html(url)

        isothermal_vledata = []
        T = []
        for i, data in enumerate(dataframes):
            col = data.columns
            if col.dtype == object:
                if len(col) == 3 and 'P' in col[0] and 'x1' in col[1] and 'y1' in col[2]:
                    T.append(float(dataframes[i - 1][1]))
                    isothermal_vledata.append(dataframes[i])

        if isothermal_vledata == []:
            st.error('There is no isothermal data available at DDBST')
        else:
            for i in range(len(T)):
                st.write('%d)' % (i + 1), 'T = ', T[i], 'K')
                st.write(isothermal_vledata[i])
            if len(T) == 1:
                choice = 1
            else:
                choice = st.number_input('Choose a dataset', value=1, min_value=1, max_value=len(T))

            if st.button('Go!'):
                st.info('Analysing dataset %d ...' % choice)
                P = isothermal_vledata[choice - 1]['P [kPa]']
                x1 = isothermal_vledata[choice - 1]['x1 [mol/mol]']
                y1 = isothermal_vledata[choice - 1]['y1 [mol/mol]']
                T = T[choice - 1]
                st.write(r'$T = %0.2f K$' % T)

                p1sat = get_psat(compounds[i1], T)
                p2sat = get_psat(compounds[i2], T)

                if p1sat > p2sat:
                    st.info('The more volatile component is %s' % menu_options[i1])
                else:
                    st.info('The more volatile component is %s' % menu_options[i2])

                p1_s = max(p1sat, p2sat)
                p2_s = min(p1sat, p2sat)

                st.write(r'$p_1^s = %0.3f kPa$' % p1_s)
                st.write(r'$p_2^s = %0.3f kPa$' % p2_s)

                x = np.linspace(0, 1, 50)
                P_raoult = x * p1_s + (1 - x) * p2_s
                y_raoult = x * p1_s / P_raoult

                n_points = len(x1) - 1

                try:
                    if x1[0] == 0 and x1[n_points] != 1:
                        x1, y1, P = x1[1:], y1[1:], P[1:]
                    if x1[0] != 0 and x1[n_points] == 1:
                        x1, y1, P = x1[:n_points], y1[:n_points], P[:n_points]
                    if x1[0] == 0 and x1[n_points] == 1:
                        x1, y1, P = x1[1:n_points], y1[1:n_points], P[1:n_points]
                except KeyError:
                    pass

                gamma1 = np.divide(P * y1, x1 * p1_s)
                gamma2 = np.divide(P * (1 - y1), ((1 - x1) * p2_s))
                G_e = constants.R * T * (xlogy(x1, gamma1) + xlogy(1 - x1, gamma2))

                fig1 = plt.figure(facecolor='white')
                plt.gca().set_aspect('equal', adjustable='box')
                plt.title(r"$y-x$")
                plt.xlim(0, 1)
                plt.ylim(0, 1)
                plt.xlabel(r'$x_1$')
                plt.ylabel(r'$y_1$')
                plt.scatter(x1, y1)
                plt.plot(x, y_raoult, label=r"$Raoult's\ Law$", color='black')
                plt.plot(x, x, color='grey')
                plt.legend(loc='best', fontsize=10)

                st.write(fig1)

                fig2 = plt.figure(facecolor='white')
                plt.title(r"$P-x$")
                plt.xlim(0, 1)
                plt.ylim(0, 1.2*max(P))
                plt.xlabel(r'$x_1$')
                plt.ylabel(r'$P\ (kPa)$')
                plt.scatter(x1, P)
                plt.plot(x, P_raoult, color='black', label=r"$Raoult's\ Law$")
                plt.legend(loc='best', fontsize=10)

                st.write(fig2)

                fig3 = plt.figure(facecolor='white')
                plt.title(r"$G^E-x$")
                plt.xlim(0, 1)
                plt.xlabel(r'$x_1$')
                plt.ylabel(r'$G^E\ (J/mol)$')
                plt.scatter(x1, G_e)
                plt.axhline(0, color='black')

                st.write(fig3)
    except:
        ''

    st.sidebar.title("Note")
    st.sidebar.info(""" The saturation pressures are obtained from 
    [DDBST's database](http://ddbonline.ddbst.com/AntoineCalculation/AntoineCalculationCGI.exe?component=Ethanol).""")