### Install SurfPack Source: https://context7.com/thermotools/surfpack/llms.txt Install the library via pip or from the source repository. ```bash pip install surfpack ``` ```bash git clone https://github.com/thermotools/SurfPack.git cd SurfPack pip install . ``` -------------------------------- ### Install SurfPack from source Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/installation.md Clone the repository and install the package locally using pip. ```bash git clone https://github.com/thermotools/SurfPack.git cd SurfPack pip install . ``` -------------------------------- ### Initialize Grid with Domain Start Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Initializes SphericalGrid and PlanarGrid objects with a specified domain start position to define the region of interest relative to the origin. ```python from surfpack import Grid, PlanarGrid, SphericalGrid, Geometry n_points = 500 domain_size = 40 # Å domain_start = 10 # Å grid = SphericalGrid(n_points, domain_size, domain_start=domain_start) ``` ```python from surfpack import Grid, PlanarGrid, SphericalGrid, Geometry n_points = 500 domain_size = 30 # Å domain_start = 10 # Å grid = PlanarGrid(n_points, domain_size, domain_start=domain_start) ``` -------------------------------- ### Install SurfPack via pip Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/installation.md Use this command to install the latest version of SurfPack from the Python Packaging Index. ```bash pip install surfpack ``` -------------------------------- ### GET /density_profiles Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Interfaces for computing density profiles under various conditions such as single component, two-phase, or wall-bounded systems. ```APIDOC ## GET /density_profiles ### Description Computes density profiles for different physical scenarios. ### Methods - density_profile_singlecomp(T, grid, rho_0=None, solver=None, verbose=False) - density_profile_twophase(rho_g, rho_l, T, grid, beta_v=0.5, rho_0=None, solver=None, verbose=0) - density_profile_wall(rho_b, T, grid, Vext=None, rho_0=None, verbose=False) ``` -------------------------------- ### GET /profile_properties Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Interfaces for calculating various profile properties such as adsorbed amount, grand potential, and surface tension. ```APIDOC ## GET /profile_properties ### Description Calculates thermodynamic properties of a fluid profile. ### Methods - N_adsorbed(rho, T, dividing_surface='e') - adsorbtion(rho, T, dividing_surface='e') - correlation(rho, T) - grand_potential(rho, T, Vext=None, bulk=False, property_flag='ir') - surface_tension(rho, T, Vext=None, dividing_surface='equimolar') - tolmann_length(rho, T) ``` -------------------------------- ### GET /bulk_properties Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Interfaces for calculating bulk fluid properties. ```APIDOC ## GET /bulk_properties ### Description Calculates properties of the bulk fluid phase. ### Methods - chemical_potential(rho, T, bulk=True, property_flag='ir') - fugacity(rho, T, Vext=None) - residual_chemical_potential(rho, T, bulk=True) ``` -------------------------------- ### Get All Weights Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/SAFT_methods.md Retrieves all weight functions used for weighted densities. This includes FMT weights and dispersion weights. It can also compute temperature differentials. ```APIDOC ## GET /thermotools/surfpack/weight_functions ### Description Get all the weights used for weighted densities in a 2D array, indexed as weight[][]. This includes FMT weights (w0, w1, w2, w3, wv1, wv2) and dispersion weights. The method can also compute temperature differentials. ### Method GET ### Endpoint /thermotools/surfpack/weight_functions ### Parameters #### Query Parameters - **T** (float) - Required - Temperature in Kelvin [K], used to get hard sphere diameters. - **dwdT** (bool) - Optional - If True, compute temperature differentials. Defaults to False. ### Response #### Success Response (200) - **weights** (2D array [Analytical]) - Weight functions, indexed as weight[][]. #### Response Example ```json { "weights": [ [2.1, 2.2, 2.3, 2.4, 2.5, 2.6], [2.7, 2.8] ] } ``` ``` -------------------------------- ### Compute Radial Distribution Functions Source: https://context7.com/thermotools/surfpack/llms.txt Calculate radial distribution functions using Percus trick with spherical geometry. This example uses Lennard-Jones fluid models and requires setting up a spherical grid and converting reduced units to SurfPack units. ```python import matplotlib.pyplot as plt from surfpack import SphericalGrid # Note: This example uses the LJSpline models for Lennard-Jones fluids from surfpack.LJspline import LJSpline_BH, LJSpline_WCA, LJSpline_UV # Initialize different LJ models dft_bh = LJSpline_BH() # Barker-Henderson dft_uv = LJSJSpline_UV() # UV-model dft_wca = LJSpline_WCA() # Weeks-Chandler-Anderson # Reduced state point T_red = 2.5 rho_red = 0.5 # Using Barker-Henderson model sigma = dft_bh.get_sigma() eps_div_k = dft_bh.get_eps_div_k() # Convert to SurfPack units rho = rho_red / (1e30 * sigma**3) # particles/Angstrom^3 sigma_aa = sigma * 1e10 # Angstrom T = T_red * eps_div_k # Kelvin # Spherical grid for RDF calculation grid = SphericalGrid(500, 5 * sigma_aa) # Compute RDF rdf = dft_bh.radial_distribution_functions([rho], T, grid=grid)[0] # RDF is callable - evaluate at contact print(f"g(sigma) = {rdf(sigma_aa):.4f}") # Plot RDF plt.plot(rdf.grid.z / sigma_aa, rdf) plt.xlabel(r'$r/\sigma$') plt.ylabel('g(r)') plt.title('Radial Distribution Function') plt.axhline(y=1, color='k', linestyle='--', alpha=0.5) plt.show() ``` -------------------------------- ### Get FMT Weights Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/SAFT_methods.md Retrieves the weight functions for the Fundamental Measure Theory (FMT) calculations. It can also compute the derivative with respect to temperature. ```APIDOC ## GET /thermotools/surfpack/weight_functions/fmt ### Description Get the FMT weight functions. This method can also compute the derivative with respect to temperature if `dwdT` is set to True. ### Method GET ### Endpoint /thermotools/surfpack/weight_functions/fmt ### Parameters #### Query Parameters - **T** (float) - Required - Temperature in Kelvin [K]. - **dwdT** (bool) - Optional - If True, compute the derivative with respect to T. Defaults to False. ### Response #### Success Response (200) - **weights** (list[list[WeightFunction]]) - FMT weight functions, indexed as wts[][]. #### Response Example ```json { "weights": [ [1.1, 1.2], [1.3, 1.4] ] } ``` ``` -------------------------------- ### Constructor: __init__ Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/PC_SAFT_methods.md Initializes a PC-SAFT model with specified components, hard-sphere model, and parameter reference. ```APIDOC ## POST /api/pcsaft/__init__ ### Description Initializes a PC-SAFT model. ### Method POST ### Endpoint /api/pcsaft/__init__ ### Parameters #### Request Body - **comps** (str) - Required - Comma separated component identifiers, following thermopack convention. - **hs_model** (SAFT_HardSphere) - Optional - Model to use for the hard-sphere contribution. Default is SAFT_WhiteBear. - **parameter_ref** (str) - Optional - Reference for parameter set to use (see ThermoPack). Default is 'default'. ``` -------------------------------- ### Initialize PC-SAFT DFT Model Source: https://context7.com/thermotools/surfpack/llms.txt Create a PC-SAFT DFT model for pure components or mixtures and access underlying ThermoPack EoS functionality. ```python from surfpack.pcsaft import PC_SAFT # Initialize PC-SAFT DFT for pure hexane dft_hex = PC_SAFT('NC6') # Initialize PC-SAFT DFT for propane-hexane mixture dft_mix = PC_SAFT('C3,NC6') # Access the underlying ThermoPack EoS T = 300 # Kelvin vle, l1ve, l2ve = dft_mix.eos.get_binary_pxy(T) # Get critical temperature Tc = dft_hex.eos.critical([1])[0] print(f"Critical temperature of hexane: {Tc:.2f} K") ``` -------------------------------- ### GET /get_sigma Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/SAFT_methods.md Retrieves the sigma parameter for a specific component. ```APIDOC ## GET /get_sigma ### Description Get the sigma parameter for a given component index. ### Method GET ### Endpoint /get_sigma ### Parameters #### Query Parameters - **ic** (int) - Required - Component index (zero-indexed) ### Response #### Success Response (200) - **value** (float) - Model sigma-parameter [m] ``` -------------------------------- ### Initialize PC-SAFT DFT Model Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Initializes a PC-SAFT DFT model for a mixture of components. Ensure ThermoPack has parameters for the specified components. ```python from surfpack.pcsaft import PC_SAFT dft = PC_SAFT('C3,NC6') # Initialise PC-SAFT DFT model for propane-hexane mixture ``` -------------------------------- ### get_load_dir Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Get the current directory used to search and load Profiles. ```APIDOC ## get_load_dir ### Description Get the current directory used to search and load Profiles. ### Response - **str** - Path to the current load directory ``` -------------------------------- ### Configure Custom Solvers for Density Profiles Source: https://context7.com/thermotools/surfpack/llms.txt Tune numerical solvers for difficult convergence problems using SequentialSolver and GridRefiner. This allows for more control over the iterative process and grid refinement strategies. ```python import matplotlib.pyplot as plt from surfpack.solvers import SequentialSolver, GridRefiner from surfpack import PlanarGrid from surfpack.pcsaft import PC_SAFT dft = PC_SAFT('NC6') T = 400 # Kelvin # Create custom sequential solver solver = SequentialSolver('NT') # NT-specification problem # Add solvers to be called sequentially # Start with careful Picard iteration solver.add_picard(1e-3, mixing_alpha=0.01) # More aggressive Picard solver.add_picard(1e-4, mixing_alpha=0.05) # Switch to Anderson acceleration solver.add_anderson(1e-6, beta_mix=0.02) # Final refinement with aggressive Anderson solver.add_anderson(1e-10, beta_mix=0.05) grid = PlanarGrid(100, 50) rho = dft.density_profile_tp(T, 1e5, [1], grid, solver=solver, verbose=True) plt.plot(grid.z, rho[0]) plt.xlabel('Position [Angstrom]') plt.ylabel('Density [particles/Angstrom^3]') plt.show() # Grid refinement for improved efficiency coarse_grid = PlanarGrid(100, 50) fine_grid = PlanarGrid(1000, 50) # Two-step refinement: converge coarse grid first gridref = GridRefiner.init_twostep(solver, coarse_grid, fine_grid, tol=1e-6) # Or multi-step refinement with intermediate grids gridref = GridRefiner.init_nsteps( solver, coarse_grid, fine_grid, n_steps=3, tol_limits=[1e-5, 1e-6] ) rho = dft.density_profile_tp(T, 1e5, [1], fine_grid, solver=gridref, verbose=True) ``` -------------------------------- ### GET /get_caching_id Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/SAFT_methods.md Retrieves the caching identifier for the current SAFT instance. ```APIDOC ## GET /get_caching_id ### Description Retrieves the caching identifier for the current SAFT instance. ### Method GET ### Endpoint /get_caching_id ``` -------------------------------- ### Initialization and Internal Methods Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/SAFT_methods.md Methods for initializing the SAFT-based functional classes and managing the hard-sphere model. ```APIDOC ## __init__(self, comps, eos, hs_model, parameter_ref) ### Description Initializes the SAFT-based functional class. This is inherited by SAFT_VR_Mie and PC_SAFT. ### Parameters - **comps** (str) - Required - Thermopack component string - **eos** (thermo) - Required - Thermopack EoS class - **hs_model** (SAFT_HardSphere) - Optional - A class inheriting from SAFT_HardSphere - **parameter_ref** (str) - Optional - Parameter reference identifier ## __repr__(self) ### Description Returns a string representation of the object including parameters, active contributions, and hard sphere model identifier. ### Returns - **str** - String representation ## refresh_hs_model(self) ### Description Update hard-sphere model such that parameters are in sync. ``` -------------------------------- ### GET /get_weights Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/PC_SAFT_methods.md Retrieves all weights used for weighted densities in a 2D array format. ```APIDOC ## GET /get_weights ### Description Get all the weights used for weighted densities in a 2D array, indexed as weight[][]. ### Parameters #### Query Parameters - **T** (float) - Required - Temperature [K], used to get hard sphere diameters - **dwdT** (bool) - Optional - Compute temperature differentials ### Response #### Success Response (200) - **2D array [Analytical]** - Weight functions, indexed as weight[][] ``` -------------------------------- ### GET /get_chain_weights Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/PC_SAFT_methods.md Retrieves the weight functions for the chain contribution, indexed by weight and component indices. ```APIDOC ## GET /get_chain_weights ### Description Get the weight functions for the chain contribution, indexed as wts[][]. The weights wts[0] correspond to the local density, wts[1] are Eq. 53 in Sauer & Gross (lambda), and wts[1] are Eq. 54 in the same paper. ### Parameters #### Query Parameters - **T** (float) - Required - Temperature [K] - **dwdT** (bool) - Optional - Compute derivative instead. ### Response #### Success Response (200) - **list[list[Analytical]]** - The weight functions, shape (3 * ncomps, ncomps) ``` -------------------------------- ### Compute Density Profiles at Walls with External Potentials Source: https://context7.com/thermotools/surfpack/llms.txt Calculates equilibrium density profiles near walls using Lennard-Jones 9-3, Hard Wall, or Slit Pore external potential models. Requires bulk density, temperature, and grid parameters. ```python import numpy as np import matplotlib.pyplot as plt from scipy.constants import Avogadro, Boltzmann from surfpack.pcsaft import PC_SAFT from surfpack.external_potential import LennardJones93, HardWall, Steele, SlitPore from surfpack import Grid, Geometry, Profile dft = PC_SAFT('C2') # Ethane T = 250 # Kelvin p = 11.61e5 # Pa # Calculate bulk density rho_b = [(1 / dft.eos.specific_volume(T, p, [1], dft.eos.VAPPH)[0]) * Avogadro / 1e30] grid = Grid(1000, Geometry.PLANAR, 30) # Get molecular parameters sigma = dft.get_sigma(0) * 1e10 # Convert to Angstrom eps_div_k = dft.get_eps_div_k(0) # Wall parameters (e.g., carbon wall) sigma_wall = 3.0 eps_div_k_wall = 30.0 # Combined parameters using Lorentz-Berthelot rules sigma_comb = 0.5 * (sigma + sigma_wall) eps_comb = np.sqrt(eps_div_k * eps_div_k_wall) * Boltzmann # Lennard-Jones 9-3 wall potential lj93 = [LennardJones93(sigma_comb, eps_comb)] rho = dft.density_profile_wall(rho_b, T, grid, lj93, verbose=True) plt.plot(grid.z, rho[0], label='LJ 9-3') # Hard wall at 1 Angstrom wall = [HardWall(1, is_pore=False)] rho_hard = dft.density_profile_wall(rho_b, T, grid, wall, verbose=True) plt.plot(grid.z, rho_hard[0], label='Hard Wall') plt.xlabel('Position [Angstrom]') plt.ylabel('Density [particles/Angstrom^3]') plt.legend() plt.title('Density Profiles at Walls') plt.show() ``` ```python # Slit pore geometry pore_width = 30 # Angstrom lj_slitpore = [SlitPore(pore_width, lj93[0])] rho_pore = dft.density_profile_wall(rho_b, T, grid, lj_slitpore, verbose=True) plt.plot(grid.z, rho_pore[0]) plt.xlabel('Position [Angstrom]') plt.ylabel('Density [particles/Angstrom^3]') plt.title(f'Density in Slit Pore (width = {pore_width} Angstrom)') plt.show() ``` -------------------------------- ### Compute Density Profile for Planar Interface (Vapour Phase) Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Computes the density profile of components in a planar interface using PC-SAFT DFT, specifying the vapour phase composition. Requires temperature, vapour composition, and a PlanarGrid. ```python # Specifying the vapour composition y = [0.4, 0.6] rho = dft.density_profile_tz(T, y, grid, z_phase=dft.VAPPH) # Indicating that specified mole fractions apply to vapour plt.plot(rho[0].grid.z, rho[0], label='C3') plt.plot(rho[1].grid.z, rho[1], label='NC6') plt.xlabel(r'Position [Å]') plt.ylabel(r'Density [particles / Å$^3$]') plt.show() ``` -------------------------------- ### GET /get_eps_div_k Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/SAFT_methods.md Retrieves the epsilon parameter divided by Boltzmann's constant for a specific component. ```APIDOC ## GET /get_eps_div_k ### Description Get the epsilon parameter divided by Boltzmann's constant for a given component index. ### Method GET ### Endpoint /get_eps_div_k ### Parameters #### Query Parameters - **ic** (int) - Required - Component index (zero-indexed) ### Response #### Success Response (200) - **value** (float) - Model epsilon-parameter, divided by Boltzmann's constant [K] ``` -------------------------------- ### Compute Adsorption Isotherms Source: https://context7.com/thermotools/surfpack/llms.txt Calculate component adsorption at the interface, utilizing caching for performance. ```python import matplotlib.pyplot as plt import numpy as np from surfpack.pcsaft import PC_SAFT dft = PC_SAFT('NC6,C2') # Hexane-ethane mixture dft.set_cache_dir('saved_profiles') # Cache computed profiles T = 300 # Kelvin ``` -------------------------------- ### Compute Density Profile with External Potential (Hard Wall) Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Computes density profiles for wall adsorption using an external potential, such as HardWall. Requires specifying temperature, pressure, bulk composition, a grid, and a list of external potentials for each component. ```python import matplotlib.pyplot as plt from surfpack.external_potential import HardWall from surfpack import PlanarGrid from surfpack.pcsaft import PC_SAFT dft = PC_SAFT('C3,NC6') # Initialise PC-SAFT DFT model for propane/hexane mixture T = 600 # K p = 1e5 z = [0.2, 0.8] # Bulk composition # The external potential is a list, with one potential for each component Vext = [HardWall(1, is_pore=False), HardWall(1, is_pore=False)] # A hard wall, positioned a 1 Å n_points = 500 domain_size = 30 # Å grid = PlanarGrid(n_points, domain_size) # Setting up grid for computation rho = dft.density_profile_wall_tp(T, p, z, grid, Vext) plt.plot(rho[0].grid.z, rho[0], label='C3') plt.plot(rho[1].grid.z, rho[1], label='NC6') plt.xlabel('Position [Å]') plt.ylabel(r'Density [Å$^{-3}$]') plt.legend() plt.show() ``` -------------------------------- ### Get Dispersion Weights Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/SAFT_methods.md Retrieves the weight functions for the dispersion term. Optionally computes the derivative with respect to temperature. ```APIDOC ## GET /thermotools/surfpack/weight_functions/dispersion ### Description Get the weights for the dispersion term. This method can also compute the derivative with respect to temperature if `dwdT` is set to True. ### Method GET ### Endpoint /thermotools/surfpack/weight_functions/dispersion ### Parameters #### Query Parameters - **T** (float) - Required - Temperature in Kelvin [K]. - **dwdT** (bool) - Optional - If True, compute the derivative with respect to T. Defaults to False. - **d** (1d array) - Optional - Pre-computed Barker-Henderson diameters. - **dd_dT** (1d array) - Optional - Pre-computed temperature derivatives of Barker-Henderson diameters. ### Response #### Success Response (200) - **weights** (2d array of WeightFunction) - The weights for the dispersion weighted densities, indexed as wts[][]. #### Response Example ```json { "weights": [ [0.1, 0.2], [0.3, 0.4] ] } ``` ``` -------------------------------- ### Manage Profile Files and Cache Source: https://context7.com/thermotools/surfpack/llms.txt Load density profiles from JSON files and manage the library's internal cache directories. ```python # Load from file rho_loaded = Profile.load_file('my_profiles/ar_kr_300K.json') # Get/set cache directories separately print(f"Load directory: {dft.get_load_dir()}") print(f"Save directory: {dft.get_save_dir()}") # Clear cache directory (prompts for confirmation) # dft.clear_cache_dir('cache/profiles') ``` -------------------------------- ### Get Weights Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Retrieves the weights for weighted densities in a 2D array, ordered as weight[][]. ```APIDOC ## get_weights(self, T) ### Description Returns the weights for weighted densities in a 2D array, ordered as weight[][]. See arrayshapes.md for a description of the ordering of different arrays. ### Method GET ### Endpoint /thermotools/surfpack/get_weights ### Parameters #### Path Parameters None #### Query Parameters - **T** (float) - Required - Temperature #### Request Body None ### Request Example ``` GET /thermotools/surfpack/get_weights?T=300.0 ``` ### Response #### Success Response (200) - **weights** (list[list[float]]) - A 2D array of weights. #### Response Example ```json { "weights": [[0.1, 0.2], [0.3, 0.4]] } ``` ``` -------------------------------- ### Compute Density Profile for Planar Interface (Liquid Phase) Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Computes the density profile of components in a planar interface using PC-SAFT DFT. Requires specifying temperature, liquid composition, and a PlanarGrid. The grid may be adapted. ```python import matplotlib.pyplot as plt from surfpack.pcsaft import PC_SAFT from surfpack import PlanarGrid dft = PC_SAFT('C3,NC6') # Initialise PC-SAFT DFT model for propane/hexane mixture T = 300 # K x = [0.2, 0.8] # Liquid composition n_points = 500 domain_size = 30 # Å grid = PlanarGrid(n_points, domain_size) # Setting up grid for computation rho = dft.density_profile_tz(T, x, grid, z_phase=dft.LIQPH) # Indicating that the specified mole fractions apply to the liquid # NOTE: The grid may be adapted during computation if it is initially too narrow to fit the profile extending into the bulk # phase on each side of the interface. We should therefore use the grid held by the returned profiles to plot. plt.plot(rho[0].grid.z, rho[0], label='C3') plt.plot(rho[1].grid.z, rho[1], label='NC6') plt.xlabel(r'Position [Å]') plt.ylabel(r'Density [particles / Å$^3$]') plt.show() ``` -------------------------------- ### adsorbtion Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Compute the adsorption of each component on the interface in a given density profile. ```APIDOC ## adsorbtion ### Description Compute the adsorption of each component on the interface in a given density profile. ### Method POST ### Endpoint /thermotools/surfpack/adsorbtion ### Parameters #### Query Parameters - **rho** (list[Profile]) - Required - The density profile for each component [1 / Å^3] - **T** (float) - Optional - Temperature [K], only required if `dividing_surface` is 't' or 'tension' - **dividing_surface** (str) - Optional - The dividing surface to use: 'e' or 'equimolar' for equimolar surface, 't' or 'tension' for surface of tension ### Response #### Success Response (200) - **1D array** (array) - The adsorption of each component [1 / Å^2] ``` -------------------------------- ### Component Parameter Configuration Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/SAFT_methods.md Methods for setting physical parameters for pure components. ```APIDOC ## set_eps_div_k(ic, eps_div_k) - **ic** (int) - Required - Component index (zero-indexed) - **eps_div_k** (float) - Required - epsilon-parameter divided by Boltzmanns constant [K] ## set_pure_assoc_param(ic, eps, beta) - **ic** (int) - Required - Component index (zero indexed) - **eps** (float) - Required - Association energy [J / mol] - **beta** (float) - Required - Association volume [-] ## set_pure_fluid_param(ic, m, sigma, eps_div_k) - **ic** (int) - Required - Component index (zero indexed) - **m** (float) - Required - Segment number [-] - **sigma** (float) - Required - sigma-parameter [m] - **eps_div_k** (float) - Required - epsilon-parameter [K] ## set_segment_number(ic, m) - **ic** (int) - Required - Component index (zero indexed) - **m** (float) - Required - Segment number ## set_sigma(ic, sigma) - **ic** (int) - Required - Component index (zero-indexed) - **sigma** (float) - Required - sigma-parameter [m] ``` -------------------------------- ### Compute Surface Tension for Pure Components Source: https://context7.com/thermotools/surfpack/llms.txt Calculate surface tension over a temperature range for single-component systems. ```python import matplotlib.pyplot as plt from surfpack.pcsaft import PC_SAFT dft = PC_SAFT('NC6') # Pure hexane # Compute surface tension at 10 temperatures from 0.7*Tc to 0.9*Tc # Returns surface tension in J/Angstrom^2 and temperatures in Kelvin surf_tens, temps = dft.surface_tension_singlecomp( n_points=10, t_min=0.7, # 0.7 * critical temperature t_max=0.9 # 0.9 * critical temperature ) # Convert to SI units (J/m^2) for plotting plt.plot(temps, surf_tens * 1e20, 'o-') plt.xlabel('Temperature [K]') plt.ylabel('Surface Tension [J/m^2]') plt.title('Surface Tension of n-Hexane') plt.show() ``` -------------------------------- ### Compute Density Profiles with Two-Phase Specification Source: https://context7.com/thermotools/surfpack/llms.txt Computes density profiles by directly specifying the bulk densities of both phases. Requires saturation properties from an Equation of State. ```python import matplotlib.pyplot as plt from surfpack.pcsaft import PC_SAFT from surfpack import PlanarGrid from scipy.constants import Avogadro dft = PC_SAFT('C2') # Ethane Tc = dft.eos.critical([1])[0] T = Tc - 50 # 50 K below critical x = [1] grid = PlanarGrid(100, 60) # Get saturation properties from EoS p, _ = dft.eos.dew_pressure(T, x) vl, = dft.eos.specific_volume(T, p, x, dft.eos.LIQPH) vg, = dft.eos.specific_volume(T, p, x, dft.eos.VAPPH) # Convert to particle density (particles/Angstrom^3) rho_l = (1 / vl) * Avogadro / 1e30 rho_g = (1 / vg) * Avogadro / 1e30 # Compute profile with explicit bulk densities rho = dft.density_profile_twophase([rho_g], [rho_l], T, grid, verbose=True) plt.plot(rho[0].grid.z, rho[0]) plt.xlabel('Position [Angstrom]') plt.ylabel('Density [particles/Angstrom^3]') plt.title(f'Ethane VLE Interface at T = {T:.1f} K') plt.show() ``` -------------------------------- ### Initialize Grid Objects Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Initializes Grid, PlanarGrid, and SphericalGrid objects with specified number of points, geometry type, and domain size. PlanarGrid and SphericalGrid are direct children of Grid. ```python from surfpack import Grid, PlanarGrid, SphericalGrid, Geometry n_points = 500 domain_size = 30 # Å grid1 = Grid(n_points, Geometry.PLANAR, domain_size) grid2 = PlanarGrid(n_points, domain_size) # Exactly equal to grid1 grid3 = Grid(n_points, Geometry.SPHERICAL, domain_size) grid4 = SphericalGrid(n_points, domain_size) # Exactly equal to grid3 ``` -------------------------------- ### Compute Density Profile at VLE Interface Source: https://context7.com/thermotools/surfpack/llms.txt Computes equilibrium density profiles across a vapor-liquid interface given temperature and liquid composition. Can also specify temperature, pressure, and total composition. Profiles can be saved and loaded. ```python import matplotlib.pyplot as plt from surfpack.pcsaft import PC_SAFT from surfpack import PlanarGrid, Profile from scipy.constants import Avogadro dft = PC_SAFT('C3,NC6') # Propane-hexane mixture T = 300 # Kelvin x = [0.2, 0.8] # Liquid composition grid = PlanarGrid(500, 30) # 500 points, 30 Angstrom domain # Compute density profile specifying liquid composition rho = dft.density_profile_tz(T, x, grid, z_phase=dft.LIQPH) # Plot density profiles (use grid from returned profiles as it may adapt) plt.plot(rho[0].grid.z, rho[0], label='C3') plt.plot(rho[1].grid.z, rho[1], label='NC6') plt.xlabel('Position [Angstrom]') plt.ylabel('Density [particles/Angstrom^3]') plt.legend() plt.title('Density Profile at VLE Interface') plt.show() ``` ```python # Alternative: specify T, P, and total composition z = [0.5, 0.5] # Total composition p = 1e6 # Pressure in Pa rho = dft.density_profile_tp(T, p, z, grid) # Save and load profiles Profile.save_list(rho, 'my_profile.json') rho_loaded = Profile.load_file('my_profile.json') ``` -------------------------------- ### Compute Surface Tension Isotherms for Mixtures Source: https://context7.com/thermotools/surfpack/llms.txt Calculate surface tension as a function of composition for binary mixtures, with optional vapor-liquid equilibrium data. ```python import matplotlib.pyplot as plt from surfpack.pcsaft import PC_SAFT dft = PC_SAFT('C3,NC6') # Propane-hexane mixture T = 300 # Kelvin # Compute surface tension vs. liquid mole fraction surf_tens, x_C3 = dft.surface_tension_isotherm(T, n_points=10) plt.plot(x_C3, surf_tens * 1e20, 'o-') plt.xlabel('Mole fraction Propane in Liquid') plt.ylabel('Surface Tension [J/m^2]') plt.title(f'Surface Tension Isotherm at {T} K') plt.show() # Get additional vapor-liquid equilibrium data surf_tens, lve = dft.surface_tension_isotherm(T, n_points=10, calc_lve=True) fig, axs = plt.subplots(1, 3, figsize=(12, 4)) axs[0].plot(lve[0], surf_tens * 1e20, 'o-') axs[0].set_xlabel('Liquid mole fraction C3') axs[1].plot(lve[1], surf_tens * 1e20, 'o-') axs[1].set_xlabel('Vapor mole fraction C3') axs[2].plot(lve[2] / 1e5, surf_tens * 1e20, 'o-') axs[2].set_xlabel('Pressure [bar]') for ax in axs: ax.set_ylabel('Surface Tension [J/m^2]') plt.tight_layout() plt.show() ``` -------------------------------- ### Compute Density Profile using Temperature, Pressure, and Total Composition Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Computes the density profile using temperature, pressure, and total composition. This method is suitable when the state is determined to be a pure vapor or liquid phase via a TP-flash. ```python # Continiued z = [0.7, 0.3] p = 1e6 T = 300 rho = dft.density_profile_tp(T, p, z, grid) ``` -------------------------------- ### Compute Adsorption Isotherm Source: https://context7.com/thermotools/surfpack/llms.txt Calculates adsorption isotherms and converts units to mol/m^2. Plots results against liquid mole fraction or pressure. ```python ads, x_liq = dft.adsorbtion_isotherm(T, n_points=10) plt.plot(x_liq, ads[0] * 1e20, label='NC6') plt.plot(x_liq, ads[1] * 1e20, label='C2') plt.xlabel('Liquid mole fraction NC6') plt.ylabel('Adsorption [mol/m^2]') plt.legend() plt.show() ``` ```python ads, lve = dft.adsorbtion_isotherm(T, n_points=10, calc_lve=True) plt.plot(lve[2] / 1e5, ads[0] * 1e20, label='NC6') plt.plot(lve[2] / 1e5, ads[1] * 1e20, label='C2') plt.xlabel('Pressure [bar]') plt.ylabel('Adsorption [mol/m^2]') plt.legend() plt.show() ``` ```python ads, x_liq = dft.adsorbtion_isotherm(T, n_points=10, x_min=0.2, x_max=0.8) ``` -------------------------------- ### Compute Surface Tension from Density Profiles Source: https://context7.com/thermotools/surfpack/llms.txt Calculate surface tension at different dividing surfaces (surface of tension, equimolar), adsorption, and Tolman length from a pre-computed density profile. Requires density profile, temperature, and component information. ```python import matplotlib.pyplot as plt from surfpack.pcsaft import PC_SAFT from surfpack import PlanarGrid dft = PC_SAFT('C3,NC6') T = 300 # Kelvin x = [0.3, 0.7] grid = PlanarGrid(500, 30) rho = dft.density_profile_tz(T, x, grid, z_phase=dft.LIQPH) # Compute surface tension at surface of tension gamma_t = dft.surface_tension(rho, T, dividing_surface='t') print(f"Surface tension (surface of tension): {gamma_t * 1e20:.6f} J/m^2") # Compute surface tension at equimolar surface gamma_e = dft.surface_tension(rho, T, dividing_surface='e') print(f"Surface tension (equimolar surface): {gamma_e * 1e20:.6f} J/m^2") # Compute adsorption at equimolar surface ads = dft.adsorbtion(rho, T, dividing_surface='e') print(f"Adsorption C3: {ads[0] * 1e20:.6f} mol/m^2") print(f"Adsorption NC6: {ads[1] * 1e20:.6f} mol/m^2") # Compute Tolman length (curvature correction) tolman = dft.tolmann_length(rho, T) print(f"Tolman length: {tolman:.4f} Angstrom") # Get dividing surface positions z_e = dft.dividing_surface_position(rho, T, dividing_surface='e') z_t = dft.dividing_surface_position(rho, T, dividing_surface='t') print(f"Equimolar surface position: {z_e:.2f} Angstrom") print(f"Surface of tension position: {z_t:.2f} Angstrom") ``` -------------------------------- ### Compute Bulk Thermodynamic Properties Source: https://context7.com/thermotools/surfpack/llms.txt Calculate chemical potential, fugacity, and energy densities using the PC-SAFT functional. ```python from surfpack.pcsaft import PC_SAFT from scipy.constants import Avogadro dft = PC_SAFT('C2') T = 250 # Kelvin # Get bulk density from EoS p = 10e5 # 10 bar v = dft.eos.specific_volume(T, p, [1], dft.eos.VAPPH)[0] rho = [(1 / v) * Avogadro / 1e30] # particles/Angstrom^3 # Chemical potential (J/particle) mu = dft.chemical_potential(rho, T) print(f"Chemical potential: {mu[0]:.4e} J/particle") # Residual chemical potential mu_res = dft.residual_chemical_potential(rho, T) print(f"Residual chemical potential: {mu_res[0]:.4e} J/particle") # Fugacity f = dft.fugacity(rho, T) print(f"Fugacity: {f[0]:.4e}") # Grand potential density (equals negative pressure for bulk) omega = dft.grand_potential(rho, T, bulk=True) print(f"Grand potential density: {omega:.4e} J/Angstrom^3") # Residual Helmholtz energy density a_res = dft.residual_helmholtz_energy_density(rho, T, bulk=True) print(f"Residual Helmholtz energy density: {a_res:.4e} J/Angstrom^3") ``` -------------------------------- ### Saving and loading profiles manually Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Use Profile.save_list and Profile.load_file to persist individual density profiles in a human-readable JSON format. ```python from surfpack import Profile rho = # ... some previously computed profile Profile.save_list(rho, 'path/to/my_profile.json') # Saving the profile rho_saved = Profile.load_file('path/to/my_profile.json') # Retriving the profile ``` -------------------------------- ### Calculation and Utility Methods Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Methods for temperature reduction, surface tension calculation, and internal utility functions. ```APIDOC ## POST /thermotools/surfpack/reduce_temperature ### Description Reduce the temperature in some meaningful manner, using LJ units when possible, doing nothing for hard spheres. ### Method POST ### Endpoint /thermotools/surfpack/reduce_temperature ### Parameters #### Request Body - **T** (float) - Required - The temperature - **c** (float) - Optional - ??? ### Response #### Success Response (200) - **float** : The reduced temperature ``` ```APIDOC ## POST /thermotools/surfpack/surface_of_tension_position ### Description Calculate the position of the surface of tension on a given density profile. ### Method POST ### Endpoint /thermotools/surfpack/surface_of_tension_position ### Parameters #### Request Body - **rho** (list[Profile]) - Required - The density profile for each component [1 / Å^3] - **T** (float) - Required - Temperature [K] ### Response #### Success Response (200) - **float** : The position of the surface of tension [Å] ``` -------------------------------- ### Compute Adsorption Isotherms Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Calculates adsorption isotherms for a mixture, plotting adsorption against liquid mole fraction. Requires LVE data calculation. ```python ads, lve = dft_mix.adsorbtion_isotherm(300, n_points=10, calc_lve=True) plt.plot(lve[0], ads[0], label='C3') plt.plot(lve[0], ads[1], label='NC6') plt.xlabel('Liquid mole fraction Propane') plt.ylabel('Adsorbtion [particles / Å$^2$]') plt.legend() plt.show() ``` -------------------------------- ### surface_tension Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Compute the surface tension. ```APIDOC ## surface_tension ### Description Compute the surface tension. ### Method POST ### Endpoint /thermotools/surfpack/surface_tension ### Parameters #### Query Parameters - **rho** (list[Profile]) - Required - Density profiles [particles / Å^3] - **T** (float) - Required - Temperature [K] - **Vext** (Profile) - Optional - External potential - **dividing_surface** (str) - Optional - The dividing surface to use (default: 'equimolar') ### Response #### Success Response (200) - **float** - The surface tension ``` -------------------------------- ### Surface Tension Isotherm Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Computes the surface tension isotherm. ```APIDOC ## surface_tension_isotherm ### Description Compute the surface tension isotherm ### Method POST (assumed, as it's a computation) ### Endpoint /thermotools/surfpack/surface_tension_isotherm ### Parameters #### Request Body - **T** (float) - Required - Temperature [K] - **n_points** (int) - Optional - Number of points to compute - **dividing_surface** (str) - Optional - Which dividing surface to use ('equimolar' or 'tension') - **solver** (any) - Optional - Solver to use - **rho0** (any) - Optional - Initial density - **calc_lve** (bool) - Optional - Whether to calculate liquid-vapor equilibrium - **verbose** (bool) - Optional - Verbosity level - **cache_dir** (str) - Optional - Directory for caching results ### Response #### Success Response (200) - **result** (any) - Surface tension isotherm data ### Request Example ```json { "T": 300.0, "n_points": 50, "dividing_surface": "equimolar" } ``` ### Response Example ```json { "result": [{"composition": 0.1, "surface_tension": 0.05}] } ``` ``` -------------------------------- ### density_profile_wall_tp Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Calculate equilibrium density profile for a given external potential based on temperature, pressure, and bulk composition. ```APIDOC ## density_profile_wall_tp ### Description Calculate equilibrium density profile for a given external potential. ### Parameters - **T** (float) - Required - Temperature [K] - **p** (float) - Required - Pressure [Pa] - **z** (list[float]) - Required - Bulk composition - **grid** (Grid) - Required - Spatial discretization - **Vext** (ExtPotential) - Optional - External potential as a function of position (default : Vext(r) = 0) - **rho0** (list[Profile]) - Optional - Initial guess for density profiles - **verbose** (bool) - Required - Print progression information during run ### Response - **list[Profile]** - The equilibrium density profiles ``` -------------------------------- ### density_profile_wall Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/Functional_methods.md Calculate equilibrium density profile for a given external potential. ```APIDOC ## density_profile_wall ### Description Calculate equilibrium density profile for a given external potential. Uses lazy evaluation to return a copy of previous result if the same calculation is done several times. ### Parameters #### Request Body - **rho_b** (float) - Required - Bulk density - **T** (float) - Required - Temperature [K] - **grid** (Grid) - Required - Spatial discretisation - **Vext** (object) - Optional - External potential - **rho_0** (list[Profile]) - Optional - Initial guess - **verbose** (bool) - Optional - Print progress info ``` -------------------------------- ### Compute Adsorption with DFT Source: https://github.com/thermotools/surfpack/blob/main/docs/v1.0.0/getting_started.md Computes the adsorption of a system using a converged density profile and temperature. The dividing surface can be specified. ```python ads = dft.adsorbtion(rho, T, dividing_surface='e') # Compute adsorbtion at the equimolar surface ```