Methods in the Functional class
SurfPack - Latest (beta)
The Functional
class, found in surfpack/Functional.py
, is the core of SurfPack Density Functional
Theory. This is the interface to almost all practical computations, such as computation of surface
tensions, adsorbtion, etc. and also contains the interfaces to methods used for computing density
profiles in systems with various boundary conditions. All DFT models in SurfPack inherit the Functional
class.
Table of contents
- Profile property interfaces
- $\rho - T$ property interfaces
- Density profile interfaces
- Bulk property interfaces
- Pure fluid properties
- Weight function interfaces
- Weighted density computations
- Utility methods
- Internal methods
- Deprecated methods
Profile property interfaces
Compute properties using a given density profile. Note that properties computed using these methods do not generally check whether the Profile is a valid equilibrium Profile. Properties are computed from the Profile as is. For methods to compute equilibrium density profiles, see the Density Profile section. For methods that implicitly compute the density profile for given boundary conditions before computing a property see rho-T properties.
Table of contents
N_adsorbed(self, rho, T=None, dividing_surface='e')
Compute the adsorbtion of each on the interface in a given density profile
Args:
rho (list[Profile]) :
The density profile for each component [1 / Å^3]
T (float) :
Temperature [K], only required if dividing_surface
is ‘t’ or ‘tension’
dividing_surface (str) :
The dividing surface to use:
‘e’ or ‘equimolar’ for equimolar surface
‘t’ or ‘tension’ for surface of tension
Returns:
1D array :
The adsobtion of each component [1 / Å^2]
adsorbtion(self, rho, T=None, dividing_surface='e')
Compute the adsorbtion of each on the interface in a given density profile.
Args:
rho (list[Profile]) :
The density profile for each component [1 / Å^3]
T (float) :
Temperature [K], only required if dividing_surface
is ‘t’ or ‘tension’
dividing_surface (str) :
The dividing surface to use:
‘e’ or ‘equimolar’ for equimolar surface
‘t’ or ‘tension’ for surface of tension
Returns:
1D array :
The adsobtion of each component [1 / Å^2]
correlation(self, rho, T)
Compute the one-body correlation function (sec. 4.2.3 in “introduction to DFT”)
Args:
rho (list[Profile]) :
Density profiles [particles / Å^3]
T (float) :
Temperature [K]
Returns:
list[Profile] :
One body correlation function of each species as a function of position,
indexed as c[
grand_potential(self, rho, T, Vext=None, bulk=False, property_flag='IR')
Compute the Grand Potential, as defined in sec. 2.7 of R. Roth - Introduction to Density Functional Theory of Classical Systems: Theory and Applications.
Args:
rho (list[Profile] or Iterable[float]) :
The density profile for each component,
or the bulk density of each component [particles / Å^3]
T (float) :
Temperature [K]
Vext (list[callable] or callable) :
External potential for each component, it is recomended to use the
callables inherriting ExtPotential in external_potential.py. Defaults to None.
bulk (bool) :
Is this a bulk computation? Defaults to False. Note: For bulk computations, the grand
potential density [J / Å^3] is returned.
property_flag (str) :
Return Residual (‘R’), Ideal (‘I’) or total (‘IR’) grand potential
Returns:
float :
The Grand Potential [J]. NOTE: For bulk computations, the grand potential
density (which is equal to the bulk pressure) [J / Å^3] is returned.
grand_potential_density(self, rho, T, Vext=None, property_flag='IR')
Compute the Grand Potential density.
Args:
rho (list[Profile] or Iterable[float]) :
The density profile for each component,
or the bulk density of each component [particles / Å^3]
T (float) :
Temperature [K]
Vext (list[callable] or callable) :
External potential for each component, it is recomended to use the
callables inherriting ExtPotential in external_potential.py. Defaults to None.
property_flag (str) :
Return Residual (‘R’), Ideal (‘I’) or total (‘IR’) grand potential density
Returns
Profile :
The Grand Potential density [J / Å^3].
reduced_helmholtz_energy_density(self, *args, **kwargs)
Returns the reduced, residual helmholtz energy density, $\phi$ (i.e. the integrand of eq. 3.4 in “introduction to DFT”)
\(\phi = \\frac{a^{res}}{k_B T}\)
where $a^{res}$ is the residual helmholtz energy density (per particle), in [J Å$^{-3}$]
residual_enthalpy_density(self, rho, T)
Compute the residual enthalpy density [J / Å^3]
Args:
rho (list[Profile]) :
The density profile for each component [particles / Å^3]
T (float) :
Temperature [K]
Returns:
Profile :
The residual enthalpy density [J / Å^3]
residual_entropy_density(self, rho, T)
Compute the residual entropy density [J / Å^3 K]
Args:
rho (list[Profile]) :
The density profile for each component [particles / Å^3]
T (float) :
Temperature [K]
Returns:
Profile :
The residual entropy density [J / Å^3 K]
residual_helmholtz_energy_density(self, rho, T, bulk=False)
Compute the residual Helmholtz energy density [J / Å^3]
Args:
rho (list[Profile] or 1d array [float]) :
The density profile or bulk density for each component [particles / Å^3]
T (float) :
Temperature [K]
bulk (bool) :
Whether to compute for bulk phase
Returns:
Profile or float:
The residual Helmholtz energy density [J / Å^3]
residual_internal_energy_density(self, rho, T)
Compute the residual internal energy density [J / Å^3]
Args:
rho (list[Profile]) :
The density profile for each component [particles / Å^3]
T (float) :
Temperature [K]
Returns:
Profile :
The residual internal energy density [J / Å^3]
surface_tension(self, rho, T, Vext=None, dividing_surface='equimolar')
Compute the surface tension for a given density profile Args: rho (list[Profile]) : Density profile for each component [particles / Å^3] T (float) : Temperature [K] Vext (list[callable], optional) : External potential dividing_surface (str, optional) : Which deviding surface to use ‘e’ or ‘equimolar’ for Equimolar surface ‘t’ or ‘tension’ for Surface of tension Returns: float : Surface tension [J / Å^2]
tolmann_length(self, rho, T)
Compute the Tolmann length, given a density profile.
Args:
rho (list[Profile]) :
The density profile of each species.
T (float) :
Temperature [K]
Returns:
float :
The Tolmann lenth
$\rho - T$ property interfaces
Compute properties at a given density and temperature, ususally by first computing a density profile for the given state.
Table of contents
adsorbtion_isotherm(self, T, n_points=30, dividing_surface='t', x_min=0.001, x_max=0.999, solver=None, rho0=None, calc_lve=False, verbose=False)
Compute the adsorbtion as a function of molar composition along an isotherm
Args:
T (float) :
Temperature [K]
n_points (int) :
Number of (evenly distriubted) points to compute. If an array is supplied, those points are used instead.
dividing_surface (str, optional) :
‘t’ or ‘tension’ for surface of tension, ‘e’ or ‘equimolar’ for equimolar surface
x_min (float, optional) :
Minimum liquid mole fraction of the first component.
x_max (float, optional) :
Maximum liquid mole fraction of the first component.
solver (SequentialSolver, optional) :
Custom solver object to use
rho0 (list[Profile], optional) :
Initial guess for denisty profile at x = [0, 1]
calc_lve (bool, optional) :
If true, return a tuple (x, y, p) with pressure (p), liquid (x) and vapour (y) composition. If false, return only liquid composition.
verbose (int, optional) :
Print progress information, higher number gives more output, default 0
Returns
tuple(gamma, x) or tuple(gamma, lve) :
Adsorbtion and composition (of first component)
radial_distribution_functions(self, rho_b, T, comp_idx=0, grid=None)
Compute the radial distribution functions $g_{i,j}$ for $i =$ comp_idx
using the “Percus trick”. To help convergence: First converge the profile for a planar geometry, exposed to an ExtendedSoft potential with a core radius $5R$, where $R$ is the maximum characteristic_length
of the mixture. Then, shift that profile to the left, and use it as an initial guess for the spherical case. If that doesn’t work, the profile can be shifted in several steps (by gradually reducing the core radius of the ExtendedSoft potential). The latter possibility is not implemented, but is just a matter of putting the “shift and recompute” part of this method in a for-loop, and adding some appropriate kwargs.
Args:
rho_b (list[float]) :
The bulk densities [particles / Å^3]
T (float) :
Temperature [K]
comp_idx (int) :
The first component in the pair, defaults to the first component
grid (Grid) :
The spatial discretisation (should have Spherical geometry for results to make sense)
Returns:
list[Profile] :
The radial distribution functions around a particle of type comp_idx
surface_tension_isotherm(self, T, n_points=30, dividing_surface='t', solver=None, rho0=None, calc_lve=False, verbose=False, cache_dir='')
Compute the surface tension as a function of molar composition along an isotherm
Args:
T (float) :
Temperature [K]
n_points (int) :
Number of (evenly distriubted) points to compute. If an array is supplied, those points are used instead.
dividing_surface (str, optional) :
‘t’ or ‘tension’ for surface of tension, ‘e’ or ‘equimolar’ for equimolar surface
solver (SequentialSolver, optional) :
Custom solver object to use
rho0 (list[Profile], optional) :
Initial guess for denisty profile at x = [0, 1]
calc_lve (bool, optional) :
If true, return a tuple (x, y, p) with pressure (p), liquid (x) and vapour (y) composition. If false, return only liquid composition.
verbose (int, optional) :
Print progress information, higher number gives more output, default 0
Returns
tuple(gamma, x) or tuple(gamma, lve) :
Surface tension and composition (of first component)
Density profile interfaces
Methods for converging a density profile given various boundary conditions.
Table of contents
density_profile_singlecomp(self, T, grid, rho_0=None, solver=None, verbose=False)
Compute the equilibrium density profile across a gas-liquid interface. For multicomponent systems, twophase_tpflash is used to compute the composition of the two phases. For single component systems, p is ignored, and pressure is computed from dew_pressure.
Args:
T (float) :
Temperature [K]
grid (Grid) :
Spatial discretisation
rho_0 (list[Profile], optional) :
Initial guess for density profile
solver (SequentialSolver or GridRefiner) :
Solver to use, uses a default SequentialSolver if none is supplied
verbose (bool, optional) :
Whether to print progress info
Returns:
list[Profile] :
The density profile for each component across the interface.
density_profile_tp(self, T, p, z, grid, rho_0=None, solver=None, verbose=False)
Compute the equilibrium density profile across a gas-liquid interface. For multicomponent systems, twophase_tpflash is used to compute the composition of the two phases. For single component systems, p is ignored, and pressure is computed from dew_pressure.
Args:
T (float) :
Temperature [K]
p (float) :
Pressure [Pa]
z (Iterable) :
Total Molar composition
grid (Grid) :
Spatial discretisation
rho_0 (list[Profile], optional) :
Initial guess for density profile
solver (SequentialSolver or GridRefiner) :
Solver to use, uses a default SequentialSolver if none is supplied
verbose (bool, optional) :
Whether to print progress info
Returns:
list[Profile] :
The density profile for each component across the interface.
density_profile_twophase(self, rho_g, rho_l, T, grid, beta_V=0.5, rho_0=None, solver=None, verbose=0)
Compute the density profile separating two phases with denisties rho_g and rho_l
Args:
rho_g (list[float]) :
Density of each component in phase 1 [particles / Å^3]
rho_l (list[float]) :
Density of each component in phase 2 [particles / Å^3]
beta_V (float) :
Liquid fraction
T (float) :
Temperature [K]
grid (Grid or GridSpec) :
The spacial discretisation. Using a GridSpec is preferred, as the method then generates a
grid that is likely to be a suitable width.
rho_0 (list[Profile], optional) :
Initial guess, optional
solver (SequentialSolver or GridRefiner) :
Solver to use, uses a default SequentialSolver if none is supplied
verbose (bool, options) :
Print progress info while running solver
Returns:
list[Profile] :
The density profile for of each component
density_profile_tz(self, T, z, grid, z_phase=1, rho_0=None, solver=None, verbose=0)
Compute the density profile separating two phases at temperature T, with liquid (or optionally vapour) composition x
Args:
T (float) :
Temperature [K]
z (ndarray[float]) :
Molar composition of liquid phase (unless x_phase=2)
grid (Grid or GridSpec) :
The spatial discretization
z_phase (int) :
ThermoPack Phase flag, indicating which phase has composition x
. x_phase=1
for liquid (default)
x_phase=2
for vapour.
rho_0 (list[Profile], optional) :
Initial guess
solver (SequentialSolver or GridRefiner, optional) :
Solver to use
verbose (int) :
Print debugging information (higher number gives more output), default 0
Returns:
list[Profile] :
The converged density profiles.
density_profile_wall(self, rho_b, T, grid, Vext=None, rho_0=None, verbose=False)
Calculate equilibrium density profile for a given external potential Note: Uses lazy evaluation for (rho_b, T, x, grid, Vext) to return a copy of previous result if the same calculation is done several times.
Args:
rho_b (list[float]) :
The bulk densities [particles / Å^3]
T (float) :
Temperature [K]
grid (Grid) :
Spatial discretization
Vext (ExtPotential, optional) :
External potential as a function of position (default : Vext(r) = 0)
Note:
Must be hashable, to use with lazy evaluation
Recomended:
Use the callable classes inherriting ExtPotential
rho_0 (list[Profile], optional) :
Initial guess for density profiles.
verbose (bool) :
Print progression information during run
Returns:
list[Profile] :
The equilibrium density profiles
density_profile_wall_tp(self, T, p, z, grid, Vext, rho0=None, verbose=0)
Calculate equilibrium density profile for a given external potential
Args:
T (float) :
Temperature [K]
p (float) :
Pressure [Pa]
z (list[float]) :
Bulk composition
grid (Grid) :
Spatial discretization
Vext (ExtPotential, optional) :
External potential as a function of position (default : Vext(r) = 0)
Note:
Must be hashable, to use with lazy evaluation
Recomended:
Use the callable classes inherriting ExtPotential
rho0 (list[Profile], optional) :
Initial guess for density profiles.
verbose (bool) :
Print progression information during run
Returns:
list[Profile] :
The equilibrium density profiles
drubble_profile_rT(self, rho_i, rho_o, T, r, grid, rho_0=None)
Compute the density profile across the interface of a droplet or bubble (drubble).
Args:
rho_i (list[float]) :
The particle densities inside the drubble.
rho_o (list[float]) :
The particle densities outside the drubble.
T (float) :
Temperature [K]
r (float) :
Drubble radius [Å]
grid (Grid) :
The grid to use (must have Geometry.SPHERICAL)
rho_0 (list[Profile], optional) :
Initial guess
Returns:
list[Profile] :
The density profiles across the interface.
Bulk property interfaces
Evaluating bulk properties.
Table of contents
chemical_potential(self, rho, T, bulk=True, property_flag='IR')
Compute the chemical potential [J]
Args:
rho (list[float]) :
Density [particles / Å^3]
T (float) :
Temperature [K]
bulk (bool) :
Only True is implemented
property_flag (str, optional) :
‘I’ for ideal, ‘R’ for residual, ‘IR’ for total.
Returns:
1d array (float) :
The chemical potentials [J / particle]
fugacity(self, rho, T, Vext=None)
Compute the fugacity at given density and temperature
Args:
rho (list[float]) :
Particle density of each species
T (flaot) :
Temperature [K]
Vext (ExternalPotential, optional) :
External potential for each particle
Returns:
1d array (flaot) :
The fugacity of each species.
residual_chemical_potential(self, rho, T, bulk=True)
Compute the residual chemical potential [J]
Args:
rho (list[float]) :
Density [particles / Å^3]
T (float) :
Temperature [K]
bulk (bool) :
Only True is implemented
Returns:
1d array (float) :
The chemical potentials [J / particle]
Pure fluid properties
Methods to efficiently and conveninetly compute properties for pure fluids. Contain some optimisations, tuning and convenience factors that are only possible for pure fluids.
Table of contents
surface_tension_singlecomp(self, n_points=30, t_min=0.5, t_max=0.99, grid=None, solver=None, rho0=None, verbose=0)
Compute the surface tension of a pure component for a series of temperatures.
Args:
n_points (int) :
Number of points to compute
t_min (float) :
Start temperature, if 0 < t_min < 1, start temperature will be t_min * Tc, where Tc is the critical temperature.
t_max (float) :
Stop temperature, if 0 < t_max < 1, stop temperature will be t_max * Tc, where Tc is the critical temperature.
grid (Grid) :
Grid to use for initial calculation.
solver (Solver) :
Solver to use for all calculations
rho0 (list[Profile]) :
Initial guess for first density profile.
verbose (int) :
Larger number gives more output during progress.
Returns:
tuple(gamma, T) :
Where gamma and T are matching 1d arrays of the surface tension and temperature.
Weight function interfaces
Get-methods for weight functions.
Table of contents
get_weights(self, T)
Returns the weights for weighted densities in a 2D array, ordered as weight[
Weighted density computations
Compute weighted densities
Table of contents
get_weighted_densities(self, *args, **kwargs)
Compute the weighted densities, and optionally differentials
Args:
rho (ndarray[Profile]) :
2D array of component densities indexed as rho[
bulk (bool) :
If True, use simplified expressions for bulk - not requiring FFT
dndrho (bool) :
Flag to activate calculation of differential
Returns:
ndarray :
array of weighted densities indexed as n[
ndarray :
array of differentials
Utility methods
Methods for setting … and getting …
Table of contents
clear_cache_dir(self, clear_dir)
Clear the directory clear_dir
, after prompting for confirmation.
Args:
clear_dir (str) :
The name of the directory.
Raises:
NotADirectoryError :
If clear_dir does not exist or is not a directory.
dividing_surface_position(self, rho, T=None, dividing_surface='e')
Compute the position of a dividing surface on a given density profile.
Args:
rho (list[Profile]) :
The density profile for each species
T (float) :
The temperature
dividing_surface (str, optional) :
Can be ‘(e)quimolar’ (default) or ‘(t)ension’.
Returns:
float :
Position of the dividing surface.
equimolar_surface_position(rho)
Calculate the position of the equimolar surface for a given density profile
Args:
rho (list[Profile]) :
The density profile for each component [1 / Å^3]
Returns:
float :
The position of the equimolar surface [Å]
get_caching_id(self)
Returns a unique ID for an initialized model. Should include information about the model type, components, parameters and mixing parameters (if applicable). Used for caching profiles.
Returns:
str :
A model identifier
get_characteristic_lengths(self)
Used to generate initial guesses for density profiles. Should return lengths that give an indication of molecular sizes. For example diameters of hard-spheres, or the Barker-Henderson diameter.
Returns:
ndarray(float) :
The characteristic length of the molecules.
get_load_dir(self)
Get the current directory used to search and load Profiles
Returns:
str :
Path to the current load directory
get_save_dir(self)
Get the current directory used to save Profiles
Returns:
str :
Path to the current save directory
reduce_temperature(self, T, c=0)
Reduce the temperature in some meaningful manner, using LJ units when possible, doing nothing for hard spheres.
Args:
T (float) :
The temperature
c (float, optional) :
???
Returns:
float :
The reduced temperature
set_cache_dir(self, cache_dir)
Forwards call to self.set_load_dir
and self.set_save_dir
.
Args:
cache_dir (str) :
Name of directory save and load files in.
Raises:
FileExistsError :
If cache_dir is the name of an existing file that is not a directory.
NotADirectoryError :
If cache_dir does not exist after successfull call to self.set_save_dir
set_load_dir(self, load_dir)
Sets this model to automatically search for computed profiles in load_dir
.
Args:
load_dir (str) :
Name of directory to load files from.
Raises:
NotADirectoryError :
If load_dir does not exist.
set_save_dir(self, save_dir)
Sets this model to automatically save computed density profiles in the directory ‘save_dir’.
Args:
save_dir (str) :
Name of directory to save to
Raises:
FileExistsError :
If save_dir is the name of an existing file that is not a directory.
surface_of_tension_position(self, rho, T)
Calculate the position of the surface of tension on a given density profile
Args:
rho (list[Profile]) :
The density profile for each component [1 / Å^3]
T (float) :
Temperature [K]
Returns:
float :
The position of the surface of tension [Å]
Internal methods
Methods for handling communication with the Fortran library.
Table of contents
__init__(self, ncomps)
Handles initialisation that is common for all functionals
Args:
ncomps (int) :
Number of components
__repr__(self)
All Functionals must implement a unique __repr__
, as these are used to generate the hashes that are used when saving profiles. The __repr__
should contain a human-readable text with (at least) the name of the model and all model parameters.
sanitize_Vext(self, Vext)
Ensure that Vext is a tuple with the proper ammount of elements.
split_component_weighted_densities(self, n)
Unsure if this is still in use, but I believe it takes in fmt-weighted densities as a 1d array and returns the same densities as a 2d array.
Args:
n (list[Profile]) :
FMT-weighted densities
Returns:
list[list[Profile]] :
FMT-weighted densities, indexed as n[
:
return:
validate_composition(self, z)
Check that the composition z
has length equal to number of components, and sums to one.
Args:
z (Iterable(float)) :
The composition
Raises:
IndexError :
If number of fractions does not match number of components.
ValueError :
If fractions do not sum to unity.
Deprecated methods
Deprecated methods are not maintained, and may be removed in the future.
Table of contents
_Functional__density_profile_twophase(self, rho_left, rho_right, T, grid, rho_0=None, constraints=None)
adsorbed_mean_density(self, profile)
Compute the mean density of an adsorbed film.
Args:
profile (Profile) :
The density profile
Returns:
float :
The mean density.
adsorbed_thickness(self, profile)
Find the thickness of an adsorbed film.
Args:
profile (Profile) :
The density profile
Returns:
float :
The thickness of the adsorbed layer.
density_profile_NT(self, rho1, rho2, T, grid, rho, rho_is_frac, rho_0=None)
density_profile_muT(self, rho1, rho2, T, grid, rho, rho_is_frac, rho_0=None)
find_non_bulk_idx(self, profile, rho_b, tol=0.01, start_idx=-1)
Possibly no longer working, used to find the the first index in a Profile which is no longer considered a point in the bulk phase, by checking the change in density and comparing to tol
.
Args:
profile (Profile) :
The density profile
rho_b (float) :
The bulk density
tol (float) :
Tolerance for relative change in density within bulk.
start_idx (int) :
Where to start searching. If start_idx < 0, search goes “right-to-left”, otherwise “left-to-right”.
Returns:
int :
The index at which the bulk ends.
interface_thickness(self, profile, positions=False)
Find the thickness of an interface.
Args:
profile (Profile) :
The density profile
positions (bool) :
Also return the position where the interface starts and stops.
Returns:
float :
The thickness of the interface.