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)
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
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
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." )
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]
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).""" )
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).""")