API Reference
This page contains the API reference for the poromics package.
Metrics (poromics)
Convenience pipelines for computing transport properties. These are the main entry points for most users.
poromics
Modules:
-
cli– -
julia_helpers– -
simulation– -
utils–
Classes:
-
PermeabilityResult–Results from an LBM flow / permeability simulation.
-
SimulationResult–Base class for simulation results.
-
TortuosityResult–Results from a tortuosity / effective diffusivity simulation.
Functions:
-
permeability_lbm–Compute absolute permeability using LBM (D3Q19 MRT).
-
tortuosity_fd–Compute tortuosity via Julia FD solver.
-
tortuosity_lbm–Compute tortuosity and effective diffusivity using LBM (D3Q7 BGK).
PermeabilityResult
PermeabilityResult(
im,
axis,
porosity,
k,
u_darcy,
u_pore,
velocity,
kinematic_pressure,
pressure=None,
*,
converged=True,
n_iterations=None,
_velocity_lu=None,
_rho_lu=None,
_rho_out=None,
_k_lu=None,
_u_darcy_lu=None,
_u_pore_lu=None,
)
Bases: SimulationResult
Results from an LBM flow / permeability simulation.
Use rescale to reinterpret the simulation for a different
voxel size, fluid viscosity, or fluid density without rerunning
the solver.
Parameters:
-
(imndarray) –The boolean image used in the simulation.
-
(axisint) –The axis along which flow was computed.
-
(porosityfloat) –Pore volume fraction.
-
(kfloat) –Permeability in m².
-
(u_darcyfloat) –Darcy (superficial) velocity in m/s.
-
(u_porefloat) –Mean pore-space velocity in m/s.
-
(velocity(ndarray, shape(nx, ny, nz, 3))) –Steady-state velocity field in m/s.
-
(kinematic_pressure(ndarray, shape(nx, ny, nz))) –Gauge kinematic pressure (p / rho) in m²/s². Density-free; always populated.
-
(pressure(ndarray or None, shape(nx, ny, nz)), default:None) –Gauge pressure in Pa. Populated only when a fluid density was provided (
rhoinpermeability_lbmorrescale). -
(convergedbool, default:True) –Whether the solver reached the requested tolerance. False means the reported k / velocity are from a pre-steady-state field and should not be trusted without further iteration.
-
(n_iterationsint or None, default:None) –Iterations the solver took. None for non-iterative backends.
Methods:
-
plot_pressure–Plot gauge pressure field on a 2D slice.
-
plot_velocity–Plot velocity magnitude and streamlines on a 2D slice.
-
rescale–Reinterpret the simulation for different physical parameters.
Source code in src/poromics/_metrics.py
plot_pressure
Plot gauge pressure field on a 2D slice.
Parameters:
-
(zint or None, default:None) –Slice index along the third axis. Defaults to nz // 2.
-
(axAxes or None, default:None) –If provided, plot on this axes. If None, create a new figure.
-
(kinematicbool, default:False) –Plot
kinematic_pressure(m²/s²) instead ofpressure(Pa). Useful when no fluid density was provided.
Returns:
-
fig(Figure) – -
ax(Axes) –
Source code in src/poromics/_metrics.py
plot_velocity
Plot velocity magnitude and streamlines on a 2D slice.
Parameters:
-
(zint or None, default:None) –Slice index along the third axis. Defaults to nz // 2.
-
(axAxes or None, default:None) –If provided, plot velocity magnitude only on this axes. If None, create a side-by-side figure (magnitude + streamlines).
Returns:
-
fig(Figure) – -
axes(ndarray of Axes (if ax is None) or Axes) –
Source code in src/poromics/_metrics.py
rescale
rescale(voxel_size, nu, rho=None)
Reinterpret the simulation for different physical parameters.
Returns a new PermeabilityResult with recomputed physical
quantities. The underlying lattice-unit fields are unchanged,
so no solver re-run is needed. This is valid because
permeability depends only on geometry, and the Stokes equations
are linear.
Parameters:
-
(voxel_sizefloat) –Physical voxel edge length in metres.
-
(nufloat) –Kinematic viscosity in m²/s.
-
(rhofloat or None, default:None) –Fluid density in kg/m³. Required for pressure conversion to Pa. If None, the
pressurefield is omitted (set to None);kinematic_pressureis always populated.
Returns:
-
result(PermeabilityResult) –
Source code in src/poromics/_metrics.py
SimulationResult
Base class for simulation results.
Parameters:
-
(imndarray) –The boolean image used in the simulation.
-
(axisint) –The axis along which the simulation was run.
-
(porosityfloat) –Pore volume fraction.
Source code in src/poromics/_metrics.py
TortuosityResult
TortuosityResult(
im,
axis,
porosity,
tau,
D_eff,
c,
formation_factor=None,
D=None,
*,
converged=True,
n_iterations=None,
)
Bases: SimulationResult
Results from a tortuosity / effective diffusivity simulation.
Tortuosity, effective diffusivity, and the concentration field are
all dimensionless (or normalized), so no rescale method is
provided. See PermeabilityResult.rescale for the flow analogue.
Parameters:
-
(imndarray) –The boolean image used in the simulation.
-
(axisint) –The axis along which diffusion was computed.
-
(porosityfloat) –Pore volume fraction.
-
(taufloat) –Tortuosity factor (>= 1).
-
(D_efffloat) –Normalized effective diffusivity (D_eff / D_0).
-
(cndarray) –Steady-state concentration field.
-
(formation_factorfloat, default:None) –Formation factor F = 1 / D_eff_norm.
-
(Dfloat or ndarray, default:None) –Bulk diffusivity (float for uniform, ndarray for spatially variable).
-
(convergedbool, default:True) –Whether the solver reached the requested tolerance. False means the reported tau / D_eff are from a pre-steady-state field and should not be trusted without further iteration.
-
(n_iterationsint or None, default:None) –Iterations the solver took. None for non-iterative backends.
Methods:
-
plot_concentration–Plot concentration field on a 2D slice.
Source code in src/poromics/_metrics.py
plot_concentration
Plot concentration field on a 2D slice.
Parameters:
-
(zint or None, default:None) –Slice index along the third axis. Defaults to nz // 2.
-
(axAxes or None, default:None) –If provided, plot concentration only on this axes. If None, create a side-by-side figure (pore structure + concentration).
Returns:
-
fig(Figure) – -
axes(ndarray of Axes (if ax is None) or Axes) –
Source code in src/poromics/_metrics.py
permeability_lbm
permeability_lbm(
im,
*,
axis: int,
nu: float = 1e-06,
rho: float | None = None,
voxel_size: float,
tol: float = 0.001,
n_steps: int = 100000,
sparse: bool = False,
verbose: bool = True,
) -> PermeabilityResult
Compute absolute permeability using LBM (D3Q19 MRT).
Solves creeping (Stokes) flow on the pore space of a 3D binary image using the Lattice Boltzmann Method. Permeability is extracted via Darcy's law.
Parameters:
-
(im(ndarray, shape(nx, ny, nz))) –Binary image. True (or 1) = pore, False (or 0) = solid.
-
(axisint) –Axis along which to apply the pressure gradient (0=x, 1=y, 2=z).
-
(nufloat, default:1e-06) –Kinematic viscosity in m²/s. Default 1e-6 (water at ~20 °C).
-
(rhofloat or None, default:None) –Fluid density in kg/m³. Required to return
pressurein pascals; if None,pressureis set to None and onlykinematic_pressure(m²/s²) is populated. Permeability and velocity are independent of density (Stokes regime). -
(voxel_sizefloat) –Physical voxel edge length in metres.
-
(tolfloat, default:0.001) –Convergence tolerance on relative velocity change.
-
(n_stepsint, default:100000) –Maximum number of LBM iterations.
-
(sparsebool, default:False) –Use Taichi sparse storage.
-
(verbosebool, default:True) –Show a rich progress bar. Default False.
Returns:
-
result(PermeabilityResult) –
Source code in src/poromics/_metrics.py
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 | |
tortuosity_fd
tortuosity_fd(
im,
*,
axis: int,
D: ndarray | None = None,
rtol: float = 1e-05,
gpu: bool = True,
verbose: bool = True,
) -> TortuosityResult
Compute tortuosity via Julia FD solver.
By default (POROMICS_JULIA_SUBPROCESS=1), runs Julia in a
persistent subprocess to avoid LLVM symbol collisions with Taichi.
The worker stays alive so Julia's JIT cache is reused across calls.
Set POROMICS_JULIA_SUBPROCESS=0 to run Julia in-process (faster
if Taichi is not used). An error is raised if Taichi was already
initialized in the same process.
Parameters:
-
(imndarray) –The input image.
-
(axisint) –The axis along which to compute tortuosity (0=x, 1=y, 2=z).
-
(Dndarray, default:None) –Diffusivity field. If None, uniform diffusivity of 1.0 is assumed.
-
(rtolfloat, default:1e-05) –Relative tolerance for the solver.
-
(gpubool, default:True) –If True (default), use GPU for computation. Poromics picks a backend based on the platform (Darwin/arm64 → Metal, Linux/x86_64 → CUDA, Windows/AMD64 → CUDA) and installs it lazily on first call. Set
POROMICS_GPU_BACKEND={metal,cuda,amdgpu}to override. When no supported backend is available or the device isn't functional, falls back to CPU with a warning. Set to False to force CPU. -
(verbosebool, default:True) –If True, print additional information during the solution process.
Returns:
-
result(TortuosityResult) –
Raises:
-
RuntimeError–If no percolating paths are found along the specified axis.
Source code in src/poromics/_metrics.py
tortuosity_lbm
tortuosity_lbm(
im,
*,
axis: int,
D: float = 1e-09,
voxel_size: float,
tol: float = 0.001,
n_steps: int = 100000,
n_flux_slices: int = 5,
sparse: bool = False,
verbose: bool = True,
) -> TortuosityResult
Compute tortuosity and effective diffusivity using LBM (D3Q7 BGK).
Solves the steady-state diffusion equation on the pore space of a 3D binary image using the Lattice Boltzmann Method.
Parameters:
-
(im(ndarray, shape(nx, ny, nz))) –Binary image. True (or 1) = pore, False (or 0) = solid.
-
(axisint) –Axis along which to apply the concentration gradient (0=x, 1=y, 2=z).
-
(Dfloat, default:1e-09) –Bulk diffusivity in m²/s. Default 1e-9.
-
(voxel_sizefloat) –Physical voxel edge length in metres.
-
(tolfloat, default:0.001) –Convergence tolerance on relative concentration change.
-
(n_stepsint, default:100000) –Maximum number of LBM iterations.
-
(n_flux_slicesint, default:5) –Number of interior slices to average when computing the flux used to derive
D_effandtau. Default 5. Use 1 for a single-midplane estimate. -
(sparsebool, default:False) –Use Taichi sparse storage.
-
(verbosebool, default:True) –Show a rich progress bar. Default False.
Returns:
-
result(TortuosityResult) –
Source code in src/poromics/_metrics.py
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 | |
Simulation solvers (poromics.simulation)
Lower-level solver classes that accept physical SI units and expose intermediate state for custom post-processing.
simulation
Classes:
-
TransientDiffusion–Transient diffusion solver on 3D voxel images.
-
TransientFlow–Transient single-phase flow solver on 3D voxel images.
TransientDiffusion
Transient diffusion solver on 3D voxel images.
Solves the time-dependent diffusion equation on the pore space using the Lattice Boltzmann Method (D3Q7 BGK). Boundary conditions are Dirichlet (fixed concentration) on the inlet/outlet faces and periodic on the remaining faces.
Parameters:
-
(im(ndarray, shape(nx, ny, nz))) –Binary image. True (or 1) = pore, False (or 0) = solid.
-
(axisint) –Axis along which to apply the concentration gradient (0=x, 1=y, 2=z).
-
(Dfloat) –Bulk diffusivity in m²/s.
-
(voxel_sizefloat) –Physical voxel edge length in metres.
-
(c_infloat, default:1.0) –Inlet concentration. Default 1.0.
-
(c_outfloat, default:0.0) –Outlet concentration. Default 0.0.
-
(sparsebool, default:False) –Use Taichi sparse storage. Default False.
Examples:
>>> solver = TransientDiffusion(im, axis=0, D=1e-9, voxel_size=1e-6)
>>> solver.run(tol=1e-2)
>>> c = solver.concentration
Methods:
-
flux–Mean diffusive flux averaged across interior slices (lattice units).
-
run–Run the solver to steady state.
-
step–Advance by one time step.
Attributes:
-
concentration–Concentration field, shape (nx, ny, nz).
-
converged–Whether the solver has converged (set by
run()). -
dt–Physical time step in seconds.
-
n_iterations–Total number of time steps taken.
-
voxel_size–Voxel edge length in metres.
Source code in src/poromics/simulation/_diffusion.py
concentration
property
Concentration field, shape (nx, ny, nz).
Units match c_in and c_out (default: dimensionless).
flux
Mean diffusive flux averaged across interior slices (lattice units).
Uses Fick's law on the concentration gradient rather than
distribution moments (which are unreliable at Dirichlet faces).
Averages -D_lu * dc/dx_lu across n_slices slices evenly
spaced in the central 60% of the domain, which smooths out
local noise while avoiding boundary-layer artifacts. Equals
the normalized effective diffusivity D_eff/D_0 for a unit
concentration drop across the domain.
Parameters:
-
(axisint or None, default:None) –Axis along which to compute flux. Defaults to the axis used in the constructor.
-
(n_slicesint, default:5) –Number of interior slices to average. Default 5.
Returns:
-
J_mean(float) –
Source code in src/poromics/simulation/_diffusion.py
run
Run the solver to steady state.
Parameters:
-
(n_stepsint, default:100000) –Maximum number of iterations.
-
(tolfloat or None, default:0.001) –Convergence tolerance on relative concentration change. None disables early stopping.
-
(log_everyint, default:500) –Log convergence every this many steps.
-
(verbosebool, default:False) –Show a progress bar. Default False.
Source code in src/poromics/simulation/_diffusion.py
TransientFlow
Transient single-phase flow solver on 3D voxel images.
Solves the incompressible Navier-Stokes equations (Stokes regime) on the pore space using the Lattice Boltzmann Method (D3Q19 MRT). Boundary conditions are fixed-pressure on the inlet/outlet faces and periodic on the remaining faces.
Parameters:
-
(im(ndarray, shape(nx, ny, nz))) –Binary image. True (or 1) = pore, False (or 0) = solid.
-
(axisint) –Axis along which to apply the pressure gradient (0=x, 1=y, 2=z).
-
(nufloat) –Kinematic viscosity in m²/s.
-
(voxel_sizefloat) –Physical voxel edge length in metres.
-
(rhofloat or None, default:None) –Fluid density in kg/m³. Required to expose
pressurein pascals; if None, onlykinematic_pressure(m²/s²) is available. Permeability and velocity are independent of density (Stokes regime), so None is fine for those. -
(rho_infloat, default:1.0) –Inlet lattice density (pressure BC). Default 1.0.
-
(rho_outfloat, default:0.99) –Outlet lattice density (pressure BC). Default 0.99.
-
(sparsebool, default:False) –Use Taichi sparse storage. Default False.
Examples:
>>> solver = TransientFlow(im, axis=0, nu=1e-6, voxel_size=1e-6,
... rho=1000.0)
>>> solver.run(tol=1e-3)
>>> v = solver.velocity # m/s
>>> P = solver.pressure # Pa (gauge, needs rho)
>>> Pk = solver.kinematic_pressure # m²/s² (density-free)
Methods:
Attributes:
-
converged–Whether the solver has converged (set by
run()). -
dt–Physical time step in seconds.
-
kinematic_pressure–Kinematic gauge pressure field in m²/s², shape (nx, ny, nz).
-
n_iterations–Total number of time steps taken.
-
pressure–Gauge pressure field in Pa, shape (nx, ny, nz).
-
velocity–Velocity field in m/s, shape (nx, ny, nz, 3).
-
voxel_size–Voxel edge length in metres.
Source code in src/poromics/simulation/_flow.py
kinematic_pressure
property
Kinematic gauge pressure field in m²/s², shape (nx, ny, nz).
Equals p / rho, i.e. the density-free part of the LBM
equation of state p = rho * cs². Always available,
regardless of whether a fluid density was provided.
pressure
property
Gauge pressure field in Pa, shape (nx, ny, nz).
Relative to the outlet face. Requires the fluid density
rho to have been provided in the constructor; otherwise
use kinematic_pressure (m²/s²) instead.
run
Run the solver to steady state.
Parameters:
-
(n_stepsint, default:100000) –Maximum number of iterations.
-
(tolfloat or None, default:0.001) –Convergence tolerance on relative velocity change. None disables early stopping.
-
(log_everyint, default:500) –Log convergence every this many steps.
-
(verbosebool, default:False) –Show a progress bar. Default False.
Source code in src/poromics/simulation/_flow.py
Julia helpers (poromics.julia_helpers)
Helper functions for interacting with Julia and the Tortuosity.jl package. These are used internally by tortuosity_fd. Feel free to explore them if you're interested in the implementation details.
julia_helpers
Functions:
-
ensure_gpu_backend–Install and load a GPU backend in Julia; verify the device is functional.
-
ensure_julia_deps_ready–Ensures Julia and Tortuosity.jl are installed.
-
import_backend–Imports Tortuosity.jl package from Julia.
-
import_package–Imports a package in Julia and returns the module.
-
init_julia–Initializes Julia and returns the Main module.
-
install_backend–Installs Julia dependencies for Poromics.
-
install_julia–Installs Julia using juliapkg.
-
is_backend_installed–Checks if Tortuosity.jl is installed.
-
is_julia_installed–Checks that Julia is installed.
-
remove_julia_env–Removes the active Julia environment directory.
ensure_gpu_backend
ensure_gpu_backend(Main: Any) -> str | None
Install and load a GPU backend in Julia; verify the device is functional.
Returns the backend package name (e.g. "Metal") when a usable GPU is
available, or None when the caller should fall back to CPU. All
fallback paths emit a warning explaining why.
Parameters:
-
(Mainjuliacall Main module) –
Returns:
-
backend(str or None) –"Metal","CUDA","AMDGPU", orNone.
Source code in src/poromics/julia_helpers.py
ensure_julia_deps_ready
Ensures Julia and Tortuosity.jl are installed.
Args: quiet: If True, suppresses output during installation. Default is False. retry: If True, retries the installation if it fails. Default is True.
Raises: ImportError: If Julia or Tortuosity.jl cannot be installed.
Source code in src/poromics/julia_helpers.py
import_backend
Imports Tortuosity.jl package from Julia.
Args: Main: Julia Main module. Default is None. If None, the Main module will be initialized.
Returns: backend: Handle to the Tortuosity.jl package.
Raises: ImportError: If Julia is not installed or the package is not found.
Source code in src/poromics/julia_helpers.py
import_package
Imports a package in Julia and returns the module.
Args: package_name: Name of the Julia package to import. Main: Julia Main module. error: If True, raises an error if the package is not found. Default is False.
Returns: package: Handle to the imported package.
Raises: ImportError: If the package is not found and error is True.
Source code in src/poromics/julia_helpers.py
init_julia
Initializes Julia and returns the Main module.
Args: quiet: If True, suppresses the output of Julia initialization. Default is False.
Returns: Main: The Julia Main module.
Raises: ImportError: If Julia is not installed.
Source code in src/poromics/julia_helpers.py
install_backend
Installs Julia dependencies for Poromics.
Args: quiet: If True, suppresses output during installation. Default is False.
Raises: ImportError: If Julia is not installed.
Source code in src/poromics/julia_helpers.py
install_julia
Installs Julia using juliapkg.
Args: quiet: If True, suppresses output during installation. Default is False.
Source code in src/poromics/julia_helpers.py
is_backend_installed
Checks if Tortuosity.jl is installed.
Args: Main: Julia Main module. Default is None. If None, it will be initialized. error: If True, raises an error if backend is not found. Default is False.
Returns: flag: True if the package is installed, False otherwise.
Raises: ImportError: If Julia is not installed or backend is not found and error is True.
Source code in src/poromics/julia_helpers.py
is_julia_installed
Checks that Julia is installed.
Args: error: If True, raises an error if Julia is not found. Default is False.
Returns: flag: True if Julia is installed, False otherwise.
Raises: ImportError: If Julia is not installed and error is True.
Source code in src/poromics/julia_helpers.py
remove_julia_env
Removes the active Julia environment directory.
When Julia or its dependencies are corrupted, this is a possible fix.