Skip to content

Activity Coefficient Models (polykin.thermo.acm)¤

This module implements activity models often used in polymer reactor models.

FloryHuggins ¤

Flory-Huggings multicomponent activity coefficient model.

This model is based on the following Gibbs energy of mixing per mole of sites:

\[ \frac{\Delta g_{mix}}{R T}= \sum_i \frac{\phi_i}{m_i}\ln{\phi_i} + \sum_i \sum_{j>i} \phi_i \phi_j \chi_{ij} \]

where \(\phi_i\) are the volume, mass or segment fractions of the components, \(\chi_{ij}\) are the interaction parameters, and \(m_i\) is the characteristic size of the components.

In this particular implementation, the interaction parameters are allowed to depend on temperature according to the following empirical relationship (as used in Aspen Plus):

\[ \chi_{ij} = a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T + e_{ij} T^2 \]

Moreover, \(\chi_{ij}=\chi_{ji}\) and \(\chi_{ii}=0\).

References

  • P.J. Flory, Principles of polymer chemistry, 1953.
PARAMETER DESCRIPTION
N

Number of components.

TYPE: int

a

Matrix (N,N) of parameters, by default 0. Only the upper triangle must be supplied.

TYPE: FloatSquareMatrix | None DEFAULT: None

b

Matrix (N,N) of parameters, by default 0. Only the upper triangle must be supplied.

TYPE: FloatSquareMatrix | None DEFAULT: None

c

Matrix (N,N) of parameters, by default 0. Only the upper triangle must be supplied.

TYPE: FloatSquareMatrix | None DEFAULT: None

d

Matrix (N,N) of parameters, by default 0. Only the upper triangle must be supplied.

TYPE: FloatSquareMatrix | None DEFAULT: None

e

Matrix (N,N) of parameters, by default 0. Only the upper triangle must be supplied.

TYPE: FloatSquareMatrix | None DEFAULT: None

Source code in src/polykin/thermo/acm/floryhuggins.py
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
class FloryHuggins():
    r"""[Flory-Huggings](https://en.wikipedia.org/wiki/Flory–Huggins_solution_theory)
    multicomponent activity coefficient model.

    This model is based on the following Gibbs energy of mixing per mole of
    sites:

    $$ \frac{\Delta g_{mix}}{R T}= \sum_i \frac{\phi_i}{m_i}\ln{\phi_i}
    + \sum_i \sum_{j>i} \phi_i \phi_j \chi_{ij} $$

    where $\phi_i$ are the volume, mass or segment fractions of the
    components, $\chi_{ij}$ are the interaction parameters, and $m_i$ is the
    characteristic size of the components. 

    In this particular implementation, the interaction parameters are allowed
    to depend on temperature according to the following empirical relationship
    (as used in Aspen Plus):

    $$ \chi_{ij} = a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T + e_{ij} T^2 $$

    Moreover, $\chi_{ij}=\chi_{ji}$ and $\chi_{ii}=0$.

    **References**

    *   P.J. Flory, Principles of polymer chemistry, 1953.

    Parameters
    ----------
    N : int
        Number of components.
    a : FloatSquareMatrix | None
        Matrix (N,N) of parameters, by default 0. Only the upper triangle must
        be supplied.
    b : FloatSquareMatrix | None
        Matrix (N,N) of parameters, by default 0. Only the upper triangle must
        be supplied.
    c : FloatSquareMatrix | None
        Matrix (N,N) of parameters, by default 0. Only the upper triangle must
        be supplied.
    d : FloatSquareMatrix | None
        Matrix (N,N) of parameters, by default 0. Only the upper triangle must
        be supplied.
    e : FloatSquareMatrix | None
        Matrix (N,N) of parameters, by default 0. Only the upper triangle must
        be supplied.

    """

    _N: int
    _a: FloatSquareMatrix
    _b: FloatSquareMatrix
    _c: FloatSquareMatrix
    _d: FloatSquareMatrix
    _e: FloatSquareMatrix

    def __init__(self,
                 N: int,
                 a: Optional[FloatSquareMatrix] = None,
                 b: Optional[FloatSquareMatrix] = None,
                 c: Optional[FloatSquareMatrix] = None,
                 d: Optional[FloatSquareMatrix] = None,
                 e: Optional[FloatSquareMatrix] = None
                 ) -> None:
        """Construct `FloryHuggins` with the given parameters."""

        # Set default values
        if a is None:
            a = np.zeros((N, N))
        if b is None:
            b = np.zeros((N, N))
        if c is None:
            c = np.zeros((N, N))
        if d is None:
            d = np.zeros((N, N))
        if e is None:
            e = np.zeros((N, N))

        # Check shapes
        for array in [a, b, c, d, e]:
            if array.shape != (N, N):
                raise ShapeError(
                    f"The shape of matrix {array} is invalid: {array.shape}.")

        # Check bounds (same as Aspen Plus)
        check_bounds(a, -1e2, 1e2, 'a')
        check_bounds(b, -1e6, 1e6, 'b')
        check_bounds(c, -1e6, 1e6, 'c')
        check_bounds(d, -1e6, 1e6, 'd')
        check_bounds(e, -1e6, 1e6, 'e')

        # Ensure chi_ii=0 and chi_ij=chi_ji
        for array in [a, b, c, d, e]:
            np.fill_diagonal(array, 0.)
            enforce_symmetry(array)

        self._N = N
        self._a = a
        self._b = b
        self._c = c
        self._d = d
        self._e = e

    @functools.cache
    def chi(self, T: float) -> FloatSquareMatrix:
        r"""Compute the matrix of interaction parameters.

        $$
        \chi_{ij} = a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T + e_{ij} T^2
        $$

        Parameters
        ----------
        T : float
            Temperature. Unit = K.

        Returns
        -------
        FloatSquareMatrix
            Matrix of interaction parameters.
        """
        return self._a + self._b/T + self._c*log(T) + self._d*T + self._e*T**2

    def Dgmix(self,
              T: Number,
              phi: FloatVector,
              m: FloatVector) -> Number:
        r"""Gibbs energy of mixing per mole of sites, $\Delta g_{mix}$.

        Parameters
        ----------
        T : float
            Temperature. Unit = K.
        phi : FloatVector
            Volume, mass or segment fractions of all components.
        m : FloatVector
            Characteristic size of all components, typically equal to 1 for
            small molecules and equal to the average degree of polymerization
            for polymers.

        Returns
        -------
        float
            Gibbs energy of mixing per mole of sites. Unit = J/mol.
        """
        p = phi > 0.
        gC = dot(phi[p]/m[p], log(phi[p]))
        gR = 0.5*dot(phi, dot(phi, self.chi(T)))
        return R*T*(gC + gR)

    def Dhmix(self,
              T: float,
              phi: FloatVector,
              m: FloatVector) -> float:
        r"""Enthalpy of mixing per mole of sites, $\Delta h_{mix}$.

        $$ \Delta h_{mix} = \Delta g_{mix} + T \Delta s_{mix} $$

        Parameters
        ----------
        T : float
            Temperature. Unit = K.
        phi : FloatVector
            Volume, mass or segment fractions of all components.
        m : FloatVector
            Characteristic size of all components, typically equal to 1 for
            small molecules and equal to the average degree of polymerization
            for polymers.

        Returns
        -------
        float
            Enthalpy of mixing per mole of sites. Unit = J/mol.
        """
        return self.Dgmix(T, phi, m) + T*self.Dsmix(T, phi, m)

    def Dsmix(self,
              T: float,
              phi: FloatVector,
              m: FloatVector) -> float:
        r"""Entropy of mixing per mole of sites, $\Delta s_{mix}$.

        $$ \Delta s_{mix} = -\left(\frac{\partial \Delta g_{mix}}
           {\partial T}\right)_{P,\phi_i,m_i} $$

        Parameters
        ----------
        T : float
            Temperature. Unit = K.
        phi : FloatVector
            Volume, mass or segment fractions of all components.
        m : FloatVector
            Characteristic size of all components, typically equal to 1 for
            small molecules and equal to the average degree of polymerization
            for polymers.

        Returns
        -------
        float
            Entropy of mixing per mole of sites. Unit = J/(mol·K).
        """
        return -derivative_complex(lambda t: self.Dgmix(t, phi, m), T)[0]

    def a(self,
          T: float,
          phi: FloatVector,
          m: FloatVector
          ) -> FloatVector:
        r"""Activities, $a_i$.

        Parameters
        ----------
        T : float
            Temperature. Unit = K.
        phi : FloatVector
            Volume, mass or segment fractions of all components.
        m : FloatVector
            Characteristic size of all components, typically equal to 1 for
            small molecules and equal to the average degree of polymerization
            for polymers.

        Returns
        -------
        FloatVector
            Activities of all components.
        """
        return FloryHuggins_activity(phi, m, self.chi(T))

Dgmix ¤

Dgmix(
    T: Number, phi: FloatVector, m: FloatVector
) -> Number

Gibbs energy of mixing per mole of sites, \(\Delta g_{mix}\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

phi

Volume, mass or segment fractions of all components.

TYPE: FloatVector

m

Characteristic size of all components, typically equal to 1 for small molecules and equal to the average degree of polymerization for polymers.

TYPE: FloatVector

RETURNS DESCRIPTION
float

Gibbs energy of mixing per mole of sites. Unit = J/mol.

Source code in src/polykin/thermo/acm/floryhuggins.py
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
def Dgmix(self,
          T: Number,
          phi: FloatVector,
          m: FloatVector) -> Number:
    r"""Gibbs energy of mixing per mole of sites, $\Delta g_{mix}$.

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    phi : FloatVector
        Volume, mass or segment fractions of all components.
    m : FloatVector
        Characteristic size of all components, typically equal to 1 for
        small molecules and equal to the average degree of polymerization
        for polymers.

    Returns
    -------
    float
        Gibbs energy of mixing per mole of sites. Unit = J/mol.
    """
    p = phi > 0.
    gC = dot(phi[p]/m[p], log(phi[p]))
    gR = 0.5*dot(phi, dot(phi, self.chi(T)))
    return R*T*(gC + gR)

Dhmix ¤

Dhmix(T: float, phi: FloatVector, m: FloatVector) -> float

Enthalpy of mixing per mole of sites, \(\Delta h_{mix}\).

\[ \Delta h_{mix} = \Delta g_{mix} + T \Delta s_{mix} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

phi

Volume, mass or segment fractions of all components.

TYPE: FloatVector

m

Characteristic size of all components, typically equal to 1 for small molecules and equal to the average degree of polymerization for polymers.

TYPE: FloatVector

RETURNS DESCRIPTION
float

Enthalpy of mixing per mole of sites. Unit = J/mol.

Source code in src/polykin/thermo/acm/floryhuggins.py
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def Dhmix(self,
          T: float,
          phi: FloatVector,
          m: FloatVector) -> float:
    r"""Enthalpy of mixing per mole of sites, $\Delta h_{mix}$.

    $$ \Delta h_{mix} = \Delta g_{mix} + T \Delta s_{mix} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    phi : FloatVector
        Volume, mass or segment fractions of all components.
    m : FloatVector
        Characteristic size of all components, typically equal to 1 for
        small molecules and equal to the average degree of polymerization
        for polymers.

    Returns
    -------
    float
        Enthalpy of mixing per mole of sites. Unit = J/mol.
    """
    return self.Dgmix(T, phi, m) + T*self.Dsmix(T, phi, m)

Dsmix ¤

Dsmix(T: float, phi: FloatVector, m: FloatVector) -> float

Entropy of mixing per mole of sites, \(\Delta s_{mix}\).

\[ \Delta s_{mix} = -\left(\frac{\partial \Delta g_{mix}} {\partial T}\right)_{P,\phi_i,m_i} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

phi

Volume, mass or segment fractions of all components.

TYPE: FloatVector

m

Characteristic size of all components, typically equal to 1 for small molecules and equal to the average degree of polymerization for polymers.

TYPE: FloatVector

RETURNS DESCRIPTION
float

Entropy of mixing per mole of sites. Unit = J/(mol·K).

Source code in src/polykin/thermo/acm/floryhuggins.py
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
def Dsmix(self,
          T: float,
          phi: FloatVector,
          m: FloatVector) -> float:
    r"""Entropy of mixing per mole of sites, $\Delta s_{mix}$.

    $$ \Delta s_{mix} = -\left(\frac{\partial \Delta g_{mix}}
       {\partial T}\right)_{P,\phi_i,m_i} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    phi : FloatVector
        Volume, mass or segment fractions of all components.
    m : FloatVector
        Characteristic size of all components, typically equal to 1 for
        small molecules and equal to the average degree of polymerization
        for polymers.

    Returns
    -------
    float
        Entropy of mixing per mole of sites. Unit = J/(mol·K).
    """
    return -derivative_complex(lambda t: self.Dgmix(t, phi, m), T)[0]

__init__ ¤

__init__(
    N: int,
    a: Optional[FloatSquareMatrix] = None,
    b: Optional[FloatSquareMatrix] = None,
    c: Optional[FloatSquareMatrix] = None,
    d: Optional[FloatSquareMatrix] = None,
    e: Optional[FloatSquareMatrix] = None,
) -> None

Construct FloryHuggins with the given parameters.

Source code in src/polykin/thermo/acm/floryhuggins.py
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
def __init__(self,
             N: int,
             a: Optional[FloatSquareMatrix] = None,
             b: Optional[FloatSquareMatrix] = None,
             c: Optional[FloatSquareMatrix] = None,
             d: Optional[FloatSquareMatrix] = None,
             e: Optional[FloatSquareMatrix] = None
             ) -> None:
    """Construct `FloryHuggins` with the given parameters."""

    # Set default values
    if a is None:
        a = np.zeros((N, N))
    if b is None:
        b = np.zeros((N, N))
    if c is None:
        c = np.zeros((N, N))
    if d is None:
        d = np.zeros((N, N))
    if e is None:
        e = np.zeros((N, N))

    # Check shapes
    for array in [a, b, c, d, e]:
        if array.shape != (N, N):
            raise ShapeError(
                f"The shape of matrix {array} is invalid: {array.shape}.")

    # Check bounds (same as Aspen Plus)
    check_bounds(a, -1e2, 1e2, 'a')
    check_bounds(b, -1e6, 1e6, 'b')
    check_bounds(c, -1e6, 1e6, 'c')
    check_bounds(d, -1e6, 1e6, 'd')
    check_bounds(e, -1e6, 1e6, 'e')

    # Ensure chi_ii=0 and chi_ij=chi_ji
    for array in [a, b, c, d, e]:
        np.fill_diagonal(array, 0.)
        enforce_symmetry(array)

    self._N = N
    self._a = a
    self._b = b
    self._c = c
    self._d = d
    self._e = e

a ¤

a(
    T: float, phi: FloatVector, m: FloatVector
) -> FloatVector

Activities, \(a_i\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

phi

Volume, mass or segment fractions of all components.

TYPE: FloatVector

m

Characteristic size of all components, typically equal to 1 for small molecules and equal to the average degree of polymerization for polymers.

TYPE: FloatVector

RETURNS DESCRIPTION
FloatVector

Activities of all components.

Source code in src/polykin/thermo/acm/floryhuggins.py
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
def a(self,
      T: float,
      phi: FloatVector,
      m: FloatVector
      ) -> FloatVector:
    r"""Activities, $a_i$.

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    phi : FloatVector
        Volume, mass or segment fractions of all components.
    m : FloatVector
        Characteristic size of all components, typically equal to 1 for
        small molecules and equal to the average degree of polymerization
        for polymers.

    Returns
    -------
    FloatVector
        Activities of all components.
    """
    return FloryHuggins_activity(phi, m, self.chi(T))

chi cached ¤

chi(T: float) -> FloatSquareMatrix

Compute the matrix of interaction parameters.

\[ \chi_{ij} = a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T + e_{ij} T^2 \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

RETURNS DESCRIPTION
FloatSquareMatrix

Matrix of interaction parameters.

Source code in src/polykin/thermo/acm/floryhuggins.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
@functools.cache
def chi(self, T: float) -> FloatSquareMatrix:
    r"""Compute the matrix of interaction parameters.

    $$
    \chi_{ij} = a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T + e_{ij} T^2
    $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.

    Returns
    -------
    FloatSquareMatrix
        Matrix of interaction parameters.
    """
    return self._a + self._b/T + self._c*log(T) + self._d*T + self._e*T**2

FloryHuggins2_activity ¤

FloryHuggins2_activity(
    phi1: Union[float, FloatArray],
    m: Union[float, FloatArray],
    chi: Union[float, FloatArray],
) -> Union[float, FloatArray]

Calculate the solvent activity of a binary polymer solution according to the Flory-Huggins model.

\[ \ln{a_1} = \ln \phi_1 + \left(\ 1 - \frac{1}{m} \right)(1-\phi_1) + \chi_{12}(1-\phi_1)^2 \]

where \(\phi_1\) is the volume, mass or segment fraction of the solvent in the solution, \(\chi\) is the solvent-polymer interaction parameter, and \(m\) is the ratio of the molar volume of the polymer to the solvent, often approximated as the degree of polymerization.

Note

The Flory-Huggins model was originally formulated using the volume fraction as primary composition variable, but many authors prefer mass fractions in order to skip issues with densities, etc. This equation can be used in all cases, as long as \(\phi_1\) is taken to be the same variable used to estimate \(\chi\). For example, if a given publication reports values of \(\chi\) estimated with the mass fraction version of the Flory-Huggins model, then \(\phi_1\) should be the mass fraction of solvent.

References

  • P.J. Flory, Principles of polymer chemistry, 1953.
PARAMETER DESCRIPTION
phi1

Volume, mass, or segment fraction of solvent in the solution, \(\phi_1\). The composition variable must match the one used in the determination of \(\chi\).

TYPE: float | FloatArray

m

Ratio of the molar volume of the polymer chain to the solvent, often approximated as the degree of polymerization.

TYPE: float | FloatArray

chi

Solvent-polymer interaction parameter, \(\chi\).

TYPE: float | FloatArray

RETURNS DESCRIPTION
FloatVector

Activity of the solvent.

See also

Examples:

Calculate the activity of ethylbenzene in a ethylbenzene-polybutadiene solution with 25 wt% solvent content. Assume \(\chi=0.29\).

>>> from polykin.thermo.acm import FloryHuggins2_gamma
>>> gamma = FloryHuggins2_gamma(phi1=0.25, m=1e6, chi=0.29)
>>> print(f"{gamma:.2f}")
0.62
Source code in src/polykin/thermo/acm/floryhuggins.py
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
def FloryHuggins2_activity(phi1: Union[float, FloatArray],
                           m: Union[float, FloatArray],
                           chi: Union[float, FloatArray]
                           ) -> Union[float, FloatArray]:
    r"""Calculate the solvent activity of a binary polymer solution according
    to the Flory-Huggins model.

    $$ \ln{a_1} = \ln \phi_1 + \left(\ 1 - \frac{1}{m} \right)(1-\phi_1)
                  + \chi_{12}(1-\phi_1)^2 $$

    where $\phi_1$ is the volume, mass or segment fraction of the solvent in
    the solution, $\chi$ is the solvent-polymer interaction parameter, and $m$
    is the ratio of the molar volume of the polymer to the solvent, often
    approximated as the degree of polymerization. 

    !!! note

        The Flory-Huggins model was originally formulated using the volume
        fraction as primary composition variable, but many authors prefer mass
        fractions in order to skip issues with densities, etc. This equation
        can be used in all cases, as long as $\phi_1$ is taken to be the same
        variable used to estimate $\chi$. For example, if a given publication
        reports values of $\chi$ estimated with the mass fraction version of
        the Flory-Huggins model, then $\phi_1$ should be the mass fraction of
        solvent.

    **References**

    *   P.J. Flory, Principles of polymer chemistry, 1953.

    Parameters
    ----------
    phi1 : float | FloatArray
        Volume, mass, or segment fraction of solvent in the solution, $\phi_1$.
        The composition variable must match the one used in the determination
        of $\chi$.
    m : float | FloatArray
        Ratio of the molar volume of the polymer chain to the solvent, often
        approximated as the degree of polymerization.
    chi : float | FloatArray
        Solvent-polymer interaction parameter, $\chi$.

    Returns
    -------
    FloatVector
        Activity of the solvent.

    See also
    --------
    * [`FloryHuggins_activity`](FloryHuggins_activity.md): equivalent method
      for multicomponent systems.

    Examples
    --------
    Calculate the activity of ethylbenzene in a ethylbenzene-polybutadiene
    solution with 25 wt% solvent content. Assume $\chi=0.29$.
    >>> from polykin.thermo.acm import FloryHuggins2_gamma
    >>> gamma = FloryHuggins2_gamma(phi1=0.25, m=1e6, chi=0.29)
    >>> print(f"{gamma:.2f}")
    0.62

    """
    phi2 = 1 - phi1
    return phi1*exp((1 - 1/m)*phi2 + chi*phi2**2)

FloryHuggins_activity ¤

FloryHuggins_activity(
    phi: FloatVector, m: FloatVector, chi: FloatSquareMatrix
) -> FloatVector

Calculate the activities of a multicomponent mixture according to the Flory-Huggins model.

\[ \ln{a_i} = \ln{\phi_i} + 1 - m_i \left(\sum_j \frac{\phi_j}{m_j} - \sum_j \phi_j \chi_{ij} + \sum_j \sum_{k>j} \phi_j \phi_k \chi_{jk} \right) \]

where \(\phi_i\) are the volume, mass or segment fractions of the components, \(\chi_{ij}\) are the interaction parameters, and \(m_i\) is the characteristic size of the components.

Note

The Flory-Huggins model was originally formulated using the volume fraction as primary composition variable, but many authors prefer mass fractions in order to skip issues with densities, etc. This equation can be used in all cases, as long as \(\phi\) is taken to be the same variable used to estimate \(\chi\). In this particular implementation, the matrix of interaction parameters is independent of molecular size and, thus, symmetric.

References

  • P.J. Flory, Principles of polymer chemistry, 1953.
  • Lindvig, Thomas, et al. "Modeling of multicomponent vapor-liquid equilibria for polymer-solvent systems." Fluid phase equilibria 220.1 (2004): 11-20.
PARAMETER DESCRIPTION
phi

Volume, mass or segment fractions of all components, \(\phi_i\). The composition variable must match the one used in the determination of \(\chi_{ij}\).

TYPE: FloatVector

m

Characteristic size of all components, typically equal to 1 for small molecules and equal to the average degree of polymerization for polymers.

TYPE: FloatVector

chi

Matrix (N,N) of interaction parameters, \(\chi_{ij}\). It is expected (but not checked) that \(\chi_{ij}=\chi_{ji}\) and \(\chi_{ii}=0\).

TYPE: FloatSquareMatrix

RETURNS DESCRIPTION
FloatVector

Activities of all components.

See also
Source code in src/polykin/thermo/acm/floryhuggins.py
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
def FloryHuggins_activity(phi: FloatVector,
                          m: FloatVector,
                          chi: FloatSquareMatrix
                          ) -> FloatVector:
    r"""Calculate the activities of a multicomponent mixture according to the
    Flory-Huggins model.

    $$ 
    \ln{a_i} = \ln{\phi_i} + 1 - m_i \left(\sum_j \frac{\phi_j}{m_j} - 
    \sum_j \phi_j \chi_{ij} + \sum_j \sum_{k>j} \phi_j \phi_k \chi_{jk} \right)
    $$

    where $\phi_i$ are the volume, mass or segment fractions of the
    components, $\chi_{ij}$ are the interaction parameters, and $m_i$ is the
    characteristic size of the components. 

    !!! note

        The Flory-Huggins model was originally formulated using the volume
        fraction as primary composition variable, but many authors prefer mass
        fractions in order to skip issues with densities, etc. This equation
        can be used in all cases, as long as $\phi$ is taken to be the same
        variable used to estimate $\chi$.
        In this particular implementation, the matrix of interaction parameters
        is independent of molecular size and, thus, symmetric.

    **References**

    *   P.J. Flory, Principles of polymer chemistry, 1953.
    *   Lindvig, Thomas, et al. "Modeling of multicomponent vapor-liquid
        equilibria for polymer-solvent systems." Fluid phase equilibria 220.1
        (2004): 11-20.

    Parameters
    ----------
    phi : FloatVector
        Volume, mass or segment fractions of all components, $\phi_i$. The
        composition variable must match the one used in the determination of
        $\chi_{ij}$.
    m : FloatVector
        Characteristic size of all components, typically equal to 1 for small
        molecules and equal to the average degree of polymerization for
        polymers.
    chi : FloatSquareMatrix
        Matrix (N,N) of interaction parameters, $\chi_{ij}$. It is expected
        (but not checked) that $\chi_{ij}=\chi_{ji}$ and $\chi_{ii}=0$.

    Returns
    -------
    FloatVector
        Activities of all components.

    See also
    --------
    * [`FloryHuggins2_activity`](FloryHuggins2_activity.md): equivalent
      method for binary solvent-polymer systems.

    """
    A = dot(phi, 1/m)
    B = dot(chi, phi)
    C = 0.5*dot(phi, dot(phi, chi))
    return phi*exp(1 - m*(A - B + C))

IdealSolution ¤

Ideal solution model.

This model is based on the following trivial molar excess Gibbs energy expression:

\[ g^{E} = 0 \]
PARAMETER DESCRIPTION
N

Number of components.

TYPE: int

name

Name.

TYPE: str DEFAULT: ''

Source code in src/polykin/thermo/acm/ideal.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class IdealSolution(SmallSpeciesActivityModel):
    r"""[Ideal solution](https://en.wikipedia.org/wiki/Ideal_solution) model.

    This model is based on the following trivial molar excess Gibbs energy
    expression:

    $$ g^{E} = 0 $$

    Parameters
    ----------
    N : int
        Number of components.
    name : str
        Name.
    """

    def __init__(self,
                 N: int,
                 name: str = ''
                 ) -> None:

        super().__init__(N, name)

    def gE(self, T: float, x: FloatVector) -> float:
        return 0.

    def gamma(self, T: float, x: FloatVector) -> FloatVector:
        return np.ones(self.N)

Dgmix ¤

Dgmix(T: float, x: FloatVector) -> float

Molar Gibbs energy of mixing, \(\Delta g_{mix}\).

\[ \Delta g_{mix} = \Delta h_{mix} -T \Delta s_{mix} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar Gibbs energy of mixing. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def Dgmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar Gibbs energy of mixing, $\Delta g_{mix}$.

    $$ \Delta g_{mix} = \Delta h_{mix} -T \Delta s_{mix} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar Gibbs energy of mixing. Unit = J/mol.
    """
    return self.gE(T, x) - T*self._Dsmix_ideal(T, x)

Dhmix ¤

Dhmix(T: float, x: FloatVector) -> float

Molar enthalpy of mixing, \(\Delta h_{mix}\).

\[ \Delta h_{mix} = h^{E} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar enthalpy of mixing. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
def Dhmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar enthalpy of mixing, $\Delta h_{mix}$.

    $$ \Delta h_{mix} = h^{E} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar enthalpy of mixing. Unit = J/mol.
    """
    return self.hE(T, x)

Dsmix ¤

Dsmix(T: float, x: FloatVector) -> float

Molar entropy of mixing, \(\Delta s_{mix}\).

\[ \Delta s_{mix} = s^{E} - R \sum_i {x_i \ln{x_i}} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar entropy of mixing. Unit = J/(mol·K).

Source code in src/polykin/thermo/acm/base.py
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def Dsmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar entropy of mixing, $\Delta s_{mix}$.

    $$ \Delta s_{mix} = s^{E} - R \sum_i {x_i \ln{x_i}} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar entropy of mixing. Unit = J/(mol·K).
    """
    return self.sE(T, x) + self._Dsmix_ideal(T, x)

N property ¤

N: int

Number of components.

activity ¤

activity(T: float, x: FloatVector) -> FloatVector

Activities, \(a_i\).

\[ a_i = x_i \gamma_i \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
FloatVector(N)

Activities of all components.

Source code in src/polykin/thermo/acm/base.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
def activity(self,
             T: float,
             x: FloatVector
             ) -> FloatVector:
    r"""Activities, $a_i$.

    $$ a_i = x_i \gamma_i $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    FloatVector (N)
        Activities of all components.
    """
    return x*self.gamma(T, x)

gE ¤

gE(T: float, x: FloatVector) -> float

Molar excess Gibbs energy, \(g^{E}\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess Gibbs energy. Unit = J/mol.

Source code in src/polykin/thermo/acm/ideal.py
37
38
def gE(self, T: float, x: FloatVector) -> float:
    return 0.

gamma ¤

gamma(T: float, x: FloatVector) -> FloatVector

Activity coefficients based on mole fraction, \(\gamma_i\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
FloatVector(N)

Activity coefficients of all components.

Source code in src/polykin/thermo/acm/ideal.py
40
41
def gamma(self, T: float, x: FloatVector) -> FloatVector:
    return np.ones(self.N)

hE ¤

hE(T: float, x: FloatVector) -> float

Molar excess enthalpy, \(h^{E}\).

\[ h^{E} = g^{E} + T s^{E} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess enthalpy. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def hE(self,
       T: float,
       x: FloatVector
       ) -> float:
    r"""Molar excess enthalpy, $h^{E}$.

    $$ h^{E} = g^{E} + T s^{E} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar excess enthalpy. Unit = J/mol.
    """
    return self.gE(T, x) + T*self.sE(T, x)

sE ¤

sE(T: float, x: FloatVector) -> float

Molar excess entropy, \(s^{E}\).

\[ s^{E} = -\left(\frac{\partial g^{E}}{\partial T}\right)_{P,x_i} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess entropy. Unit = J/(mol·K).

Source code in src/polykin/thermo/acm/base.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def sE(self,
       T: float,
       x: FloatVector
       ) -> float:
    r"""Molar excess entropy, $s^{E}$.

    $$ s^{E} = -\left(\frac{\partial g^{E}}{\partial T}\right)_{P,x_i} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar excess entropy. Unit = J/(mol·K).
    """
    return -1*derivative_complex(lambda t: self.gE(t, x), T)[0]

NRTL ¤

NRTL multicomponent activity coefficient model.

This model is based on the following molar excess Gibbs energy expression:

\[ \frac{g^{E}}{RT} = \sum_i x_i \frac{\displaystyle\sum_j x_j \tau_{ji} G_{ji}} {\displaystyle\sum_j x_j G_{ji}} \]

where \(x_i\) are the mole fractions, \(\tau_{ij}\) are the interaction parameters, \(\alpha_{ij}\) are the non-randomness parameters, and \(G_{ij}=\exp(-\alpha_{ij} \tau_{ij})\).

In this particular implementation, the model parameters are allowed to depend on temperature according to the following empirical relationship (as done in Aspen Plus):

\[\begin{aligned} \tau_{ij} &= a_{ij} + b_{ij}/T + e_{ij} \ln{T} + f_{ij} T \\ \alpha_{ij} &= c_{ij} + d_{ij}(T - 273.15) \end{aligned}\]

Moreover, \(\tau_{ij}\neq\tau_{ji}\), \(\tau_{ii}=0\), and \(\alpha_{ij}=\alpha_{ji}\).

References

  • Renon, H. and Prausnitz, J.M. (1968), Local compositions in thermodynamic excess functions for liquid mixtures. AIChE J., 14: 135-144.
PARAMETER DESCRIPTION
N

Number of components.

TYPE: int

a

Matrix of interaction parameters, by default 0.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

b

Matrix of interaction parameters, by default 0. Unit = K.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

c

Matrix of interaction parameters, by default 0.3. Only the upper triangle must be supplied.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

d

Matrix of interaction parameters, by default 0. Only the upper triangle must be supplied. Unit = 1/K.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

e

Matrix of interaction parameters, by default 0.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

f

Matrix of interaction parameters, by default 0.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

name

Name.

TYPE: str DEFAULT: ''

See also
  • NRTL_gamma: related activity coefficient method.
Source code in src/polykin/thermo/acm/nrtl.py
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
class NRTL(SmallSpeciesActivityModel):
    r"""[NRTL](https://en.wikipedia.org/wiki/Non-random_two-liquid_model)
    multicomponent activity coefficient model.

    This model is based on the following molar excess Gibbs energy
    expression:

    $$ \frac{g^{E}}{RT} = 
        \sum_i x_i \frac{\displaystyle\sum_j x_j \tau_{ji} G_{ji}}
        {\displaystyle\sum_j x_j G_{ji}} $$

    where $x_i$ are the mole fractions, $\tau_{ij}$ are the interaction
    parameters, $\alpha_{ij}$ are the non-randomness parameters, and
    $G_{ij}=\exp(-\alpha_{ij} \tau_{ij})$. 

    In this particular implementation, the model parameters are allowed to
    depend on temperature according to the following empirical relationship
    (as done in Aspen Plus):

    \begin{aligned}
    \tau_{ij} &= a_{ij} + b_{ij}/T + e_{ij} \ln{T} + f_{ij} T \\
    \alpha_{ij} &= c_{ij} + d_{ij}(T - 273.15)
    \end{aligned}

    Moreover, $\tau_{ij}\neq\tau_{ji}$, $\tau_{ii}=0$, and
    $\alpha_{ij}=\alpha_{ji}$.

    **References**

    *   Renon, H. and Prausnitz, J.M. (1968), Local compositions in
        thermodynamic excess functions for liquid mixtures. AIChE J.,
        14: 135-144.

    Parameters
    ----------
    N : int
        Number of components.
    a : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.
    b : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0. Unit = K.
    c : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.3. Only the upper
        triangle must be supplied.
    d : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0. Only the upper triangle
        must be supplied. Unit = 1/K.
    e : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.
    f : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.
    name: str
        Name.

    See also
    --------
    * [`NRTL_gamma`](NRTL_gamma.md): related activity coefficient method.

    """

    _a: FloatSquareMatrix
    _b: FloatSquareMatrix
    _c: FloatSquareMatrix
    _d: FloatSquareMatrix
    _e: FloatSquareMatrix
    _f: FloatSquareMatrix

    def __init__(self,
                 N: int,
                 a: Optional[FloatSquareMatrix] = None,
                 b: Optional[FloatSquareMatrix] = None,
                 c: Optional[FloatSquareMatrix] = None,
                 d: Optional[FloatSquareMatrix] = None,
                 e: Optional[FloatSquareMatrix] = None,
                 f: Optional[FloatSquareMatrix] = None,
                 name: str = ''
                 ) -> None:

        # Set default values
        if a is None:
            a = np.zeros((N, N))
        if b is None:
            b = np.zeros((N, N))
        if c is None:
            c = np.full((N, N), 0.3)
        if d is None:
            d = np.zeros((N, N))
        if e is None:
            e = np.zeros((N, N))
        if f is None:
            f = np.zeros((N, N))

        # Check shapes
        for array in [a, b, c, d, e, f]:
            if array.shape != (N, N):
                raise ShapeError(
                    f"The shape of matrix {array} is invalid: {array.shape}.")

        # Check bounds (same as Aspen Plus)
        check_bounds(a, -1e2, 1e2, 'a')
        check_bounds(b, -3e4, 3e4, 'b')
        check_bounds(c, 0., 1., 'c')
        check_bounds(d, -0.02, 0.02, 'd')

        # Ensure tau_ii=0
        for array in [a, b, e, f]:
            np.fill_diagonal(array, 0.)

        # Ensure alpha_ij=alpha_ji
        for array in [c, d]:
            np.fill_diagonal(array, 0.)
            enforce_symmetry(array)

        super().__init__(N, name)
        self._a = a
        self._b = b
        self._c = c
        self._d = d
        self._e = e
        self._f = f

    @functools.cache
    def alpha(self,
              T: float
              ) -> FloatSquareMatrix:
        r"""Compute matrix of non-randomness parameters.

        $$ \alpha_{ij} = c_{ij} + d_{ij}(T - 273.15) $$

        Parameters
        ----------
        T : float
            Temperature. Unit = K.

        Returns
        -------
        FloatSquareMatrix (N,N)
            Non-randomness parameters.
        """
        return self._c + self._d*(T - 273.15)

    @functools.cache
    def tau(self,
            T: float
            ) -> FloatSquareMatrix:
        r"""Compute the matrix of interaction parameters.

        $$ \tau_{ij} = a_{ij} + b_{ij}/T + e_{ij} \ln{T} + f_{ij} T $$

        Parameters
        ----------
        T : float
            Temperature. Unit = K.

        Returns
        -------
        FloatSquareMatrix (N,N)
            Interaction parameters.
        """
        return self._a + self._b/T + self._e*log(T) + self._f*T

    def gE(self, T: float, x: FloatVector) -> float:
        tau = self.tau(T)
        alpha = self.alpha(T)
        G = exp(-alpha*tau)
        A = dot(x, tau*G)
        B = dot(x, G)
        return R*T*dot(x, A/B)

    def gamma(self, T: float, x: FloatVector) -> FloatVector:
        return NRTL_gamma(x, self.tau(T), self.alpha(T))

Dgmix ¤

Dgmix(T: float, x: FloatVector) -> float

Molar Gibbs energy of mixing, \(\Delta g_{mix}\).

\[ \Delta g_{mix} = \Delta h_{mix} -T \Delta s_{mix} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar Gibbs energy of mixing. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def Dgmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar Gibbs energy of mixing, $\Delta g_{mix}$.

    $$ \Delta g_{mix} = \Delta h_{mix} -T \Delta s_{mix} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar Gibbs energy of mixing. Unit = J/mol.
    """
    return self.gE(T, x) - T*self._Dsmix_ideal(T, x)

Dhmix ¤

Dhmix(T: float, x: FloatVector) -> float

Molar enthalpy of mixing, \(\Delta h_{mix}\).

\[ \Delta h_{mix} = h^{E} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar enthalpy of mixing. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
def Dhmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar enthalpy of mixing, $\Delta h_{mix}$.

    $$ \Delta h_{mix} = h^{E} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar enthalpy of mixing. Unit = J/mol.
    """
    return self.hE(T, x)

Dsmix ¤

Dsmix(T: float, x: FloatVector) -> float

Molar entropy of mixing, \(\Delta s_{mix}\).

\[ \Delta s_{mix} = s^{E} - R \sum_i {x_i \ln{x_i}} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar entropy of mixing. Unit = J/(mol·K).

Source code in src/polykin/thermo/acm/base.py
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def Dsmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar entropy of mixing, $\Delta s_{mix}$.

    $$ \Delta s_{mix} = s^{E} - R \sum_i {x_i \ln{x_i}} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar entropy of mixing. Unit = J/(mol·K).
    """
    return self.sE(T, x) + self._Dsmix_ideal(T, x)

N property ¤

N: int

Number of components.

activity ¤

activity(T: float, x: FloatVector) -> FloatVector

Activities, \(a_i\).

\[ a_i = x_i \gamma_i \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
FloatVector(N)

Activities of all components.

Source code in src/polykin/thermo/acm/base.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
def activity(self,
             T: float,
             x: FloatVector
             ) -> FloatVector:
    r"""Activities, $a_i$.

    $$ a_i = x_i \gamma_i $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    FloatVector (N)
        Activities of all components.
    """
    return x*self.gamma(T, x)

alpha cached ¤

alpha(T: float) -> FloatSquareMatrix

Compute matrix of non-randomness parameters.

\[ \alpha_{ij} = c_{ij} + d_{ij}(T - 273.15) \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

RETURNS DESCRIPTION
FloatSquareMatrix(N, N)

Non-randomness parameters.

Source code in src/polykin/thermo/acm/nrtl.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
@functools.cache
def alpha(self,
          T: float
          ) -> FloatSquareMatrix:
    r"""Compute matrix of non-randomness parameters.

    $$ \alpha_{ij} = c_{ij} + d_{ij}(T - 273.15) $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.

    Returns
    -------
    FloatSquareMatrix (N,N)
        Non-randomness parameters.
    """
    return self._c + self._d*(T - 273.15)

gE ¤

gE(T: float, x: FloatVector) -> float

Molar excess Gibbs energy, \(g^{E}\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess Gibbs energy. Unit = J/mol.

Source code in src/polykin/thermo/acm/nrtl.py
183
184
185
186
187
188
189
def gE(self, T: float, x: FloatVector) -> float:
    tau = self.tau(T)
    alpha = self.alpha(T)
    G = exp(-alpha*tau)
    A = dot(x, tau*G)
    B = dot(x, G)
    return R*T*dot(x, A/B)

gamma ¤

gamma(T: float, x: FloatVector) -> FloatVector

Activity coefficients based on mole fraction, \(\gamma_i\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
FloatVector(N)

Activity coefficients of all components.

Source code in src/polykin/thermo/acm/nrtl.py
191
192
def gamma(self, T: float, x: FloatVector) -> FloatVector:
    return NRTL_gamma(x, self.tau(T), self.alpha(T))

hE ¤

hE(T: float, x: FloatVector) -> float

Molar excess enthalpy, \(h^{E}\).

\[ h^{E} = g^{E} + T s^{E} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess enthalpy. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def hE(self,
       T: float,
       x: FloatVector
       ) -> float:
    r"""Molar excess enthalpy, $h^{E}$.

    $$ h^{E} = g^{E} + T s^{E} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar excess enthalpy. Unit = J/mol.
    """
    return self.gE(T, x) + T*self.sE(T, x)

sE ¤

sE(T: float, x: FloatVector) -> float

Molar excess entropy, \(s^{E}\).

\[ s^{E} = -\left(\frac{\partial g^{E}}{\partial T}\right)_{P,x_i} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess entropy. Unit = J/(mol·K).

Source code in src/polykin/thermo/acm/base.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def sE(self,
       T: float,
       x: FloatVector
       ) -> float:
    r"""Molar excess entropy, $s^{E}$.

    $$ s^{E} = -\left(\frac{\partial g^{E}}{\partial T}\right)_{P,x_i} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar excess entropy. Unit = J/(mol·K).
    """
    return -1*derivative_complex(lambda t: self.gE(t, x), T)[0]

tau cached ¤

tau(T: float) -> FloatSquareMatrix

Compute the matrix of interaction parameters.

\[ \tau_{ij} = a_{ij} + b_{ij}/T + e_{ij} \ln{T} + f_{ij} T \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

RETURNS DESCRIPTION
FloatSquareMatrix(N, N)

Interaction parameters.

Source code in src/polykin/thermo/acm/nrtl.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
@functools.cache
def tau(self,
        T: float
        ) -> FloatSquareMatrix:
    r"""Compute the matrix of interaction parameters.

    $$ \tau_{ij} = a_{ij} + b_{ij}/T + e_{ij} \ln{T} + f_{ij} T $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.

    Returns
    -------
    FloatSquareMatrix (N,N)
        Interaction parameters.
    """
    return self._a + self._b/T + self._e*log(T) + self._f*T

NRTL_gamma ¤

NRTL_gamma(
    x: FloatVector,
    tau: FloatSquareMatrix,
    alpha: FloatSquareMatrix,
) -> FloatVector

Calculate the activity coefficients of a multicomponent mixture according to the NRTL model.

\[ \ln{\gamma_i} = \frac{\displaystyle\sum_{k}{x_{k}\tau_{ki}G_{ki}}} {\displaystyle\sum_{k}{x_{k}G_{ki}}} +\sum_{j}{\frac{x_{j}G_{ij}}{\displaystyle\sum_{k}{x_{k}G_{kj}}}} {\left ({\tau_{ij}-\frac{\displaystyle\sum_{k}{x_{k}\tau_{kj}G_{kj}}} {\displaystyle\sum_{k}{x_{k}G_{kj}}}}\right )} \]

where \(x_i\) are the mole fractions, \(\tau_{ij}\) are the interaction parameters, \(\alpha_{ij}\) are the non-randomness parameters, and \(G_{ij}=\exp(-\alpha_{ij} \tau_{ij})\).

References

  • Renon, H. and Prausnitz, J.M. (1968), Local compositions in thermodynamic excess functions for liquid mixtures. AIChE J., 14: 135-144.
PARAMETER DESCRIPTION
x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

tau

Interaction parameters, \(\tau_{ij}\). It is expected (but not checked) that \(\tau_{ii}=0\).

TYPE: FloatSquareMatrix(N, N)

alpha

Non-randomness parameters, \(\alpha_{ij}\). It is expected (but not checked) that \(\alpha_{ij}=\alpha_{ji}\).

TYPE: FloatSquareMatrix(N, N)

RETURNS DESCRIPTION
FloatVector(N)

Activity coefficients of all components.

See also
  • NRTL: related class.
Source code in src/polykin/thermo/acm/nrtl.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
def NRTL_gamma(x: FloatVector,
               tau: FloatSquareMatrix,
               alpha: FloatSquareMatrix
               ) -> FloatVector:
    r"""Calculate the activity coefficients of a multicomponent mixture
    according to the NRTL model.

    $$ \ln{\gamma_i} = \frac{\displaystyle\sum_{k}{x_{k}\tau_{ki}G_{ki}}}
    {\displaystyle\sum_{k}{x_{k}G_{ki}}}
    +\sum_{j}{\frac{x_{j}G_{ij}}{\displaystyle\sum_{k}{x_{k}G_{kj}}}}
    {\left ({\tau_{ij}-\frac{\displaystyle\sum_{k}{x_{k}\tau_{kj}G_{kj}}}
    {\displaystyle\sum_{k}{x_{k}G_{kj}}}}\right )} $$

    where $x_i$ are the mole fractions, $\tau_{ij}$ are the interaction
    parameters, $\alpha_{ij}$ are the non-randomness parameters, and 
    $G_{ij}=\exp(-\alpha_{ij} \tau_{ij})$.

    **References**

    *   Renon, H. and Prausnitz, J.M. (1968), Local compositions in
        thermodynamic excess functions for liquid mixtures. AIChE J.,
        14: 135-144.

    Parameters
    ----------
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.
    tau : FloatSquareMatrix (N,N)
        Interaction parameters, $\tau_{ij}$. It is expected (but not checked)
        that $\tau_{ii}=0$.
    alpha : FloatSquareMatrix (N,N)
        Non-randomness parameters, $\alpha_{ij}$. It is expected (but not
        checked) that $\alpha_{ij}=\alpha_{ji}$.

    Returns
    -------
    FloatVector (N)
        Activity coefficients of all components.

    See also
    --------
    * [`NRTL`](NRTL.md): related class.

    """

    G = exp(-alpha*tau)

    # N = x.size
    # A = np.empty(N)
    # B = np.empty(N)
    # for i in range(N):
    #     A[i] = np.sum(x*tau[:, i]*G[:, i])
    #     B[i] = np.sum(x*G[:, i])
    # C = np.zeros(N)
    # for j in range(N):
    #     C += x[j]*G[:, j]/B[j]*(tau[:, j] - A[j]/B[j])

    A = dot(x, tau*G)
    B = dot(x, G)
    C = dot(tau*G, x/B) - dot(G, x*A/B**2)

    return exp(A/B + C)

UNIQUAC ¤

UNIQUAC multicomponent activity coefficient model.

This model is based on the following molar excess Gibbs energy expression:

\[\begin{aligned} g^E &= g^R + g^C \\ \frac{g^R}{R T} &= -\sum_i q_i x_i \ln{\left ( \sum_j \theta_j \tau_{ji} \right )} \\ \frac{g^C}{R T} &= \sum_i x_i \ln{\frac{\Phi_i}{x_i}} + 5\sum_i q_ix_i \ln{\frac{\theta_i}{\Phi_i}} \end{aligned}\]

with:

\[\begin{aligned} \Phi_i =\frac{x_i r_i}{\sum_j x_j r_j} \\ \theta_i =\frac{x_i q_i}{\sum_j x_j q_j} \end{aligned}\]

where \(x_i\) are the mole fractions, \(q_i\) (a relative surface) and \(r_i\) (a relative volume) denote the pure-component parameters, and \(\tau_{ij}\) are the interaction parameters.

In this particular implementation, the interaction parameters are allowed to depend on temperature according to the following empirical relationship (as done in Aspen Plus):

\[ \tau_{ij} = \exp( a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T ) \]

Moreover, \(\tau_{ij} \neq \tau_{ji}\) and \(\tau_{ii}=1\).

References

  • Abrams, D.S. and Prausnitz, J.M. (1975), Statistical thermodynamics of liquid mixtures: A new expression for the excess Gibbs energy of partly or completely miscible systems. AIChE J., 21: 116-128.
PARAMETER DESCRIPTION
N

Number of components.

TYPE: int

q

Relative surface areas of all components.

TYPE: FloatVectorLike(N)

r

Relative volumes of all components.

TYPE: FloatVectorLike(N)

a

Matrix of interaction parameters, by default 0.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

b

Matrix of interaction parameters, by default 0. Unit = K.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

c

Matrix of interaction parameters, by default 0.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

d

Matrix of interaction parameters, by default 0.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

name

Name.

TYPE: str DEFAULT: ''

See also
Source code in src/polykin/thermo/acm/uniquac.py
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
class UNIQUAC(SmallSpeciesActivityModel):
    r"""[UNIQUAC](https://en.wikipedia.org/wiki/UNIQUAC) multicomponent
    activity coefficient model.

    This model is based on the following molar excess Gibbs energy
    expression:

    \begin{aligned}
    g^E &= g^R + g^C \\
    \frac{g^R}{R T} &= -\sum_i q_i x_i \ln{\left ( \sum_j \theta_j \tau_{ji} \right )} \\
    \frac{g^C}{R T} &= \sum_i x_i \ln{\frac{\Phi_i}{x_i}} + 5\sum_i q_ix_i \ln{\frac{\theta_i}{\Phi_i}}
    \end{aligned}

    with:

    \begin{aligned}
    \Phi_i =\frac{x_i r_i}{\sum_j x_j r_j} \\
    \theta_i =\frac{x_i q_i}{\sum_j x_j q_j}
    \end{aligned}

    where $x_i$ are the mole fractions, $q_i$ (a relative surface) and $r_i$
    (a relative volume) denote the pure-component parameters, and $\tau_{ij}$
    are the interaction parameters. 

    In this particular implementation, the interaction parameters are allowed
    to depend on temperature according to the following empirical relationship
    (as done in Aspen Plus):

    $$ \tau_{ij} = \exp( a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T ) $$

    Moreover, $\tau_{ij} \neq \tau_{ji}$ and $\tau_{ii}=1$.

    **References**

    *   Abrams, D.S. and Prausnitz, J.M. (1975), Statistical thermodynamics of
        liquid mixtures: A new expression for the excess Gibbs energy of partly
        or completely miscible systems. AIChE J., 21: 116-128.

    Parameters
    ----------
    N : int
        Number of components.
    q : FloatVectorLike (N)
        Relative surface areas of all components.
    r : FloatVectorLike (N)
        Relative volumes of all components.
    a : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.
    b : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0. Unit = K.
    c : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.
    d : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.
    name : str
        Name.

    See also
    --------
    * [`UNIQUAC_gamma`](UNIQUAC_gamma.md): related activity coefficient method.

    """

    _q: FloatVector
    _r: FloatVector
    _a: FloatSquareMatrix
    _b: FloatSquareMatrix
    _c: FloatSquareMatrix
    _d: FloatSquareMatrix

    def __init__(self,
                 N: int,
                 q: FloatVectorLike,
                 r: FloatVectorLike,
                 a: Optional[FloatSquareMatrix] = None,
                 b: Optional[FloatSquareMatrix] = None,
                 c: Optional[FloatSquareMatrix] = None,
                 d: Optional[FloatSquareMatrix] = None,
                 name: str = ''
                 ) -> None:

        # Set default values
        if a is None:
            a = np.zeros((N, N))
        if b is None:
            b = np.zeros((N, N))
        if c is None:
            c = np.zeros((N, N))
        if d is None:
            d = np.zeros((N, N))

        # Check shapes -> move to func
        q = np.asarray(q)
        r = np.asarray(r)
        for vector in [q, r]:
            if vector.shape != (N,):
                raise ShapeError(
                    f"The shape of vector {vector} is invalid: {vector.shape}.")
        for array in [a, b, c, d]:
            if array.shape != (N, N):
                raise ShapeError(
                    f"The shape of matrix {array} is invalid: {array.shape}.")

        # Check bounds (same as Aspen Plus)
        check_bounds(a, -50., 50., 'a')
        check_bounds(b, -1.5e4, 1.5e4, 'b')

        # Ensure tau_ii=1
        for array in [a, b, c, d]:
            np.fill_diagonal(array, 0.)

        super().__init__(N, name)
        self._q = q
        self._r = r
        self._a = a
        self._b = b
        self._c = c
        self._d = d

    @functools.cache
    def tau(self,
            T: float
            ) -> FloatSquareMatrix:
        r"""Compute the matrix of interaction parameters.

        $$ \tau_{ij} = \exp( a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T ) $$

        Parameters
        ----------
        T : float
            Temperature. Unit = K.

        Returns
        -------
        FloatSquareMatrix (N,N)
            Interaction parameters.
        """
        return exp(self._a + self._b/T + self._c*log(T) + self._d*T)

    def gE(self,
           T: float,
           x: FloatVector
           ) -> float:

        r = self._r
        q = self._q
        tau = self.tau(T)

        phi = x*r/dot(x, r)
        theta = x*q/dot(x, q)

        p = x > 0.
        gC = np.sum(x[p]*(log(phi[p]/x[p]) + 5*q[p]*log(theta[p]/phi[p])))
        gR = -np.sum(q[p]*x[p]*log(dot(theta, tau)[p]))

        return R*T*(gC + gR)

    def gamma(self,
              T: float,
              x: FloatVector
              ) -> FloatVector:
        return UNIQUAC_gamma(x, self._q, self._r, self.tau(T))

Dgmix ¤

Dgmix(T: float, x: FloatVector) -> float

Molar Gibbs energy of mixing, \(\Delta g_{mix}\).

\[ \Delta g_{mix} = \Delta h_{mix} -T \Delta s_{mix} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar Gibbs energy of mixing. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def Dgmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar Gibbs energy of mixing, $\Delta g_{mix}$.

    $$ \Delta g_{mix} = \Delta h_{mix} -T \Delta s_{mix} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar Gibbs energy of mixing. Unit = J/mol.
    """
    return self.gE(T, x) - T*self._Dsmix_ideal(T, x)

Dhmix ¤

Dhmix(T: float, x: FloatVector) -> float

Molar enthalpy of mixing, \(\Delta h_{mix}\).

\[ \Delta h_{mix} = h^{E} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar enthalpy of mixing. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
def Dhmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar enthalpy of mixing, $\Delta h_{mix}$.

    $$ \Delta h_{mix} = h^{E} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar enthalpy of mixing. Unit = J/mol.
    """
    return self.hE(T, x)

Dsmix ¤

Dsmix(T: float, x: FloatVector) -> float

Molar entropy of mixing, \(\Delta s_{mix}\).

\[ \Delta s_{mix} = s^{E} - R \sum_i {x_i \ln{x_i}} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar entropy of mixing. Unit = J/(mol·K).

Source code in src/polykin/thermo/acm/base.py
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def Dsmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar entropy of mixing, $\Delta s_{mix}$.

    $$ \Delta s_{mix} = s^{E} - R \sum_i {x_i \ln{x_i}} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar entropy of mixing. Unit = J/(mol·K).
    """
    return self.sE(T, x) + self._Dsmix_ideal(T, x)

N property ¤

N: int

Number of components.

activity ¤

activity(T: float, x: FloatVector) -> FloatVector

Activities, \(a_i\).

\[ a_i = x_i \gamma_i \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
FloatVector(N)

Activities of all components.

Source code in src/polykin/thermo/acm/base.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
def activity(self,
             T: float,
             x: FloatVector
             ) -> FloatVector:
    r"""Activities, $a_i$.

    $$ a_i = x_i \gamma_i $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    FloatVector (N)
        Activities of all components.
    """
    return x*self.gamma(T, x)

gE ¤

gE(T: float, x: FloatVector) -> float

Molar excess Gibbs energy, \(g^{E}\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess Gibbs energy. Unit = J/mol.

Source code in src/polykin/thermo/acm/uniquac.py
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
def gE(self,
       T: float,
       x: FloatVector
       ) -> float:

    r = self._r
    q = self._q
    tau = self.tau(T)

    phi = x*r/dot(x, r)
    theta = x*q/dot(x, q)

    p = x > 0.
    gC = np.sum(x[p]*(log(phi[p]/x[p]) + 5*q[p]*log(theta[p]/phi[p])))
    gR = -np.sum(q[p]*x[p]*log(dot(theta, tau)[p]))

    return R*T*(gC + gR)

gamma ¤

gamma(T: float, x: FloatVector) -> FloatVector

Activity coefficients based on mole fraction, \(\gamma_i\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
FloatVector(N)

Activity coefficients of all components.

Source code in src/polykin/thermo/acm/uniquac.py
178
179
180
181
182
def gamma(self,
          T: float,
          x: FloatVector
          ) -> FloatVector:
    return UNIQUAC_gamma(x, self._q, self._r, self.tau(T))

hE ¤

hE(T: float, x: FloatVector) -> float

Molar excess enthalpy, \(h^{E}\).

\[ h^{E} = g^{E} + T s^{E} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess enthalpy. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def hE(self,
       T: float,
       x: FloatVector
       ) -> float:
    r"""Molar excess enthalpy, $h^{E}$.

    $$ h^{E} = g^{E} + T s^{E} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar excess enthalpy. Unit = J/mol.
    """
    return self.gE(T, x) + T*self.sE(T, x)

sE ¤

sE(T: float, x: FloatVector) -> float

Molar excess entropy, \(s^{E}\).

\[ s^{E} = -\left(\frac{\partial g^{E}}{\partial T}\right)_{P,x_i} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess entropy. Unit = J/(mol·K).

Source code in src/polykin/thermo/acm/base.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def sE(self,
       T: float,
       x: FloatVector
       ) -> float:
    r"""Molar excess entropy, $s^{E}$.

    $$ s^{E} = -\left(\frac{\partial g^{E}}{\partial T}\right)_{P,x_i} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar excess entropy. Unit = J/(mol·K).
    """
    return -1*derivative_complex(lambda t: self.gE(t, x), T)[0]

tau cached ¤

tau(T: float) -> FloatSquareMatrix

Compute the matrix of interaction parameters.

\[ \tau_{ij} = \exp( a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T ) \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

RETURNS DESCRIPTION
FloatSquareMatrix(N, N)

Interaction parameters.

Source code in src/polykin/thermo/acm/uniquac.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
@functools.cache
def tau(self,
        T: float
        ) -> FloatSquareMatrix:
    r"""Compute the matrix of interaction parameters.

    $$ \tau_{ij} = \exp( a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T ) $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.

    Returns
    -------
    FloatSquareMatrix (N,N)
        Interaction parameters.
    """
    return exp(self._a + self._b/T + self._c*log(T) + self._d*T)

UNIQUAC_gamma ¤

UNIQUAC_gamma(
    x: FloatVector,
    q: FloatVector,
    r: FloatVector,
    tau: FloatSquareMatrix,
) -> FloatVector

Calculate the activity coefficients of a multicomponent mixture according to the UNIQUAC model.

\[\begin{aligned} \ln{\gamma_i} &= \ln{\gamma_i^R} + \ln{\gamma_i^C} \\ \ln{\gamma_i^R} &= q_i \left(1 - \ln{s_i} - \sum_j \theta_j\frac{\tau_{ij}}{s_j} \right) \\ \ln{\gamma_i^C} &= 1 - J_i + \ln{J_i} - 5 q_i \left(1 - \frac{J_i}{L_i} + \ln{\frac{J_i}{L_i}} \right) \end{aligned}\]

with:

\[\begin{aligned} J_i &=\frac{r_i}{\sum_j x_j r_j} \\ L_i &=\frac{q_i}{\sum_j x_j q_j} \\ \theta_i &= x_i L_i \\ s_i &= \sum_j \theta_j \tau_{ji} \end{aligned}\]

where \(x_i\) are the mole fractions, \(q_i\) and \(r_i\) denote the pure-component parameters, and \(\tau_{ij}\) are the interaction parameters.

References

  • Abrams, D.S. and Prausnitz, J.M. (1975), Statistical thermodynamics of liquid mixtures: A new expression for the excess Gibbs energy of partly or completely miscible systems. AIChE J., 21: 116-128.
  • JM Smith, HC Van Ness, MM Abbott. Introduction to chemical engineering thermodynamics, 5th edition, 1996, p. 740-741.
PARAMETER DESCRIPTION
x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

q

Relative surface areas of all components.

TYPE: FloatVector(N)

r

Relative volumes of all components.

TYPE: FloatVector(N)

tau

Interaction parameters, \(\tau_{ij}\). It is expected (but not checked) that \(\tau_{ii}=1\).

TYPE: FloatSquareMatrix(N, N)

RETURNS DESCRIPTION
FloatVector(N)

Activity coefficients of all components.

See also
Source code in src/polykin/thermo/acm/uniquac.py
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
def UNIQUAC_gamma(x: FloatVector,
                  q: FloatVector,
                  r: FloatVector,
                  tau: FloatSquareMatrix
                  ) -> FloatVector:
    r"""Calculate the activity coefficients of a multicomponent mixture
    according to the UNIQUAC model.

    \begin{aligned}
    \ln{\gamma_i} &= \ln{\gamma_i^R} + \ln{\gamma_i^C} \\
    \ln{\gamma_i^R} &= q_i \left(1 - \ln{s_i} - 
                       \sum_j \theta_j\frac{\tau_{ij}}{s_j} \right) \\
    \ln{\gamma_i^C} &= 1 - J_i + \ln{J_i} - 5 q_i \left(1 - \frac{J_i}{L_i} +
                      \ln{\frac{J_i}{L_i}} \right)
    \end{aligned}

    with:

    \begin{aligned}
    J_i &=\frac{r_i}{\sum_j x_j r_j} \\
    L_i &=\frac{q_i}{\sum_j x_j q_j} \\
    \theta_i &= x_i L_i \\
    s_i &= \sum_j \theta_j \tau_{ji}
    \end{aligned}

    where $x_i$ are the mole fractions, $q_i$ and $r_i$ denote the
    pure-component parameters, and $\tau_{ij}$ are the interaction parameters.

    **References**

    *   Abrams, D.S. and Prausnitz, J.M. (1975), Statistical thermodynamics of
        liquid mixtures: A new expression for the excess Gibbs energy of partly
        or completely miscible systems. AIChE J., 21: 116-128.
    *   JM Smith, HC Van Ness, MM Abbott. Introduction to chemical engineering
        thermodynamics, 5th edition, 1996, p. 740-741.

    Parameters
    ----------
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.
    q : FloatVector (N)
        Relative surface areas of all components.
    r : FloatVector (N)
        Relative volumes of all components. 
    tau : FloatSquareMatrix (N,N)
        Interaction parameters, $\tau_{ij}$. It is expected (but not checked)
        that $\tau_{ii}=1$.

    Returns
    -------
    FloatVector (N)
        Activity coefficients of all components.

    See also
    --------
    * [`UNIQUAC`](UNIQUAC.md): related class.

    """

    J = r/dot(x, r)
    L = q/dot(x, q)
    theta = x*L
    s = dot(theta, tau)

    return J*exp(1 - J + q*(1 - log(s) - dot(tau, theta/s)
                            - 5*(1 - J/L + log(J/L))))

Wilson ¤

Wilson multicomponent activity coefficient model.

This model is based on the following molar excess Gibbs energy expression:

\[ \frac{g^{E}}{RT} = -\sum_{i} x_i\ln{\left(\sum_{j}{x_{j}\Lambda_{ij}}\right)} \]

where \(x_i\) are the mole fractions and \(\Lambda_{ij}\) are the interaction parameters.

In this particular implementation, the interaction parameters are allowed to depend on temperature according to the following empirical relationship (as done in Aspen Plus):

\[ \Lambda_{ij} = \exp( a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T ) \]

Moreover, \(\Lambda_{ij} \neq \Lambda_{ji}\) and \(\Lambda_{ii}=1\).

References

  • G.M. Wilson, J. Am. Chem. Soc., 1964, 86, 127.
PARAMETER DESCRIPTION
N

Number of components.

TYPE: int

a

Matrix of interaction parameters, by default 0.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

b

Matrix of interaction parameters, by default 0. Unit = K.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

c

Matrix of interaction parameters, by default 0.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

d

Matrix of interaction parameters, by default 0.

TYPE: FloatSquareMatrix(N, N) | None DEFAULT: None

name

Name.

TYPE: str DEFAULT: ''

See also
Source code in src/polykin/thermo/acm/wilson.py
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
class Wilson(SmallSpeciesActivityModel):
    r"""Wilson multicomponent activity coefficient model.

    This model is based on the following molar excess Gibbs energy
    expression:

    $$ \frac{g^{E}}{RT} =
        -\sum_{i} x_i\ln{\left(\sum_{j}{x_{j}\Lambda_{ij}}\right)} $$

    where $x_i$ are the mole fractions and $\Lambda_{ij}$ are the interaction
    parameters.

    In this particular implementation, the interaction parameters are allowed
    to depend on temperature according to the following empirical relationship
    (as done in Aspen Plus):

    $$ \Lambda_{ij} = \exp( a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T ) $$

    Moreover, $\Lambda_{ij} \neq \Lambda_{ji}$ and $\Lambda_{ii}=1$.

    **References**

    *   G.M. Wilson, J. Am. Chem. Soc., 1964, 86, 127.

    Parameters
    ----------
    N : int
        Number of components.
    a : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.
    b : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0. Unit = K.
    c : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.
    d : FloatSquareMatrix (N,N) | None
        Matrix of interaction parameters, by default 0.
    name: str
        Name.

    See also
    --------
    * [`Wilson_gamma`](Wilson_gamma.md): related activity coefficient
    method.

    """

    _a: FloatSquareMatrix
    _b: FloatSquareMatrix
    _c: FloatSquareMatrix
    _d: FloatSquareMatrix

    def __init__(self,
                 N: int,
                 a: Optional[FloatSquareMatrix] = None,
                 b: Optional[FloatSquareMatrix] = None,
                 c: Optional[FloatSquareMatrix] = None,
                 d: Optional[FloatSquareMatrix] = None,
                 name: str = ''
                 ) -> None:

        # Set default values
        if a is None:
            a = np.zeros((N, N))
        if b is None:
            b = np.zeros((N, N))
        if c is None:
            c = np.zeros((N, N))
        if d is None:
            d = np.zeros((N, N))

        # Check shapes
        for array in [a, b, c, d]:
            if array.shape != (N, N):
                raise ShapeError(
                    f"The shape of matrix {array} is invalid: {array.shape}.")

        # Check bounds (same as Aspen Plus)
        check_bounds(a, -50., 50., 'a')
        check_bounds(b, -1.5e4, 1.5e4, 'b')

        # Ensure Lambda_ii=1
        for array in [a, b, c, d]:
            np.fill_diagonal(array, 0.)

        super().__init__(N, name)
        self._a = a
        self._b = b
        self._c = c
        self._d = d

    @functools.cache
    def Lambda(self,
               T: float
               ) -> FloatSquareMatrix:
        r"""Compute the matrix of interaction parameters.

        $$ \Lambda_{ij}=\exp(a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T) $$

        Parameters
        ----------
        T : float
            Temperature. Unit = K.

        Returns
        -------
        FloatSquareMatrix (N,N)
            Interaction parameters.
        """
        return exp(self._a + self._b/T + self._c*log(T) + self._d*T)

    def gE(self, T: float, x: FloatVector) -> float:
        return -R*T*dot(x, log(dot(self.Lambda(T), x)))

    def gamma(self, T: float, x: FloatVector) -> FloatVector:
        return Wilson_gamma(x, self.Lambda(T))

Dgmix ¤

Dgmix(T: float, x: FloatVector) -> float

Molar Gibbs energy of mixing, \(\Delta g_{mix}\).

\[ \Delta g_{mix} = \Delta h_{mix} -T \Delta s_{mix} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar Gibbs energy of mixing. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def Dgmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar Gibbs energy of mixing, $\Delta g_{mix}$.

    $$ \Delta g_{mix} = \Delta h_{mix} -T \Delta s_{mix} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar Gibbs energy of mixing. Unit = J/mol.
    """
    return self.gE(T, x) - T*self._Dsmix_ideal(T, x)

Dhmix ¤

Dhmix(T: float, x: FloatVector) -> float

Molar enthalpy of mixing, \(\Delta h_{mix}\).

\[ \Delta h_{mix} = h^{E} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar enthalpy of mixing. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
def Dhmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar enthalpy of mixing, $\Delta h_{mix}$.

    $$ \Delta h_{mix} = h^{E} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar enthalpy of mixing. Unit = J/mol.
    """
    return self.hE(T, x)

Dsmix ¤

Dsmix(T: float, x: FloatVector) -> float

Molar entropy of mixing, \(\Delta s_{mix}\).

\[ \Delta s_{mix} = s^{E} - R \sum_i {x_i \ln{x_i}} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar entropy of mixing. Unit = J/(mol·K).

Source code in src/polykin/thermo/acm/base.py
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def Dsmix(self,
          T: float,
          x: FloatVector
          ) -> float:
    r"""Molar entropy of mixing, $\Delta s_{mix}$.

    $$ \Delta s_{mix} = s^{E} - R \sum_i {x_i \ln{x_i}} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar entropy of mixing. Unit = J/(mol·K).
    """
    return self.sE(T, x) + self._Dsmix_ideal(T, x)

Lambda cached ¤

Lambda(T: float) -> FloatSquareMatrix

Compute the matrix of interaction parameters.

\[ \Lambda_{ij}=\exp(a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T) \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

RETURNS DESCRIPTION
FloatSquareMatrix(N, N)

Interaction parameters.

Source code in src/polykin/thermo/acm/wilson.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
@functools.cache
def Lambda(self,
           T: float
           ) -> FloatSquareMatrix:
    r"""Compute the matrix of interaction parameters.

    $$ \Lambda_{ij}=\exp(a_{ij} + b_{ij}/T + c_{ij} \ln{T} + d_{ij} T) $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.

    Returns
    -------
    FloatSquareMatrix (N,N)
        Interaction parameters.
    """
    return exp(self._a + self._b/T + self._c*log(T) + self._d*T)

N property ¤

N: int

Number of components.

activity ¤

activity(T: float, x: FloatVector) -> FloatVector

Activities, \(a_i\).

\[ a_i = x_i \gamma_i \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
FloatVector(N)

Activities of all components.

Source code in src/polykin/thermo/acm/base.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
def activity(self,
             T: float,
             x: FloatVector
             ) -> FloatVector:
    r"""Activities, $a_i$.

    $$ a_i = x_i \gamma_i $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    FloatVector (N)
        Activities of all components.
    """
    return x*self.gamma(T, x)

gE ¤

gE(T: float, x: FloatVector) -> float

Molar excess Gibbs energy, \(g^{E}\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess Gibbs energy. Unit = J/mol.

Source code in src/polykin/thermo/acm/wilson.py
131
132
def gE(self, T: float, x: FloatVector) -> float:
    return -R*T*dot(x, log(dot(self.Lambda(T), x)))

gamma ¤

gamma(T: float, x: FloatVector) -> FloatVector

Activity coefficients based on mole fraction, \(\gamma_i\).

PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
FloatVector(N)

Activity coefficients of all components.

Source code in src/polykin/thermo/acm/wilson.py
134
135
def gamma(self, T: float, x: FloatVector) -> FloatVector:
    return Wilson_gamma(x, self.Lambda(T))

hE ¤

hE(T: float, x: FloatVector) -> float

Molar excess enthalpy, \(h^{E}\).

\[ h^{E} = g^{E} + T s^{E} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess enthalpy. Unit = J/mol.

Source code in src/polykin/thermo/acm/base.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def hE(self,
       T: float,
       x: FloatVector
       ) -> float:
    r"""Molar excess enthalpy, $h^{E}$.

    $$ h^{E} = g^{E} + T s^{E} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar excess enthalpy. Unit = J/mol.
    """
    return self.gE(T, x) + T*self.sE(T, x)

sE ¤

sE(T: float, x: FloatVector) -> float

Molar excess entropy, \(s^{E}\).

\[ s^{E} = -\left(\frac{\partial g^{E}}{\partial T}\right)_{P,x_i} \]
PARAMETER DESCRIPTION
T

Temperature. Unit = K.

TYPE: float

x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

RETURNS DESCRIPTION
float

Molar excess entropy. Unit = J/(mol·K).

Source code in src/polykin/thermo/acm/base.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def sE(self,
       T: float,
       x: FloatVector
       ) -> float:
    r"""Molar excess entropy, $s^{E}$.

    $$ s^{E} = -\left(\frac{\partial g^{E}}{\partial T}\right)_{P,x_i} $$

    Parameters
    ----------
    T : float
        Temperature. Unit = K.
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.

    Returns
    -------
    float
        Molar excess entropy. Unit = J/(mol·K).
    """
    return -1*derivative_complex(lambda t: self.gE(t, x), T)[0]

Wilson_gamma ¤

Wilson_gamma(
    x: FloatVector, Lambda: FloatSquareMatrix
) -> FloatVector

Calculate the activity coefficients of a multicomponent mixture according to the Wilson model.

\[ \ln{\gamma_i} = -\ln{\left(\displaystyle\sum_{j}{x_{j}\Lambda_{ij}}\right)} + 1 - \sum_{k}{\frac{x_{k}\Lambda_{ki}} {\displaystyle\sum_{j}{x_{j}\Lambda_{kj}}}} \]

where \(x_i\) are the mole fractions and \(\Lambda_{ij}\) are the interaction parameters.

References

  • G.M. Wilson, J. Am. Chem. Soc., 1964, 86, 127.
PARAMETER DESCRIPTION
x

Mole fractions of all components. Unit = mol/mol.

TYPE: FloatVector(N)

Lambda

Interaction parameters, \(\Lambda_{ij}\). It is expected (but not checked) that \(\Lambda_{ii}=1\).

TYPE: FloatSquareMatrix(N, N)

RETURNS DESCRIPTION
FloatVector(N)

Activity coefficients of all components.

See also
Source code in src/polykin/thermo/acm/wilson.py
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
def Wilson_gamma(x: FloatVector,
                 Lambda: FloatSquareMatrix
                 ) -> FloatVector:
    r"""Calculate the activity coefficients of a multicomponent mixture
    according to the Wilson model.

    $$ \ln{\gamma_i} = 
    -\ln{\left(\displaystyle\sum_{j}{x_{j}\Lambda_{ij}}\right)} + 1 -
    \sum_{k}{\frac{x_{k}\Lambda_{ki}}
    {\displaystyle\sum_{j}{x_{j}\Lambda_{kj}}}} $$

    where $x_i$ are the mole fractions and $\Lambda_{ij}$ are the interaction
    parameters.

    **References**

    *   G.M. Wilson, J. Am. Chem. Soc., 1964, 86, 127.

    Parameters
    ----------
    x : FloatVector (N)
        Mole fractions of all components. Unit = mol/mol.
    Lambda : FloatSquareMatrix (N,N)
        Interaction parameters, $\Lambda_{ij}$. It is expected (but not
        checked) that $\Lambda_{ii}=1$.

    Returns
    -------
    FloatVector (N)
        Activity coefficients of all components.

    See also
    --------
    * [`Wilson`](Wilson.md): related class.

    """
    A = dot(Lambda, x)
    return exp(1. - dot(x/A, Lambda))/A

Tutorial