Mesoporous pore size distribution#

Module doc#

Methods of calculating a pore size distribution for pores in the mesopore range (2-100 nm), based on the Kelvin equation and pore condensation/evaporation.

pygaps.characterisation.psd_meso.psd_mesoporous(isotherm: PointIsotherm | ModelIsotherm, psd_model: str = 'pygaps-DH', pore_geometry: str = 'cylinder', meniscus_geometry: str = None, branch: str = 'des', thickness_model: str | PointIsotherm | ModelIsotherm | t.Callable[[float], float] = 'Harkins/Jura', kelvin_model: str | t.Callable[[float], float] = 'Kelvin', p_limits: tuple[float, float] = None, verbose: bool = False)[source]#

Calculate the mesopore size distribution using a Kelvin-type model.

Expected pore geometry must be specified as pore_geometry. If the meniscus (adsorbed/gas interface) geometry is known, it can be equally specified, otherwise it will be inferred from the pore geometry.

The thickness_model parameter is a string which names the thickness equation which should be used. Alternatively, a user can implement their own thickness model, either as an Isotherm or a function which describes the adsorbed layer. In that case, instead of a string, pass the Isotherm object or the callable function as the thickness_model parameter.

Parameters:
  • isotherm (PointIsotherm, ModelIsotherm) -- Isotherm for which the pore size distribution will be calculated.

  • psd_model (str) -- The pore size distribution model to use.

  • pore_geometry (str) -- The geometry of the meniscus (adsorbed/gas interface) in the pores.

  • meniscus_geometry (str, optional) -- The geometry of the adsorbent pores.

  • branch ({'ads', 'des'}, optional) -- Branch of the isotherm to use. It defaults to desorption.

  • thickness_model (str, callable, optional) -- The thickness model to use for PSD, It defaults to Harkins/Jura.

  • kelvin_model (str, callable, optional) -- A custom user kelvin model. It should be a callable that only takes relative pressure as an argument.

  • p_limits (tuple[float, float]) -- Pressure range in which to calculate PSD, defaults to (0.1, 0.99).

  • verbose (bool) -- Prints out extra information on the calculation and graphs the results.

Returns:

dict -- A dictionary of results of the form:

  • pore_widths (ndarray) : the widths (or diameter) of the pores, nm

  • pore_volumes (ndarray) : pore volume for each pore width, cm3/material

  • pore_volume_cumulative (ndarray) : cumulative sum of pore volumes, in cm3/material

  • pore_distribution (ndarray) : contribution of each pore width to the overall pore distribution, cm3/material/nm

  • pore_areas (ndarray) : specific area for each pore width, m2/material

  • pore_area_total (float) : total specific area, m2/material

  • limits (tuple[int, int]) : indices of selection limits

Raises:

Notes

Calculates the pore size distribution using a 'classical' model which attempts to describe the adsorption in a pore as a combination of a statistical thickness and a condensation/evaporation behaviour related to adsorbate surface tension. It is based on solving the following equation:

\[\Delta V_n = V_{k,n} + V_{t,n}\]

Which states that the volume adsorbed or desorbed during a pressure step, \(\Delta V_n\), can be described as a sum of the volume involved in capillary condensation / evaporation (\(\Delta V_{k,n}\)), and the volume corresponding to the increase / decrease of the adsorbed layer thickness in the surface of all non-filled pores (\(\Delta V_{t,n}\)).

Expressions are derived for the pore volume as a function of pore geometry, the shape of the liquid-gas interface (meniscus), relationship between pore width and critical condensation width (\(R_{p}\)), rearranging the equation to:

\[V_{p,n} = (\Delta V_n - V_{t,n}) R_p\]

Currently, the methods provided are:

  • the pygaps-DH model, a custom expanded DH model for multiple pore geometries

  • the original BJH or Barrett, Joyner and Halenda method

  • the original DH or Dollimore-Heal method

According to Rouquerol [1], in adopting this approach, it is assumed that:

  • The Kelvin equation is applicable over the pore range (mesopores). In pores which are below a certain size (around 2.5 nm), the granularity of the liquid-vapour interface becomes too large the method to hold.

  • The meniscus curvature is controlled be the pore size and shape. Ideal shapes for the curvature are assumed.

  • The pores are rigid and of well defined shape. They are considered open-ended and non-intersecting.

  • The filling/emptying of each pore does not depend on its location, i.e. no diffusion or blocking effects.

  • Adsorption on the pore walls is not different from surface adsorption.

Caution

A common mantra of data processing is: garbage in = garbage out. Only use methods when you are aware of their limitations and shortcomings.

References

See also

pygaps.characterisation.psd_meso.psd_pygapsdh

low-level pygaps-DH method

pygaps.characterisation.psd_meso.psd_bjh

low-level BJH or Barrett, Joyner and Halenda method

pygaps.characterisation.psd_meso.psd_dollimore_heal

low-level DH or Dollimore-Heal method

pygaps.characterisation.psd_meso.psd_pygapsdh(volume_adsorbed: list[float], relative_pressure: list[float], pore_geometry: str, thickness_model: Callable, condensation_model: Callable)[source]#

Calculate a pore size distribution using an expanded Dollimore-Heal method. This function should not be used with isotherms (use instead pygaps.characterisation.psd_meso.psd_mesoporous()).

Parameters:
  • volume_adsorbed (array) -- Volume adsorbed of "liquid" phase in cm3/material.

  • relative_pressure (array) -- Relative pressure.

  • pore_geometry (str) -- The geometry of the pore, eg. 'sphere', 'cylinder' or 'slit'.

  • thickness_model (callable) -- Function which returns the thickness of the adsorbed layer at a pressure p, in nm.

  • condensation_model (callable) -- Function which returns the critical kelvin radius at a pressure p, in nm.

Returns:

dict -- A dictionary of results of the form:

  • pore_widths (ndarray) : the widths (or diameter) of the pores, nm

  • pore_volumes (ndarray) : pore volume for each pore width, cm3/material

  • pore_areas (ndarray) : specific area for each pore width, m2/material

  • pore_distribution (ndarray) : volumetric pore distribution, cm3/material/nm

Notes

This method is an extended DH method which is applicable to multiple pore geometries (slit, cylinder, spherical).

The calculation is performed in terms of the characteristic dimension of the pore geometry: width for slits, diameter for cylinders and spheres. The characteristic dimension is calculated in terms of the Kelvin radius and adsorbed layer thickness:

\[w_p = 2 * r_p = (r_k + t)\]

The Kelvin radius and layer thickness are calculated based on the functions provided, no assessment of the meniscus shape or thickness is performed here.

The basic equation for all geometries is as follows:

\[V_p = \Big[\Delta V_n - \Delta t_n \sum_{i=1}^{n-1} \Big(\frac{\bar{w}_{p,i} - 2 t_{n}}{\bar{w}_{p,i}}\Big)^{l-1} \frac{2 l V_{p,i}}{w_{p,i}}\Big] \Big(\frac{\bar{w}_p}{\bar{w}_p - 2 t_n}\Big)^l\]
Where :
  • \(V_p\) is the volume of pores of size \(\bar{r}_p\)

  • \(\Delta V_n\) is the adsorbed volume change between two points

  • \(\bar{r}_p\) is the average pore radius calculated as a sum of the kelvin radius and layer thickness of the pores at pressure p between two measurement points

  • \(\bar{r}_k\) is the average kelvin radius between two pressure points

  • \(t_n\) is the layer thickness at point n

  • \(\bar{t}_n\) is the average layer thickness between two pressure points

  • \(\Delta t_n\) is the change in layer thickness between two pressure points

  • \(l\) is the characteristic dimension of the system

In order to account for different geometries, factors are calculated in terms of a characteristic number of the system:

  • In a slit pore, the relationship between pore volume and pore surface is \(A_p = 2 V_p / w_p\). The pore area stays the same throughout any changes in layer thickness, therefore no correction factor is applied. Finally, the relationship between the volume of the kelvin capillary and the total pore width is \(\frac{\bar{w}_{p,i}}{\bar{w}_{p,i} - 2 t_{n,i}}\).

  • In a cylindrical pore, the relationship between pore volume and pore surface is \(A_p = 4 V_p / w_p\). The ratio between average pore area at a point and total pore area can be expressed by using \(\frac{\bar{w}_{p,i} - 2 t_{n,i}}{\bar{w}_{p,i}}\). Finally, the relationship between the inner Kelvin capillary and the total pore diameter is \(\frac{\bar{w}_{p,i}}{\bar{w}_{p,i} - 2 t_{n,i}}^2\).

  • In a spherical pore, the relationship between pore volume and pore surface is \(A_p = 6 V_p / w_p\). The ratio between average pore area at a point and total pore area can be expressed by using \(\frac{\bar{w}_{p,i} - 2 t_{n,i}}{\bar{w}_{p,i}}^2\). Finally, the relationship between the inner Kelvin sphere and the total pore diameter is \(\frac{\bar{w}_{p,i}}{\bar{w}_{p,i} - 2 t_{n,i}}^3\).

References

pygaps.characterisation.psd_meso.psd_bjh(volume_adsorbed: list[float], relative_pressure: list[float], pore_geometry: str, thickness_model: Callable, condensation_model: Callable)[source]#

Calculate a pore size distribution using the original BJH method. This function should not be used with isotherms (use instead pygaps.characterisation.psd_meso.psd_mesoporous()).

Parameters:
  • volume_adsorbed (array) -- Volume adsorbed of "liquid" phase in cm3/material.

  • relative_pressure (array) -- Relative pressure.

  • pore_geometry (str) -- The geometry of the pore, eg. 'sphere', 'cylinder' or 'slit'.

  • thickness_model (callable) -- Function which returns the thickness of the adsorbed layer at a pressure p, in nm.

  • condensation_model (callable) -- Function which returns the critical kelvin radius at a pressure p, in nm.

Returns:

dict -- A dictionary of results of the form:

  • pore_widths (ndarray) : the widths (or diameter) of the pores, nm

  • pore_volumes (ndarray) : pore volume for each pore width, cm3/material

  • pore_areas (ndarray) : specific area for each pore width, m2/material

  • pore_distribution (ndarray) : volumetric pore distribution, cm3/material/nm

Notes

The BJH or Barrett, Joyner and Halenda [2] method for calculation of pore size distribution is based on a classical description of the adsorbate behaviour in the adsorbent pores. Under this method, the adsorbate is adsorbing on the pore walls forming a layer of known thickness, therefore decreasing the apparent pore volume until condensation takes place, filling the entire pore. The two variables, layer thickness and critical pore width where condensation takes place can be respectively modelled by a thickness model (such as Halsey, Harkins & Jura, etc.) and a model for condensation/evaporation based on a form of the Kelvin equation.

\[1/2 w_p = r_p = r_k + t\]

The original model used the desorption curve as a basis for calculating pore size distribution. Between two points of the curve, the volume desorbed can be described as the volume contribution from pore evaporation and the volume from layer thickness decrease as per the equation above. The computation is done cumulatively, starting from the filled pores and calculating for each point the volume adsorbed in a pore from the following equation:

\[V_p = \Big[\Delta V_n - \Delta t_n \sum_{i=1}^{n-1} \Big(\frac{\bar{r}_{p,i} - t_{n}}{\bar{r}_{p,i}}\Big) A_{p,i}\Big] \Big(\frac{\bar{r}_p}{\bar{r}_k + \Delta t_n}\Big)^2\]
Where :
  • \(V_p\) is the volume of pores of size \(\bar{r}_p\)

  • \(\Delta V_n\) is the adsorbed volume change between two points

  • \(\bar{r}_p\) is the average pore radius calculated as a sum of the kelvin radius and layer thickness of the pores at pressure p between two measurement points

  • \(\bar{r}_k\) is the average kelvin radius between two measurement points

  • \(t_n\) is the layer thickness at point n

  • \(\bar{t}_n\) is the average layer thickness between two measurement points

  • \(\Delta t_n\) is the change in layer thickness between two measurement points

Then, by plotting \(V_p / (2 \Delta r_p)\) versus the width of the pores calculated for each point, the pore size distribution can be obtained.

The code in this function is an accurate implementation of the original BJH method.

References

pygaps.characterisation.psd_meso.psd_dollimore_heal(volume_adsorbed: list[float], relative_pressure: list[float], pore_geometry: str, thickness_model: Callable, condensation_model: Callable)[source]#

Calculate a pore size distribution using the original Dollimore-Heal method. This function should not be used with isotherms (use instead pygaps.characterisation.psd_meso.psd_mesoporous()).

Parameters:
  • volume_adsorbed (array) -- Volume adsorbed of "liquid" phase in cm3/material.

  • relative_pressure (array) -- Relative pressure.

  • pore_geometry (str) -- The geometry of the pore, eg. 'sphere', 'cylinder' or 'slit'.

  • thickness_model (callable) -- Function which returns the thickness of the adsorbed layer at a pressure p, in nm.

  • condensation_model (callable) -- Function which returns the critical kelvin radius at a pressure p, in nm.

Returns:

dict -- A dictionary of results of the form:

  • pore_widths (ndarray) : the widths (or diameter) of the pores, nm

  • pore_volumes (ndarray) : pore volume for each pore width, cm3/material

  • pore_areas (ndarray) : specific area for each pore width, m2/material

  • pore_distribution (ndarray) : volumetric pore distribution, cm3/material/nm

Notes

The DH or Dollimore-Heal method [3] of calculation of pore size distribution is an extension of the BJH method.

Like the BJH method, it is based on a classical description of the adsorbate behaviour in the adsorbent pores. Under this method, the adsorbate is adsorbing on the pore walls in a predictable way, and decreasing the apparent pore radius until condensation takes place, filling the entire pore. The two components, layer thickness (t) and radius (r_k) where condensation takes place can be modelled by a thickness model (such as Halsey, Harkins & Jura, etc.) and a critical radius model for condensation/evaporation, based on a form of the Kelvin equation.

\[1/2 w_p = r_p = r_k + t\]

The original model used the desorption curve as a basis for calculating pore size distribution. Between two points of the curve, the volume desorbed can be described as the volume contribution from pore evaporation and the volume from layer thickness decrease as per the equation above. The computation is done cumulatively, starting from the filled pores and calculating for each point the volume adsorbed in a pore from the following equation:

\[ \begin{align}\begin{aligned}V_p = \Big(\Delta V_n - \Delta V_m\Big)\Big(\frac{\bar{r}_p}{\bar{r}_p - t_n}\Big)^2\\V_p = \Big[\Delta V_n - \Delta t_n \sum_{i=1}^{n-1} A_{p,i} + \Delta t_n \bar{t}_n \sum_{i=1}^{n-1} 2 \pi L_{p,i} \Big]\Big(\frac{\bar{r}_p}{\bar{r}_p - t_n}\Big)^2\end{aligned}\end{align} \]
Where :
  • \(\bar{r}_p\) is the average pore radius calculated as a sum of the kelvin radius and layer thickness of the pores at pressure p between two measurement points

  • \(V_p\) is the volume of pores of size \(\bar{r}_p\)

  • \(\Delta V_n\) is the adsorbed volume change between two points

  • \(\bar{t}_n\) is the average layer thickness between two measurement points

  • \(\Delta t_n\) is the change in layer thickness between two measurement points

Then, by plotting \(V_p/(2*\Delta r_p)\) versus the width of the pores calculated for each point, the pore size distribution can be obtained.

The code in this function is an accurate implementation of the original DH method.

References

Available Kelvin models#

Module contains functions to calculate the critical evaporation/condensation pore radius the mesopore range, as a function of pressure.

pygaps.characterisation.models_kelvin.get_meniscus_geometry(branch: str, pore_geometry: str)[source]#

Determine the meniscus geometry.

Parameters:
  • branch ({'ads', 'des'}) -- Branch of the isotherm used.

  • geometry ({'slit', 'cylinder', 'halfopen-cylinder', 'sphere'}) -- Geometry of the pore.

Returns:

str -- Geometry of the meniscus in the pore.

pygaps.characterisation.models_kelvin.kelvin_radius(pressure: list[float], meniscus_geometry: str, temperature: float, liquid_density: float, adsorbate_molar_mass: float, adsorbate_surface_tension: float)[source]#

Calculate the kelvin radius of the pore, using the standard form of the kelvin equation.

Parameters:
  • pressure -- Relative pressure (p/p0), unitless.

  • meniscus_geometry (str) -- Geometry of the interface of the vapour and liquid phase. WARNING: it is not the same as the pore geometry.

  • temperature (float) -- Temperature in kelvin.

  • liquid_density (float) -- Density of the adsorbed phase, assuming it can be approximated as a liquid g/cm3.

  • adsorbate_molar_mass (float) -- Molar area of the adsorbate, g/mol.

  • adsorbate_surface_tension (float) -- Surface tension of the adsorbate, in mN/m.

Returns:

float -- Kelvin radius(nm).

Notes

Description

The standard kelvin equation for determining critical pore radius for condensation or evaporation.

\[\ln\Big(\frac{p}{p_0}\Big) = -\frac{2 \cos\theta M_m \gamma}{r_K\rho_l RT}\]

Limitations

The Kelvin equation assumes that adsorption in a pore is not different than adsorption on a standard surface. Therefore, no interactions with the adsorbent is accounted for.

Furthermore, the geometry of the pore itself is considered to be invariant accross the entire adsorbate.

See also

pygaps.characterisation.models_kelvin.kelvin_radius_kjs

KJS corrected Kelvin function

pygaps.characterisation.models_kelvin.kelvin_radius_kjs(pressure: list[float], meniscus_geometry: str, temperature: float, liquid_density: float, adsorbate_molar_mass: float, adsorbate_surface_tension: float)[source]#

Calculate the kelvin radius of the pore, using the Kruck-Jaroniec-Sayari correction.

Parameters:
  • pressure -- Relative pressure (p/p0), unitless.

  • meniscus_geometry (str) -- Geometry of the interface of the vapour and liquid phase. WARNING: it is not the same as the pore geometry.

  • temperature (float) -- Temperature in kelvin.

  • liquid_density (float) -- Density of the adsorbed phase, assuming it can be approximated as a liquid g/cm3.

  • adsorbate_molar_mass (float) -- Molar area of the adsorbate, g/mol.

  • adsorbate_surface_tension (float) -- Surface tension of the adsorbate, in mN/m.

Returns:

float -- Kelvin radius(nm).

Notes

Description

The KJS correction to the kelvin equation equation is modified with a constant term of 0.3 nm. The authors arrived at this constant by using the adsorption branch of the isotherm on several MCM-41 materials calibrated with XRD data.

\[\ln\Big(\frac{p}{p_0}\Big) = -\frac{2 \cos\theta M_m \gamma}{r_K\rho_l RT} + 0.3\]

Limitations

Besides the standard limitations of the Kelvin equation, the KJS correction is empirical in nature.

References

See also

pygaps.characterisation.models_kelvin.kelvin_radius

standard Kelvin function

pygaps.characterisation.models_kelvin.get_kelvin_model(model: str | Callable, **model_args)[source]#

Return a function calculating an kelvin-based critical radius.

The model parameter is a string which names the Kelvin model to be used. Alternatively, a user can implement their own model, as a function which returns the critical radius the adsorbed layer. In that case, instead of a string, pass a callable function as the model parameter.

Parameters:
  • model (str or callable) -- Name of the kelvin model to use or function that returns a critical radius.

  • model_args (dict) -- any arguments needed for the model

Returns:

callable -- A callable that takes pressure in and returns a critical kelvin radius at that point.

Raises:

ParameterError -- When string is not in the dictionary of models.

Available thickness models#

See Available thickness models.