Systems
A System describes what you want to solve: dimensionality, density, temperature, and the interaction potential. The package exports two neutral system types and two charged wrappers:
SimpleFluid— single componentSimpleMixture— multi-component (mixtures)SimpleChargedFluid— one-component plasma (OCP): a single mobile charged species in a uniform neutralizing backgroundSimpleChargedMixture— electrolyte mixture: multiple mobile charged species (no background; must be electroneutral)
| Type | Components | ρ (density) input | evaluate_potential return |
|---|---|---|---|
SimpleFluid | 1 | Number | Number |
SimpleMixture | ≥ 2 | AbstractVector (length = Ns) | Ns×Ns matrix (e.g. SMatrix) |
SimpleChargedFluid | 1 + background | (in base) | (from base) |
SimpleChargedMixture | ≥ 2 | (in base) | (from base) |
Internally, for mixtures the density vector is stored as a diagonal matrix with StaticArrays.SVector storage for performance.
SimpleFluid
SimpleFluid assumes rotationally symmetric pair interactions (depend only on the center-to-center distance) and no external field.
OrnsteinZernike.SimpleFluid — TypeSimpleFluid{dims,Tρ,TkT,P} <: AbstractSingleComponentHomogeneous, isotropic single-component system with a scalar-valued potential.
Construct with:
SimpleFluid(dims, ρ::Number, kBT, potential)julia
Fields:
- ρ::Number — number density
- kBT — thermal energy
- potential::P — scalar-valued interaction potential (
evaluate_potential(potential, r)::Number)
Example: 2D Lennard–Jones (single component)
using OrnsteinZernike
potential = LennardJones(1.0, 1.0) # ϵ=1, σ=1
kBT = 1.0
ρ = 0.5
dims = 2
system = SimpleFluid(dims, ρ, kBT, potential)2D SimpleFluid (single component):
ρ = 0.5
kBT = 1.0
potential = LennardJones{Float64, Float64}(1.0, 1.0)
SimpleMixture
SimpleMixture is for multi-component systems. Pass a vector of species densities; the potential must evaluate to an Ns×Ns matrix giving all pair interactions.
OrnsteinZernike.SimpleMixture — TypeSimpleMixture{dims,Ns,Tρ,TkT,P} <: AbstractMixtureHomogeneous, isotropic mixture with a matrix-valued potential.
Construct with:
SimpleMixture(dims, ρ::AbstractVector, kBT, potential)julia
Notes:
ρis converted to a diagonal matrix withStaticArrays.SVectorstorage (as before).evaluate_potential(potential, r)must return anNs×Nsmatrix (e.g.,StaticArrays.SMatrix{Ns,Ns}).
Example: 3D 10-component hard-sphere mixture
D = collect(0.1:0.1:1.0) # species diameters
potential = HardSpheres(D)
kBT = 1.0
ρ = fill(0.1, 10) # number densities per species
dims = 3
system = SimpleMixture(dims, ρ, kBT, potential)3D SimpleMixture (Ns=10):
ρ = [0.1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.1 0.0 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.1 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.1 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.1 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0.0; 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.1]
kBT = 1.0
potential = HardSpheres{StaticArraysCore.SMatrix{10, 10, Float64, 100}}([0.1 0.15000000000000002 0.2 0.25 0.3 0.35 0.39999999999999997 0.45 0.5 0.55; 0.15000000000000002 0.2 0.25 0.30000000000000004 0.35 0.4 0.44999999999999996 0.5 0.55 0.6; 0.2 0.25 0.3 0.35 0.4 0.44999999999999996 0.5 0.55 0.6 0.65; 0.25 0.30000000000000004 0.35 0.4 0.45 0.5 0.55 0.6000000000000001 0.65 0.7; 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75; 0.35 0.4 0.44999999999999996 0.5 0.55 0.6 0.6499999999999999 0.7 0.75 0.8; 0.39999999999999997 0.44999999999999996 0.5 0.55 0.6 0.6499999999999999 0.7 0.75 0.8 0.85; 0.45 0.5 0.55 0.6000000000000001 0.65 0.7 0.75 0.8 0.8500000000000001 0.9; 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.8500000000000001 0.9 0.95; 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1.0])
Charged systems
SimpleChargedFluid — One-Component Plasma (OCP)
SimpleChargedFluid models a single mobile charged species embedded in a uniform neutralizing background (“jellium”). This means you do not need a counter-ion species: electroneutrality is enforced by the background.
- Background charge density is implicitly
ρ_bg = − ρ · z(not mobile, not part of the potential; it only neutralizes and fixes the small-k behavior). - Debye screening uses mobile charges only:
κ_D^2 = 4π ℓ_B ρ z^2(in 3D reduced units). - The solver handles the
k→0Coulomb singularity via an Ewald-like split; background terms cancel the divergent constants so structure is well-defined. - Use
SimpleChargedMixtureinstead if you want explicit co-/counter-ions (no background, mixture must be electroneutral).
OrnsteinZernike.SimpleChargedFluid — TypeSimpleChargedFluid{dims,Tρ,TkT,P,Tz} <: AbstractSingleComponentSingle-component electrolyte wrapper (one-component plasma). Keeps electrostatics (charges, Bjerrum length, split κ) as system-level state; short-range/core physics remain in potential.
Fields:
- base::SimpleFluid — underlying neutral single-component system
- z::Tz — charge (in units of e)
- ℓB::Float64 — Bjerrum length (in your length units)
- Cd::Float64 — surface area constant for the dimension (4π, 2π, 2) for d = 3, 2, 1
Example: 3D classical OCP (hard-sphere core + Coulomb + neutralizing background)
dims = 3
ρ = 0.5
kBT = 1.0
core = HardSpheres(1.0) # short-range core (optional)
base = SimpleFluid(dims, ρ, kBT, core)
# OCP: single species of charge z in a uniform neutralizing background
z = 1.0
lB = 7.0 # Bjerrum length
sys = SimpleChargedFluid(base, z, lB) # κ chosen automatically (Debye)
# Now use closures/solvers as usual:
# sol = solve(sys, HypernettedChain(); method=NgIteration(M=2000, dr=0.01))3D SimpleChargedFluid (single component):
z = 1.0, ℓB = 7.0
3D SimpleFluid (single component):
ρ = 0.5
kBT = 1.0
potential = HardSpheres{Float64}(1.0)
SimpleChargedMixture — Electrolyte mixtures
SimpleChargedMixture wraps a neutral SimpleMixture and adds per-species charges z. No background is added; the system must satisfy electroneutrality ∑ᵢ ρᵢ zᵢ ≈ 0.
OrnsteinZernike.SimpleChargedMixture — TypeSimpleChargedMixture{dims,Ns,Tρ,TkT,P,Tz} <: AbstractMixtureMixture electrolyte wrapper. Electrostatics live on the system; potentials remain short-range.
Fields:
- base::SimpleMixture — underlying neutral mixture
- z::SVector{Ns,Tz} — per-species charges
- ℓB::Float64 — Bjerrum length
- Cd::Float64 — surface area constant for the dimension (4π, 2π, 2) for d = 3, 2, 1
Example: 3D 1:1 restricted primitive model (RPM)
dims = 3
ρ = [0.3, 0.3] # mobile species densities
kBT = 1.0
hs = HardSpheres([1.0, 1.0]) # per-species diameters (short-range)
base = SimpleMixture(dims, ρ, kBT, hs)
z = [ 1.0, -1.0 ] # charges (must be electroneutral with ρ)
lB = 7.0 # Bjerrum length
sys = SimpleChargedMixture(base, z, lB)3D SimpleChargedMixture (Ns=2):
z = [1.0, -1.0], ℓB = 7.0
3D SimpleMixture (Ns=2):
ρ = [0.3 0.0; 0.0 0.3]
kBT = 1.0
potential = HardSpheres{StaticArraysCore.SMatrix{2, 2, Float64, 4}}([1.0 1.0; 1.0 1.0])
Backward compatibility
The old SimpleLiquid constructors are still available as deprecated aliases:
SimpleLiquid(dims, ρ::Number, kBT, potential) → SimpleFluidSimpleLiquid(dims, ρ::Vector, kBT, potential) → SimpleMixture
You’ll see a deprecation warning; please migrate to the new names.
Common pitfalls
- Density/potential mismatch: If
ρis a vector of lengthNs, thenevaluate_potential(potential, r)must return anNs×Nsmatrix (e.g.,SMatrix{Ns,Ns}). - Units: Ensure the potential and
kBTare in consistent reduced units. - For OCP (
SimpleChargedFluid): Remember the neutralizing background is implicit and non-mobile; use mixtures if you need explicit counter-ions. - For
SimpleChargedMixture: The mixture must be electroneutral:∑ᵢ ρᵢ zᵢ ≈ 0.