Bulk properties

Excess properties are properties of mixtures which quantify the non-ideal behavior of real mixtures. They are defined as the difference between the value of the property in a real mixture and the value that would exist in an ideal solution under the same conditions.

\[G^E = G - G^{I,S} = \Delta G_{mix}\]
\[H^E = H - H^{I,S} = \Delta H_{mix}\]
\[S^E = H - H^{I,S} = \Delta S_{mix}\]

Gibbs excess models are defined in terms of a mathematical expression that describes the excess Gibbs energy of a mixture as a function of the composition of the components in the mixture and temperature. Then, the other excess properties can be derived from the excess Gibbs energy derivatives.

Example model

First, we are going the import the yaeos library and instantiate a UNIFACLV model with two components. Later in this tutorial you will learn got to instantiate different models, but for now we will use this one as an example.

The important thing to understand is that all the Excess Gibbs models can evaluate the thermodynamic properties explained in this section.

[1]:
import yaeos


# UNIFAC functional groups: n-hexane - toluene
groups = [              # Functional groups of each molecule
    {1: 2, 2: 4},       # {"CH3": 2, "CH2": 4}
    {9: 5, 11: 1},      # {"ACH": 5, "ACCH3": 1}
]

model = yaeos.UNIFACVLE(groups)

Properties of Excess Gibbs Models

All the properties of Excess Gibbs models are evaluated from the Excess Gibbs \(G^{E}(\vec{n}, T)\) function. If you want to know how each bulk property is calculated, please refer to the Fortran User Documentation

We can obtain different bulk properties from a \(G^{E}(\vec{n}, T)\) model specifying the number of moles, and temperature. But also, derivatives could be obtained if asked for.

All not asked derivatives will be set as None. The derivatives are returned as a Python dictionary with the keys dt, dn, etc. respectively. The compositional derivatives are always returned as Numpy arrays.

Excess Gibbs free energy \(G^{E}(\vec{n}, T)\)

[2]:
n = [4.0, 6.0]  # number of moles [mol]
T = 303.15      # temperature [K]

model.excess_gibbs(n, T) # Calculate excess Gibbs [bar L]
[2]:
28.2282850182722

You can obtain the next derivatives:

\[\left(\frac{\partial G^{E}(\vec{n}, T)}{\partial T}\right)_{\vec{n}} \quad \left(\frac{\partial G^{E}(\vec{n}, T)}{\partial n_i}\right)_{T, n_{j \neq i}} \left(\frac{\partial^2 G^{E}(\vec{n}, T)}{\partial T^2}\right)_{\vec{n}} \quad\]
\[\left(\frac{\partial^2 G^{E}(\vec{n}, T)}{\partial n_i \partial T}\right)_{n_{j \neq i}} \left(\frac{\partial^2 G^{E}(\vec{n}, T)}{\partial n_i \partial n_j}\right)_{T, n_{k \neq i,j}} \quad\]

Ask for derivatives as follows:

[3]:
# Asking for all derivatives
Ge, derivatives = model.excess_gibbs(n, T, dt=True, dt2=True, dn=True, dtn=True, dn2=True)

# Displaying results
print("Excess Gibbs: ", Ge)
print("Derivatives: ", derivatives)
Excess Gibbs:  28.2282850182722
Derivatives:  {'dt': 0.028783083761225278, 'dt2': -3.7129021802873095e-05, 'dn': array([4.31577166, 1.82753306]), 'dtn': array([0.00247121, 0.00314971]), 'dn2': array([[-0.84169974,  0.56113316],
       [ 0.56113316, -0.37408877]])}

Logarithm of activity coefficients \(ln \, \gamma(\vec{n},T)\)

[4]:
n = [4.0, 6.0]  # number of moles [mol]
T = 303.15      # temperature [K]

model.ln_gamma(n, T) # natural logarithm of activity coefficients
[4]:
array([0.17122481, 0.07250592])

You can obtain the next derivatives:

\[\left(\frac{\partial ln \, \gamma_i}{\partial T}\right)_{\vec{n}} \quad \left(\frac{\partial ln \, \gamma_i}{\partial n_j}\right)_{T, n_{k \neq j}}\]

Ask for derivatives as follows:

[5]:
# Asking for all derivatives
ln_gamma, derivatives = model.ln_gamma(n, T, dt=True, dn=True)

# Displaying results
print("ln gamma: ", ln_gamma)
print("Derivatives: ", derivatives)
ln gamma:  [0.17122481 0.07250592]
Derivatives:  {'dt': array([-0.00046678, -0.00011421]), 'dn': array([[-0.03339377,  0.02226251],
       [ 0.02226251, -0.01484167]])}

Excess enthalpy \(H^{E}(\vec{n}, T)\)

[6]:
n = [4.0, 6.0]  # number of moles [mol]
T = 303.15      # temperature [K]

model.excess_enthalpy(n, T) # Excess enthalpy [bar L]
[6]:
19.50269317605676

You can obtain the next derivatives:

\[\left(\frac{\partial H^{E}(\vec{n}, T)}{\partial T}\right)_{\vec{n}} \quad \left(\frac{\partial H^{E}(\vec{n}, T)}{\partial n_i}\right)_{T, n_{i \neq j}}\]

Ask for derivatives as follows:

[7]:
# Asking for all derivatives
He, derivatives = model.excess_enthalpy(n, T, dt=True, dn=True)

# Displaying results
print("Excess enthalpy ", He)
print("Derivatives: ", derivatives)
Excess enthalpy  19.50269317605676
Derivatives:  {'dt': 0.011255662959540978, 'dn': array([3.56662377, 0.87269968])}

Excess entropy \(S^{E}(\vec{n}, T)\)

[8]:
n = [4.0, 6.0]  # number of moles [mol]
T = 303.15      # temperature [K]

model.excess_entropy(n, T) # Excess entropy [bar L / K]
[8]:
-0.028783083761225278

You can obtain the next derivatives:

\[\left(\frac{\partial S^{E}(\vec{n}, T)}{\partial T}\right)_{\vec{n}} \quad \left(\frac{\partial S^{E}(\vec{n}, T)}{\partial n_i}\right)_{T, n_{i \neq j}}\]

Ask for derivatives as follows:

[9]:
# Asking for all derivatives
Se, derivatives = model.excess_entropy(n, T, dt=True, dn=True)

# Displaying results
print("Excess entropy ", Se)
print("Derivatives: ", derivatives)
Excess entropy  -0.028783083761225278
Derivatives:  {'dt': 3.7129021802873095e-05, 'dn': array([-0.00247121, -0.00314971])}

Excess heat capacity \(C_p^{E}(\vec{n}, T)\)

[10]:
n = [4.0, 6.0]  # number of moles [mol]
T = 303.15      # temperature [K]

model.excess_cp(n, T) # Excess entropy [bar L / K]
[10]:
0.011255662959540978