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} <: AbstractSingleComponent
Homogeneous, 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} <: AbstractMixture
Homogeneous, isotropic mixture with a matrix-valued potential.
Construct with:
SimpleMixture(dims, ρ::AbstractVector, kBT, potential)
julia
Notes:
ρ
is converted to a diagonal matrix withStaticArrays.SVector
storage (as before).evaluate_potential(potential, r)
must return anNs×Ns
matrix (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→0
Coulomb singularity via an Ewald-like split; background terms cancel the divergent constants so structure is well-defined. - Use
SimpleChargedMixture
instead if you want explicit co-/counter-ions (no background, mixture must be electroneutral).
OrnsteinZernike.SimpleChargedFluid
— TypeSimpleChargedFluid{dims,Tρ,TkT,P,Tz} <: AbstractSingleComponent
Single-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} <: AbstractMixture
Mixture 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) → SimpleFluid
SimpleLiquid(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×Ns
matrix (e.g.,SMatrix{Ns,Ns}
). - Units: Ensure the potential and
kBT
are 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
.