CalebBell / thermo

Thermodynamics and Phase Equilibrium component of Chemical Engineering Design Library (ChEDL)
MIT License
594 stars 114 forks source link

Help with implementing binary excess enthalpy predictions #149

Closed Garren-H closed 1 month ago

Garren-H commented 1 month ago

Hi all, I recently came across this toolbox, which I would like to use. I did not see any place where I could ask question regarding the use, hence I am raising this issue (not really an issue, more of a discussion). The problem is that the instructions is just way too difficult to understand, and confusing at times. My main goal is to use this package to estimate the excess enthalpy in binary mixtures using the UNIFAC Dortmund method. To start off I have some excel file which is read to a pandas dataframe. These have components (IUPAC names), composition of component 1 and temperatures and pressures. Following the documentation I have come up with the following code. The main issue I have is the importing the correct group assignments and the correct data for the parameters. Which is not as detailed in the docs, but there is alluded to that different UNIFAC methods have different groups, hence making it difficult??

My full code is here ``` import thermo.unifac thermo.unifac.load_group_assignments_DDBST() # Need help here. Not sure if this is the correct assignments for UNIFAC Dortmund from thermo.unifac import UNIFAC, DOUFSG, DOUFMG, DOUFIP2016 # Same here, not sure if these are the correct datasets. Got this from the docs from chemicals import search_chemical import numpy as np import pandas as pd from IPython.display import clear_output from All_code import subsets # my own code which extracts data to a pandas dataframe from the excel file given some combination of functional groups # set functional groups functional_groups = np.array(['all']) # Extract data from my toolbox subset_df, subset_Indices, subset_Indices_T, Info_Indices, init_indices, init_indices_T = subsets(functional_groups).get_subset_df() # Obtain groups all_chem_mix = [] for i in range(subset_Indices_T.shape[0]): # loop through number of binary mixtures c1 = subset_df['Component 1'][subset_Indices_T[i,0]] c2 = subset_df['Component 2'][subset_Indices_T[i,1]] chem_group1 = thermo.unifac.DDBST_MODIFIED_UNIFAC_assignments[search_chemical(c1).InChI_key] # obtain group for component 1; not sure if this is the correct database chem_group2 = thermo.unifac.DDBST_MODIFIED_UNIFAC_assignments[search_chemical(c2).InChI_key] # Obtain groups for component 2; not sure if this is the correct database all_chem_mix += [[chem_group1, chem_group2]] # combine groups into a list of lists # obtain prediction y = [] for i in range(subset_Indices_T.shape[0]): # loop through number of binary mixtures print(f'Mixture {i+1} out of {subset_Indices_T.shape[0]}') for j in range(subset_Indices_T[i,0], subset_Indices_T[i,1] + 1): # loop through each datapoint in the binary mixtures print(f'Condiditions {j+1} out of {subset_Indices_T[-1,1]+1}') x = subset_df['Composition component 1 [mol/mol]'][j] # obtain composition of 1 xs = [x, 1-x] # T = subset_df['Temperature [K]'][j] # Obtain tempearture GE = UNIFAC.from_subgroups(T=T, xs=xs, chemgroups=all_chem_mix[i], version=1, interaction_data=DOUFIP2016, subgroups=DOUFSG) # not sure if this is correct, also should there not be some pressure dependence? y += [GE.HE()] # obtain predictions clear_output(wait=True) ```

The parts I need help with is:

thermo.unifac.load_group_assignments_DDBST() # Need help here. Not sure if this is the correct assignments for UNIFAC Dortmund

from thermo.unifac import UNIFAC, DOUFSG, DOUFMG, DOUFIP2016 # Same here, not sure if these are the correct datasets. Got this from the docs

chem_group1 = thermo.unifac.DDBST_MODIFIED_UNIFAC_assignments[search_chemical(c1).InChI_key] # obtain group for component 1; not sure if this is the correct database chem_group2 = thermo.unifac.DDBST_MODIFIED_UNIFAC_assignments[search_chemical(c2).InChI_key] # Obtain groups for component 2; not sure if this is the correct database

GE = UNIFAC.from_subgroups(T=T, xs=xs, chemgroups=all_chem_mix[i], version=1, interaction_data=DOUFIP2016, subgroups=DOUFSG) # not sure if this is correct, also should there not be some pressure dependence?

Any assistance with this will be much appreciated

Many thanks Garren

CalebBell commented 1 month ago

Hi Garren, Your approach looks correct to me. You are using a lower-level interface, and using it correctly. Pressure dependence of liquid phase enthalpy is an option in a higher level interface that can consume the UNIFAC object you are creating, see https://thermo.readthedocs.io/thermo.phases.html#thermo.phases.GibbsExcessLiquid.H for the details of the formulas; the pressure dependence of enthalpy in a activity-based model comes from the Poynting correction factor, and is small except at very high pressures. One test showing how to use UNIFAC to do pressure-dependent flashes (you can query H() to obtain enthalpy on the result) is: https://github.com/CalebBell/thermo/blob/42649a952bf39678b33de6fb2ba2a34a72f2ddb7/tests/test_flash_vl.py#L580 Sincerely, Caleb

Garren-H commented 1 month ago

Thanks for the assistance Caleb, it it much appreciated.

As a final note I would just like to say thanks for developing this toolbox. I was planning Aspen and manually obtaining the excess enthalpy across several mixtures, compositions and temperatures. This toolbox has saved me significant time!