Activity Coefficients

class pyrast.activity_coefficients.ActivityCoefficient(*args, **kwargs)[source]
__init__(partial_fug: ndarray | list, loadings: ndarray | list, isotherms: list, model: str, *, total_loading: bool = False, verbose: bool = False, model_parameters: dict | None = None, c: float = 1, param_guess: dict | None = None, param_tol: float = 1e-06, param_bounds: dict | None = None, optimization_options: dict | None = None, root_bracketing_options: dict | None = None)[source]

Initializes an activity coefficient model.

Activity coefficient models are used in real adsorbed solution theory (RAST) to account for non-ideal interactions between adsorbed species. This base class provides the framework for fitting activity coefficient models from binary mixture data. There are two ways to fit the model parameters:

1) Component loadings: If the user provides component loadings for different partial fugacities, the model parameters will be fit by minimizing the residual between the predicted and observed activity coefficients for each component. At each iteration, a 1D solver is used to find the spreading pressure that gives the observed loading for each component. This approach is more reliable for fitting activity coefficient models. If only one data point is provided, the models can still be fit assuming a default value for the C parameter, which can be adjusted by passing the ‘c’ argument. With multiple data points, the C parameter will be used as an initial guess and fit along with the other model parameters.

2) Total loading: If the user provides total loadings for different partial fugacities, the model parameters will be fit by minimizing the residual between the predicted total loading from a RAST calculation and the provided total loading. This approach is more computationally expensive, but is useful for experimental data where component loadings are difficult to measure. The user must provide at least as many total loading data points as model parameters.

For a full discussion of the fitting procedure and the underlying equations, see the documentation or paper discussion. Fitting activity coefficient models can be challenging, and convergence depends on the quality of the data and the choice of fitting options. If you have trouble fitting a model, try adjusting the initial guess, tolerances, or optimization options.

Parameters:
  • partial_fug (array-like) – Partial fugacities of each component in the gas phase.

  • loadings (array-like) – Adsorbed phase loadings of each component (or total loading if total_loading=True).

  • isotherms (list) – List of pure component isotherm objects for each component.

  • model (str) – Name of the activity coefficient model to use. Must be one of the registered models in pyRAST.

  • total_loading (bool, optional) – If True, the input loadings are treated as total loadings and RAST calculations are used to fit the model parameters. Default is False.

  • verbose (bool, optional) – If True, prints convergence information during fitting. Default is False.

  • model_parameters (dict, optional) – If provided, these parameters will be used instead of fitting from data. Keys must match the parameter names for the specified model.

  • c (float, optional) – Sets the C parameter for fitting to single point data, or used as the initial guess for C when fitting to multiple data points. Default is 1.

  • param_guess (dict, optional) – Initial guess for model parameters when fitting from data. Keys must match the parameter names for the specified model. If not provided, the guess will be set to the parameter values that produce ideal behavior (gamma=1).

  • param_tol (float, optional) – Tolerance in parameter values for convergence when fitting to data. This can often be adjusted lower without significantly affecting the fit quality. This is passed as the ‘xtol’ parameter to scipy.optimize.least_squares. If specified again in optimization_options, it will override this value. Default is 1e-6.

  • param_bounds (dict, optional) – Bounds for model parameters when fitting from data. Keys must match the parameter names for the specified model. If not provided, the bounds will be set to the default specified in the model class.

  • optimization_options (dict, optional) – Options for the least-squares optimization when fitting to data. This is passed directly to scipy.optimize.least_squares, so you can specify any options available there. Default is None.

  • root_bracketing_options (dict, optional) – Options for the root bracketing when fitting from component loading data. This is passed as keyword arguments to the _bracket_phi function that is used to find the spreading pressure at each iteration. The default values for these parameters are: phi_low=1e-12, phi_high=1.0, max_expand=60, phi_cap=np.inf. Adjusting these parameters can help with finding a root for phi, although if root finding continuously fails it is likely that the model is not suitable for the system you are trying to fit.

Returns:

Model parameters are stored in self.model_parameters.

Return type:

None

Raises:

ValueError – If input arrays have inconsistent shapes or invalid values or if input dictionary keys do not match model parameter names.

_enforce_parameter_bounds(guess)[source]

Enforces parameter bounds on the initial guess.

Parameters:

guess (dict) – Initial guess for model parameters.

Returns:

Guess with parameters enforced within bounds.

Return type:

dict

_fit_component_loadings(verbose, optimization_options, root_bracketing_options)[source]

Fits model parameters to component loading data.

This method fits the model parameters to component loading data by minimizing the difference between the predicted and observed ln(activity coefficients). It uses a least-squares approach to find the optimal parameters. At each step, the model parameters are updated and used in a 1D root-finding calculation to find the spreading pressure that gives the observed total loading for each data point. All model parameters can be fit simultaneously using 2+ data points, or the C parameter can be fixed and the other parameters fit using a single data point.

Parameters:
  • verbose (bool) – If True, prints model parameters and residual information after fitting.

  • optimization_options (dict) – Options for the least-squares optimization when fitting model parameters. This is passed directly to scipy.optimize.least_squares, so you can specify any options available there.

  • root_bracketing_options (dict) – Options for the root bracketing when fitting from component loading data. This is passed as keyword arguments to the _bracket_phi function that is used to find the spreading pressure at each iteration.

Returns:

Model parameters are stored in self.model_parameters.

Return type:

None

Raises:
  • RuntimeError – If the fit to component loadings fails to converge or if a root cannot be found for the spreading pressure at any iteration.

  • ValueError – If residuals are not finite at the bracketing limits for root finding.

_fit_total_loading(verbose, optimization_options)[source]

Fits model parameters to total loading data.

This method fits the model parameters to the total loading data by minimizing the difference between the predicted and observed total loadings. It uses a least-squares approach to find the optimal parameters. At each step, the model parameters are updated and used in a RAST calculation to predict the total loading.

Note: Using total loading data can be less reliable for fitting activity coefficient models as multiple combinations of parameters can give similar total loading predictions. Only use this method if you do not have component loading data available.

Parameters:
  • verbose (bool) – If True, prints model parameters at each iteration and convergence information.

  • optimization_options (dict) – Options for the least-squares optimization when fitting from data. This is passed directly to scipy.optimize.least_squares, so you can specify any options available there.

Returns:

Model parameters are stored in self.model_parameters.

Return type:

None

Raises:

RuntimeError – If the fit to total loading fails to converge.

gamma(x, phi)[source]

Calculates activity coefficients (gamma) from ln_gamma.

Parameters:
  • x (array-like) – Mole fractions of components in the adsorbed phase.

  • phi (float) – Spreading pressure.

Returns:

Activity coefficients for each component.

Return type:

np.ndarray

inverse_excess_loading(x, phi)[source]

Calculates inverse excess loading.

This method is implemented in every subclass for the specific model.

ln_gamma(x, phi)[source]

Calculates natural log of activity coefficients.

This method is implemented in every subclass for the specific model.

class pyrast.activity_coefficients.SMargules(*args, **kwargs)[source]

The Symmetric Margules model (also the constant temperature variant of the Siperstein and Myers ABC model) is the simplest activity coefficient model for adsorbed solutions. It is best suited for: UPDATE

The excess Gibbs free energy in the Symmetric Margules model is given by:

\[\frac{g^E}{RT} = A x_1 x_2 (1 - e^{-C \phi})\]

Sources: Siperstein, F. R. & Myers, A. L. Mixed-gas adsorption. AIChE Journal 47, 1141-1159 (2001).

Luberti, M., Mennitto, R., Brandani, S., Santori, G. & Sarkisov, L. Activity coefficient models for accurate prediction of adsorption azeotropes. Adsorption 27, 1191-1206 (2021).

inverse_excess_loading(x, phi)[source]

Calculates the inverse of the excess loading given composition and phi.

The excess loading in the Symmetric Margules model is calculated as:

\[\left(\frac{1}{q}\right)^E = A C x_1 x_2 e^{-C \phi}\]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Inverse of the excess loading for the mixture.

Return type:

float

ln_gamma(x, phi)[source]

Calculates the natural log of the activity coefficients for each component.

In the Symmetric Margules model, the activity coefficients are calculated as:

\[\ln \gamma_i = A x_j^2 (1 - e^{-C \phi})\]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Natural log of the activity coefficients for each component.

Return type:

np.ndarray

class pyrast.activity_coefficients.AMargules(*args, **kwargs)[source]

The Asymmetric Margules model is an extension of the traditional Margules model that allows for asymmetry in the activity coefficients of the components in a binary mixture. It is best suited for mixtures where adsorbates differ slightly in size, shape, or polarity. It is more flexible than the symmetric Margules model, but is not great for highly non-ideal mixtures.

The excess Gibbs free energy in the Asymmetric Margules model is given by:

\[\frac{g^E}{RT} = x_1 x_2 (A_{12} x_2 + A_{21} x_1) (1 - e^{-C \phi})\]

Source: Krishna, R. & van Baten, J. M. How reliable is the Real Adsorbed Solution Theory (RAST) for estimating ternary mixture equilibrium in microporous host materials? Fluid Phase Equilibria 589, 114260 (2025).

inverse_excess_loading(x, phi)[source]

Calculates the inverse of the excess loading given composition and phi.

The excess loading in the Asymmetric Margules model is calculated as:

\[\left(\frac{1}{q}\right)^E = C x_1 x_2 (A_{12} x_2 + A_{21} x_1) e^{-C \phi}\]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Inverse of the excess loading for the mixture.

Return type:

float

ln_gamma(x, phi)[source]

Calculates the natural log of the activity coefficients for each component.

In the Asymmetric Margules model, the activity coefficients are calculated as:

\[ \begin{align}\begin{aligned}\ln \gamma_1 = x_2^2 (A_{12} + 2(A_{21} - A_{12}) x_1) (1 - e^{-C \phi})\\\ln \gamma_2 = x_1^2 (A_{21} + 2(A_{12} - A_{21}) x_2) (1 - e^{-C \phi})\end{aligned}\end{align} \]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Natural log of the activity coefficients for each component.

Return type:

np.ndarray

class pyrast.activity_coefficients.VanLaar(*args, **kwargs)[source]

The Van Laar model is analagous to the Van Laar model for vapor liquid equlibria. The Van Laar model is asymmetric and is best suited for: UPDATE

The excess Gibbs free energy in the Van Laar model is given by:

\[\frac{g^E}{RT} = \frac{A_{12} A_{21} x_1 x_2}{A_{12} x_1 + A_{21} x_2} (1 - e^{-C \phi})\]

Source: Luberti, M., Mennitto, R., Brandani, S., Santori, G. & Sarkisov, L. Activity coefficient models for accurate prediction of adsorption azeotropes. Adsorption 27, 1191-1206 (2021).

inverse_excess_loading(x, phi)[source]

Calculates the inverse of the excess loading given composition and phi.

The excess loading in the Van Laar model is calculated as:

\[\left(\frac{1}{q}\right)^E = \frac{A_{12} A_{21} x_1 x_2}{A_{12} x_1 + A_{21} x_2} C e^{-C \phi}\]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Inverse of the excess loading for the mixture.

Return type:

float

ln_gamma(x, phi)[source]

Calculates the natural log of the activity coefficients for each component.

In the Van Laar model, the activity coefficients are calculated as:

\[ \begin{align}\begin{aligned}\ln \gamma_1 = \frac{A_{12}}{(1 + \frac{A_{12} x_1}{A_{21} x_2})^2} (1 - e^{-C \phi})\\\ln \gamma_2 = \frac{A_{21}}{(1 + \frac{A_{21} x_2}{A_{12} x_1})^2} (1 - e^{-C \phi})\end{aligned}\end{align} \]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Natural log of the activity coefficients for each component.

Return type:

np.ndarray

class pyrast.activity_coefficients.Wilson(*args, **kwargs)[source]

The Wilson model is analagous to the Wilson model for vapor liquid equlibria. The Wilson model is asymmetric and is best suited for: UPDATE

The excess Gibbs free energy in the Wilson model is given by:

\[\frac{g^E}{RT} = [-x_1 \ln(x_1 + x_2 \Lambda_{12}) - x_2 \ln(x_2 + x_1 \Lambda_{21})] (1 - e^{-C \phi})\]

Source: Krishna, R. & van Baten, J. M. How reliable is the Real Adsorbed Solution Theory (RAST) for estimating ternary mixture equilibrium in microporous host materials? Fluid Phase Equilibria 589, 114260 (2025).

inverse_excess_loading(x, phi)[source]

Calculates the inverse of the excess loading given composition and phi.

The excess loading in the Wilson model is calculated as:

\[\left(\frac{1}{q}\right)^E = [-x_1 \ln(x_1 + x_2 \Lambda_{12}) - x_2 \ln(x_2 + x_1 \Lambda_{21})] C e^{-C \phi}\]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Inverse of the excess loading for the mixture.

Return type:

float

ln_gamma(x, phi)[source]

Calculates the natural log of the activity coefficients for each component.

In the Wilson model, the activity coefficients are calculated as:

\[ \begin{align}\begin{aligned}\ln \gamma_1 = \left(1 - \ln(x_1 + x_2 \Lambda_{12}) - \frac{x_1}{x_1 + x_2 \Lambda_{12}} - \frac{x_2 \Lambda_{21}}{x_2 + x_1 \Lambda_{21}}\right) (1 - e^{-C \phi})\\\ln \gamma_2 = \left(1 - \ln(x_2 + x_1 \Lambda_{21}) - \frac{x_2}{x_2 + x_1 \Lambda_{21}} - \frac{x_1 \Lambda_{12}}{x_1 + x_2 \Lambda_{12}}\right) (1 - e^{-C \phi})\end{aligned}\end{align} \]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Natural log of the activity coefficients for each component.

Return type:

np.ndarray

class pyrast.activity_coefficients.ANRTL(*args, **kwargs)[source]

The Asymmetric NRTL model is analagous to the Asymmetric NRTL model for vapor liquid equlibria. The Asymmetric NRTL model is best suited for: UPDATE

The excess Gibbs free energy in the Asymmetric NRTL model is given by:

\[ \begin{align}\begin{aligned}\frac{g^E}{RT} = \frac{x_1 x_2 \tau_{12} (G_{12} - 1)} {x_1 G_{12} + x_2} (1 - e^{-C \phi})\\G_{12} = \exp(-\alpha \tau_{12}), \ \tau_{12} = -\tau_{21}, \ \alpha = 0.3\end{aligned}\end{align} \]

Sources: Kaur, H., Tun, H., Sees, M. & Chen, C.-C. Local composition activity coefficient model for mixed-gas adsorption equilibria. Adsorption 25, 951-964 (2019).

Kopatsis, A., Salinger, A. & Myers, A. L. Thermodynamics of solutions with solvent and solute in different pure states. AIChE Journal 34, 1275-1286 (1988).

inverse_excess_loading(x, phi)[source]

Calculates the inverse of the excess loading given composition and phi.

The excess loading in the Asymmetric NRTL model is calculated as:

\[\left(\frac{1}{q}\right)^E = \frac{x_1 x_2 \tau_{12} (G_{12} - 1)} {x_1 G_{12} + x_2} C e^{-C \phi}\]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Inverse of the excess loading for the mixture.

Return type:

float

ln_gamma(x, phi)[source]

Calculates the natural log of the activity coefficients for each component.

In the Asymmetric NRTL model, the activity coefficients are calculated as:

\[ \begin{align}\begin{aligned}\ln \gamma_1 = \frac{x_2^2 \tau_{12} (G_{12} - 1)}{(x_1 G_{12} + x_2)^2} (1 - e^{-C \phi})\\\ln \gamma_2 = \frac{x_1^2 \tau_{21} (G_{21} - 1)}{(x_2 G_{21} + x_1)^2} (1 - e^{-C \phi})\end{aligned}\end{align} \]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Natural log of the activity coefficients for each component.

Return type:

np.ndarray

class pyrast.activity_coefficients.SNRTL(*args, **kwargs)[source]

The Symmetric NRTL model is analagous to the Symmetric NRTL model for vapor liquid equlibria. The Symmetric NRTL model is best suited for: UPDATE

The excess Gibbs free energy in the Symmetric NRTL model is given by:

\[ \begin{align}\begin{aligned}\frac{g^E}{RT} = \frac{x_1 x_2 \tau_{12} (G_{12} - 1)} {x_1 G_{12} + x_2} (1 - e^{-C \phi})\\G_{12} = \exp(-\alpha \tau_{12}), \ \tau_{12} = \tau_{21}, \ \alpha = 0.3\end{aligned}\end{align} \]

Sources: Kaur, H., Tun, H., Sees, M. & Chen, C.-C. Local composition activity coefficient model for mixed-gas adsorption equilibria. Adsorption 25, 951-964 (2019).

Kopatsis, A., Salinger, A. & Myers, A. L. Thermodynamics of solutions with solvent and solute in different pure states. AIChE Journal 34, 1275-1286 (1988).

inverse_excess_loading(x, phi)[source]

Calculates the inverse of the excess loading given composition and phi.

The excess loading in the Symmetric NRTL model is calculated as:

\[\left(\frac{1}{q}\right)^E = \frac{x_1 x_2 \tau_{12} (G_{12} - 1)} {x_1 G_{12} + x_2} C e^{-C \phi}\]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Inverse of the excess loading for the mixture.

Return type:

float

ln_gamma(x, phi)[source]

Calculates the natural log of the activity coefficients for each component.

In the Symmetric NRTL model, the activity coefficients are calculated as:

\[ \begin{align}\begin{aligned}\ln \gamma_1 = \frac{x_2^2 \tau_{12} (G_{12} - 1)}{(x_1 G_{12} + x_2)^2} (1 - e^{-C \phi})\\\ln \gamma_2 = \frac{x_1^2 \tau_{21} (G_{21} - 1)}{(x_2 G_{21} + x_1)^2} (1 - e^{-C \phi})\end{aligned}\end{align} \]
Parameters:
  • x (array-like) – Mole fractions of the components in the mixture.

  • phi (float) – Spreading pressure for the mixture.

Returns:

Natural log of the activity coefficients for each component.

Return type:

np.ndarray